Пример #1
0
 public WhileBinder(Binder enclosing, StatementSyntax syntax)
     : base(enclosing)
 {
     Debug.Assert(syntax != null && (syntax.CSharpKind() == SyntaxKind.WhileStatement || syntax.CSharpKind() == SyntaxKind.DoStatement));
     this.syntax = syntax;
 }
 public WhileBinder(Binder enclosing, StatementSyntax syntax)
     : base(enclosing)
 {
     Debug.Assert(syntax != null && (syntax.CSharpKind() == SyntaxKind.WhileStatement || syntax.CSharpKind() == SyntaxKind.DoStatement));
     this.syntax = syntax;
 }
Пример #3
0
        private static TextSpan?TryCreateSpanForStatement(StatementSyntax statement, int position)
        {
            if (statement == null)
            {
                return(null);
            }

            switch (statement.CSharpKind())
            {
            case SyntaxKind.Block:
                // If the user was on the close curly of the block, then set the breakpoint
                // there.  Otherwise, set it on the open curly.
                var block = (BlockSyntax)statement;
                if (position >= block.OpenBraceToken.FullSpan.End)
                {
                    return(CreateSpan(block.CloseBraceToken));
                }
                else
                {
                    return(CreateSpan(block.OpenBraceToken));
                }

            case SyntaxKind.LocalDeclarationStatement:
                // If the declaration has multiple variables then just set the bp on the first
                // variable declarator.  Otherwise, set the breakpoint over this entire
                // statement.
                var declarationStatement = (LocalDeclarationStatementSyntax)statement;
                return(TryCreateSpanForVariableDeclaration(declarationStatement.Declaration, declarationStatement.Modifiers,
                                                           declarationStatement.SemicolonToken, position));

            case SyntaxKind.LabeledStatement:
                // Create the breakpoint on the actual statement we are labeling:
                var labeledStatement = (LabeledStatementSyntax)statement;
                return(TryCreateSpanForStatement(labeledStatement.Statement, position));

            case SyntaxKind.WhileStatement:
                // Note: if the user was in the body of the while, then we would have hit its
                // nested statement on the way up.  This means we must be on the "while(expr)"
                // part.  Rather than putting a bp on the entire statement, just put it on the
                // top portion.
                var whileStatement = (WhileStatementSyntax)statement;
                return(CreateSpan(whileStatement, whileStatement.CloseParenToken));

            case SyntaxKind.DoStatement:
                // Note: if the user was in the body of the while, then we would have hit its nested
                // statement on the way up.  This means we're either in the "while(expr)" portion or
                // the "do" portion.
                var doStatement = (DoStatementSyntax)statement;
                if (position < doStatement.Statement.Span.Start)
                {
                    return(TryCreateSpanForStatement(doStatement.Statement, position));
                }
                else
                {
                    return(CreateSpan(doStatement.WhileKeyword,
                                      LastNotMissing(doStatement.CloseParenToken, doStatement.SemicolonToken)));
                }

            case SyntaxKind.ForStatement:
                // Note: if the user was in the body of the for, then we would have hit its nested
                // statement on the way up.  If they were in the condition or the incrementors, then
                // we would have those on the way up as well (in TryCreateBreakpointSpanForExpression or
                // CreateBreapointSpanForVariableDeclarator). So the user must be on the 'for'
                // itself. in that case, set the bp on the variable declaration or initializers
                var forStatement = (ForStatementSyntax)statement;
                if (forStatement.Declaration != null)
                {
                    // for (int i = 0; ...
                    var firstVariable = forStatement.Declaration.Variables.FirstOrDefault();
                    return(CreateSpan(default(SyntaxTokenList), forStatement.Declaration.Type, firstVariable));
                }
                else if (forStatement.Initializers.Count > 0)
                {
                    // for (i = 0; ...
                    return(CreateSpan(forStatement.Initializers[0]));
                }
                else if (forStatement.Condition != null)
                {
                    // for (; i > 0; ...)
                    return(CreateSpan(forStatement.Condition));
                }
                else if (forStatement.Incrementors.Count > 0)
                {
                    // for (;;...)
                    return(CreateSpan(forStatement.Incrementors[0]));
                }
                else
                {
                    // for (;;)
                    //
                    // In this case, just set the bp on the contained statement.
                    return(TryCreateSpanForStatement(forStatement.Statement, position));
                }

            case SyntaxKind.ForEachStatement:
                // Note: if the user was in the body of the foreach, then we would have hit its
                // nested statement on the way up.  If they were in the expression then we would
                // have hit that on the way up as well. In "foreach(var f in expr)" we allow a
                // bp on "foreach", "var f" and "in".
                var forEachStatement = (ForEachStatementSyntax)statement;
                if (position < forEachStatement.OpenParenToken.Span.End || position > forEachStatement.CloseParenToken.SpanStart)
                {
                    return(CreateSpan(forEachStatement.ForEachKeyword));
                }
                else if (position < forEachStatement.InKeyword.FullSpan.Start)
                {
                    return(CreateSpan(forEachStatement.Type, forEachStatement.Identifier));
                }
                else if (position < forEachStatement.Expression.FullSpan.Start)
                {
                    return(CreateSpan(forEachStatement.InKeyword));
                }
                else
                {
                    return(CreateSpan(forEachStatement.Expression));
                }

            case SyntaxKind.UsingStatement:
                var usingStatement = (UsingStatementSyntax)statement;
                if (usingStatement.Declaration != null)
                {
                    return(TryCreateSpanForNode(usingStatement.Declaration, position));
                }
                else
                {
                    return(CreateSpan(usingStatement, usingStatement.CloseParenToken));
                }

            case SyntaxKind.FixedStatement:
                var fixedStatement = (FixedStatementSyntax)statement;
                return(TryCreateSpanForNode(fixedStatement.Declaration, position));

            case SyntaxKind.CheckedStatement:
            case SyntaxKind.UncheckedStatement:
                var checkedStatement = (CheckedStatementSyntax)statement;
                return(TryCreateSpanForStatement(checkedStatement.Block, position));

            case SyntaxKind.UnsafeStatement:
                var unsafeStatement = (UnsafeStatementSyntax)statement;
                return(TryCreateSpanForStatement(unsafeStatement.Block, position));

            case SyntaxKind.LockStatement:
                // Note: if the user was in the body of the 'lock', then we would have hit its
                // nested statement on the way up.  This means we must be on the "lock(expr)" part.
                // Rather than putting a bp on the entire statement, just put it on the top portion.
                var lockStatement = (LockStatementSyntax)statement;
                return(CreateSpan(lockStatement, lockStatement.CloseParenToken));

            case SyntaxKind.IfStatement:
                // Note: if the user was in the body of the 'if' or the 'else', then we would have
                // hit its nested statement on the way up.  This means we must be on the "if(expr)"
                // part. Rather than putting a bp on the entire statement, just put it on the top
                // portion.
                var ifStatement = (IfStatementSyntax)statement;
                return(CreateSpan(ifStatement, ifStatement.CloseParenToken));

            case SyntaxKind.SwitchStatement:
                // Note: Any nested statements in the switch will already have been hit on the
                // way up.  Similarly, hitting a 'case' label will already have been taken care
                // of.  So i nthis case, we just set the bp on the "switch(expr)" itself.
                var switchStatement = (SwitchStatementSyntax)statement;
                return(CreateSpan(switchStatement, switchStatement.CloseParenToken));

            case SyntaxKind.TryStatement:
                // Note: if the user was in the body of the 'try', then we would have hit its nested
                // statement on the way up.  This means we must be on the "try" part.  In this case,
                // just set the BP on the start of the block.  Note: if they were in a catch or
                // finally section, then then that will already have been taken care of above.
                var tryStatement = (TryStatementSyntax)statement;
                return(TryCreateSpanForStatement(tryStatement.Block, position));

            // All these cases are handled by just putting a breakpoint over the entire
            // statement
            case SyntaxKind.GotoStatement:
            case SyntaxKind.GotoCaseStatement:
            case SyntaxKind.GotoDefaultStatement:
            case SyntaxKind.BreakStatement:
            case SyntaxKind.ContinueStatement:
            case SyntaxKind.ReturnStatement:
            case SyntaxKind.YieldReturnStatement:
            case SyntaxKind.YieldBreakStatement:
            case SyntaxKind.ThrowStatement:
            case SyntaxKind.ExpressionStatement:
            case SyntaxKind.EmptyStatement:
            default:
                // Fallback case.  If it was none of the above types of statements, then we make a span
                // over the entire statement.  Note: this is not a very desirable thing to do (as
                // statements can often span multiple lines.  So, when possible, we should try to do
                // better.
                return(CreateSpan(statement));
            }
        }
        private static Binder AdjustBinderForPositionWithinStatement(int position, Binder binder, StatementSyntax stmt)
        {
            switch (stmt.CSharpKind())
            {
                case SyntaxKind.ForEachStatement:
                    var forEachStmt = (ForEachStatementSyntax)stmt;
                    if (LookupPosition.IsBetweenTokens(position, forEachStmt.InKeyword, forEachStmt.Statement.GetFirstToken()))
                    {
                        binder = binder.Next;
                        Debug.Assert(binder is ScopedExpressionBinder);
                    }
                    break;

                case SyntaxKind.ForStatement:
                    var forStmt = (ForStatementSyntax)stmt;
                    if (LookupPosition.IsBetweenTokens(position, forStmt.OpenParenToken, forStmt.FirstSemicolonToken))
                    {
                        binder = binder.Next;
                        Debug.Assert(binder is ForLoopInitializationBinder);
                    }
                    break;

                case SyntaxKind.SwitchStatement:
                    var switchStmt = (SwitchStatementSyntax)stmt;
                    if (LookupPosition.IsBetweenTokens(position, switchStmt.OpenParenToken, switchStmt.OpenBraceToken))
                    {
                        binder = binder.Next;
                        Debug.Assert(binder is ScopedExpressionBinder);
                    }
                    break;
            }

            return binder;
        }
