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