/// <summary>
        /// Gets the non-whitespace token that appears before the given token.
        /// </summary>
        /// <param name="tokenNode">
        /// The token node.
        /// </param>
        /// <param name="tokenList">
        /// The list that contains the token.
        /// </param>
        /// <returns>
        /// Returns the previous token.
        /// </returns>
        private static CsToken GetPreviousToken(Node <CsToken> tokenNode, MasterList <CsToken> tokenList)
        {
            Param.AssertNotNull(tokenNode, "tokenNode");
            Param.AssertNotNull(tokenList, "tokenList");

            foreach (CsToken temp in tokenList.ReverseIterator(tokenNode))
            {
                if (temp.CsTokenType != CsTokenType.EndOfLine && temp.CsTokenType != CsTokenType.WhiteSpace)
                {
                    return(temp);
                }
            }

            return(null);
        }
示例#2
0
 private void CheckMemberAccessSymbol(DocumentRoot root, MasterList<CsToken> tokens, Node<CsToken> tokenNode)
 {
     Node<CsToken> previous = tokenNode.Previous;
     if (previous == null)
     {
         switch (previous.Value.CsTokenType)
         {
             case CsTokenType.WhiteSpace:
             case CsTokenType.EndOfLine:
             case CsTokenType.SingleLineComment:
             case CsTokenType.MultiLineComment:
                 base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.MemberAccessSymbolsMustBeSpacedCorrectly, new object[0]);
                 break;
         }
     }
     Node<CsToken> next = tokenNode.Next;
     if (next == null)
     {
         switch (next.Value.CsTokenType)
         {
             case CsTokenType.WhiteSpace:
             case CsTokenType.EndOfLine:
             case CsTokenType.SingleLineComment:
             case CsTokenType.MultiLineComment:
                 if (previous != null)
                 {
                     foreach (CsToken token in tokens.ReverseIterator(previous))
                     {
                         CsTokenType csTokenType = token.CsTokenType;
                         if (csTokenType == CsTokenType.Operator)
                         {
                             return;
                         }
                         if (((csTokenType != CsTokenType.WhiteSpace) && (csTokenType != CsTokenType.EndOfLine)) && ((csTokenType != CsTokenType.SingleLineComment) && (csTokenType != CsTokenType.MultiLineComment)))
                         {
                             break;
                         }
                     }
                 }
                 base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.MemberAccessSymbolsMustBeSpacedCorrectly, new object[0]);
                 break;
         }
     }
 }
