using System.Collections.Immutable; using Microsoft.CodeAnalysis.CSharp.Emit; using Microsoft.CodeAnalysis.CSharp.Emit.NoPia; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CodeGen; using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Symbols; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp; internal sealed class SynthesizedClosureMethod : SynthesizedMethodBaseSymbol, ISynthesizedMethodBodyImplementationSymbol, ISymbolInternal { private readonly ImmutableArray _structEnvironments; internal readonly DebugId LambdaId; internal MethodSymbol TopLevelMethod { get; } protected override ImmutableArray BaseMethodParameters => BaseMethod.Parameters; protected override ImmutableArray ExtraSynthesizedRefParameters => ImmutableArray.CastUp(_structEnvironments); internal int ExtraSynthesizedParameterCount { get { if (!_structEnvironments.IsDefault) { return _structEnvironments.Length; } return 0; } } internal override bool InheritsBaseMethodAttributes => true; internal override bool GenerateDebugInfo => !IsAsync; IMethodSymbolInternal? ISynthesizedMethodBodyImplementationSymbol.Method => (IMethodSymbolInternal?)(object)TopLevelMethod; bool ISynthesizedMethodBodyImplementationSymbol.HasMethodBodyDependency => true; public ClosureKind ClosureKind { get; } internal SynthesizedClosureMethod(NamedTypeSymbol containingType, ImmutableArray structEnvironments, ClosureKind closureKind, MethodSymbol topLevelMethod, DebugId topLevelMethodId, MethodSymbol originalMethod, SyntaxReference blockSyntax, DebugId lambdaId, TypeCompilationState compilationState) : base(containingType, originalMethod, blockSyntax, originalMethod.DeclaringSyntaxReferences[0].GetLocation(), (originalMethod is LocalFunctionSymbol) ? MakeName(topLevelMethod.Name, originalMethod.Name, topLevelMethodId, closureKind, lambdaId) : MakeName(topLevelMethod.Name, topLevelMethodId, closureKind, lambdaId), MakeDeclarationModifiers(closureKind, originalMethod), originalMethod.IsIterator) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) TopLevelMethod = topLevelMethod; ClosureKind = closureKind; LambdaId = lambdaId; SynthesizedClosureEnvironment synthesizedClosureEnvironment = ContainingType as SynthesizedClosureEnvironment; TypeMap typeMap; ImmutableArray newTypeParameters; ImmutableArray oldTypeParameters; switch (closureKind) { case ClosureKind.Singleton: case ClosureKind.General: typeMap = synthesizedClosureEnvironment.TypeMap.WithConcatAlphaRename(originalMethod, this, out newTypeParameters, out oldTypeParameters, synthesizedClosureEnvironment.OriginalContainingMethodOpt); break; case ClosureKind.Static: case ClosureKind.ThisOnly: typeMap = TypeMap.Empty.WithConcatAlphaRename(originalMethod, this, out newTypeParameters, out oldTypeParameters); break; default: throw ExceptionUtilities.UnexpectedValue((object)closureKind); } if (!structEnvironments.IsDefaultOrEmpty && newTypeParameters.Length != 0) { ArrayBuilder instance = ArrayBuilder.GetInstance(); ImmutableArray.Enumerator enumerator = structEnvironments.GetEnumerator(); while (enumerator.MoveNext()) { SynthesizedClosureEnvironment current = enumerator.Current; NamedTypeSymbol namedTypeSymbol; if (current.Arity == 0) { namedTypeSymbol = current; } else { ImmutableArray constructedFromTypeParameters = current.ConstructedFromTypeParameters; ImmutableArray immutableArray = typeMap.SubstituteTypeParameters(constructedFromTypeParameters); namedTypeSymbol = current.Construct(immutableArray); } instance.Add(namedTypeSymbol); } _structEnvironments = instance.ToImmutableAndFree(); } else { _structEnvironments = ImmutableArray.CastUp(structEnvironments); } AssignTypeMapAndTypeParameters(typeMap, newTypeParameters); EnsureAttributesExist(compilationState); } private void EnsureAttributesExist(TypeCompilationState compilationState) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 PEModuleBuilder moduleBuilderOpt = compilationState.ModuleBuilderOpt; if (moduleBuilderOpt == null) { return; } if ((int)RefKind == 3) { moduleBuilderOpt.EnsureIsReadOnlyAttributeExists(); } ParameterHelpers.EnsureRefKindAttributesExist(moduleBuilderOpt, Parameters); if (((PEModuleBuilder)moduleBuilderOpt).Compilation.ShouldEmitNativeIntegerAttributes()) { if (base.ReturnType.ContainsNativeIntegerWrapperType()) { moduleBuilderOpt.EnsureNativeIntegerAttributeExists(); } ParameterHelpers.EnsureNativeIntegerAttributeExists(moduleBuilderOpt, Parameters); } ParameterHelpers.EnsureScopedRefAttributeExists(moduleBuilderOpt, Parameters); if (compilationState.Compilation.ShouldEmitNullableAttributes(this)) { if (ShouldEmitNullableContextValue(out var _)) { moduleBuilderOpt.EnsureNullableContextAttributeExists(); } if (ReturnTypeWithAnnotations.NeedsNullableAttribute()) { moduleBuilderOpt.EnsureNullableAttributeExists(); } } ParameterHelpers.EnsureNullableAttributeExists(moduleBuilderOpt, this, Parameters); } private static DeclarationModifiers MakeDeclarationModifiers(ClosureKind closureKind, MethodSymbol originalMethod) { DeclarationModifiers declarationModifiers = ((closureKind == ClosureKind.ThisOnly) ? DeclarationModifiers.Private : DeclarationModifiers.Internal); if (closureKind == ClosureKind.Static) { declarationModifiers |= DeclarationModifiers.Static; } if (originalMethod.IsAsync) { declarationModifiers |= DeclarationModifiers.Async; } if (originalMethod.IsExtern) { declarationModifiers |= DeclarationModifiers.Extern; } return declarationModifiers; } private static string MakeName(string topLevelMethodName, string localFunctionName, DebugId topLevelMethodId, ClosureKind closureKind, DebugId lambdaId) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) return GeneratedNames.MakeLocalFunctionName(topLevelMethodName, localFunctionName, (closureKind == ClosureKind.General) ? (-1) : topLevelMethodId.Ordinal, topLevelMethodId.Generation, lambdaId.Ordinal, lambdaId.Generation); } private static string MakeName(string topLevelMethodName, DebugId topLevelMethodId, ClosureKind closureKind, DebugId lambdaId) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) return GeneratedNames.MakeLambdaMethodName(topLevelMethodName, (closureKind == ClosureKind.General) ? (-1) : topLevelMethodId.Ordinal, topLevelMethodId.Generation, lambdaId.Ordinal, lambdaId.Generation); } internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree localTree) { return TopLevelMethod.CalculateLocalSyntaxOffset(localPosition, localTree); } internal override ExecutableCodeBinder? TryGetBodyBinder(BinderFactory? binderFactoryOpt = null, bool ignoreAccessibility = false) { throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/SynthesizedClosureMethod.cs", 238); } }