Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
 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);
 }
Ejemplo n.º 3
0
 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
                ));
 }
Ejemplo n.º 4
0
 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
                ));
 }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 7
0
 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);
 }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
        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);
        }
Ejemplo n.º 11
0
        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));
        }