private static DeclarationModifiers MakeDeclarationModifiers( ClosureKind closureKind, MethodSymbol originalMethod ) { var mods = closureKind == ClosureKind.ThisOnly ? DeclarationModifiers.Private : DeclarationModifiers.Internal; if (closureKind == ClosureKind.Static) { mods |= DeclarationModifiers.Static; } if (originalMethod.IsAsync) { mods |= DeclarationModifiers.Async; } if (originalMethod.IsExtern) { mods |= DeclarationModifiers.Extern; } return(mods); }
private static string MakeName(string topLevelMethodName, MethodDebugId topLevelMethodId, ClosureKind closureKind, int lambdaOrdinal) { // Lambda method name must contain the declaring method ordinal to be unique unless the method is emitted into a closure class exclusive to the declaring method. // Lambdas that only close over "this" are emitted directly into the top-level method containing type. // Lambdas that don't close over anything (static) are emitted into a shared closure singleton. return GeneratedNames.MakeLambdaMethodName( topLevelMethodName, (closureKind == ClosureKind.General) ? -1 : topLevelMethodId.Ordinal, topLevelMethodId.Generation, lambdaOrdinal); }
private static string MakeName( string topLevelMethodName, string localFunctionName, DebugId topLevelMethodId, ClosureKind closureKind, DebugId lambdaId ) { 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 ) { // Lambda method name must contain the declaring method ordinal to be unique unless the method is emitted into a closure class exclusive to the declaring method. // Lambdas that only close over "this" are emitted directly into the top-level method containing type. // Lambdas that don't close over anything (static) are emitted into a shared closure singleton. return(GeneratedNames.MakeLambdaMethodName( topLevelMethodName, (closureKind == ClosureKind.General) ? -1 : topLevelMethodId.Ordinal, topLevelMethodId.Generation, lambdaId.Ordinal, lambdaId.Generation )); }
internal SynthesizedLambdaMethod( VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, NamedTypeSymbol containingType, ClosureKind closureKind, MethodSymbol topLevelMethod, int topLevelMethodOrdinal, BoundLambda lambdaNode, int lambdaOrdinal) : base(containingType, lambdaNode.Symbol, null, lambdaNode.SyntaxTree.GetReference(lambdaNode.Body.Syntax), lambdaNode.Syntax.GetLocation(), MakeName(slotAllocatorOpt, compilationState, closureKind, topLevelMethod, topLevelMethodOrdinal, lambdaOrdinal), (closureKind == ClosureKind.ThisOnly ? DeclarationModifiers.Private : DeclarationModifiers.Internal) | (lambdaNode.Symbol.IsAsync ? DeclarationModifiers.Async : 0)) { this.topLevelMethod = topLevelMethod; TypeMap typeMap; ImmutableArray <TypeParameterSymbol> typeParameters; LambdaFrame lambdaFrame; if (!topLevelMethod.IsGenericMethod) { typeMap = TypeMap.Empty; typeParameters = ImmutableArray <TypeParameterSymbol> .Empty; } else if ((object)(lambdaFrame = this.ContainingType as LambdaFrame) != null) { typeMap = lambdaFrame.TypeMap; typeParameters = ImmutableArray <TypeParameterSymbol> .Empty; } else { typeMap = TypeMap.Empty.WithAlphaRename(topLevelMethod, this, out typeParameters); } AssignTypeMapAndTypeParameters(typeMap, typeParameters); }
internal SynthesizedLambdaMethod( NamedTypeSymbol containingType, ClosureKind closureKind, MethodSymbol topLevelMethod, DebugId topLevelMethodId, BoundLambda lambdaNode, DebugId lambdaId) : base(containingType, lambdaNode.Symbol, null, lambdaNode.SyntaxTree.GetReference(lambdaNode.Body.Syntax), lambdaNode.Syntax.GetLocation(), MakeName(topLevelMethod.Name, topLevelMethodId, closureKind, lambdaId), (closureKind == ClosureKind.ThisOnly ? DeclarationModifiers.Private : DeclarationModifiers.Internal) | (lambdaNode.Symbol.IsAsync ? DeclarationModifiers.Async : 0)) { _topLevelMethod = topLevelMethod; TypeMap typeMap; ImmutableArray<TypeParameterSymbol> typeParameters; LambdaFrame lambdaFrame; if (!topLevelMethod.IsGenericMethod) { typeMap = TypeMap.Empty; typeParameters = ImmutableArray<TypeParameterSymbol>.Empty; } else if ((object)(lambdaFrame = this.ContainingType as LambdaFrame) != null) { typeMap = lambdaFrame.TypeMap; typeParameters = ImmutableArray<TypeParameterSymbol>.Empty; } else { typeMap = TypeMap.Empty.WithAlphaRename(topLevelMethod, this, out typeParameters); } AssignTypeMapAndTypeParameters(typeMap, typeParameters); }
private static string MakeName(string topLevelMethodName, string localFunctionName, DebugId topLevelMethodId, ClosureKind closureKind, DebugId lambdaId) { return GeneratedNames.MakeLocalFunctionName( topLevelMethodName, localFunctionName, (closureKind == ClosureKind.General) ? -1 : topLevelMethodId.Ordinal, topLevelMethodId.Generation, lambdaId.Ordinal, lambdaId.Generation); }
internal SynthesizedLambdaMethod( NamedTypeSymbol containingType, ImmutableArray<TypeSymbol> structClosures, ClosureKind closureKind, MethodSymbol topLevelMethod, DebugId topLevelMethodId, IBoundLambdaOrFunction lambdaNode, DebugId lambdaId) : base(containingType, lambdaNode.Symbol, null, lambdaNode.Syntax.SyntaxTree.GetReference(lambdaNode.Body.Syntax), lambdaNode.Syntax.GetLocation(), lambdaNode is BoundLocalFunctionStatement ? MakeName(topLevelMethod.Name, lambdaNode.Symbol.Name, topLevelMethodId, closureKind, lambdaId) : MakeName(topLevelMethod.Name, topLevelMethodId, closureKind, lambdaId), (closureKind == ClosureKind.ThisOnly ? DeclarationModifiers.Private : DeclarationModifiers.Internal) | (closureKind == ClosureKind.Static ? DeclarationModifiers.Static : 0) | (lambdaNode.Symbol.IsAsync ? DeclarationModifiers.Async : 0)) { _topLevelMethod = topLevelMethod; TypeMap typeMap; ImmutableArray<TypeParameterSymbol> typeParameters; ImmutableArray<TypeParameterSymbol> constructedFromTypeParameters; LambdaFrame lambdaFrame; lambdaFrame = this.ContainingType as LambdaFrame; switch (closureKind) { case ClosureKind.Singleton: // all type parameters on method (except the top level method's) case ClosureKind.General: // only lambda's type parameters on method (rest on class) Debug.Assert(lambdaFrame != null); typeMap = lambdaFrame.TypeMap.WithConcatAlphaRename(lambdaNode.Symbol, this, out typeParameters, out constructedFromTypeParameters, lambdaFrame.ContainingMethod); break; case ClosureKind.ThisOnly: // all type parameters on method case ClosureKind.Static: Debug.Assert(lambdaFrame == null); typeMap = TypeMap.Empty.WithConcatAlphaRename(lambdaNode.Symbol, this, out typeParameters, out constructedFromTypeParameters, null); break; default: throw ExceptionUtilities.Unreachable; } if (!structClosures.IsDefaultOrEmpty && typeParameters.Length != 0) { var constructedStructClosures = ArrayBuilder<TypeSymbol>.GetInstance(); foreach (var closure in structClosures) { var frame = (LambdaFrame)closure; NamedTypeSymbol constructed; if (frame.Arity == 0) { constructed = frame; } else { var originals = frame.ConstructedFromTypeParameters; var newArgs = typeMap.SubstituteTypeParameters(originals); constructed = frame.Construct(newArgs); } constructedStructClosures.Add(constructed); } structClosures = constructedStructClosures.ToImmutableAndFree(); } _structClosures = structClosures; AssignTypeMapAndTypeParameters(typeMap, typeParameters); }
internal SynthesizedClosureMethod( NamedTypeSymbol containingType, ImmutableArray <SynthesizedClosureEnvironment> structEnvironments, ClosureKind closureKind, MethodSymbol topLevelMethod, DebugId topLevelMethodId, MethodSymbol originalMethod, SyntaxReference blockSyntax, DebugId lambdaId) : base(containingType, originalMethod, null, 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)) { _topLevelMethod = topLevelMethod; ClosureKind = closureKind; LambdaId = lambdaId; TypeMap typeMap; ImmutableArray <TypeParameterSymbol> typeParameters; ImmutableArray <TypeParameterSymbol> constructedFromTypeParameters; var lambdaFrame = ContainingType as SynthesizedClosureEnvironment; switch (closureKind) { case ClosureKind.Singleton: // all type parameters on method (except the top level method's) case ClosureKind.General: // only lambda's type parameters on method (rest on class) Debug.Assert(lambdaFrame != null); typeMap = lambdaFrame.TypeMap.WithConcatAlphaRename( originalMethod, this, out typeParameters, out constructedFromTypeParameters, lambdaFrame.OriginalContainingMethodOpt); break; case ClosureKind.ThisOnly: // all type parameters on method case ClosureKind.Static: Debug.Assert(lambdaFrame == null); typeMap = TypeMap.Empty.WithConcatAlphaRename( originalMethod, this, out typeParameters, out constructedFromTypeParameters, stopAt: null); break; default: throw ExceptionUtilities.UnexpectedValue(closureKind); } if (!structEnvironments.IsDefaultOrEmpty && typeParameters.Length != 0) { var constructedStructClosures = ArrayBuilder <NamedTypeSymbol> .GetInstance(); foreach (var env in structEnvironments) { NamedTypeSymbol constructed; if (env.Arity == 0) { constructed = env; } else { var originals = env.ConstructedFromTypeParameters; var newArgs = typeMap.SubstituteTypeParameters(originals); constructed = env.Construct(newArgs); } constructedStructClosures.Add(constructed); } _structEnvironments = constructedStructClosures.ToImmutableAndFree(); } else { _structEnvironments = ImmutableArray <NamedTypeSymbol> .CastUp(structEnvironments); } AssignTypeMapAndTypeParameters(typeMap, typeParameters); }
internal SynthesizedLambdaMethod( NamedTypeSymbol containingType, ImmutableArray <TypeSymbol> structClosures, ClosureKind closureKind, MethodSymbol topLevelMethod, DebugId topLevelMethodId, IBoundLambdaOrFunction lambdaNode, DebugId lambdaId) : base(containingType, lambdaNode.Symbol, null, lambdaNode.Syntax.SyntaxTree.GetReference(lambdaNode.Body.Syntax), lambdaNode.Syntax.GetLocation(), lambdaNode is BoundLocalFunctionStatement ? MakeName(topLevelMethod.Name, lambdaNode.Symbol.Name, topLevelMethodId, closureKind, lambdaId) : MakeName(topLevelMethod.Name, topLevelMethodId, closureKind, lambdaId), (closureKind == ClosureKind.ThisOnly ? DeclarationModifiers.Private : DeclarationModifiers.Internal) | (closureKind == ClosureKind.Static ? DeclarationModifiers.Static : 0) | (lambdaNode.Symbol.IsAsync ? DeclarationModifiers.Async : 0)) { _topLevelMethod = topLevelMethod; ClosureKind = closureKind; TypeMap typeMap; ImmutableArray <TypeParameterSymbol> typeParameters; ImmutableArray <TypeParameterSymbol> constructedFromTypeParameters; LambdaFrame lambdaFrame; lambdaFrame = this.ContainingType as LambdaFrame; switch (closureKind) { case ClosureKind.Singleton: // all type parameters on method (except the top level method's) case ClosureKind.General: // only lambda's type parameters on method (rest on class) Debug.Assert(lambdaFrame != null); typeMap = lambdaFrame.TypeMap.WithConcatAlphaRename(lambdaNode.Symbol, this, out typeParameters, out constructedFromTypeParameters, lambdaFrame.ContainingMethod); break; case ClosureKind.ThisOnly: // all type parameters on method case ClosureKind.Static: Debug.Assert(lambdaFrame == null); typeMap = TypeMap.Empty.WithConcatAlphaRename(lambdaNode.Symbol, this, out typeParameters, out constructedFromTypeParameters, null); break; default: throw ExceptionUtilities.Unreachable; } if (!structClosures.IsDefaultOrEmpty && typeParameters.Length != 0) { var constructedStructClosures = ArrayBuilder <TypeSymbol> .GetInstance(); foreach (var closure in structClosures) { var frame = (LambdaFrame)closure; NamedTypeSymbol constructed; if (frame.Arity == 0) { constructed = frame; } else { var originals = frame.ConstructedFromTypeParameters; var newArgs = typeMap.SubstituteTypeParameters(originals); constructed = frame.Construct(newArgs); } constructedStructClosures.Add(constructed); } structClosures = constructedStructClosures.ToImmutableAndFree(); } _structClosures = structClosures; AssignTypeMapAndTypeParameters(typeMap, typeParameters); }
private static string MakeName(VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, ClosureKind closureKind, MethodSymbol topLevelMethod, int topLevelMethodOrdinal, int lambdaOrdinal) { // TODO: slotAllocatorOpt?.GetPrevious() // Lambda method name must contain the declaring method ordinal to be unique unless the method is emitted into a closure class exclusive to the declaring method. // Lambdas that only close over "this" are emitted directly into the top-level method containing type. // Lambdas that don't close over anything (static) are emitted into a shared closure singleton. return(GeneratedNames.MakeLambdaMethodName( topLevelMethod.Name, (closureKind == ClosureKind.General) ? -1 : topLevelMethodOrdinal, compilationState.ModuleBuilderOpt.CurrentGenerationOrdinal, lambdaOrdinal)); }