private void CheckStatementCurlyBracketPlacement(CsElement element, Statement statement) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(statement, "statement"); switch (statement.StatementType) { case StatementType.Else: // Check that there is nothing between the starting else keyword and the opening bracket. this.CheckChainedStatementCurlyBracketPlacement(element, statement); this.CheckBlockStatementsCurlyBracketPlacement(element, statement); // Check that there is nothing between the closing bracket and the else keyword of the attached else statement. ElseStatement elseStatement = (ElseStatement)statement; if (elseStatement.AttachedElseStatement != null) { this.CheckTrailingStatementCurlyBracketPlacement(element, statement); } break; case StatementType.Catch: case StatementType.Finally: // Check that there is nothing between the starting catch or finally keyword and the opening bracket. this.CheckChainedStatementCurlyBracketPlacement(element, statement); this.CheckBlockStatementsCurlyBracketPlacement(element, statement); break; case StatementType.If: this.CheckBlockStatementsCurlyBracketPlacement(element, statement); // Check that there is nothing between the closing bracket and the else keyword of the attached else statement. IfStatement ifStatement = (IfStatement)statement; if (ifStatement.AttachedElseStatement != null) { this.CheckTrailingStatementCurlyBracketPlacement(element, statement); } break; case StatementType.Try: // Check that there is nothing between the starting try keyword and the opening bracket. this.CheckBlockStatementsCurlyBracketPlacement(element, statement); TryStatement tryStatement = (TryStatement)statement; if (tryStatement.FinallyStatement != null || (tryStatement.CatchStatements != null && tryStatement.CatchStatements.Count > 0)) { // There is something attached to the end of this try statement. Check that there is nothing between // the closing bracket of the try statement and the start of the attached statement. this.CheckTrailingStatementCurlyBracketPlacement(element, tryStatement); } if (tryStatement.CatchStatements != null && tryStatement.CatchStatements.Count > 0) { CatchStatement[] catchStatementArray = new CatchStatement[tryStatement.CatchStatements.Count]; tryStatement.CatchStatements.CopyTo(catchStatementArray, 0); for (int i = 0; i < catchStatementArray.Length; ++i) { if (catchStatementArray.Length > i + 1 || tryStatement.FinallyStatement != null) { // There is something attached to the end of this catch statement, either another catch or a finally. // Check that there is nothing between the closing bracket of this catch statement and the start of the attached // statement. this.CheckTrailingStatementCurlyBracketPlacement(element, catchStatementArray[i]); } } } break; case StatementType.Checked: case StatementType.Fixed: case StatementType.For: case StatementType.Foreach: case StatementType.Lock: case StatementType.Switch: case StatementType.Unchecked: case StatementType.Unsafe: case StatementType.Using: case StatementType.While: // Check that there is nothing between the starting keyword and the opening bracket. this.CheckBlockStatementsCurlyBracketPlacement(element, statement); break; case StatementType.DoWhile: this.CheckBlockStatementsCurlyBracketPlacement(element, statement); this.CheckTrailingStatementCurlyBracketPlacement(element, statement); break; default: break; } }
/// <summary> /// Looks for an else-statement, and if it is found, parses and returns it. /// </summary> /// <param name="parentReference"> /// The parent code unit. /// </param> /// <param name="parentStatement"> /// The parent of the else-statement. /// </param> /// <param name="unsafeCode"> /// Indicates whether the code being parsed resides in an unsafe code block. /// </param> /// <returns> /// Returns the statement. /// </returns> private ElseStatement GetAttachedElseStatement(Reference<ICodePart> parentReference, Statement parentStatement, bool unsafeCode) { Param.AssertNotNull(parentReference, "parentReference"); Param.AssertNotNull(parentStatement, "parentStatement"); Param.Ignore(unsafeCode); ElseStatement statement = null; // Check if the next keyword is an else. Symbol symbol = this.GetNextSymbol(parentReference); if (symbol.SymbolType == SymbolType.Else) { Reference<ICodePart> statementReference = new Reference<ICodePart>(); // Advance to this keyword and add it. Node<CsToken> firstTokenNode = this.tokens.InsertLast(this.GetToken(CsTokenType.Else, SymbolType.Else, statementReference)); // Check if the next keyword is an if. Expression conditional = null; symbol = this.GetNextSymbol(statementReference); if (symbol != null && symbol.SymbolType == SymbolType.If) { // Advance to this keyword and add it. this.tokens.Add(this.GetToken(CsTokenType.If, SymbolType.If, statementReference)); // Get the opening parenthesis. Bracket openParenthesis = this.GetBracketToken(CsTokenType.OpenParenthesis, SymbolType.OpenParenthesis, statementReference); Node<CsToken> openParenthesisNode = this.tokens.InsertLast(openParenthesis); // Get the expression within the parenthesis. conditional = this.GetNextExpression(ExpressionPrecedence.None, statementReference, unsafeCode); if (conditional == null) { throw new SyntaxException(this.document.SourceCode, symbol.LineNumber); } // Get the closing parenthesis. Bracket closeParenthesis = this.GetBracketToken(CsTokenType.CloseParenthesis, SymbolType.CloseParenthesis, statementReference); Node<CsToken> closeParenthesisNode = this.tokens.InsertLast(closeParenthesis); openParenthesis.MatchingBracketNode = closeParenthesisNode; closeParenthesis.MatchingBracketNode = openParenthesisNode; } // Get the embedded statement. Statement childStatement = this.GetNextStatement(statementReference, unsafeCode); if (childStatement == null) { throw this.CreateSyntaxException(); } // Create the token list for the statement. CsTokenList partialTokens = new CsTokenList(this.tokens, firstTokenNode, this.tokens.Last); // Create the else-statement. statement = new ElseStatement(partialTokens, conditional); statement.EmbeddedStatement = childStatement; ((IWriteableCodeUnit)statement).SetParent(parentStatement); // Check if there is another else or an else-if attached to this statement. ElseStatement attached = this.GetAttachedElseStatement(statementReference, statement, unsafeCode); if (attached != null) { statement.AttachedElseStatement = attached; } statementReference.Target = statement; } return statement; }
/// <summary> /// The save. /// </summary> /// <param name="elseStatement"> /// The else statement. /// </param> private void Save(ElseStatement elseStatement) { this.cppWriter.Write("else"); this.Save(elseStatement.EmbeddedStatement); }