示例#3
0
 private void CheckSymbol(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.SymbolsMustBeSpacedCorrectly, new object[] { tokenNode.Value.Text });
     }
     Node<CsToken> next = tokenNode.Next;
     if (((next != null) && (next.Value.CsTokenType != CsTokenType.WhiteSpace)) && (next.Value.CsTokenType != CsTokenType.EndOfLine))
     {
         if (previous != null)
         {
             foreach (CsToken token in tokens.ReverseIterator(previous))
             {
                 if (token.CsTokenType == CsTokenType.Operator)
                 {
                     return;
                 }
                 if (((token.CsTokenType != CsTokenType.WhiteSpace) && (token.CsTokenType != CsTokenType.EndOfLine)) && (((token.CsTokenType != CsTokenType.SingleLineComment) && (token.CsTokenType != CsTokenType.MultiLineComment)) && (token.CsTokenType != CsTokenType.PreprocessorDirective)))
                 {
                     break;
                 }
             }
         }
         base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.SymbolsMustBeSpacedCorrectly, new object[] { tokenNode.Value.Text });
     }
 }
        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 a open bracket for spacing.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens being parsed.
        /// </param>
        /// <param name="tokenNode">
        /// The token to check.
        /// </param>
        private void CheckOpenCurlyBracket(MasterList<CsToken> tokens, Node<CsToken> tokenNode)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(tokenNode, "tokenNode");

            // Open curly brackets should be preceded either by whitespace, or an open paren.
            Node<CsToken> previousNode = tokenNode.Previous;
            if (previousNode != null)
            {
                CsTokenType lastType = previousNode.Value.CsTokenType;
                if (lastType != CsTokenType.WhiteSpace && lastType != CsTokenType.EndOfLine && lastType != CsTokenType.OpenParenthesis)
                {
                    this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.OpeningCurlyBracketsMustBeSpacedCorrectly);
                }

                if (lastType == CsTokenType.WhiteSpace)
                {
                    // If this is preceded by whitespace, make sure that the character just
                    // before the whitespace is not an open paren.
                    foreach (CsToken item in tokens.ReverseIterator(previousNode))
                    {
                        CsTokenType itemType = item.CsTokenType;
                        if (itemType == CsTokenType.OpenParenthesis)
                        {
                            this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.OpeningCurlyBracketsMustBeSpacedCorrectly);
                        }
                        else if (itemType != CsTokenType.WhiteSpace)
                        {
                            break;
                        }
                    }
                }
            }

            // Open curly brackets should always be followed by whitespace.
            Node<CsToken> nextNode = tokenNode.Next;
            if (nextNode != null && nextNode.Value.CsTokenType != CsTokenType.WhiteSpace && nextNode.Value.CsTokenType != CsTokenType.EndOfLine)
            {
                this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.OpeningCurlyBracketsMustBeSpacedCorrectly);
            }
        }
        /// <summary>
        /// Checks a member access symbol for spacing.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens being parsed.
        /// </param>
        /// <param name="tokenNode">
        /// The token to check.
        /// </param>
        private void CheckMemberAccessSymbol(MasterList<CsToken> tokens, Node<CsToken> tokenNode)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(tokenNode, "tokenNode");

            // Member access symbols should not have any whitespace on either side.
            Node<CsToken> previousNode = tokenNode.Previous;
            if (previousNode != null)
            {
                CsTokenType previousTokenType = previousNode.Value.CsTokenType;
                if (previousTokenType == CsTokenType.WhiteSpace || previousTokenType == CsTokenType.EndOfLine || previousTokenType == CsTokenType.SingleLineComment
                    || previousTokenType == CsTokenType.MultiLineComment)
                {
                    if (!this.IsTokenFirstNonWhitespaceTokenOnLine(tokens, tokenNode))
                    {
                        this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.MemberAccessSymbolsMustBeSpacedCorrectly);
                    }
                }
            }

            Node<CsToken> nextNode = tokenNode.Next;
            if (nextNode != null)
            {
                CsTokenType tokenType = nextNode.Value.CsTokenType;
                if (tokenType == CsTokenType.WhiteSpace || tokenType == CsTokenType.EndOfLine || tokenType == CsTokenType.SingleLineComment
                    || tokenType == CsTokenType.MultiLineComment)
                {
                    // Make sure the previous token is not the operator keyword.
                    if (previousNode != null)
                    {
                        foreach (CsToken item in tokens.ReverseIterator(previousNode))
                        {
                            CsTokenType itemType = item.CsTokenType;
                            if (itemType == CsTokenType.Operator)
                            {
                                return;
                            }
                            else if (itemType != CsTokenType.WhiteSpace && itemType != CsTokenType.EndOfLine && itemType != CsTokenType.SingleLineComment
                                     && itemType != CsTokenType.MultiLineComment)
                            {
                                break;
                            }
                        }
                    }

                    this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.MemberAccessSymbolsMustBeSpacedCorrectly);
                }
            }
        }
示例#7
0
        /// <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;
                        }
                    }
                }
            }
        }
