Files
2026-08-27 10:56:38 -06:00

710 lines
32 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp;
internal abstract class UnboundLambdaState
{
private sealed class ReturnInferenceCacheKey
{
public readonly ImmutableArray<TypeWithAnnotations> ParameterTypes;
public readonly ImmutableArray<RefKind> ParameterRefKinds;
public readonly NamedTypeSymbol? TaskLikeReturnTypeOpt;
public static readonly ReturnInferenceCacheKey Empty = new ReturnInferenceCacheKey(ImmutableArray<TypeWithAnnotations>.Empty, ImmutableArray<RefKind>.Empty, null);
private ReturnInferenceCacheKey(ImmutableArray<TypeWithAnnotations> parameterTypes, ImmutableArray<RefKind> parameterRefKinds, NamedTypeSymbol? taskLikeReturnTypeOpt)
{
ParameterTypes = parameterTypes;
ParameterRefKinds = parameterRefKinds;
TaskLikeReturnTypeOpt = taskLikeReturnTypeOpt;
}
public override bool Equals(object? obj)
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
if (this == obj)
{
return true;
}
if (!(obj is ReturnInferenceCacheKey returnInferenceCacheKey) || returnInferenceCacheKey.ParameterTypes.Length != ParameterTypes.Length || !TypeSymbol.Equals(returnInferenceCacheKey.TaskLikeReturnTypeOpt, TaskLikeReturnTypeOpt, (TypeCompareKind)0))
{
return false;
}
for (int i = 0; i < ParameterTypes.Length; i++)
{
if (!returnInferenceCacheKey.ParameterTypes[i].Equals(ParameterTypes[i], (TypeCompareKind)0) || returnInferenceCacheKey.ParameterRefKinds[i] != ParameterRefKinds[i])
{
return false;
}
}
return true;
}
public override int GetHashCode()
{
int num = TaskLikeReturnTypeOpt?.GetHashCode() ?? 0;
ImmutableArray<TypeWithAnnotations>.Enumerator enumerator = ParameterTypes.GetEnumerator();
while (enumerator.MoveNext())
{
num = Hash.Combine<TypeSymbol>(enumerator.Current.Type, num);
}
return num;
}
public static ReturnInferenceCacheKey Create(NamedTypeSymbol? delegateType, bool isAsync)
{
GetFields(delegateType, isAsync, out ImmutableArray<TypeWithAnnotations> parameterTypes, out ImmutableArray<RefKind> parameterRefKinds, out NamedTypeSymbol taskLikeReturnTypeOpt);
if (parameterTypes.IsEmpty && parameterRefKinds.IsEmpty && (object)taskLikeReturnTypeOpt == null)
{
return Empty;
}
return new ReturnInferenceCacheKey(parameterTypes, parameterRefKinds, taskLikeReturnTypeOpt);
}
public static void GetFields(NamedTypeSymbol? delegateType, bool isAsync, out ImmutableArray<TypeWithAnnotations> parameterTypes, out ImmutableArray<RefKind> parameterRefKinds, out NamedTypeSymbol? taskLikeReturnTypeOpt)
{
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
parameterTypes = ImmutableArray<TypeWithAnnotations>.Empty;
parameterRefKinds = ImmutableArray<RefKind>.Empty;
taskLikeReturnTypeOpt = null;
MethodSymbol methodSymbol = DelegateInvokeMethod(delegateType);
if ((object)methodSymbol == null)
{
return;
}
int parameterCount = methodSymbol.ParameterCount;
if (parameterCount > 0)
{
ArrayBuilder<TypeWithAnnotations> instance = ArrayBuilder<TypeWithAnnotations>.GetInstance(parameterCount);
ArrayBuilder<RefKind> instance2 = ArrayBuilder<RefKind>.GetInstance(parameterCount);
ImmutableArray<ParameterSymbol>.Enumerator enumerator = methodSymbol.Parameters.GetEnumerator();
while (enumerator.MoveNext())
{
ParameterSymbol current = enumerator.Current;
instance2.Add(current.RefKind);
instance.Add(current.TypeWithAnnotations);
}
parameterTypes = instance.ToImmutableAndFree();
parameterRefKinds = instance2.ToImmutableAndFree();
}
if (isAsync && methodSymbol.ReturnType is NamedTypeSymbol namedTypeSymbol && !namedTypeSymbol.IsVoidType() && namedTypeSymbol.IsCustomTaskType(out object _))
{
taskLikeReturnTypeOpt = namedTypeSymbol.ConstructedFrom;
}
}
}
private sealed class BindingCacheComparer : IEqualityComparer<(NamedTypeSymbol Type, bool IsExpressionTree)>
{
public static readonly BindingCacheComparer Instance = new BindingCacheComparer();
public bool Equals([AllowNull] (NamedTypeSymbol Type, bool IsExpressionTree) x, [AllowNull] (NamedTypeSymbol Type, bool IsExpressionTree) y)
{
if (x.IsExpressionTree == y.IsExpressionTree)
{
return Symbol.Equals(x.Type, y.Type, (TypeCompareKind)0);
}
return false;
}
public int GetHashCode([DisallowNull] (NamedTypeSymbol Type, bool IsExpressionTree) obj)
{
return Hash.Combine<NamedTypeSymbol>(obj.Type, obj.IsExpressionTree.GetHashCode());
}
}
private UnboundLambda _unboundLambda;
internal readonly Binder Binder;
private ImmutableDictionary<(NamedTypeSymbol Type, bool IsExpressionLambda), BoundLambda>? _bindingCache;
private ImmutableDictionary<ReturnInferenceCacheKey, BoundLambda>? _returnInferenceCache;
private BoundLambda? _errorBinding;
public UnboundLambda UnboundLambda => _unboundLambda;
public abstract MessageID MessageID { get; }
public abstract bool HasSignature { get; }
public abstract bool HasExplicitlyTypedParameterList { get; }
public abstract int ParameterCount { get; }
public abstract bool IsAsync { get; }
public abstract bool IsStatic { get; }
public abstract bool HasParamsArray { get; }
public UnboundLambdaState(Binder binder, bool includeCache)
{
if (includeCache)
{
_bindingCache = ImmutableDictionary<(NamedTypeSymbol, bool), BoundLambda>.Empty.WithComparers(BindingCacheComparer.Instance);
_returnInferenceCache = ImmutableDictionary<ReturnInferenceCacheKey, BoundLambda>.Empty;
}
Binder = binder;
}
public void SetUnboundLambda(UnboundLambda unbound)
{
_unboundLambda = unbound;
}
protected abstract UnboundLambdaState WithCachingCore(bool includeCache);
internal UnboundLambdaState WithCaching(bool includeCache)
{
if (_bindingCache == null != includeCache)
{
return this;
}
return WithCachingCore(includeCache);
}
public abstract string ParameterName(int index);
public abstract bool ParameterIsDiscard(int index);
public abstract SyntaxList<AttributeListSyntax> ParameterAttributes(int index);
public abstract bool HasExplicitReturnType(out RefKind refKind, out TypeWithAnnotations returnType);
public abstract Location ParameterLocation(int index);
public abstract TypeWithAnnotations ParameterTypeWithAnnotations(int index);
public abstract RefKind RefKind(int index);
public abstract ScopedKind DeclaredScope(int index);
public abstract ParameterSyntax? ParameterSyntax(int i);
protected BoundBlock BindLambdaBody(LambdaSymbol lambdaSymbol, Binder lambdaBodyBinder, BindingDiagnosticBag diagnostics)
{
if (lambdaSymbol.DeclaringCompilation?.TestOnlyCompilationData is LambdaBindingData lambdaBindingData)
{
Interlocked.Increment(ref lambdaBindingData.LambdaBindingCount);
}
return BindLambdaBodyCore(lambdaSymbol, lambdaBodyBinder, diagnostics);
}
protected abstract BoundBlock BindLambdaBodyCore(LambdaSymbol lambdaSymbol, Binder lambdaBodyBinder, BindingDiagnosticBag diagnostics);
protected abstract BoundExpression? GetLambdaExpressionBody(BoundBlock body);
protected abstract BoundBlock CreateBlockFromLambdaExpressionBody(Binder lambdaBodyBinder, BoundExpression expression, BindingDiagnosticBag diagnostics);
public virtual void GenerateAnonymousFunctionConversionError(BindingDiagnosticBag diagnostics, TypeSymbol targetType)
{
Binder.GenerateAnonymousFunctionConversionError(diagnostics, _unboundLambda.Syntax, _unboundLambda, targetType);
}
public BoundLambda Bind(NamedTypeSymbol delegateType, bool isTargetExpressionTree)
{
bool flag = Binder.InExpressionTree || isTargetExpressionTree;
if (!_bindingCache.TryGetValue((delegateType, flag), out BoundLambda value))
{
value = ReallyBind(delegateType, flag);
return ImmutableInterlocked.GetOrAdd(ref _bindingCache, (delegateType, flag), value);
}
return value;
}
internal IEnumerable<TypeSymbol> InferredReturnTypes()
{
bool any = false;
foreach (BoundLambda value in _returnInferenceCache.Values)
{
TypeWithAnnotations typeWithAnnotations = value.InferredReturnType.TypeWithAnnotations;
if (typeWithAnnotations.HasType)
{
any = true;
yield return typeWithAnnotations.Type;
}
}
if (!any)
{
TypeWithAnnotations typeWithAnnotations2 = BindForErrorRecovery().InferredReturnType.TypeWithAnnotations;
if (typeWithAnnotations2.HasType)
{
yield return typeWithAnnotations2.Type;
}
}
}
private static MethodSymbol? DelegateInvokeMethod(NamedTypeSymbol? delegateType)
{
return delegateType.GetDelegateType()?.DelegateInvokeMethod;
}
private static TypeWithAnnotations DelegateReturnTypeWithAnnotations(MethodSymbol? invokeMethod, out RefKind refKind)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected I4, but got Unknown
if ((object)invokeMethod == null)
{
refKind = (RefKind)0;
return default(TypeWithAnnotations);
}
refKind = (RefKind)(int)invokeMethod.RefKind;
return invokeMethod.ReturnTypeWithAnnotations;
}
internal (ImmutableArray<RefKind>, ArrayBuilder<ScopedKind>, ImmutableArray<TypeWithAnnotations>, bool) CollectParameterProperties()
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
ArrayBuilder<RefKind> instance = ArrayBuilder<RefKind>.GetInstance(ParameterCount);
ArrayBuilder<ScopedKind> instance2 = ArrayBuilder<ScopedKind>.GetInstance(ParameterCount);
ArrayBuilder<TypeWithAnnotations> instance3 = ArrayBuilder<TypeWithAnnotations>.GetInstance(ParameterCount);
bool item = false;
for (int i = 0; i < ParameterCount; i++)
{
RefKind val = RefKind(i);
ScopedKind val2 = DeclaredScope(i);
TypeWithAnnotations typeWithAnnotations = ParameterTypeWithAnnotations(i);
if ((int)val2 == 0 && ParameterHelpers.IsRefScopedByDefault(Binder.UseUpdatedEscapeRules, val))
{
val2 = (ScopedKind)1;
if (_unboundLambda.ParameterAttributes(i).Any())
{
item = true;
}
}
instance.Add(val);
instance2.Add(val2);
instance3.Add(typeWithAnnotations);
}
ImmutableArray<RefKind> item2 = instance.ToImmutableAndFree();
ImmutableArray<TypeWithAnnotations> item3 = instance3.ToImmutableAndFree();
return (item2, instance2, item3, item);
}
internal NamedTypeSymbol? InferDelegateType()
{
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Invalid comparison between Unknown and I4
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
if (!HasExplicitlyTypedParameterList)
{
return null;
}
(ImmutableArray<RefKind>, ArrayBuilder<ScopedKind>, ImmutableArray<TypeWithAnnotations>, bool) tuple = CollectParameterProperties();
ImmutableArray<RefKind> item = tuple.Item1;
ArrayBuilder<ScopedKind> item2 = tuple.Item2;
ImmutableArray<TypeWithAnnotations> item3 = tuple.Item3;
bool item4 = tuple.Item4;
LambdaSymbol lambdaSymbol = CreateLambdaSymbol(Binder.ContainingMemberOrLambda, default(TypeWithAnnotations), item3, item, (RefKind)0);
if (!HasExplicitReturnType(out var refKind, out var returnType))
{
ExecutableCodeBinder executableCodeBinder = new ExecutableCodeBinder(_unboundLambda.Syntax, lambdaSymbol, GetWithParametersBinder(lambdaSymbol, Binder));
BoundBlock block = BindLambdaBody(lambdaSymbol, executableCodeBinder, BindingDiagnosticBag.Discarded);
ArrayBuilder<(BoundReturnStatement, TypeWithAnnotations)> instance = ArrayBuilder<(BoundReturnStatement, TypeWithAnnotations)>.GetInstance();
BoundLambda.BlockReturns.GetReturnTypes(instance, block);
InferredLambdaReturnType inferredLambdaReturnType = BoundLambda.InferReturnType(instance, _unboundLambda, executableCodeBinder, null, IsAsync, Binder.Conversions);
returnType = inferredLambdaReturnType.TypeWithAnnotations;
refKind = inferredLambdaReturnType.RefKind;
if (!returnType.HasType && inferredLambdaReturnType.NumExpressions > 0)
{
return null;
}
}
if (item4)
{
for (int i = 0; i < ParameterCount; i++)
{
if ((int)DeclaredScope(i) == 0 && (int)item2[i] == 1 && _unboundLambda.ParameterAttributes(i).Any())
{
item2[i] = lambdaSymbol.Parameters[i].EffectiveScope;
}
}
}
if (!returnType.HasType)
{
returnType = TypeWithAnnotations.Create(Binder.Compilation.GetSpecialType((SpecialType)6));
}
return Binder.GetMethodGroupOrLambdaDelegateType(_unboundLambda.Syntax, lambdaSymbol, item2.ToImmutableAndFree(), ImmutableArrayExtensions.SelectAsArray<ParameterSymbol, bool>(lambdaSymbol.Parameters, (Func<ParameterSymbol, bool>)((ParameterSymbol p) => p.HasUnscopedRefAttribute)), refKind, returnType);
}
private BoundLambda ReallyBind(NamedTypeSymbol delegateType, bool inExpressionTree)
{
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Invalid comparison between Unknown and I4
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
RefKind refKind;
TypeWithAnnotations typeWithAnnotations = DelegateReturnTypeWithAnnotations(DelegateInvokeMethod(delegateType), out refKind);
BindingDiagnosticBag instance = BindingDiagnosticBag.GetInstance(withDiagnostics: true, _unboundLambda.WithDependencies);
CSharpCompilation compilation = Binder.Compilation;
ReturnInferenceCacheKey returnInferenceCacheKey = ReturnInferenceCacheKey.Create(delegateType, IsAsync);
LambdaSymbol lambdaSymbol;
Binder binder;
BoundBlock boundBlock;
if (!inExpressionTree && (int)refKind == 0 && _returnInferenceCache.TryGetValue(returnInferenceCacheKey, out BoundLambda value))
{
BoundExpression lambdaExpressionBody = GetLambdaExpressionBody(value.Body);
if (lambdaExpressionBody != null && (lambdaSymbol = value.Symbol).RefKind == refKind && (object)LambdaSymbol.InferenceFailureReturnType != lambdaSymbol.ReturnType && lambdaSymbol.ReturnTypeWithAnnotations.Equals(typeWithAnnotations, (TypeCompareKind)0))
{
binder = value.Binder;
boundBlock = CreateBlockFromLambdaExpressionBody(binder, lambdaExpressionBody, instance);
((BindingDiagnosticBag<AssemblySymbol>)(object)instance).AddRange(value.Diagnostics, false);
goto IL_0115;
}
}
lambdaSymbol = CreateLambdaSymbol(Binder.ContainingMemberOrLambda, typeWithAnnotations, returnInferenceCacheKey.ParameterTypes, returnInferenceCacheKey.ParameterRefKinds, refKind);
binder = new ExecutableCodeBinder(_unboundLambda.Syntax, lambdaSymbol, GetWithParametersBinder(lambdaSymbol, Binder), inExpressionTree ? BinderFlags.InExpressionTree : BinderFlags.None);
boundBlock = BindLambdaBody(lambdaSymbol, binder, instance);
goto IL_0115;
IL_0115:
lambdaSymbol.GetDeclarationDiagnostics(instance);
if ((int)lambdaSymbol.RefKind == 3)
{
compilation.EnsureIsReadOnlyAttributeExists(instance, lambdaSymbol.DiagnosticLocation, modifyCompilation: false);
}
ImmutableArray<ParameterSymbol> parameters = lambdaSymbol.Parameters;
ParameterHelpers.EnsureRefKindAttributesExist(compilation, parameters, instance, modifyCompilation: false);
if (typeWithAnnotations.HasType)
{
if (compilation.ShouldEmitNativeIntegerAttributes(typeWithAnnotations.Type))
{
compilation.EnsureNativeIntegerAttributeExists(instance, lambdaSymbol.DiagnosticLocation, modifyCompilation: false);
}
if (compilation.ShouldEmitNullableAttributes(lambdaSymbol) && typeWithAnnotations.NeedsNullableAttribute())
{
compilation.EnsureNullableAttributeExists(instance, lambdaSymbol.DiagnosticLocation, modifyCompilation: false);
}
}
ParameterHelpers.EnsureNativeIntegerAttributeExists(compilation, parameters, instance, modifyCompilation: false);
ParameterHelpers.EnsureScopedRefAttributeExists(compilation, parameters, instance, modifyCompilation: false);
ParameterHelpers.EnsureNullableAttributeExists(compilation, lambdaSymbol, parameters, instance, modifyCompilation: false);
ValidateUnsafeParameters(instance, returnInferenceCacheKey.ParameterTypes);
if (ControlFlowPass.Analyze(compilation, lambdaSymbol, boundBlock, ((BindingDiagnosticBag)instance).DiagnosticBag))
{
if (Microsoft.CodeAnalysis.CSharp.Binder.MethodOrLambdaRequiresValue(lambdaSymbol, Binder.Compilation))
{
instance.Add(ErrorCode.ERR_AnonymousReturnExpected, lambdaSymbol.DiagnosticLocation, MessageID.Localize(), delegateType);
}
else
{
boundBlock = FlowAnalysisPass.AppendImplicitReturn(boundBlock, lambdaSymbol);
}
}
if (IsAsync && !ErrorFacts.PreventsSuccessfulDelegateConversion(((BindingDiagnosticBag)instance).DiagnosticBag) && typeWithAnnotations.HasType && !typeWithAnnotations.IsVoidType() && !lambdaSymbol.IsAsyncEffectivelyReturningTask(compilation) && !lambdaSymbol.IsAsyncEffectivelyReturningGenericTask(compilation))
{
instance.Add(ErrorCode.ERR_CantConvAsyncAnonFuncReturns, lambdaSymbol.DiagnosticLocation, lambdaSymbol.MessageID.Localize(), delegateType);
}
return new BoundLambda(_unboundLambda.Syntax, _unboundLambda, boundBlock, ((BindingDiagnosticBag<AssemblySymbol>)(object)instance).ToReadOnlyAndFree(), binder, delegateType, default(InferredLambdaReturnType))
{
WasCompilerGenerated = _unboundLambda.WasCompilerGenerated
};
}
internal LambdaSymbol CreateLambdaSymbol(Symbol containingSymbol, TypeWithAnnotations returnType, ImmutableArray<TypeWithAnnotations> parameterTypes, ImmutableArray<RefKind> parameterRefKinds, RefKind refKind)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
return new LambdaSymbol(Binder, Binder.Compilation, containingSymbol, _unboundLambda, parameterTypes, parameterRefKinds, refKind, returnType);
}
internal LambdaSymbol CreateLambdaSymbol(NamedTypeSymbol delegateType, Symbol containingSymbol)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
RefKind refKind;
TypeWithAnnotations returnType = DelegateReturnTypeWithAnnotations(DelegateInvokeMethod(delegateType), out refKind);
ReturnInferenceCacheKey.GetFields(delegateType, IsAsync, out ImmutableArray<TypeWithAnnotations> parameterTypes, out ImmutableArray<RefKind> parameterRefKinds, out NamedTypeSymbol _);
return CreateLambdaSymbol(containingSymbol, returnType, parameterTypes, parameterRefKinds, refKind);
}
private void ValidateUnsafeParameters(BindingDiagnosticBag diagnostics, ImmutableArray<TypeWithAnnotations> targetParameterTypes)
{
if (!HasSignature)
{
return;
}
int num = Math.Min(targetParameterTypes.Length, ParameterCount);
for (int i = 0; i < num; i++)
{
if (targetParameterTypes[i].Type.ContainsPointer())
{
Binder.ReportUnsafeIfNotAllowed(ParameterLocation(i), diagnostics);
}
}
}
private BoundLambda ReallyInferReturnType(NamedTypeSymbol? delegateType, ImmutableArray<TypeWithAnnotations> parameterTypes, ImmutableArray<RefKind> parameterRefKinds)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
RefKind refKind;
TypeWithAnnotations returnType;
bool flag = HasExplicitReturnType(out refKind, out returnType);
var (lambdaSymbol, boundBlock, executableCodeBinder, bindingDiagnosticBag) = BindWithParameterAndReturnType(parameterTypes, parameterRefKinds, returnType, refKind);
InferredLambdaReturnType inferredReturnType;
if (flag)
{
inferredReturnType = new InferredLambdaReturnType(0, isExplicitType: true, hadExpressionlessReturn: false, refKind, returnType, inferredFromFunctionType: false, ImmutableArray<DiagnosticInfo>.Empty, ImmutableArray<AssemblySymbol>.Empty);
}
else
{
ArrayBuilder<(BoundReturnStatement, TypeWithAnnotations)> instance = ArrayBuilder<(BoundReturnStatement, TypeWithAnnotations)>.GetInstance();
BoundLambda.BlockReturns.GetReturnTypes(instance, boundBlock);
inferredReturnType = BoundLambda.InferReturnType(instance, _unboundLambda, executableCodeBinder, delegateType, lambdaSymbol.IsAsync, executableCodeBinder.Conversions);
refKind = inferredReturnType.RefKind;
returnType = inferredReturnType.TypeWithAnnotations;
if (!returnType.HasType)
{
returnType = (((object)delegateType == null && instance.Count == 0) ? TypeWithAnnotations.Create(Binder.Compilation.GetSpecialType((SpecialType)6)) : TypeWithAnnotations.Create(LambdaSymbol.InferenceFailureReturnType));
}
instance.Free();
}
BoundLambda result = new BoundLambda(_unboundLambda.Syntax, _unboundLambda, boundBlock, ((BindingDiagnosticBag<AssemblySymbol>)(object)bindingDiagnosticBag).ToReadOnlyAndFree(), executableCodeBinder, delegateType, inferredReturnType)
{
WasCompilerGenerated = _unboundLambda.WasCompilerGenerated
};
if (!flag)
{
lambdaSymbol.SetInferredReturnType(refKind, returnType);
}
return result;
}
private (LambdaSymbol lambdaSymbol, BoundBlock block, ExecutableCodeBinder lambdaBodyBinder, BindingDiagnosticBag diagnostics) BindWithParameterAndReturnType(ImmutableArray<TypeWithAnnotations> parameterTypes, ImmutableArray<RefKind> parameterRefKinds, TypeWithAnnotations returnType, RefKind refKind)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
BindingDiagnosticBag instance = BindingDiagnosticBag.GetInstance(withDiagnostics: true, _unboundLambda.WithDependencies);
LambdaSymbol lambdaSymbol = CreateLambdaSymbol(Binder.ContainingMemberOrLambda, returnType, parameterTypes, parameterRefKinds, refKind);
ExecutableCodeBinder executableCodeBinder = new ExecutableCodeBinder(_unboundLambda.Syntax, lambdaSymbol, GetWithParametersBinder(lambdaSymbol, Binder));
BoundBlock item = BindLambdaBody(lambdaSymbol, executableCodeBinder, instance);
lambdaSymbol.GetDeclarationDiagnostics(instance);
return (lambdaSymbol: lambdaSymbol, block: item, lambdaBodyBinder: executableCodeBinder, diagnostics: instance);
}
public BoundLambda BindForReturnTypeInference(NamedTypeSymbol delegateType)
{
ReturnInferenceCacheKey returnInferenceCacheKey = ReturnInferenceCacheKey.Create(delegateType, IsAsync);
if (!_returnInferenceCache.TryGetValue(returnInferenceCacheKey, out BoundLambda value))
{
value = ReallyInferReturnType(delegateType, returnInferenceCacheKey.ParameterTypes, returnInferenceCacheKey.ParameterRefKinds);
return ImmutableInterlocked.GetOrAdd(ref _returnInferenceCache, returnInferenceCacheKey, value);
}
return value;
}
public virtual Binder GetWithParametersBinder(LambdaSymbol lambdaSymbol, Binder binder)
{
return new WithLambdaParametersBinder(lambdaSymbol, binder);
}
public BoundLambda BindForErrorRecovery()
{
if (_errorBinding == null)
{
Interlocked.CompareExchange(ref _errorBinding, ReallyBindForErrorRecovery(), null);
}
return _errorBinding;
}
private BoundLambda ReallyBindForErrorRecovery()
{
return GuessBestBoundLambda(_bindingCache) ?? rebind(GuessBestBoundLambda(_returnInferenceCache)) ?? rebind(ReallyInferReturnType(null, ImmutableArray<TypeWithAnnotations>.Empty, ImmutableArray<RefKind>.Empty));
[return: NotNullIfNotNull("lambda")]
BoundLambda? rebind(BoundLambda? lambda)
{
if (lambda == null)
{
return null;
}
NamedTypeSymbol delegateType = (NamedTypeSymbol)lambda.Type;
ReturnInferenceCacheKey.GetFields(delegateType, IsAsync, out ImmutableArray<TypeWithAnnotations> parameterTypes, out ImmutableArray<RefKind> parameterRefKinds, out NamedTypeSymbol _);
return ReallyBindForErrorRecovery(delegateType, lambda.InferredReturnType, parameterTypes, parameterRefKinds);
}
}
private BoundLambda ReallyBindForErrorRecovery(NamedTypeSymbol? delegateType, InferredLambdaReturnType inferredReturnType, ImmutableArray<TypeWithAnnotations> parameterTypes, ImmutableArray<RefKind> parameterRefKinds)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
TypeWithAnnotations typeWithAnnotations = inferredReturnType.TypeWithAnnotations;
RefKind refKind = inferredReturnType.RefKind;
if (!typeWithAnnotations.HasType)
{
typeWithAnnotations = DelegateReturnTypeWithAnnotations(DelegateInvokeMethod(delegateType), out refKind);
if (!typeWithAnnotations.HasType || typeWithAnnotations.Type.ContainsTypeParameter())
{
typeWithAnnotations = TypeWithAnnotations.Create((inferredReturnType.HadExpressionlessReturn || inferredReturnType.NumExpressions == 0) ? Binder.Compilation.GetSpecialType((SpecialType)6) : Binder.CreateErrorType());
refKind = (RefKind)0;
}
}
(LambdaSymbol lambdaSymbol, BoundBlock block, ExecutableCodeBinder lambdaBodyBinder, BindingDiagnosticBag diagnostics) tuple = BindWithParameterAndReturnType(parameterTypes, parameterRefKinds, typeWithAnnotations, refKind);
BoundBlock item = tuple.block;
ExecutableCodeBinder item2 = tuple.lambdaBodyBinder;
BindingDiagnosticBag item3 = tuple.diagnostics;
return new BoundLambda(_unboundLambda.Syntax, _unboundLambda, item, ((BindingDiagnosticBag<AssemblySymbol>)(object)item3).ToReadOnlyAndFree(), item2, delegateType, new InferredLambdaReturnType(inferredReturnType.NumExpressions, inferredReturnType.IsExplicitType, inferredReturnType.HadExpressionlessReturn, refKind, typeWithAnnotations, inferredReturnType.InferredFromFunctionType, ImmutableArray<DiagnosticInfo>.Empty, ImmutableArray<AssemblySymbol>.Empty))
{
WasCompilerGenerated = _unboundLambda.WasCompilerGenerated
};
}
private static BoundLambda? GuessBestBoundLambda<T>(ImmutableDictionary<T, BoundLambda> candidates) where T : notnull
{
return candidates.Count switch
{
0 => null,
1 => candidates.First().Value,
_ => (from lambda in (from lambda in candidates
group lambda by lambda.Value.Diagnostics.Diagnostics.Length into @group
orderby @group.Key
select @group).First()
orderby GetLambdaSortString(lambda.Value.Symbol)
select lambda).FirstOrDefault().Value,
};
}
private static string GetLambdaSortString(LambdaSymbol lambda)
{
PooledStringBuilder instance = PooledStringBuilder.GetInstance();
ImmutableArray<ParameterSymbol>.Enumerator enumerator = lambda.Parameters.GetEnumerator();
while (enumerator.MoveNext())
{
ParameterSymbol current = enumerator.Current;
instance.Builder.Append(current.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageNoParameterNamesFormat));
}
if (lambda.ReturnTypeWithAnnotations.HasType)
{
instance.Builder.Append(lambda.ReturnTypeWithAnnotations.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat));
}
return instance.ToStringAndFree();
}
public bool GenerateSummaryErrors(BindingDiagnosticBag diagnostics)
{
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
IEnumerable<ImmutableBindingDiagnostic<AssemblySymbol>> first = _bindingCache.Select<KeyValuePair<(NamedTypeSymbol, bool), BoundLambda>, ImmutableBindingDiagnostic<AssemblySymbol>>(delegate(KeyValuePair<(NamedTypeSymbol Type, bool IsExpressionLambda), BoundLambda> boundLambda)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
KeyValuePair<(NamedTypeSymbol, bool), BoundLambda> keyValuePair = boundLambda;
return keyValuePair.Value.Diagnostics;
});
IEnumerable<ImmutableBindingDiagnostic<AssemblySymbol>> second = _returnInferenceCache.Values.Select((BoundLambda boundLambda) => boundLambda.Diagnostics);
IEnumerable<ImmutableBindingDiagnostic<AssemblySymbol>> enumerable = first.Concat(second);
FirstAmongEqualsSet<Diagnostic> firstAmongEqualsSet = null;
foreach (ImmutableBindingDiagnostic<AssemblySymbol> item in enumerable)
{
if (firstAmongEqualsSet == null)
{
firstAmongEqualsSet = CreateFirstAmongEqualsSet(item.Diagnostics);
}
else
{
firstAmongEqualsSet.IntersectWith(item.Diagnostics);
}
}
if (firstAmongEqualsSet != null && PreventsSuccessfulDelegateConversion(firstAmongEqualsSet))
{
((BindingDiagnosticBag)diagnostics).AddRange((IEnumerable<Diagnostic>)firstAmongEqualsSet);
return true;
}
FirstAmongEqualsSet<Diagnostic> firstAmongEqualsSet2 = null;
foreach (ImmutableBindingDiagnostic<AssemblySymbol> item2 in enumerable)
{
if (firstAmongEqualsSet2 == null)
{
firstAmongEqualsSet2 = CreateFirstAmongEqualsSet(item2.Diagnostics);
}
else
{
firstAmongEqualsSet2.UnionWith(item2.Diagnostics);
}
}
if (firstAmongEqualsSet2 != null && PreventsSuccessfulDelegateConversion(firstAmongEqualsSet2))
{
((BindingDiagnosticBag)diagnostics).AddRange((IEnumerable<Diagnostic>)firstAmongEqualsSet2);
return true;
}
return false;
}
private static bool PreventsSuccessfulDelegateConversion(FirstAmongEqualsSet<Diagnostic> set)
{
foreach (Diagnostic item in set)
{
if (ErrorFacts.PreventsSuccessfulDelegateConversion((ErrorCode)item.Code))
{
return true;
}
}
return false;
}
private static FirstAmongEqualsSet<Diagnostic> CreateFirstAmongEqualsSet(ImmutableArray<Diagnostic> bag)
{
return new FirstAmongEqualsSet<Diagnostic>(bag, (IEqualityComparer<Diagnostic>)CommonDiagnosticComparer.Instance, CanonicallyCompareDiagnostics);
}
private static int CanonicallyCompareDiagnostics(Diagnostic x, Diagnostic y)
{
if (x.Code != y.Code)
{
return x.Code - y.Code;
}
int num = x.Arguments?.Count ?? 0;
int num2 = y.Arguments?.Count ?? 0;
int i = 0;
for (int num3 = Math.Min(num, num2); i < num3; i++)
{
object obj = x.Arguments[i];
int num4 = string.CompareOrdinal(strB: y.Arguments[i]?.ToString(), strA: obj?.ToString());
if (num4 != 0)
{
return num4;
}
}
return num - num2;
}
}