예제 #1
0
 public static SmallDictionary<CSharpSyntaxNode, Binder> BuildMap(MethodSymbol method, CSharpSyntaxNode syntax, Binder enclosing, out bool sawYield)
 {
     var builder = new LocalBinderFactory(method, enclosing);
     builder.Visit(syntax);
     sawYield = builder._sawYield;
     return builder._map;
 }
예제 #2
0
        private void ComputeBinderMap()
        {
            SmallDictionary <SyntaxNode, Binder> map;
            ImmutableArray <MethodSymbol>        methodSymbolsWithYield;

            // Ensure that the member symbol is a method symbol.
            if ((object)_memberSymbol != null && _root != null)
            {
                var methodsWithYield = ArrayBuilder <SyntaxNode> .GetInstance();

                var symbolsWithYield = ArrayBuilder <MethodSymbol> .GetInstance();

                map = LocalBinderFactory.BuildMap(_memberSymbol, _root, this, methodsWithYield, _binderUpdatedHandler);
                foreach (var methodWithYield in methodsWithYield)
                {
                    Binder binder = this;
                    if (methodWithYield.Kind() != SyntaxKind.GlobalStatement &&
                        (methodWithYield == _root || map.TryGetValue(methodWithYield, out binder)))
                    {
                        Symbol containing = binder.ContainingMemberOrLambda;

                        // get the closest enclosing InMethodBinder and make it an iterator
                        InMethodBinder inMethod = null;
                        while (binder != null)
                        {
                            inMethod = binder as InMethodBinder;
                            if (inMethod != null)
                            {
                                break;
                            }
                            binder = binder.Next;
                        }
                        if (inMethod != null && (object)inMethod.ContainingMemberOrLambda == containing)
                        {
                            inMethod.MakeIterator();
                            symbolsWithYield.Add((MethodSymbol)inMethod.ContainingMemberOrLambda);
                        }
                        else
                        {
                            Debug.Assert(methodWithYield == _root && methodWithYield is ExpressionSyntax);
                        }
                    }
                    else
                    {
                        // skip over it, this is an error
                    }
                }
                methodsWithYield.Free();
                methodSymbolsWithYield = symbolsWithYield.ToImmutableAndFree();
            }
            else
            {
                map = SmallDictionary <SyntaxNode, Binder> .Empty;
                methodSymbolsWithYield = ImmutableArray <MethodSymbol> .Empty;
            }

            Interlocked.CompareExchange(ref _lazyBinderMap, map, null);
            ImmutableInterlocked.InterlockedCompareExchange(ref _methodSymbolsWithYield, methodSymbolsWithYield, default(ImmutableArray <MethodSymbol>));
        }
예제 #3
0
        public static SmallDictionary <SyntaxNode, Binder> BuildMap(
            Symbol containingMemberOrLambda,
            SyntaxNode syntax,
            Binder enclosing,
            Action <Binder, SyntaxNode> binderUpdatedHandler = null
            )
        {
            var builder = new LocalBinderFactory(containingMemberOrLambda, syntax, enclosing);

            StatementSyntax statement;
            var             expressionSyntax = syntax as ExpressionSyntax;

            if (expressionSyntax != null)
            {
                enclosing = new ExpressionVariableBinder(syntax, enclosing);

                if ((object)binderUpdatedHandler != null)
                {
                    binderUpdatedHandler(enclosing, syntax);
                }

                builder.AddToMap(syntax, enclosing);
                builder.Visit(expressionSyntax, enclosing);
            }
            else if (
                syntax.Kind() != SyntaxKind.Block && (statement = syntax as StatementSyntax) != null
                )
            {
                CSharpSyntaxNode embeddedScopeDesignator;
                enclosing = builder.GetBinderForPossibleEmbeddedStatement(
                    statement,
                    enclosing,
                    out embeddedScopeDesignator
                    );

                if ((object)binderUpdatedHandler != null)
                {
                    binderUpdatedHandler(enclosing, embeddedScopeDesignator);
                }

                if (embeddedScopeDesignator != null)
                {
                    builder.AddToMap(embeddedScopeDesignator, enclosing);
                }

                builder.Visit(statement, enclosing);
            }
            else
            {
                if ((object)binderUpdatedHandler != null)
                {
                    binderUpdatedHandler(enclosing, null);
                }

                builder.Visit((CSharpSyntaxNode)syntax, enclosing);
            }

            return(builder._map);
        }
