コード例 #1
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>));
        }
コード例 #2
0
        public override void VisitLocalFunctionStatement(LocalFunctionStatementSyntax node)
        {
            bool   oldSawYield        = _sawYield;
            Symbol oldMethod          = _containingMemberOrLambda;
            Binder binder             = _enclosing;
            LocalFunctionSymbol match = FindLocalFunction(node, _enclosing);

            if ((object)match != null)
            {
                _containingMemberOrLambda = match;

                binder = match.IsGenericMethod
                    ? new WithMethodTypeParametersBinder(match, _enclosing)
                    : _enclosing;

                binder = binder.WithUnsafeRegionIfNecessary(node.Modifiers);
                binder = new InMethodBinder(match, binder);
            }

            BlockSyntax blockBody = node.Body;

            if (blockBody != null)
            {
                _sawYield = false;
                Visit(blockBody, binder);

                if (_sawYield)
                {
                    _methodsWithYields.Add(blockBody);
                }
            }

            ArrowExpressionClauseSyntax arrowBody = node.ExpressionBody;

            if (arrowBody != null)
            {
                _sawYield = false;
                Visit(arrowBody, binder);
                Debug.Assert(!_sawYield);
            }

            _containingMemberOrLambda = oldMethod;
            _sawYield = oldSawYield;
        }