示例#8
0
        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;
                    }
                }
            }
        }
        /// <summary>
        /// Checks a unary symbol for spacing.
        /// </summary>
        /// <param name="tokens">
        /// The master list of tokens.
        /// </param>
        /// <param name="tokenNode">
        /// The token to check.
        /// </param>
        private void CheckUnarySymbol(MasterList<CsToken> tokens, Node<CsToken> tokenNode)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(tokenNode, "tokenNode");

            // These symbols should be preceded by whitespace but not followed by whitespace. They can
            // also be preceded by an open paren or an open square bracket.
            Node<CsToken> previousNode = tokenNode.Previous;
            if (previousNode != null)
            {
                CsTokenType previousNodeTokenType = previousNode.Value.CsTokenType;
                if (previousNodeTokenType != CsTokenType.WhiteSpace && previousNodeTokenType != CsTokenType.EndOfLine
                    && previousNodeTokenType != CsTokenType.OpenParenthesis && previousNodeTokenType != CsTokenType.OpenSquareBracket
                    && previousNodeTokenType != CsTokenType.CloseParenthesis)
                {
                    this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.SymbolsMustBeSpacedCorrectly, tokenNode.Value.Text);
                }

                // They should not be preceded by whitespace if the whitespace is preceded by a paranthesis.
                if (previousNodeTokenType == CsTokenType.WhiteSpace || previousNodeTokenType == CsTokenType.EndOfLine)
                {
                    foreach (CsToken item in tokens.ReverseIterator(previousNode))
                    {
                        if (item.CsTokenType == CsTokenType.OpenParenthesis || item.CsTokenType == CsTokenType.OpenSquareBracket)
                        {
                            this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.SymbolsMustBeSpacedCorrectly, tokenNode.Value.Text);
                        }
                        else if (item.CsTokenType == CsTokenType.WhiteSpace)
                        {
                            continue;
                        }

                        if (item.CsTokenType != CsTokenType.OpenParenthesis && item.CsTokenType != CsTokenType.OpenSquareBracket
                            && item.CsTokenType != CsTokenType.WhiteSpace)
                        {
                            break;
                        }
                    }
                }
            }

            Node<CsToken> nextNode = tokenNode.Next;
            if (nextNode != null)
            {
                CsTokenType tokenType = nextNode.Value.CsTokenType;
                if (tokenType == CsTokenType.WhiteSpace || tokenType == CsTokenType.EndOfLine || tokenType == CsTokenType.SingleLineComment
                    || tokenType == CsTokenType.MultiLineComment)
                {
                    this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.SymbolsMustBeSpacedCorrectly, tokenNode.Value.Text);
                }
            }
        }
        /// <summary>
        /// Checks a symbol for spacing.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens being parsed.
        /// </param>
        /// <param name="tokenNode">
        /// The token to check.
        /// </param>
        private void CheckSymbol(MasterList<CsToken> tokens, Node<CsToken> tokenNode)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(tokenNode, "tokenNode");

            OperatorSymbol operatorSymbol = tokenNode.Value as OperatorSymbol;
            if (operatorSymbol != null && operatorSymbol.SymbolType == OperatorType.NullConditional)
            {
                // Symbols should not have whitespace on both sides for operator '?.'.
                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.SymbolsMustBeSpacedCorrectly, tokenNode.Value.Text);
                }

                Node<CsToken> nextNode = tokenNode.Next;
                if (nextNode != null && nextNode.Value.CsTokenType == CsTokenType.WhiteSpace && nextNode.Value.CsTokenType != CsTokenType.EndOfLine)
                {
                    this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.SymbolsMustBeSpacedCorrectly, tokenNode.Value.Text);
                }

                if (operatorSymbol.Text.Length > 2 || operatorSymbol.Text.Contains("\r") || operatorSymbol.Text.Contains("\n") || operatorSymbol.Text.Contains(" "))
                {
                    this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.DoNotSplitNullConditionalOperators, tokenNode.Value.Text);
                }
            }
            else
            {
                // Symbols should have whitespace on both sides.
                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.SymbolsMustBeSpacedCorrectly, tokenNode.Value.Text);
                }

                Node<CsToken> nextNode = tokenNode.Next;
                if (nextNode != null && nextNode.Value.CsTokenType != CsTokenType.WhiteSpace && nextNode.Value.CsTokenType != CsTokenType.EndOfLine)
                {
                    // Make sure the previous token is not operator.
                    if (previousNode != null)
                    {
                        foreach (CsToken item in tokens.ReverseIterator(previousNode))
                        {
                            if (item.CsTokenType == CsTokenType.Operator)
                            {
                                return;
                            }
                            else if (item.CsTokenType != CsTokenType.WhiteSpace && item.CsTokenType != CsTokenType.EndOfLine
                                     && item.CsTokenType != CsTokenType.SingleLineComment && item.CsTokenType != CsTokenType.MultiLineComment
                                     && item.CsTokenType != CsTokenType.PreprocessorDirective)
                            {
                                break;
                            }
                        }
                    }

                    this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.LineNumber, Rules.SymbolsMustBeSpacedCorrectly, tokenNode.Value.Text);
                }
            }
        }
        /// <summary>
        /// Checks to make sure that the slashes in in the comment are followed by a space.
        /// </summary>
        /// <param name="tokens">
        /// The list of tokens being parsed.
        /// </param>
        /// <param name="tokenNode">
        /// The comment token.
        /// </param>
        private void CheckSingleLineComment(MasterList<CsToken> tokens, Node<CsToken> tokenNode)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(tokenNode, "tokenNode");

            // If the token length is less then two, this is not a valid comment so just ignore it.
            if (tokenNode.Value.Text.Length > 2)
            {
                bool addViolation = false;

                // The first character in the comment must be a space, except for the following four cases:
                // 1. The comment may start with three or more slashes: ///whatever
                // 2. The command may start with a backwards slash: //\whatever
                // 3. The comment may start with a dash if there are at last two dashes: //--
                // 4. The character after the second slash may be a newline character.
                string text = tokenNode.Value.Text;
                if (text[2] != ' ' && text[2] != '\t' && text[2] != '/' && text[2] != '\\' && text[1] != '\n' && text[1] != '\r'
                    && (text.Length < 4 || text[2] != '-' || text[3] != '-'))
                {
                    // The comment does not start with a single space.
                    addViolation = true;
                }
                else if (text.Length > 3 && (text[3] == ' ' || text[3] == '\t') && text[2] != '\\')
                {
                    // The comment starts with more than one space. This is only a violation if this is the first 
                    // single-line comment in a row. If there is another single-line comment directly above this one
                    // with no blank line between them, this is not a violation.
                    bool first = true;
                    int newLineCount = 0;

                    foreach (CsToken previousToken in tokens.ReverseIterator(tokenNode.Previous))
                    {
                        if (previousToken.CsTokenType == CsTokenType.EndOfLine)
                        {
                            if (++newLineCount == 2)
                            {
                                break;
                            }
                        }
                        else if (previousToken.CsTokenType == CsTokenType.SingleLineComment)
                        {
                            first = false;
                            break;
                        }
                        else if (previousToken.CsTokenType != CsTokenType.WhiteSpace)
                        {
                            break;
                        }
                    }

                    if (first)
                    {
                        addViolation = true;
                    }

                    if (tokenNode.Value.Parent is FileHeader)
                    {
                        // Starting with multiple spaces is only an issue if we're outside the FileHeader
                        addViolation = false;
                    }
                }

                if (addViolation)
                {
                    this.AddViolation(tokenNode.Value.FindParentElement(), tokenNode.Value.Location, Rules.SingleLineCommentsMustBeginWithSingleSpace);
                }
            }
        }
        private void CheckSemicolonAndComma(MasterList<CsToken> tokens, Node<CsToken> tokenNode)
        {
            Param.AssertNotNull(tokenNode, "tokenNode");
            Param.AssertNotNull(tokens, "tokens");

            bool comma = false;
            if (tokenNode.Value.Text == ",")
            {
                comma = true;
            }
            else
            {
                Debug.Assert(tokenNode.Value.Text == ";", "The token should either be a comma or a semicolon");
            }

            // There is a special case here where we allow <,,> [,,] or (;;), or variations thereof.
            // In these cases, there should be no spaces around the comma or semicolon.
            string[] open = new[] { "[", "<" };
            string[] close = new[] { "]", ">" };

            if (!comma)
            {
                open = new[] { "(" };
                close = new[] { ")" };
            }

            bool specialCaseBackwards = true;
            bool specialCaseForwards = true;

            // Work backwards and look for the previous character on this line.
            bool found = false;
            Node<CsToken> itemNode = tokenNode.Previous;
            if (itemNode != null)
            {
                for (int i = 0; i < open.Length; ++i)
                {
                    if (itemNode.Value.Text == open[i])
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    if (itemNode.Value.Text == tokenNode.Value.Text)
                    {
                        found = true;
                    }
                    else
                    {
                        specialCaseBackwards = false;
                    }
                }
            }

            if (!found)
            {
                specialCaseBackwards = false;
            }

            // Work backwards until the first non-whitespace or newline.
            // If thats a LabelColon then thats fine too. Fix for #7183
            foreach (CsToken previousNonWhitespaceToken in tokens.ReverseIterator(tokenNode.Previous))
            {
                if (previousNonWhitespaceToken.CsTokenType == CsTokenType.LabelColon)
                {
                    specialCaseBackwards = true;
                    break;
                }

                if (previousNonWhitespaceToken.CsTokenType != CsTokenType.WhiteSpace && previousNonWhitespaceToken.CsTokenType != CsTokenType.EndOfLine)
                {
                    break;
                }
            }

            // Work forwards and look for the next character on this line.
            found = false;
            itemNode = tokenNode.Next;
            if (itemNode != null)
            {
                for (int i = 0; i < close.Length; ++i)
                {
                    if (itemNode.Value.Text == close[i])
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    if (itemNode.Value.Text == tokenNode.Value.Text)
                    {
                        found = true;
                    }
                    else
                    {
                        specialCaseForwards = false;
                    }
                }
            }

            if (!found)
            {
                specialCaseForwards = false;
            }

            if (!specialCaseBackwards)
            {
                Node<CsToken> previousNode = tokenNode.Previous;

                // Make sure this is not preceded by whitespace.
                if (previousNode != null && (previousNode.Value.CsTokenType == CsTokenType.WhiteSpace || previousNode.Value.CsTokenType == CsTokenType.EndOfLine))
                {
                    this.AddViolation(
                        tokenNode.Value.FindParentElement(), tokenNode.Value.Location, comma ? Rules.CommasMustBeSpacedCorrectly : Rules.SemicolonsMustBeSpacedCorrectly);
                }
            }

            if (!specialCaseForwards)
            {
                Node<CsToken> nextNode = tokenNode.Next;

                // Make sure this is followed by whitespace or a close paren.
                if (nextNode != null && nextNode.Value.CsTokenType != CsTokenType.WhiteSpace && nextNode.Value.CsTokenType != CsTokenType.EndOfLine
                    && nextNode.Value.CsTokenType != CsTokenType.CloseParenthesis)
                {
                    this.AddViolation(
                        tokenNode.Value.FindParentElement(), tokenNode.Value.Location, comma ? Rules.CommasMustBeSpacedCorrectly : Rules.SemicolonsMustBeSpacedCorrectly);
                }
            }
        }
        /// <summary>
        /// Gets the non-whitespace token that appears before the given token.
        /// </summary>
        /// <param name="tokenNode">
        /// The token node.
        /// </param>
        /// <param name="tokenList">
        /// The list that contains the token.
        /// </param>
        /// <returns>
        /// Returns the previous token.
        /// </returns>
        private static CsToken GetPreviousToken(Node<CsToken> tokenNode, MasterList<CsToken> tokenList)
        {
            Param.AssertNotNull(tokenNode, "tokenNode");
            Param.AssertNotNull(tokenList, "tokenList");

            foreach (CsToken temp in tokenList.ReverseIterator(tokenNode))
            {
                if (temp.CsTokenType != CsTokenType.EndOfLine && temp.CsTokenType != CsTokenType.WhiteSpace)
                {
                    return temp;
                }
            }

            return null;
        }
