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));
            }
        }
Пример #2
0
        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));
            }
        }