private static SyntaxToken GetFirstIncludedToken(StatementSyntax statement, bool inRecursiveCall = false) { Debug.Assert(statement != null); switch (statement.Kind) { case SyntaxKind.Block: return(((BlockSyntax)statement).OpenBraceToken); case SyntaxKind.BreakStatement: return(((BreakStatementSyntax)statement).BreakKeyword); case SyntaxKind.CheckedStatement: case SyntaxKind.UncheckedStatement: return(((CheckedStatementSyntax)statement).Keyword); case SyntaxKind.ContinueStatement: return(((ContinueStatementSyntax)statement).ContinueKeyword); case SyntaxKind.ExpressionStatement: case SyntaxKind.LocalDeclarationStatement: return(statement.GetFirstToken()); case SyntaxKind.DoStatement: return(((DoStatementSyntax)statement).DoKeyword); case SyntaxKind.EmptyStatement: return(default(SyntaxToken)); //The caller will have to check for this. case SyntaxKind.FixedStatement: return(((FixedStatementSyntax)statement).FixedKeyword); case SyntaxKind.ForEachStatement: // NB: iteration variable is only in scope in body. ForEachStatementSyntax forEachSyntax = (ForEachStatementSyntax)statement; if (inRecursiveCall) { return(forEachSyntax.ForEachKeyword); } return(GetFirstIncludedToken(forEachSyntax.Statement, inRecursiveCall: true)); case SyntaxKind.ForStatement: // Section 8.8.3 of the spec says that the scope of the loop variable starts at // its declaration. If it's not there, then the scope we are interested in is // the loop body. ForStatementSyntax forSyntax = (ForStatementSyntax)statement; if (inRecursiveCall) { return(forSyntax.ForKeyword); } VariableDeclarationSyntax declOpt = forSyntax.Declaration; return(declOpt == null?GetFirstIncludedToken(forSyntax.Statement, inRecursiveCall : true) : declOpt.GetFirstToken()); case SyntaxKind.GotoDefaultStatement: case SyntaxKind.GotoCaseStatement: case SyntaxKind.GotoStatement: return(((GotoStatementSyntax)statement).GotoKeyword); case SyntaxKind.IfStatement: return(((IfStatementSyntax)statement).IfKeyword); case SyntaxKind.LabeledStatement: return(((LabeledStatementSyntax)statement).Identifier); case SyntaxKind.LockStatement: return(((LockStatementSyntax)statement).LockKeyword); case SyntaxKind.ReturnStatement: return(((ReturnStatementSyntax)statement).ReturnKeyword); case SyntaxKind.SwitchStatement: return(((SwitchStatementSyntax)statement).OpenBraceToken); case SyntaxKind.ThrowStatement: return(((ThrowStatementSyntax)statement).ThrowKeyword); case SyntaxKind.TryStatement: return(((TryStatementSyntax)statement).TryKeyword); case SyntaxKind.UnsafeStatement: return(((UnsafeStatementSyntax)statement).UnsafeKeyword); case SyntaxKind.UsingStatement: return(((UsingStatementSyntax)statement).UsingKeyword); case SyntaxKind.WhileStatement: return(((WhileStatementSyntax)statement).WhileKeyword); case SyntaxKind.YieldReturnStatement: case SyntaxKind.YieldBreakStatement: return(((YieldStatementSyntax)statement).YieldKeyword); default: throw ExceptionUtilities.UnexpectedValue(statement.Kind); } }