示例#1
0
            private BoundNode VisitLambdaOrFunction(IBoundLambdaOrFunction node)
            {
                Debug.Assert((object)node.Symbol != null);
                SeenLambda = true;
                var oldParent = _currentParent;
                var oldBlock  = _currentScope;

                _currentParent             = node.Symbol;
                _currentScope              = node.Body;
                ScopeParent[_currentScope] = oldBlock;
                ScopeOwner.Add(_currentScope, _currentParent);
                var wasInExpressionLambda = _inExpressionLambda;

                _inExpressionLambda = _inExpressionLambda || ((node as BoundLambda)?.Type.IsExpressionTree() ?? false);

                if (!_inExpressionLambda)
                {
                    // for the purpose of constructing frames parameters are scoped as if they are inside the lambda block
                    foreach (var parameter in node.Symbol.Parameters)
                    {
                        VariableScope[parameter] = _currentScope;
                    }

                    foreach (var local in node.Body.Locals)
                    {
                        VariableScope[local] = _currentScope;
                    }
                }

                var result = base.VisitBlock(node.Body);

                _inExpressionLambda = wasInExpressionLambda;
                _currentParent      = oldParent;
                _currentScope       = oldBlock;
                return(result);
            }
        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);
        }
示例#3
0
            private BoundNode VisitLambdaOrFunction(IBoundLambdaOrFunction node)
            {
                Debug.Assert((object)node.Symbol != null);
                SeenLambda = true;
                var oldParent = _currentParent;
                var oldBlock = _currentScope;
                _currentParent = node.Symbol;
                _currentScope = node.Body;
                ScopeParent[_currentScope] = oldBlock;
                ScopeOwner.Add(_currentScope, _currentParent);
                var wasInExpressionLambda = _inExpressionLambda;
                _inExpressionLambda = _inExpressionLambda || ((node as BoundLambda)?.Type.IsExpressionTree() ?? false);

                if (!_inExpressionLambda)
                {
                    // for the purpose of constructing frames parameters are scoped as if they are inside the lambda block
                    foreach (var parameter in node.Symbol.Parameters)
                    {
                        VariableScope[parameter] = _currentScope;
                    }

                    foreach (var local in node.Body.Locals)
                    {
                        VariableScope[local] = _currentScope;
                    }
                }

                var result = base.VisitBlock(node.Body);
                _inExpressionLambda = wasInExpressionLambda;
                _currentParent = oldParent;
                _currentScope = oldBlock;
                return result;
            }
        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);
        }