示例#14
0
 private void CheckOpenCurlyBracket(DocumentRoot root, MasterList<CsToken> tokens, Node<CsToken> tokenNode)
 {
     Node<CsToken> previous = tokenNode.Previous;
     if (previous != null)
     {
         CsTokenType csTokenType = previous.Value.CsTokenType;
         if (((csTokenType != CsTokenType.WhiteSpace) && (csTokenType != CsTokenType.EndOfLine)) && (csTokenType != CsTokenType.OpenParenthesis))
         {
             base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.OpeningCurlyBracketsMustBeSpacedCorrectly, new object[0]);
         }
         if (csTokenType == CsTokenType.WhiteSpace)
         {
             foreach (CsToken token in tokens.ReverseIterator(previous))
             {
                 CsTokenType type2 = token.CsTokenType;
                 if (type2 == CsTokenType.OpenParenthesis)
                 {
                     base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.OpeningCurlyBracketsMustBeSpacedCorrectly, new object[0]);
                 }
                 else if (type2 != CsTokenType.WhiteSpace)
                 {
                     break;
                 }
             }
         }
     }
     Node<CsToken> next = tokenNode.Next;
     if (((next != null) && (next.Value.CsTokenType != CsTokenType.WhiteSpace)) && (next.Value.CsTokenType != CsTokenType.EndOfLine))
     {
         base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.OpeningCurlyBracketsMustBeSpacedCorrectly, new object[0]);
     }
 }
        /// <summary>
        /// Checks to see if the passed in node is the first node on its line.
        /// </summary>
        /// <param name="tokens">
        /// The master list of tokens.
        /// </param>
        /// <param name="node">
        /// The node to check.
        /// </param>
        /// <returns>
        /// True if this node is the first on the line, otherwise false.
        /// </returns>
        private bool IsTokenFirstNonWhitespaceTokenOnLine(MasterList<CsToken> tokens, Node<CsToken> node)
        {
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(node, "node");

            Node<CsToken> previousNode = node.Previous;
            if (previousNode == null)
            {
                return true;
            }

            bool returnValue = true;
            foreach (CsToken item in tokens.ReverseIterator(previousNode))
            {
                if (item.LineNumber != node.Value.LineNumber)
                {
                    break;
                }

                if (item.CsTokenType != CsTokenType.WhiteSpace)
                {
                    returnValue = false;
                    break;
                }
            }

            return returnValue;
        }
