/// <summary> /// Initializes a new instance of the DoWhileStatement class. /// </summary> /// <param name="proxy">Proxy object for the statement.</param> /// <param name="condition">The expression within the while statement.</param> /// <param name="body">The body of the do-while-statement.</param> internal DoWhileStatement(CodeUnitProxy proxy, Expression condition, Statement body) : base(proxy, StatementType.DoWhile) { Param.AssertNotNull(proxy, "proxy"); Param.AssertNotNull(condition, "condition"); Param.AssertNotNull(body, "body"); this.condition.Value = condition; this.body.Value = body; }
/// <summary> /// Gets the child block statement from the given statement. If the statement itself is a block statement, /// it will be returned instead. /// </summary> /// <param name="statement">The statement.</param> /// <returns>Returns the block statement or null if there is none.</returns> private static BlockStatement GetChildBlockStatement(Statement statement) { Param.AssertNotNull(statement, "statement"); if (statement.StatementType == StatementType.Block) { return (BlockStatement)statement; } return statement.FindFirstChild<BlockStatement>(); }
/// <summary> /// Called when a statement is visited. /// </summary> /// <param name="statement">The statement being visited.</param> /// <param name="parentExpression">The parent expression, if any.</param> /// <param name="parentStatement">The parent statement, if any.</param> /// <param name="parentElement">The parent element, if any.</param> /// <returns>Returns true to continue, or false to stop the walker.</returns> private bool VisitStatement(Statement statement, Expression parentExpression, Statement parentStatement, Element parentElement) { Param.AssertNotNull(statement, "statement"); Param.Ignore(parentExpression); Param.Ignore(parentStatement); Param.AssertNotNull(parentElement, "parentElement"); this.CheckForUnnecessaryStatements(statement, parentElement); return true; }
/// <summary> /// Visits one code unit in the document. /// </summary> /// <param name="codeUnit">The item being visited.</param> /// <param name="parentElement">The parent element, if any.</param> /// <param name="parentStatement">The parent statement, if any.</param> /// <param name="parentExpression">The parent expression, if any.</param> /// <param name="parentClause">The parent query clause, if any.</param> /// <param name="parentToken">The parent token, if any.</param> /// <param name="topLevelElements">The number of classes and namespaces seen in the document.</param> /// <returns>Returns true to continue, or false to stop the walker.</returns> private bool VisitCodeUnit( CodeUnit codeUnit, Element parentElement, Statement parentStatement, Expression parentExpression, QueryClause parentClause, Token parentToken, TopLevelElements topLevelElements) { Param.AssertNotNull(codeUnit, "codeUnit"); Param.Ignore(parentElement, parentStatement, parentExpression, parentClause, parentToken); Param.AssertNotNull(topLevelElements, "topLevelElements"); if (codeUnit.CodeUnitType == CodeUnitType.Element) { return this.VisitElement((Element)codeUnit, parentElement, topLevelElements); } else if (codeUnit.CodeUnitType == CodeUnitType.Statement) { return this.VisitStatement((Statement)codeUnit, parentExpression, parentStatement, parentElement); } else if (codeUnit.CodeUnitType == CodeUnitType.Expression) { return this.VisitExpression((Expression)codeUnit, parentExpression, parentStatement, parentElement); } return !this.Cancel; }
/// <summary> /// Checks the statement, which is a parent of a block statement, to make sure that it is not empty. /// </summary> /// <param name="statement">The statement to check.</param> /// <returns>Returns true if the statement was empty.</returns> private static bool IsEmptyParentOfBlockStatement(Statement statement) { Param.AssertNotNull(statement, "statement"); // Find the block statement under this statement. for (Statement childStatement = statement.FindFirstChildStatement(); childStatement != null; childStatement = childStatement.FindNextSiblingStatement()) { if (childStatement.StatementType == StatementType.Block) { if (childStatement.Children.StatementCount == 0) { return true; } break; } } return false; }
/// <summary> /// Gets the opening curly bracket from the block statement. /// </summary> /// <param name="statement">The block statement.</param> /// <returns>Returns the opening curly bracket or null if there is none.</returns> private static OpenCurlyBracketToken GetOpeningCurlyBracketFromStatement(Statement statement) { Param.AssertNotNull(statement, "statement"); Statement blockStatement = null; // We have to match a special case for switch statement because they are the only bracketed // statements which do not have a child block statement, due to the current design of the parser. // It's a bit annoying to put the special case here, but not too bad. if (statement.StatementType == StatementType.Switch) { blockStatement = statement; } else { blockStatement = GetChildBlockStatement(statement); } if (blockStatement != null) { return blockStatement.FindFirstChild<OpenCurlyBracketToken>(); } return null; }
/// <summary> /// Checks the curly brackets under the given statement. /// </summary> /// <param name="statement">The statement being visited.</param> /// <param name="parentExpression">The parent expression, if any.</param> /// <param name="parentStatement">The parent statement, if any.</param> /// <param name="parentElement">The parent element, if any.</param> /// <returns>Returns true to continue, or false to stop the walker.</returns> private bool VisitStatement( Statement statement, Expression parentExpression, Statement parentStatement, Element parentElement) { Param.AssertNotNull(statement, "statement"); Param.Ignore(parentExpression); Param.Ignore(parentStatement); Param.AssertNotNull(parentElement, "parentElement"); switch (statement.StatementType) { case StatementType.Block: // A block statement can be the right-hand statement in a lambda expression. In this case, we allow // the block to be written all on a single line if the whole parent statement is on a single line. bool allowAllOnOneLine = false; LambdaExpression lambdaParent = statement.Parent as LambdaExpression; if (lambdaParent != null && lambdaParent.Location.StartPoint.LineNumber == lambdaParent.Location.EndPoint.LineNumber) { allowAllOnOneLine = true; } // Curly bracket block statements may not be all on one line. this.CheckBracketPlacement( statement, parentElement, statement, statement.FindFirstChild<OpenCurlyBracketToken>(), allowAllOnOneLine); break; case StatementType.Switch: // Switch statements may not be all on one line. this.CheckBracketPlacement( statement, parentElement, statement, statement.FindFirstChild<OpenCurlyBracketToken>(), false); break; case StatementType.If: // If-statements should always be followed by a curly bracket block. this.CheckMissingBlock(parentElement, statement, ((IfStatement)statement).Body, statement.FriendlyTypeText, false); break; case StatementType.Else: // Else-statements should always be followed by a curly bracket block. this.CheckMissingBlock(parentElement, statement, ((ElseStatement)statement).Body, statement.FriendlyTypeText, false); break; case StatementType.While: // While-statements should always be followed by a curly bracket block. this.CheckMissingBlock(parentElement, statement, ((WhileStatement)statement).Body, statement.FriendlyTypeText, false); break; case StatementType.For: // For-statements should always be followed by a curly bracket block. this.CheckMissingBlock(parentElement, statement, ((ForStatement)statement).Body, statement.FriendlyTypeText, false); break; case StatementType.Foreach: // Foreach-statements should always be followed by a curly bracket block. this.CheckMissingBlock(parentElement, statement, ((ForeachStatement)statement).Body, statement.FriendlyTypeText, false); break; case StatementType.DoWhile: // Do-while-statements should always be followed by a curly bracket block. this.CheckMissingBlock(parentElement, statement, ((DoWhileStatement)statement).Body, statement.FriendlyTypeText, false); break; case StatementType.Using: // Using-statements should always be followed by a curly bracket block. this.CheckMissingBlock(parentElement, statement, ((UsingStatement)statement).Body, statement.FriendlyTypeText, true); break; default: break; } return true; }
/// <summary> /// Processes the given statement. /// </summary> /// <param name="statement">The statement to process.</param> /// <param name="element">The parent element.</param> /// <param name="validPrefixes">The list of acceptable Hungarian-type prefixes.</param> private void ProcessStatement(Statement statement, Element element, Dictionary<string, string> validPrefixes) { Param.AssertNotNull(statement, "statement"); Param.AssertNotNull(element, "element"); Param.AssertNotNull(validPrefixes, "validPrefixes"); // Check the statement's variables. VariableCollection variables = statement.Variables; if (variables != null) { foreach (IVariable variable in variables) { this.CheckMethodVariablePrefix(variable, element, validPrefixes); this.CheckUnderscores(element, variables); } } // Check the expressions under this statement. if (statement.Children.ExpressionCount > 0) { for (Expression expression = statement.FindFirstChildExpression(); expression != null; expression = expression.FindNextSiblingExpression()) { this.ProcessExpression(expression, element, validPrefixes); } } // Check each of the statements under this statement. if (statement.Children.StatementCount > 0) { for (Statement childStatement = statement.FindFirstChildStatement(); childStatement != null; childStatement = childStatement.FindNextSiblingStatement()) { this.ProcessStatement(childStatement, element, validPrefixes); } } }
/// <summary> /// Checks the curly bracket placement on a block statement. /// </summary> /// <param name="element">The element containing the statement.</param> /// <param name="statement">The statement to check.</param> private void CheckBlockStatementsCurlyBracketPlacement(Element element, Statement statement) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(statement, "statement"); // Find the opening curly bracket. var curlyBracket = GetOpeningCurlyBracketFromStatement(statement); if (curlyBracket != null) { // Find the previous item before this opening curly bracket. var previousItem = GetPreviousNonWhitespaceItem(curlyBracket.FindPrevious()); if (previousItem != null) { this.CheckTokenPrecedingOrFollowingCurlyBracket(element, previousItem); } } }
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; } }
/// <summary> /// Checks the placement of the given statement. /// </summary> /// <param name="element">The element containing the statement.</param> /// <param name="statement">The statement to check.</param> /// <param name="previousStatement">The statement just before this statement.</param> private void CheckStatementFormattingRulesForStatement(Element element, Statement statement, Statement previousStatement) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(statement, "statement"); Param.Ignore(previousStatement); // Check if the statement is empty. if (statement.StatementType == StatementType.Empty) { Debug.Assert(statement.FindFirstDescendentToken() != null, "The statement has no tokens."); // There is a special case where an empty statement is allowed. In some cases, a label statement must be used to mark the end of a // scope. C# requires that labels have at least one statement after them. In the developer wants to use a label to mark the end of the // scope, he does not want to put a statement after the label. The best course of action is to insert a single semicolon here. For example:\ // { // if (true) // { // goto end; // } // end:; // } if (previousStatement == null || previousStatement.StatementType != StatementType.Label) { this.AddViolation(element, statement.LineNumber, Rules.CodeMustNotContainEmptyStatements); } } else if (previousStatement != null) { // Make sure this statement is not on the same line as the previous statement. Token statementFirstToken = statement.FindFirstDescendentToken(); Token previousStatementLastToken = previousStatement.FindLastDescendentToken(); if (statementFirstToken.Location.StartPoint.LineNumber == previousStatementLastToken.Location.EndPoint.LineNumber) { this.AddViolation(element, statementFirstToken.LineNumber, Rules.CodeMustNotContainMultipleStatementsOnOneLine); } } // Check the curly bracket spacing in this statement. this.CheckStatementCurlyBracketPlacement(element, statement); // Check the child statements under this statement. this.CheckStatementFormattingRulesForStatements(element, statement); // Check the expressions under this statement. this.CheckStatementFormattingRulesForExpressions(element, statement); }
/// <summary> /// Gets the closing curly bracket from the block statement. /// </summary> /// <param name="statement">The block statement.</param> /// <returns>Returns the closing curly bracket or null if there is none.</returns> private static CloseCurlyBracketToken GetClosingBracketFromStatement(Statement statement) { Param.AssertNotNull(statement, "statement"); BlockStatement blockStatement = GetChildBlockStatement(statement); if (blockStatement != null) { return blockStatement.FindFirstChild<CloseCurlyBracketToken>(); } return null; }
/// <summary> /// Checks to make sure that if, while, for, and foreach statements are followed by a curly bracket block. /// </summary> /// <param name="parentElement">The element containing the statement.</param> /// <param name="statement">The statement which may or may not be missing the child block</param> /// <param name="embeddedStatement">The statement embedded within the if, while, for, or foreach statement.</param> /// <param name="statementType">The user-friendly type of the statement.</param> /// <param name="allowStacks">True to allow statements of the same type to be stacked together where only the last statement in the stack has curly brackets.</param> private void CheckMissingBlock(Element parentElement, Statement statement, Statement embeddedStatement, string statementType, bool allowStacks) { Param.AssertNotNull(parentElement, "parentElement"); Param.AssertNotNull(statement, "statement"); Param.Ignore(embeddedStatement); Param.AssertValidString(statementType, "statementType"); Param.Ignore(allowStacks); if (embeddedStatement != null && embeddedStatement.StatementType != StatementType.Block) { Statement firstChildStatement = statement.FindFirstChildStatement(); if (!allowStacks || firstChildStatement == null || firstChildStatement.StatementType != statement.StatementType) { this.AddViolation(parentElement, embeddedStatement.LineNumber, Rules.CurlyBracketsMustNotBeOmitted, statementType); } } }
/// <summary> /// Checks the placement of curly brackets within the given item. /// </summary> /// <param name="item">The item containing the brackets to check.</param> /// <param name="parentElement">The element containing the brackets.</param> /// <param name="parentStatement">The statement containing the brackets, if any.</param> /// <param name="openBracket">The opening curly bracket within the token list.</param> /// <param name="allowAllOnOneLine">Indicates whether the brackets are allowed to be all on one line.</param> private void CheckBracketPlacement( CodeUnit item, Element parentElement, Statement parentStatement, OpenBracketToken openBracket, bool allowAllOnOneLine) { Param.AssertNotNull(item, "item"); Param.AssertNotNull(parentElement, "parentElement"); Param.Ignore(parentStatement); Param.AssertNotNull(openBracket, "openBracket"); Param.Ignore(allowAllOnOneLine); if (openBracket.MatchingBracket != null && !openBracket.Generated && !openBracket.MatchingBracket.Generated) { // Check if the two brackets are on the same line as each other. if (openBracket.LineNumber == openBracket.MatchingBracket.LineNumber) { // This is an error if the brackets are not allowed to be all on the same line. if (!allowAllOnOneLine) { // Statements within constructor initializers are allowed to be all on the same line // since sometimes this is the only way to write the statement. if (parentStatement == null) { this.AddViolation(parentElement, openBracket.LineNumber, Rules.ElementMustNotBeOnSingleLine, parentElement.FriendlyTypeText); } else if (parentStatement.StatementType != StatementType.ConstructorInitializer) { this.AddViolation(parentElement, openBracket.LineNumber, Rules.StatementMustNotBeOnSingleLine); } } else { // The brackets are only allowed to be on the same line if the entire statement is on the same line. Token first = item.FindFirstDescendentToken(); Token last = item.FindLastDescendentToken(); if (first != null && last != null && first.LineNumber != last.LineNumber) { this.AddViolation(parentElement, openBracket.LineNumber, Rules.CurlyBracketsForMultiLineStatementsMustNotShareLine, GetOpeningOrClosingBracketText(openBracket)); } } } else { // The brackets are on different lines. Both brackets must be on a line all by themselves. if (LayoutRules.BracketSharesLine(openBracket, false)) { this.AddViolation(parentElement, openBracket.LineNumber, Rules.CurlyBracketsForMultiLineStatementsMustNotShareLine, GetOpeningOrClosingBracketText(openBracket)); } if (LayoutRules.BracketSharesLine(openBracket.MatchingBracket, true)) { this.AddViolation(parentElement, openBracket.MatchingBracket.LineNumber, Rules.CurlyBracketsForMultiLineStatementsMustNotShareLine, GetOpeningOrClosingBracketText(openBracket.MatchingBracket)); } } } }
/// <summary> /// Checks the curly brackets under the given expression. /// </summary> /// <param name="expression">The expression being visited.</param> /// <param name="parentExpression">The parent expression, if any.</param> /// <param name="parentStatement">The parent statement, if any.</param> /// <param name="parentElement">The parent element, if any.</param> /// <returns>Returns true to continue, or false to stop the walker.</returns> private bool VisitExpression( Expression expression, Expression parentExpression, Statement parentStatement, Element parentElement) { Param.AssertNotNull(expression, "expression"); Param.Ignore(parentExpression); Param.Ignore(parentStatement); Param.AssertNotNull(parentElement, "parentElement"); switch (expression.ExpressionType) { case ExpressionType.AnonymousMethod: case ExpressionType.Lambda: // An anonymous method or lambda expression is allowed to be all on a single line as long as the entire // expression is on one line. OpenCurlyBracketToken openBracket = expression.FindFirstChild<OpenCurlyBracketToken>(); if (openBracket != null) { bool allowAllOnOneLine = expression.Location.StartPoint.LineNumber == expression.Location.EndPoint.LineNumber; this.CheckBracketPlacement( expression, parentElement, parentStatement, openBracket, allowAllOnOneLine); } break; case ExpressionType.ArrayInitializer: case ExpressionType.ObjectInitializer: case ExpressionType.CollectionInitializer: // If this object or collection initializer is a direct child of another // expression, then use the token list of the parent expression. // This ensures that the initializer cannot only exist all on // one single line if it is also on the same line as the rest of the // parent expression. If this is not a direct child of aanother expression, // this restriction does not apply. CodeUnit openBracketParent = expression; Expression expressionParent = expression.Parent as Expression; if (expressionParent != null) { openBracketParent = expressionParent; } var openCurlyBracket = expression.FindFirstChild<OpenCurlyBracketToken>(); if (openCurlyBracket != null) { this.CheckBracketPlacement( openBracketParent, parentElement, parentStatement, openCurlyBracket, true); } break; default: break; } return true; }
/// <summary> /// Checks to see if the statement is unnecessary. /// </summary> /// <param name="statement">The statement to check.</param> /// <param name="parentElement">The parent element of the statement.</param> private void CheckForUnnecessaryStatements(Statement statement, Element parentElement) { Param.AssertNotNull(statement, "statement"); Param.AssertNotNull(parentElement, "parentElement"); if (!parentElement.Generated) { if (statement.StatementType == StatementType.Finally || statement.StatementType == StatementType.Checked || statement.StatementType == StatementType.Unchecked || statement.StatementType == StatementType.Lock || statement.StatementType == StatementType.Unsafe) { if (IsEmptyParentOfBlockStatement(statement)) { this.AddViolation(parentElement, statement.LineNumber, Rules.RemoveUnnecessaryCode, statement.FriendlyTypeText); } } else if (statement.StatementType == StatementType.Try) { if (IsUnnecessaryTryStatement((TryStatement)statement)) { this.AddViolation(parentElement, statement.LineNumber, Rules.RemoveUnnecessaryCode, statement.FriendlyTypeText); } } } }
/// <summary> /// Called when an expression is visited. /// </summary> /// <param name="expression">The expression being visited.</param> /// <param name="parentExpression">The parent expression, if any.</param> /// <param name="parentStatement">The parent statement, if any.</param> /// <param name="parentElement">The parent element, if any.</param> /// <returns>Returns true to continue, or false to stop the walker.</returns> private bool VisitExpression(Expression expression, Expression parentExpression, Statement parentStatement, Element parentElement) { Param.AssertNotNull(expression, "expression"); Param.Ignore(parentExpression); Param.Ignore(parentStatement); Param.AssertNotNull(parentElement, "parentElement"); if (!parentElement.Generated) { // Determine whether this expression is a method invocation which contains call to Debug.Fail or Debug.Assert. if (expression.ExpressionType == ExpressionType.MethodInvocation) { MethodInvocationExpression methodInvocation = (MethodInvocationExpression)expression; if (methodInvocation.Name.MatchTokens("Debug", ".", "Assert") || methodInvocation.Name.MatchTokens("System", ".", "Diagnostics", ".", "Debug", ".", "Assert")) { this.CheckDebugAssertMessage(parentElement, methodInvocation); } else if (methodInvocation.Name.MatchTokens("Debug", ".", "Fail") || methodInvocation.Name.MatchTokens("System", ".", "Diagnostics", ".", "Debug", ".", "Fail")) { this.CheckDebugFailMessage(parentElement, methodInvocation); } } else if (expression.ExpressionType == ExpressionType.Parenthesized) { this.CheckParenthesizedExpression(parentElement, (ParenthesizedExpression)expression); } else if (expression.ExpressionType == ExpressionType.Arithmetic) { this.CheckArithmeticExpressionParenthesis(parentElement, (ArithmeticExpression)expression); } else if (expression.ExpressionType == ExpressionType.ConditionalLogical) { this.CheckConditionalLogicalExpressionParenthesis(parentElement, (ConditionalLogicalExpression)expression); } else if (expression.ExpressionType == ExpressionType.AnonymousMethod) { this.CheckAnonymousMethodParenthesis(parentElement, (AnonymousMethodExpression)expression); } } return true; }
/// <summary> /// Checks the curly bracket placement on a statement which is chained from another statement. /// </summary> /// <param name="element">The element containing the statement.</param> /// <param name="statement">The statement to check.</param> private void CheckChainedStatementCurlyBracketPlacement(Element element, Statement statement) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(statement, "statement"); // Get the previous token before the start of this statement. if (statement.FindFirstChildToken() != null) { // Find the opening curly bracket. var curlyBracket = GetOpeningCurlyBracketFromStatement(statement); if (curlyBracket != null) { // Find the previous token before this opening curly bracket. var previousItem = GetPreviousNonWhitespaceItem(curlyBracket.FindPrevious()); if (previousItem != null) { this.CheckTokenPrecedingOrFollowingCurlyBracket(element, previousItem); } } } }
/// <summary> /// Visits one code unit in the document. /// </summary> /// <param name="codeUnit">The item being visited.</param> /// <param name="parentElement">The parent element, if any.</param> /// <param name="parentStatement">The parent statement, if any.</param> /// <param name="parentExpression">The parent expression, if any.</param> /// <param name="parentClause">The parent query clause, if any.</param> /// <param name="parentToken">The parent token, if any.</param> /// <param name="settings">The settings.</param> /// <returns>Returns true to continue, or false to stop the walker.</returns> private bool VisitCodeUnit( CodeUnit codeUnit, Element parentElement, Statement parentStatement, Expression parentExpression, QueryClause parentClause, Token parentToken, Settings settings) { Param.AssertNotNull(codeUnit, "codeUnit"); Param.Ignore(parentElement, parentStatement, parentExpression, parentClause, parentToken); Param.AssertNotNull(settings, "settings"); if (codeUnit.CodeUnitType == CodeUnitType.Element) { return this.VisitElement((Element)codeUnit, settings); } else if (codeUnit.CodeUnitType == CodeUnitType.Expression) { return this.VisitExpression((Expression)codeUnit, parentElement); } else if (codeUnit.Is(LexicalElementType.Token)) { Token token = (Token)codeUnit; if (token.TokenType == TokenType.Type && !token.Parent.Is(TokenType.Type)) { // Check that the type is using the built-in types, if applicable. this.CheckBuiltInType((TypeToken)token, parentElement); } else if (token.TokenType == TokenType.String) { // Check that the string is not using the empty string "" syntax. this.CheckEmptyString(token, parentElement); } } else if (codeUnit.Is(PreprocessorType.Region)) { this.CheckRegion((RegionDirective)codeUnit, parentElement, settings); } else if (codeUnit.Is(LexicalElementType.Comment)) { this.CheckForEmptyComments((Comment)codeUnit, parentElement); } return !this.Cancel; }
/// <summary> /// Checks the curly at the end of a statement which trails the rest of the statement. /// </summary> /// <param name="element">The element containing the statement.</param> /// <param name="statement">The statement to check.</param> private void CheckTrailingStatementCurlyBracketPlacement(Element element, Statement statement) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(statement, "statement"); var curlyBracket = GetClosingBracketFromStatement(statement); if (curlyBracket != null) { // Find the next token after this closing curly bracket. var nextItem = GetNextNonWhitespaceItem(curlyBracket.FindNext()); if (nextItem != null) { this.CheckTokenPrecedingOrFollowingCurlyBracket(element, nextItem); } } }