Files

189 lines
8.4 KiB
C#
Raw Permalink Normal View History

2026-08-27 10:56:38 -06:00
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<NamedTypeSymbol> _structEnvironments;
internal readonly DebugId LambdaId;
internal MethodSymbol TopLevelMethod { get; }
protected override ImmutableArray<ParameterSymbol> BaseMethodParameters => BaseMethod.Parameters;
protected override ImmutableArray<TypeSymbol> ExtraSynthesizedRefParameters => ImmutableArray<TypeSymbol>.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<SynthesizedClosureEnvironment> 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<TypeParameterSymbol> newTypeParameters;
ImmutableArray<TypeParameterSymbol> 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<NamedTypeSymbol> instance = ArrayBuilder<NamedTypeSymbol>.GetInstance();
ImmutableArray<SynthesizedClosureEnvironment>.Enumerator enumerator = structEnvironments.GetEnumerator();
while (enumerator.MoveNext())
{
SynthesizedClosureEnvironment current = enumerator.Current;
NamedTypeSymbol namedTypeSymbol;
if (current.Arity == 0)
{
namedTypeSymbol = current;
}
else
{
ImmutableArray<TypeParameterSymbol> constructedFromTypeParameters = current.ConstructedFromTypeParameters;
ImmutableArray<TypeParameterSymbol> immutableArray = typeMap.SubstituteTypeParameters(constructedFromTypeParameters);
namedTypeSymbol = current.Construct(immutableArray);
}
instance.Add(namedTypeSymbol);
}
_structEnvironments = instance.ToImmutableAndFree();
}
else
{
_structEnvironments = ImmutableArray<NamedTypeSymbol>.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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)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);
}
}