示例#16
0
        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 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);
                    }
                }
            }
        }
示例#18
0
 private void CheckSingleLineComment(DocumentRoot root, MasterList<CsToken> tokens, Node<CsToken> tokenNode)
 {
     if (tokenNode.Value.Text.Length > 2)
     {
         string text = tokenNode.Value.Text;
         if ((((text[2] != ' ') && (text[2] != '\t')) && ((text[2] != '/') && (text[2] != '\\'))) && (((text[1] != '\n') && (text[1] != '\r')) && (((text.Length < 4) || (text[2] != '-')) || (text[3] != '-'))))
         {
             base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.SingleLineCommentsMustBeginWithSingleSpace, new object[0]);
         }
         else if (((text.Length > 3) && ((text[3] == ' ') || (text[3] == '\t'))) && (text[2] != '\\'))
         {
             bool flag = true;
             int num = 0;
             foreach (CsToken token in tokens.ReverseIterator(tokenNode.Previous))
             {
                 if (token.CsTokenType == CsTokenType.EndOfLine)
                 {
                     if (++num != 2)
                     {
                         continue;
                     }
                     break;
                 }
                 if (token.CsTokenType == CsTokenType.SingleLineComment)
                 {
                     flag = false;
                     break;
                 }
                 if (token.CsTokenType != CsTokenType.WhiteSpace)
                 {
                     break;
                 }
             }
             if (flag)
             {
                 base.AddViolation(root, tokenNode.Value.LineNumber, Microsoft.StyleCop.CSharp.Rules.SingleLineCommentsMustBeginWithSingleSpace, new object[0]);
             }
         }
     }
 }
