/// <summary> /// Gets the non-whitespace token that appears after the given token. /// </summary> /// <param name="tokenNode"> /// The token node. /// </param> /// <param name="tokenList"> /// The list that contains the token. /// </param> /// <returns> /// Returns the next token. /// </returns> private static CsToken GetNextToken(Node <CsToken> tokenNode, MasterList <CsToken> tokenList) { Param.AssertNotNull(tokenNode, "tokenNode"); Param.AssertNotNull(tokenList, "tokenList"); foreach (CsToken temp in tokenList.ForwardIterator(tokenNode)) { if (temp.CsTokenType != CsTokenType.EndOfLine && temp.CsTokenType != CsTokenType.WhiteSpace) { return(temp); } } return(null); }
private void CheckCloseCurlyBracket(DocumentRoot root, MasterList<CsToken> tokens, Node<CsToken> tokenNode) { Node<CsToken> previous = tokenNode.Previous; if (((previous != null) && (previous.Value.CsTokenType != CsTokenType.WhiteSpace)) && (previous.Value.CsTokenType != CsTokenType.EndOfLine)) { base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.ClosingCurlyBracketsMustBeSpacedCorrectly, new object[0]); } Node<CsToken> next = tokenNode.Next; if (next != null) { CsTokenType csTokenType = next.Value.CsTokenType; if ((((csTokenType != CsTokenType.WhiteSpace) && (csTokenType != CsTokenType.EndOfLine)) && ((csTokenType != CsTokenType.CloseParenthesis) && (csTokenType != CsTokenType.Semicolon))) && (csTokenType != CsTokenType.Comma)) { base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.ClosingCurlyBracketsMustBeSpacedCorrectly, new object[0]); } if (csTokenType == CsTokenType.WhiteSpace) { foreach (CsToken token in tokens.ForwardIterator(tokenNode.Next.Next)) { CsTokenType type2 = token.CsTokenType; switch (type2) { case CsTokenType.CloseParenthesis: case CsTokenType.Semicolon: case CsTokenType.Comma: { base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.ClosingCurlyBracketsMustBeSpacedCorrectly, new object[0]); continue; } } if (type2 != CsTokenType.WhiteSpace) { return; } } } } }
private void CheckCloseParen(DocumentRoot root, MasterList<CsToken> tokens, Node<CsToken> tokenNode) { Node<CsToken> previous = tokenNode.Previous; if ((previous != null) && ((previous.Value.CsTokenType == CsTokenType.WhiteSpace) || (previous.Value.CsTokenType == CsTokenType.EndOfLine))) { base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.ClosingParenthesisMustBeSpacedCorrectly, new object[0]); } Node<CsToken> next = tokenNode.Next; if (next == null) { return; } CsTokenType csTokenType = next.Value.CsTokenType; if (((csTokenType == CsTokenType.WhiteSpace || csTokenType == CsTokenType.EndOfLine || csTokenType == CsTokenType.CloseParenthesis || csTokenType == CsTokenType.OpenParenthesis || csTokenType == CsTokenType.CloseSquareBracket || csTokenType == CsTokenType.OpenSquareBracket || csTokenType == CsTokenType.CloseAttributeBracket || csTokenType == CsTokenType.Semicolon || csTokenType == CsTokenType.Comma || csTokenType == CsTokenType.Other || csTokenType == CsTokenType.Base || csTokenType == CsTokenType.This || csTokenType == CsTokenType.Null || csTokenType == CsTokenType.New || csTokenType == CsTokenType.Number || csTokenType == CsTokenType.String // Oleg Shuruev added || csTokenType == CsTokenType.Typeof) || ((csTokenType == CsTokenType.Delegate) || ((csTokenType == CsTokenType.OperatorSymbol) && (((OperatorSymbol)next.Value).SymbolType == OperatorType.AddressOf)))) || next.Value.Text.StartsWith(".", StringComparison.Ordinal)) { goto Label_01C1; } bool flag = false; if (csTokenType == CsTokenType.OperatorSymbol) { OperatorSymbol symbol = next.Value as OperatorSymbol; if ((symbol.SymbolType == OperatorType.Negative) || (symbol.SymbolType == OperatorType.Positive)) { flag = true; } } if (flag) { goto Label_01C1; } bool flag2 = false; if (csTokenType == CsTokenType.LabelColon) { foreach (CsToken token in tokens.ReverseIterator(tokenNode.Previous)) { switch (token.CsTokenType) { case CsTokenType.EndOfLine: goto Label_019E; case CsTokenType.Case: flag2 = true; goto Label_019E; } } } Label_019E: if (!flag2) { base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.ClosingParenthesisMustBeSpacedCorrectly, new object[0]); } Label_01C1: if (csTokenType == CsTokenType.WhiteSpace) { foreach (CsToken token2 in tokens.ForwardIterator(tokenNode.Next.Next)) { CsTokenType type3 = token2.CsTokenType; switch (type3) { case CsTokenType.CloseParenthesis: case CsTokenType.OpenParenthesis: case CsTokenType.CloseSquareBracket: case CsTokenType.OpenSquareBracket: case CsTokenType.Semicolon: case CsTokenType.Comma: { base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.ClosingParenthesisMustBeSpacedCorrectly, new object[0]); continue; } } if (type3 != CsTokenType.WhiteSpace) { return; } } } }
private void CheckOpenParen(DocumentRoot root, MasterList<CsToken> tokens, Node<CsToken> tokenNode) { Node<CsToken> node2; bool flag = false; bool flag2 = false; Node<CsToken> previous = tokenNode.Previous; if ((previous != null) && (previous.Value.CsTokenType == CsTokenType.WhiteSpace)) { foreach (CsToken token in tokens.ReverseIterator(previous)) { switch (token.CsTokenType) { case CsTokenType.WhiteSpace: { continue; } case CsTokenType.EndOfLine: flag = true; goto Label_017C; case CsTokenType.Case: case CsTokenType.Catch: case CsTokenType.CloseSquareBracket: case CsTokenType.Comma: case CsTokenType.Equals: case CsTokenType.Fixed: case CsTokenType.For: case CsTokenType.Foreach: case CsTokenType.From: case CsTokenType.Group: case CsTokenType.If: case CsTokenType.In: case CsTokenType.Into: case CsTokenType.Join: case CsTokenType.Let: case CsTokenType.Lock: case CsTokenType.MultiLineComment: case CsTokenType.Number: case CsTokenType.OperatorSymbol: case CsTokenType.OpenCurlyBracket: case CsTokenType.OrderBy: case CsTokenType.Return: case CsTokenType.Select: case CsTokenType.Semicolon: case CsTokenType.Switch: case CsTokenType.Throw: case CsTokenType.Using: case CsTokenType.Where: case CsTokenType.While: case CsTokenType.WhileDo: case CsTokenType.Yield: goto Label_017C; } base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.OpeningParenthesisMustBeSpacedCorrectly, new object[0]); } } Label_017C: node2 = tokenNode.Next; if ((node2 != null) && ((node2.Value.CsTokenType == CsTokenType.WhiteSpace) || (node2.Value.CsTokenType == CsTokenType.EndOfLine))) { foreach (CsToken token2 in tokens.ForwardIterator(node2)) { CsTokenType csTokenType = token2.CsTokenType; if (csTokenType == CsTokenType.EndOfLine) { flag2 = true; break; } if (((csTokenType != CsTokenType.WhiteSpace) && (csTokenType != CsTokenType.SingleLineComment)) && (csTokenType != CsTokenType.MultiLineComment)) { base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.OpeningParenthesisMustBeSpacedCorrectly, new object[0]); break; } } } if (flag && flag2) { base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.OpeningParenthesisMustBeSpacedCorrectly, new object[0]); } }
private void CheckNewKeywordSpacing(DocumentRoot root, MasterList<CsToken> tokens, Node<CsToken> tokenNode) { Node<CsToken> next = tokenNode.Next; if (next != null) { if ((next.Value.CsTokenType == CsTokenType.WhiteSpace) || (next.Value.CsTokenType == CsTokenType.EndOfLine)) { foreach (CsToken token in tokens.ForwardIterator(next.Next)) { if (token.CsTokenType == CsTokenType.OpenSquareBracket) { base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.CodeMustNotContainSpaceAfterNewKeywordInImplicitlyTypedArrayAllocation, new object[0]); break; } if ((token.CsTokenType != CsTokenType.WhiteSpace) && (token.CsTokenType != CsTokenType.EndOfLine)) { break; } } } else if (next.Value.CsTokenType != CsTokenType.OpenSquareBracket) { base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.KeywordsMustBeSpacedCorrectly, new object[] { tokenNode.Value.Text }); } } }
private void CheckKeywordWithoutSpace(DocumentRoot root, MasterList<CsToken> tokens, Node<CsToken> tokenNode) { Node<CsToken> next = tokenNode.Next; if ((next != null) && ((next.Value.CsTokenType == CsTokenType.WhiteSpace) || (next.Value.CsTokenType == CsTokenType.EndOfLine))) { foreach (CsToken token in tokens.ForwardIterator(next.Next)) { if (token.CsTokenType == CsTokenType.OpenParenthesis) { base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.KeywordsMustBeSpacedCorrectly, new object[] { tokenNode.Value.Text }); break; } if ((token.CsTokenType != CsTokenType.WhiteSpace) && (token.CsTokenType != CsTokenType.EndOfLine)) { break; } } } }
private void CheckOpenParen(MasterList<CsToken> tokens, Node<CsToken> tokenNode) { Param.AssertNotNull(tokens, "tokens"); Param.AssertNotNull(tokenNode, "tokenNode"); bool firstOnLine = false; bool lastOnLine = false; // Open parenthesis should never be preceded by whitespace unless it is the // first thing on the line or it follows a keyword or it follows a symbol or a number. Node<CsToken> previousNode = tokenNode.Previous; if (previousNode != null) { if (previousNode.Value.CsTokenType == CsTokenType.WhiteSpace) { foreach (CsToken item in tokens.ReverseIterator(previousNode)) { CsTokenType itemType = item.CsTokenType; if (itemType == CsTokenType.WhiteSpace) { continue; } if (itemType == CsTokenType.EndOfLine) { firstOnLine = true; break; } if (itemType == CsTokenType.Case || itemType == CsTokenType.Catch || itemType == CsTokenType.CloseSquareBracket || itemType == CsTokenType.Comma || itemType == CsTokenType.Equals || itemType == CsTokenType.Fixed || itemType == CsTokenType.For || itemType == CsTokenType.Foreach || itemType == CsTokenType.From || ////itemType == CsTokenType.Goto || itemType == CsTokenType.Group || itemType == CsTokenType.If || itemType == CsTokenType.In || itemType == CsTokenType.Into || itemType == CsTokenType.Join || itemType == CsTokenType.Let || itemType == CsTokenType.Lock || itemType == CsTokenType.MultiLineComment || ////itemType == CsTokenType.New || itemType == CsTokenType.Number || itemType == CsTokenType.OperatorSymbol || itemType == CsTokenType.OpenCurlyBracket || itemType == CsTokenType.OrderBy || itemType == CsTokenType.Return || itemType == CsTokenType.Select || itemType == CsTokenType.Semicolon || ////itemType == CsTokenType.SingleLineComment || itemType == CsTokenType.Switch || itemType == CsTokenType.Throw || itemType == CsTokenType.Using || itemType == CsTokenType.Where || itemType == CsTokenType.While || itemType == CsTokenType.WhileDo || itemType == CsTokenType.Yield || itemType == CsTokenType.LabelColon || itemType == CsTokenType.Async || itemType == CsTokenType.By || itemType == CsTokenType.When) { break; } this.AddViolation(tokenNode.Value.FindParentElement(), previousNode.Value.Location, Rules.OpeningParenthesisMustBeSpacedCorrectly); } } } // Open parens should never be followed by whitespace unless // it is the last thing on the line. Node<CsToken> next = tokenNode.Next; if (next != null && (next.Value.CsTokenType == CsTokenType.WhiteSpace || next.Value.CsTokenType == CsTokenType.EndOfLine)) { // Look to see if there is any non whitespace character // on this line other than a comment. foreach (CsToken item in tokens.ForwardIterator(next)) { CsTokenType itemType = item.CsTokenType; if (itemType == CsTokenType.EndOfLine) { lastOnLine = true; break; } else if (itemType != CsTokenType.WhiteSpace && itemType != CsTokenType.SingleLineComment && itemType != CsTokenType.MultiLineComment) { this.AddViolation(tokenNode.Value.FindParentElement(), next.Value.Location, Rules.OpeningParenthesisMustBeSpacedCorrectly); break; } } } // Open parens cannot be the only thing on the line. if (firstOnLine && lastOnLine) { this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.OpeningParenthesisMustBeSpacedCorrectly); } }
/// <summary> /// Checks the spacing around a 'new' keyword. /// </summary> /// <param name="tokens"> /// The token list. /// </param> /// <param name="tokenNode"> /// The token node to check. /// </param> private void CheckNewKeywordSpacing(MasterList<CsToken> tokens, Node<CsToken> tokenNode) { Param.AssertNotNull(tokens, "tokens"); Param.AssertNotNull(tokenNode, "tokenNode"); // The keywords must be followed by a space, unless the next token is an opening square bracket, in which case // there should be no space. Node<CsToken> temp = tokenNode.Next; if (temp != null) { if (temp.Value.CsTokenType == CsTokenType.WhiteSpace || temp.Value.CsTokenType == CsTokenType.EndOfLine) { // The keyword is followed by whitespace. Make sure the next non-whitespace character is not an opening bracket. foreach (CsToken nextNonWhitespaceToken in tokens.ForwardIterator(temp.Next)) { if (nextNonWhitespaceToken.CsTokenType == CsTokenType.OpenSquareBracket) { this.AddViolation( tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.CodeMustNotContainSpaceAfterNewKeywordInImplicitlyTypedArrayAllocation); break; } else if (nextNonWhitespaceToken.CsTokenType != CsTokenType.WhiteSpace && nextNonWhitespaceToken.CsTokenType != CsTokenType.EndOfLine) { break; } } } else if (temp.Value.CsTokenType != CsTokenType.OpenSquareBracket) { // The keyword is not followed by whitespace. this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.KeywordsMustBeSpacedCorrectly, tokenNode.Value.Text); } } }
/// <summary> /// Checks a keyword that should not be followed by a space. /// </summary> /// <param name="tokens"> /// The list of tokens being parsed. /// </param> /// <param name="tokenNode"> /// The token to check. /// </param> private void CheckKeywordWithoutSpace(MasterList<CsToken> tokens, Node<CsToken> tokenNode) { Param.AssertNotNull(tokens, "tokens"); Param.AssertNotNull(tokenNode, "tokenNode"); // Keywords must not contain any space before the open parenthesis. Node<CsToken> temp = tokenNode.Next; if (temp != null && (temp.Value.CsTokenType == CsTokenType.WhiteSpace || temp.Value.CsTokenType == CsTokenType.EndOfLine)) { // Make sure the next non-whitespace character is not an open parenthesis. foreach (CsToken nextNonWhitespaceToken in tokens.ForwardIterator(temp.Next)) { if (nextNonWhitespaceToken.CsTokenType == CsTokenType.OpenParenthesis) { this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.KeywordsMustBeSpacedCorrectly, tokenNode.Value.Text); break; } else if (nextNonWhitespaceToken.CsTokenType != CsTokenType.WhiteSpace && nextNonWhitespaceToken.CsTokenType != CsTokenType.EndOfLine) { break; } } } }
private void CheckCloseSquareBracket(MasterList<CsToken> tokens, Node<CsToken> tokenNode, Node<CsToken> parentTokenNode) { Param.AssertNotNull(tokens, "tokens"); Param.AssertNotNull(tokenNode, "tokenNode"); Param.Ignore(parentTokenNode); // Close brackets should never be preceded by whitespace. Node<CsToken> previousNode = tokenNode.Previous; if (previousNode != null && (previousNode.Value.CsTokenType == CsTokenType.WhiteSpace || previousNode.Value.CsTokenType == CsTokenType.EndOfLine)) { this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.ClosingSquareBracketsMustBeSpacedCorrectly); } // Close brackets should be followed either by whitespace, a bracket, // a paren, a semicolon, a comma, a period, or an increment or decrement symbol. Node<CsToken> nextNode = tokenNode.Next ?? parentTokenNode.Next; if (nextNode != null) { CsTokenType nextType = nextNode.Value.CsTokenType; if (nextType != CsTokenType.WhiteSpace && nextType != CsTokenType.EndOfLine && nextType != CsTokenType.CloseParenthesis && nextType != CsTokenType.OpenParenthesis && // someDictionary["Test"](); nextType != CsTokenType.CloseSquareBracket && // someIndexer[someArray[1]] = 2; nextType != CsTokenType.OpenSquareBracket && // someArray[1][2] = 2; nextType != CsTokenType.Semicolon && nextType != CsTokenType.Comma && nextType != CsTokenType.CloseGenericBracket && nextNode.Value.Text != "++" && nextNode.Value.Text != "--" && nextNode.Value.Text != "?." && nextNode.Value.Text != "?" && !nextNode.Value.Text.StartsWith(".", StringComparison.Ordinal)) { this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.ClosingSquareBracketsMustBeSpacedCorrectly); } if (nextType == CsTokenType.WhiteSpace) { // If this is followed by whitespace, make sure that the character just // after the whitespace is not a paren, bracket, comma, or semicolon. foreach (CsToken item in tokens.ForwardIterator(nextNode.Next)) { CsTokenType itemType = item.CsTokenType; if (itemType == CsTokenType.CloseParenthesis || itemType == CsTokenType.OpenParenthesis || itemType == CsTokenType.CloseSquareBracket || itemType == CsTokenType.OpenSquareBracket || itemType == CsTokenType.Semicolon || itemType == CsTokenType.Comma) { this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.ClosingSquareBracketsMustBeSpacedCorrectly); } else if (itemType != CsTokenType.WhiteSpace) { break; } } } } }
private void CheckCloseParen(MasterList<CsToken> tokens, Node<CsToken> tokenNode) { Param.AssertNotNull(tokens, "tokens"); Param.AssertNotNull(tokenNode, "tokenNode"); // Close parens should never be preceded by whitespace. Node<CsToken> previousNode = tokenNode.Previous; if (previousNode != null) { if (previousNode.Value.CsTokenType == CsTokenType.WhiteSpace || (previousNode.Value.CsTokenType == CsTokenType.EndOfLine && previousNode.Previous.Value.CsTokenType != CsTokenType.SingleLineComment)) { this.AddViolation(tokenNode.Value.FindParentElement(), previousNode.Value.Location, Rules.ClosingParenthesisMustBeSpacedCorrectly); } } // Find out what comes after the closing paren. Node<CsToken> nextNode = tokenNode.Next; if (nextNode != null) { CsTokenType nextType = nextNode.Value.CsTokenType; CsTokenType nextNextType = nextNode.Next == null ? CsTokenType.Other : nextNode.Next.Value.CsTokenType; if (tokenNode.Value.Parent is CastExpression) { // There should not be any whitespace after the closing parenthesis in a cast expression. if (nextType == CsTokenType.WhiteSpace) { this.AddViolation(tokenNode.Value.FindParentElement(), nextNode.Value.Location, Rules.ClosingParenthesisMustBeSpacedCorrectly); } } else if (nextType == CsTokenType.LabelColon || nextNextType == CsTokenType.LabelColon) { // If the next token is a colon, it's allowed to omit the whitespace only if we are in a switch\case statement. bool followsCase = false; foreach (CsToken item in tokens.ReverseIterator(tokenNode.Previous)) { CsTokenType itemType = item.CsTokenType; if (itemType == CsTokenType.EndOfLine) { break; } else if (itemType == CsTokenType.Case) { followsCase = true; break; } } if ((followsCase && nextType == CsTokenType.WhiteSpace) || (!followsCase && nextType != CsTokenType.WhiteSpace)) { this.AddViolation(tokenNode.Value.FindParentElement(), nextNode.Value.Location, Rules.ClosingParenthesisMustBeSpacedCorrectly); } } else if (nextType == CsTokenType.WhiteSpace) { // Make sure that the character just after the whitespace is not a paren, bracket, a comma, or a semicolon. foreach (CsToken item in tokens.ForwardIterator(tokenNode.Next.Next)) { if (IsAllowedAfterClosingParenthesis(item)) { this.AddViolation(tokenNode.Value.FindParentElement(), nextNode.Value.Location, Rules.ClosingParenthesisMustBeSpacedCorrectly); } else if (item.CsTokenType != CsTokenType.WhiteSpace) { break; } } } else { // For all other types, the parenthesis must be followed by whitespace, unless the next character is a paren, bracket, comma, or a semicolon. if (nextNode.Value.CsTokenType != CsTokenType.EndOfLine && !IsAllowedAfterClosingParenthesis(nextNode.Value)) { this.AddViolation(tokenNode.Value.FindParentElement(), nextNode.Value.Location, Rules.ClosingParenthesisMustBeSpacedCorrectly); } } } }
/// <summary> /// Checks a close bracket for spacing. /// </summary> /// <param name="tokens"> /// The list of tokens being parsed. /// </param> /// <param name="tokenNode"> /// The token to check. /// </param> private void CheckCloseCurlyBracket(MasterList<CsToken> tokens, Node<CsToken> tokenNode) { Param.AssertNotNull(tokens, "tokens"); Param.AssertNotNull(tokenNode, "tokenNode"); // Close curly brackets should always be preceded by whitespace. Node<CsToken> previousNode = tokenNode.Previous; if (previousNode != null && previousNode.Value.CsTokenType != CsTokenType.WhiteSpace && previousNode.Value.CsTokenType != CsTokenType.EndOfLine) { this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.ClosingCurlyBracketsMustBeSpacedCorrectly); } // Close curly brackets should be followed either by: // whitespace // a close paren // a dot, // a semicolon // open square bracket // or a comma. Node<CsToken> nextNode = tokenNode.Next; if (nextNode != null) { CsTokenType nextType = nextNode.Value.CsTokenType; if (nextType != CsTokenType.WhiteSpace && nextType != CsTokenType.EndOfLine && nextType != CsTokenType.CloseParenthesis && !IsTokenADot(nextNode.Value) && nextType != CsTokenType.Semicolon && nextType != CsTokenType.OpenSquareBracket && nextType != CsTokenType.Comma) { this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.ClosingCurlyBracketsMustBeSpacedCorrectly); } if (nextType == CsTokenType.WhiteSpace) { // If this is followed by whitespace, make sure that the character just // after the whitespace is not a close paren, semicolon, comma or dot. foreach (CsToken item in tokens.ForwardIterator(tokenNode.Next.Next)) { CsTokenType itemType = item.CsTokenType; if (itemType == CsTokenType.CloseParenthesis || itemType == CsTokenType.Semicolon || itemType == CsTokenType.Comma || IsTokenADot(item)) { this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.ClosingCurlyBracketsMustBeSpacedCorrectly); } else if (itemType != CsTokenType.WhiteSpace) { break; } } } } }
/// <summary> /// Gets the non-whitespace token that appears after the given token. /// </summary> /// <param name="tokenNode"> /// The token node. /// </param> /// <param name="tokenList"> /// The list that contains the token. /// </param> /// <returns> /// Returns the next token. /// </returns> private static CsToken GetNextToken(Node<CsToken> tokenNode, MasterList<CsToken> tokenList) { Param.AssertNotNull(tokenNode, "tokenNode"); Param.AssertNotNull(tokenList, "tokenList"); foreach (CsToken temp in tokenList.ForwardIterator(tokenNode)) { if (temp.CsTokenType != CsTokenType.EndOfLine && temp.CsTokenType != CsTokenType.WhiteSpace) { return temp; } } return null; }
/// <summary> /// Checks a close paren for spacing. /// </summary> /// <param name="root">The document root.</param> /// <param name="tokens">The list of tokens being parsed.</param> /// <param name="tokenNode">The token to check.</param> private void CheckCloseParen(DocumentRoot root, MasterList<CsToken> tokens, Node<CsToken> tokenNode) { Param.AssertNotNull(root, "root"); Param.AssertNotNull(tokens, "tokens"); Param.AssertNotNull(tokenNode, "tokenNode"); // Close parens should never be preceded by whitespace. Node<CsToken> previousNode = tokenNode.Previous; if (previousNode != null && (previousNode.Value.CsTokenType == CsTokenType.WhiteSpace || previousNode.Value.CsTokenType == CsTokenType.EndOfLine)) { this.AddViolation(root, tokenNode.Value.LineNumber, Rules.ClosingParenthesisMustBeSpacedCorrectly); } // This not a violation if the token following the close paren is an unknown token, // which means that this is probably the closing paren of a cast operation. The same // goes if the next token is "base" or "this". Node<CsToken> nextNode = tokenNode.Next; if (nextNode != null) { CsTokenType nextType = nextNode.Value.CsTokenType; // The closing parenthesis could be the end of a cast expression if it comes // before one of the following types of tokens. // TODO: Once it is possible to determine the parent expression of a token, // we can explicitly check whether the closing parenthesis is part of a cast // expression, and all of the following cases. if (nextType != CsTokenType.WhiteSpace && nextType != CsTokenType.EndOfLine && nextType != CsTokenType.CloseParenthesis && nextType != CsTokenType.OpenParenthesis && nextType != CsTokenType.CloseSquareBracket && nextType != CsTokenType.OpenSquareBracket && nextType != CsTokenType.CloseAttributeBracket && nextType != CsTokenType.Semicolon && nextType != CsTokenType.Comma && nextType != CsTokenType.Other && nextType != CsTokenType.Base && nextType != CsTokenType.This && nextType != CsTokenType.Null && nextType != CsTokenType.New && nextType != CsTokenType.Number && nextType != CsTokenType.String && nextType != CsTokenType.Delegate && (nextType != CsTokenType.OperatorSymbol || ((OperatorSymbol)nextNode.Value).SymbolType != OperatorType.AddressOf) && !nextNode.Value.Text.StartsWith(".", StringComparison.Ordinal)) { // This is allowed also if the next token is a positive or negative sign. bool cancel = false; if (nextType == CsTokenType.OperatorSymbol) { OperatorSymbol operatorSymbol = nextNode.Value as OperatorSymbol; if (operatorSymbol.SymbolType == OperatorType.Negative || operatorSymbol.SymbolType == OperatorType.Positive) { cancel = true; } } if (!cancel) { // If the next token is a colon, this is allowed if we are in a switch\case statement. bool followsCase = false; if (nextType == CsTokenType.LabelColon) { foreach (CsToken item in tokens.ReverseIterator(tokenNode.Previous)) { CsTokenType itemType = item.CsTokenType; if (itemType == CsTokenType.EndOfLine) { break; } else if (itemType == CsTokenType.Case) { followsCase = true; break; } } } if (!followsCase) { this.AddViolation(root, tokenNode.Value.LineNumber, Rules.ClosingParenthesisMustBeSpacedCorrectly); } } } if (nextType == CsTokenType.WhiteSpace) { // If this is followed by whitespace, make sure that the character just // after the whitespace is not a paren, bracket, a comma, or a semicolon. foreach (CsToken item in tokens.ForwardIterator(tokenNode.Next.Next)) { CsTokenType itemType = item.CsTokenType; if (itemType == CsTokenType.CloseParenthesis || itemType == CsTokenType.OpenParenthesis || itemType == CsTokenType.CloseSquareBracket || itemType == CsTokenType.OpenSquareBracket || itemType == CsTokenType.Semicolon || itemType == CsTokenType.Comma) { this.AddViolation(root, tokenNode.Value.LineNumber, Rules.ClosingParenthesisMustBeSpacedCorrectly); } else if (itemType != CsTokenType.WhiteSpace) { break; } } } } }
/// <summary> /// Checks a close bracket for spacing. /// </summary> /// <param name="root">The document root.</param> /// <param name="tokens">The list of tokens being parsed.</param> /// <param name="tokenNode">The token to check.</param> private void CheckCloseCurlyBracket(DocumentRoot root, MasterList<CsToken> tokens, Node<CsToken> tokenNode) { Param.AssertNotNull(root, "root"); Param.AssertNotNull(tokens, "tokens"); Param.AssertNotNull(tokenNode, "tokenNode"); // Close curly brackets should always be preceded by whitespace. Node<CsToken> previousNode = tokenNode.Previous; if (previousNode != null && previousNode.Value.CsTokenType != CsTokenType.WhiteSpace && previousNode.Value.CsTokenType != CsTokenType.EndOfLine) { this.AddViolation(root, tokenNode.Value.LineNumber, Rules.ClosingCurlyBracketsMustBeSpacedCorrectly); } // Close curly brackets should be followed either by whitespace, a close paren, // a semicolon, or a comma. Node<CsToken> nextNode = tokenNode.Next; if (nextNode != null) { CsTokenType nextType = nextNode.Value.CsTokenType; if (nextType != CsTokenType.WhiteSpace && nextType != CsTokenType.EndOfLine && nextType != CsTokenType.CloseParenthesis && nextType != CsTokenType.Semicolon && nextType != CsTokenType.Comma) { this.AddViolation(root, tokenNode.Value.LineNumber, Rules.ClosingCurlyBracketsMustBeSpacedCorrectly); } if (nextType == CsTokenType.WhiteSpace) { // If this is followed by whitespace, make sure that the character just // after the whitespace is not a close paren, semicolon, or comma. foreach (CsToken item in tokens.ForwardIterator(tokenNode.Next.Next)) { CsTokenType itemType = item.CsTokenType; if (itemType == CsTokenType.CloseParenthesis || itemType == CsTokenType.Semicolon || itemType == CsTokenType.Comma) { this.AddViolation(root, tokenNode.Value.LineNumber, Rules.ClosingCurlyBracketsMustBeSpacedCorrectly); } else if (itemType != CsTokenType.WhiteSpace) { break; } } } } }