189 lines
8.4 KiB
C#
189 lines
8.4 KiB
C#
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);
|
||
|
|
}
|
||
|
|
}
|