예제 #4
0
        public static SmallDictionary <CSharpSyntaxNode, Binder> BuildMap(MethodSymbol method, CSharpSyntaxNode syntax, Binder enclosing, out bool sawYield)
        {
            var builder = new LocalBinderFactory(method, enclosing);

            builder.Visit(syntax);
            sawYield = builder._sawYield;
            return(builder._map);
        }
예제 #5
0
        // methodsWithYields will contain all function-declaration-like CSharpSyntaxNodes with yield statements contained within them.
        // Currently the types of these are restricted to only be whatever the syntax parameter is, plus any LocalFunctionStatementSyntax contained within it.
        // This may change if the language is extended to allow iterator lambdas, in which case the lambda would also be returned.
        // (lambdas currently throw a diagnostic in WithLambdaParametersBinder.GetIteratorElementType when a yield is used within them)
        public static SmallDictionary <SyntaxNode, Binder> BuildMap(
            Symbol containingMemberOrLambda,
            SyntaxNode syntax,
            Binder enclosing,
            ArrayBuilder <SyntaxNode> methodsWithYields,
            Func <Binder, SyntaxNode, Binder> rootBinderAdjusterOpt = null)
        {
            var builder = new LocalBinderFactory(containingMemberOrLambda, syntax, enclosing, methodsWithYields);

            StatementSyntax statement;
            var             expressionSyntax = syntax as ExpressionSyntax;

            if (expressionSyntax != null)
            {
                enclosing = new ExpressionVariableBinder(syntax, enclosing);

                if ((object)rootBinderAdjusterOpt != null)
                {
                    enclosing = rootBinderAdjusterOpt(enclosing, syntax);
                }

                builder.AddToMap(syntax, enclosing);
                builder.Visit(expressionSyntax, enclosing);
            }
            else if (syntax.Kind() != SyntaxKind.Block && (statement = syntax as StatementSyntax) != null)
            {
                CSharpSyntaxNode embeddedScopeDesignator;
                enclosing = builder.GetBinderForPossibleEmbeddedStatement(statement, enclosing, out embeddedScopeDesignator);

                if ((object)rootBinderAdjusterOpt != null)
                {
                    enclosing = rootBinderAdjusterOpt(enclosing, embeddedScopeDesignator);
                }

                if (embeddedScopeDesignator != null)
                {
                    builder.AddToMap(embeddedScopeDesignator, enclosing);
                }

                builder.Visit(statement, enclosing);
            }
            else
            {
                if ((object)rootBinderAdjusterOpt != null)
                {
                    enclosing = rootBinderAdjusterOpt(enclosing, null);
                }

                builder.Visit((CSharpSyntaxNode)syntax, enclosing);
            }

            // the other place this is possible is in a local function
            if (builder._sawYield)
            {
                methodsWithYields.Add(syntax);
            }
            return(builder._map);
        }
예제 #6
0
 // methodsWithYields will contain all function-declaration-like CSharpSyntaxNodes with yield statements contained within them.
 // Currently the types of these are restricted to only be whatever the syntax parameter is, plus any LocalFunctionStatementSyntax contained within it.
 // This may change if the language is extended to allow iterator lambdas, in which case the lambda would also be returned.
 // (lambdas currently throw a diagnostic in WithLambdaParametersBinder.GetIteratorElementType when a yield is used within them)
 public static SmallDictionary<CSharpSyntaxNode, Binder> BuildMap(MethodSymbol method, CSharpSyntaxNode syntax, Binder enclosing, ArrayBuilder<CSharpSyntaxNode> methodsWithYields)
 {
     var builder = new LocalBinderFactory(method, enclosing, methodsWithYields);
     builder.Visit(syntax);
     // the other place this is possible is in a local function
     if (builder._sawYield)
         methodsWithYields.Add(syntax);
     return builder._map;
 }
