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>)); }
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; }