Пример #5
0
        public void FlattenStatement(StatementSyntax ss, List<FlatStatement> instructions)
        {
            switch (ss.CSharpKind())
            {
                case SyntaxKind.Block:
                    Flatten((BlockSyntax)ss,instructions);
                    return;
                case SyntaxKind.ExpressionStatement:
                    Flatten((ExpressionStatementSyntax)ss,instructions);
                    return;
                case SyntaxKind.ReturnStatement:
                    Flatten((ReturnStatementSyntax)ss,instructions);
                    return;
                case SyntaxKind.LocalDeclarationStatement:
                    Flatten((LocalDeclarationStatementSyntax)ss,instructions);
                    return;
                case SyntaxKind.ForStatement:
                    Flatten((ForStatementSyntax)ss,instructions);
                    return;
                case SyntaxKind.IfStatement:
                    Flatten((IfStatementSyntax)ss,instructions);
                    return;
                case SyntaxKind.BreakStatement:
                    Flatten((BreakStatementSyntax)ss,instructions);
                    return;
                case SyntaxKind.ContinueStatement:
                    Flatten((ContinueStatementSyntax)ss, instructions);
                    return;
                case SyntaxKind.TryStatement:
                    Flatten((TryStatementSyntax)ss,instructions);
                    return;
                case SyntaxKind.DoStatement:
                    Flatten((DoStatementSyntax)ss,instructions);
                    return;
                case SyntaxKind.WhileStatement:
                    Flatten((WhileStatementSyntax)ss,instructions);
                    return;
                case SyntaxKind.EmptyStatement:
                    // do nothing. :)
                    return;
                case SyntaxKind.SwitchStatement:
                    Flatten((SwitchStatementSyntax)ss,instructions);
                    return;
                case SyntaxKind.ThrowStatement:
                    Flatten((ThrowStatementSyntax)ss,instructions);
                    return;
                case SyntaxKind.ForEachStatement:
                    Flatten((ForEachStatementSyntax)ss,instructions);
                    return;
                case SyntaxKind.LockStatement:
                    Flatten((LockStatementSyntax)ss, instructions);
                    return;
                case SyntaxKind.UsingStatement:
                    Flatten((UsingStatementSyntax)ss, instructions);
                    return;
                case SyntaxKind.GotoStatement:
                case SyntaxKind.GotoCaseStatement:
                case SyntaxKind.GotoDefaultStatement:
                    Flatten((GotoStatementSyntax)ss, instructions);
                    return;

                case SyntaxKind.CheckedStatement:
                case SyntaxKind.FixedStatement:
                case SyntaxKind.GlobalStatement:
                case SyntaxKind.LabeledStatement:

                case SyntaxKind.UncheckedStatement:
                case SyntaxKind.UnsafeStatement:
                case SyntaxKind.YieldBreakStatement:
                case SyntaxKind.YieldReturnStatement:
                    throw new NotImplementedException("statement type " + ss.GetType().ToString() + ": " + ss.CSharpKind().ToString());
                    break;
                default:
                    throw new NotImplementedException("statement type " + ss.GetType().ToString() + ": " + ss.CSharpKind().ToString());
                    break;
            }
        }