예제 #7
0
        private void ComputeBinderMap()
        {
            SmallDictionary <SyntaxNode, Binder> map;

            if (_memberSymbol is SynthesizedSimpleProgramEntryPointSymbol entryPoint && _root == entryPoint.SyntaxNode)
            {
                var scopeOwner = new SimpleProgramBinder(this, entryPoint);
                map = LocalBinderFactory.BuildMap(_memberSymbol, _root, scopeOwner, _binderUpdatedHandler);
                map.Add(_root, scopeOwner);
            }
예제 #8
0
        // methodsWithYields will contain all function-declaration-like CSharpSyntaxNodes with yield statements contained within them.
        // Currently the types of these are restricted to only be whatever the syntax parameter is, plus any LocalFunctionStatementSyntax contained within it.
        // This may change if the language is extended to allow iterator lambdas, in which case the lambda would also be returned.
        // (lambdas currently throw a diagnostic in WithLambdaParametersBinder.GetIteratorElementType when a yield is used within them)
        public static SmallDictionary<SyntaxNode, Binder> BuildMap(
            Symbol containingMemberOrLambda, 
            SyntaxNode syntax, 
            Binder enclosing, 
            ArrayBuilder<SyntaxNode> methodsWithYields,
            Func<Binder, SyntaxNode, Binder> rootBinderAdjusterOpt = null)
        {
            var builder = new LocalBinderFactory(containingMemberOrLambda, syntax, enclosing, methodsWithYields);

            StatementSyntax statement;
            var expressionSyntax = syntax as ExpressionSyntax;
            if (expressionSyntax != null)
            {
                enclosing = new ExpressionVariableBinder(syntax, enclosing);

                if ((object)rootBinderAdjusterOpt != null)
                {
                    enclosing = rootBinderAdjusterOpt(enclosing, syntax);
                }

                builder.AddToMap(syntax, enclosing);
                builder.Visit(expressionSyntax, enclosing);
            }
            else if (syntax.Kind() != SyntaxKind.Block && (statement = syntax as StatementSyntax) != null)
            {
                CSharpSyntaxNode embeddedScopeDesignator;
                enclosing = builder.GetBinderForPossibleEmbeddedStatement(statement, enclosing, out embeddedScopeDesignator);

                if ((object)rootBinderAdjusterOpt != null)
                {
                    enclosing = rootBinderAdjusterOpt(enclosing, embeddedScopeDesignator);
                }

                if (embeddedScopeDesignator != null)
                {
                    builder.AddToMap(embeddedScopeDesignator, enclosing);
                }

                builder.Visit(statement, enclosing);
            }
            else
            {
                if ((object)rootBinderAdjusterOpt != null)
                {
                    enclosing = rootBinderAdjusterOpt(enclosing, null);
                }

                builder.Visit((CSharpSyntaxNode)syntax, enclosing);
            }

            // the other place this is possible is in a local function
            if (builder._sawYield)
                methodsWithYields.Add(syntax);
            return builder._map;
        }
예제 #9
0
        // methodsWithYields will contain all function-declaration-like CSharpSyntaxNodes with yield statements contained within them.
        // Currently the types of these are restricted to only be whatever the syntax parameter is, plus any LocalFunctionStatementSyntax contained within it.
        // This may change if the language is extended to allow iterator lambdas, in which case the lambda would also be returned.
        // (lambdas currently throw a diagnostic in WithLambdaParametersBinder.GetIteratorElementType when a yield is used within them)
        public static SmallDictionary<CSharpSyntaxNode, Binder> BuildMap(Symbol containingMemberOrLambda, CSharpSyntaxNode syntax, Binder enclosing, ArrayBuilder<CSharpSyntaxNode> methodsWithYields)
        {
            var builder = new LocalBinderFactory(containingMemberOrLambda, syntax, enclosing, methodsWithYields);

            if (syntax is ExpressionSyntax)
            {
                var binder = new PatternVariableBinder(syntax, enclosing);
                builder.AddToMap(syntax, binder);
                builder.Visit(syntax, binder);
            }
            else
            {
                builder.Visit(syntax);
            }

            // the other place this is possible is in a local function
            if (builder._sawYield)
                methodsWithYields.Add(syntax);
            return builder._map;
        }
예제 #10
0
        // methodsWithYields will contain all function-declaration-like CSharpSyntaxNodes with yield statements contained within them.
        // Currently the types of these are restricted to only be whatever the syntax parameter is, plus any LocalFunctionStatementSyntax contained within it.
        // This may change if the language is extended to allow iterator lambdas, in which case the lambda would also be returned.
        // (lambdas currently throw a diagnostic in WithLambdaParametersBinder.GetIteratorElementType when a yield is used within them)
        public static SmallDictionary <CSharpSyntaxNode, Binder> BuildMap(Symbol containingMemberOrLambda, CSharpSyntaxNode syntax, Binder enclosing, ArrayBuilder <CSharpSyntaxNode> methodsWithYields)
        {
            var builder = new LocalBinderFactory(containingMemberOrLambda, syntax, enclosing, methodsWithYields);

            if (syntax is ExpressionSyntax)
            {
                var binder = new PatternVariableBinder(syntax, enclosing);
                builder.AddToMap(syntax, binder);
                builder.Visit(syntax, binder);
            }
            else
            {
                builder.Visit(syntax);
            }

            // the other place this is possible is in a local function
            if (builder._sawYield)
            {
                methodsWithYields.Add(syntax);
            }
            return(builder._map);
        }