示例#19
0
        /// <summary>
        /// Checks a symbol 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 CheckSymbol(DocumentRoot root, MasterList<CsToken> tokens, Node<CsToken> tokenNode)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(tokens, "tokens");
            Param.AssertNotNull(tokenNode, "tokenNode");

            // Symbols should have whitespace on both sides.
            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.SymbolsMustBeSpacedCorrectly, tokenNode.Value.Text);
            }

            Node<CsToken> nextNode = tokenNode.Next;
            if (nextNode != null &&
                nextNode.Value.CsTokenType != CsTokenType.WhiteSpace &&
                nextNode.Value.CsTokenType != CsTokenType.EndOfLine)
            {
                // Make sure the previous token is not operator.
                if (previousNode != null)
                {
                    foreach (CsToken item in tokens.ReverseIterator(previousNode))
                    {
                        if (item.CsTokenType == CsTokenType.Operator)
                        {
                            return;
                        }
                        else if (item.CsTokenType != CsTokenType.WhiteSpace &&
                            item.CsTokenType != CsTokenType.EndOfLine &&
                            item.CsTokenType != CsTokenType.SingleLineComment &&
                            item.CsTokenType != CsTokenType.MultiLineComment &&
                            item.CsTokenType != CsTokenType.PreprocessorDirective)
                        {
                            break;
                        }
                    }
                }

                this.AddViolation(root, tokenNode.Value.LineNumber, Rules.SymbolsMustBeSpacedCorrectly, tokenNode.Value.Text);
            }
        }