/// <summary> /// Looks for a catch-statement, and if it is found, parses and returns it. /// </summary> /// <param name="parentProxy">Represents the parent item.</param> /// <param name="tryStatement">The parent try statement.</param> /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param> /// <returns>Returns the statement.</returns> private CatchStatement GetAttachedCatchStatement(CodeUnitProxy parentProxy, TryStatement tryStatement, bool unsafeCode) { Param.AssertNotNull(parentProxy, "parentProxy"); Param.AssertNotNull(tryStatement, "tryStatement"); Param.Ignore(unsafeCode); CatchStatement catchStatement = null; // Look for a catch keyword. Symbol symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.Catch) { this.AdvanceToNextCodeSymbol(parentProxy); var statementProxy = new CodeUnitProxy(this.document); // Move up to the catch keyword and add it. this.GetToken(statementProxy, TokenType.Catch, SymbolType.Catch); Expression catchExpression = null; // Get the opening parenthesis, if there is one. symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.OpenParenthesis) { BracketToken openParenthesis = (BracketToken)this.GetToken(statementProxy, TokenType.OpenParenthesis, SymbolType.OpenParenthesis); // Get the type, if there is one. symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.Other) { catchExpression = this.GetNextExpression(statementProxy, ExpressionPrecedence.None, unsafeCode, true, true); } // Get the closing parenthesis. BracketToken closeParenthesis = (BracketToken)this.GetToken(statementProxy, TokenType.CloseParenthesis, SymbolType.CloseParenthesis); openParenthesis.MatchingBracket = closeParenthesis; closeParenthesis.MatchingBracket = openParenthesis; } // Get the embedded statement. This must be a block statement. BlockStatement childStatement = this.GetNextStatement(statementProxy, unsafeCode) as BlockStatement; if (childStatement == null) { throw this.CreateSyntaxException(); } // Create the catch statement. catchStatement = new CatchStatement(statementProxy, tryStatement, catchExpression, childStatement); parentProxy.Children.Add(catchStatement); } return catchStatement; }
private void CheckStatementCurlyBracketPlacement(Element 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; } }