public override BoundNode VisitScope(BoundScope node) { Debug.Assert(!node.Locals.IsEmpty); var newLocals = ArrayBuilder <LocalSymbol> .GetInstance(); var hoistedLocalsWithDebugScopes = ArrayBuilder <StateMachineFieldSymbol> .GetInstance(); foreach (var local in node.Locals) { Debug.Assert(local.SynthesizedKind == SynthesizedLocalKind.UserDefined && local.ScopeDesignatorOpt?.Kind() == SyntaxKind.SwitchSection); if (!NeedsProxy(local)) { newLocals.Add(local); continue; } hoistedLocalsWithDebugScopes.Add(((CapturedToStateMachineFieldReplacement)proxies[local]).HoistedField); } var statements = VisitList(node.Statements); // wrap the node in an iterator scope for debugging if (hoistedLocalsWithDebugScopes.Count != 0) { BoundStatement translated; if (newLocals.Count == 0) { newLocals.Free(); translated = new BoundStatementList(node.Syntax, statements); } else { translated = node.Update(newLocals.ToImmutableAndFree(), statements); } return(MakeStateMachineScope(hoistedLocalsWithDebugScopes.ToImmutable(), translated)); } else { hoistedLocalsWithDebugScopes.Free(); newLocals.Free(); return(node.Update(node.Locals, statements)); } }
public override BoundNode VisitScope(BoundScope node) { Debug.Assert(!node.Locals.IsEmpty); var newLocalsBuilder = ArrayBuilder <LocalSymbol> .GetInstance(); var hoistedLocalsWithDebugScopes = ArrayBuilder <StateMachineFieldSymbol> .GetInstance(); bool localsRewritten = false; foreach (var local in node.Locals) { // BoundScope is only used for switch Debug.Assert(local.SynthesizedKind == SynthesizedLocalKind.UserDefined && (local.ScopeDesignatorOpt?.Kind() == SyntaxKind.SwitchSection || local.ScopeDesignatorOpt?.Kind() == SyntaxKind.SwitchExpressionArm)); LocalSymbol localToUse; if (TryRewriteLocal(local, out localToUse)) { newLocalsBuilder.Add(localToUse); localsRewritten |= ((object)local != localToUse); continue; } hoistedLocalsWithDebugScopes.Add(((CapturedToStateMachineFieldReplacement)proxies[local]).HoistedField); } var statements = VisitList(node.Statements); // wrap the node in an iterator scope for debugging if (hoistedLocalsWithDebugScopes.Count != 0) { BoundStatement translated; if (newLocalsBuilder.Count == 0) { newLocalsBuilder.Free(); translated = new BoundStatementList(node.Syntax, statements); } else { translated = node.Update(newLocalsBuilder.ToImmutableAndFree(), statements); } return(MakeStateMachineScope(hoistedLocalsWithDebugScopes.ToImmutable(), translated)); } else { hoistedLocalsWithDebugScopes.Free(); ImmutableArray <LocalSymbol> newLocals; if (localsRewritten) { newLocals = newLocalsBuilder.ToImmutableAndFree(); } else { newLocalsBuilder.Free(); newLocals = node.Locals; } return(node.Update(newLocals, statements)); } }