Ejemplo n.º 1
0
        /// <summary>
        /// Extracts a variable from the clause.
        /// </summary>
        /// <param name="firstToken">The first token of the variable.</param>
        /// <param name="allowTypelessVariable">Indicates whether to allow a variable with no type defined.</param>
        /// <param name="onlyTypelessVariable">Indicates whether to only get a typeless variable.</param>
        /// <returns>Returns the variable.</returns>
        protected static QueryClauseVariable ExtractQueryVariable(Token firstToken, bool allowTypelessVariable, bool onlyTypelessVariable)
        {
            Param.RequireNotNull(firstToken, "firstToken");
            Param.Ignore(allowTypelessVariable);
            Param.Ignore(onlyTypelessVariable);

            if (onlyTypelessVariable || !firstToken.Is(TokenType.Type))
            {
                // In this case there is no type, only an identifier.
                return new QueryClauseVariable(null, firstToken.Text, firstToken.Location, firstToken.Generated);
            }
            else
            {
                TypeToken type = (TypeToken)firstToken;

                // Attempt to get the identifier token coming after the type token.
                Token identifier = firstToken.FindNextSiblingToken();
                if (identifier == null || identifier.TokenType != TokenType.Literal)
                {
                    CsLanguageService.Debug.Assert(allowTypelessVariable, "The clause does not allow typeless variables. The parser should have thrown syntax exception already.");
                    return new QueryClauseVariable(null, type.Text, type.Location, type.Generated);
                }
                else
                {
                    // There is a type and an identifier.
                    return new QueryClauseVariable(type, identifier.Text, CodeUnit.JoinLocations(type, identifier), type.Generated || identifier.Generated);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of the LiteralExpression class.
        /// </summary>
        /// <param name="proxy">Proxy object for the expression.</param>
        /// <param name="token">The literal token.</param>
        internal LiteralExpression(CodeUnitProxy proxy, Token token)
            : base(proxy, ExpressionType.Literal)
        {
            Param.AssertNotNull(proxy, "proxy");
            Param.AssertNotNull(token, "token");

            this.token.Value = token;
        }
Ejemplo n.º 3
0
        /// <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>
        /// Fixes the error.
        /// </summary>
        /// <param name="violationContext">Context for the violation.</param>
        /// <param name="token">The token that is missing a prefix.</param>
        private void FixPrefixLocalCallsWithThisViolation(ViolationContext violationContext, Token token)
        {
            Param.Ignore(violationContext);
            Param.AssertNotNull(token, "token");

            CsDocument document = token.Document;

            // Find the item that is going to get replaced.
            CodeUnit itemToReplace = token;
            LiteralExpression parent = token.Parent as LiteralExpression;
            if (parent != null)
            {
                itemToReplace = parent;
            }

            // Record the location of this item.
            CodeUnitLocationMarker marker = document.GetCodeUnitLocationMarker(itemToReplace);

            // If the token is not already wrapped by a literal expression, create one.
            LiteralExpression rightHandSide = parent;
            if (rightHandSide == null)
            {
                rightHandSide = document.CreateLiteralExpression(token);
            }

            // Create the left-hand side and the expression.
            LiteralExpression leftHandSide = document.CreateLiteralExpression(document.CreateThisToken());
            MemberAccessExpression expression = document.CreateMemberAccessExpression(leftHandSide, rightHandSide);

            // Insert the member access expression in the same location as the previous literal.
            document.Insert(expression, marker);
        }
        /// <summary>
        /// Parses the given literal token.
        /// </summary>
        /// <param name="token">The literal token node.</param>
        /// <param name="expression">The expression that contains the token.</param>
        /// <param name="parentExpression">The parent of the expression that contains the token.</param>
        /// <param name="parentElement">The element that contains the expression.</param>
        /// <param name="parentClass">The class that the element belongs to.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        private void CheckClassMemberRulesForLiteralToken(
            Token token,
            Expression expression,
            Expression parentExpression,
            Element parentElement,
            ClassBase parentClass,
            Dictionary<string, List<Element>> members)
        {
            Param.AssertNotNull(token, "token");
            Param.AssertNotNull(expression, "expression");
            Param.Ignore(parentExpression);
            Param.AssertNotNull(parentElement, "parentElement");
            Param.Ignore(parentClass);
            Param.Ignore(members);

            // Skip types. We only care about named members.
            if (token.TokenType != TokenType.Type)
            {
                // If the name starts with a dot, ignore it.
                if (!token.Text.StartsWith(".", StringComparison.Ordinal))
                {
                    if (token.Text == "base" && parentExpression != null)
                    {
                        // An item is only allowed to start with base if there is an implementation of the
                        // item in the local class and the caller is trying to explicitly call the base
                        // class implementation instead of the local class implementation. Extract the name
                        // of the item being accessed.
                        Token name = ReadabilityRules.ExtractBaseClassMemberName(parentExpression, token);
                        if (name != null)
                        {
                            ICollection<Element> matches = ReadabilityRules.FindClassMember(name.Text, parentClass, members, true);

                            // Check to see if there is a non-static match.
                            bool found = false;
                            if (matches != null)
                            {
                                foreach (Element match in matches)
                                {
                                    if (!match.ContainsModifier(TokenType.Static))
                                    {
                                        found = true;
                                        break;
                                    }
                                }
                            }

                            if (!found)
                            {
                                this.AddViolation(parentElement, name.LineNumber, Rules.DoNotPrefixCallsWithBaseUnlessLocalImplementationExists, name);
                            }
                        }
                    }
                    else if (token.Text != "this")
                    {
                        // Check whether this word should really start with this.
                        this.CheckWordUsageAgainstClassMemberRules(
                            token.Text,
                            token,
                            token.LineNumber,
                            expression,
                            parentElement,
                            parentClass,
                            members);
                    }
                }
            }
        }
        /// <summary>
        /// Determines whether the given word is the name of a local variable.
        /// </summary>
        /// <param name="word">The name to check.</param>
        /// <param name="item">The token containing the word.</param>
        /// <param name="parent">The expression that the word appears in.</param>
        /// <returns>True if the word is the name of a local variable, false if not.</returns>
        private static bool IsLocalMember(string word, Token item, Expression parent)
        {
            Param.AssertValidString(word, "word");
            Param.AssertNotNull(item, "item");
            Param.AssertNotNull(parent, "parent");

            CodeUnit p = parent;
            while (p != null)
            {
                // Check to see if the name matches a local variable.
                if (ReadabilityRules.ContainsVariable(p.Variables, word, item))
                {
                    return true;
                }

                // If the parent is an element (other than an accessor), do not look any higher up the stack than this.
                if (p.CodeUnitType == CodeUnitType.Element && !p.Is(ElementType.Accessor))
                {
                    break;
                }

                // Check to see whether the variable is defined within the parent.
                p = p.Parent;
            }

            return false;
        }
        /// <summary>
        /// Extracts the name of the member being called from the base class.
        /// </summary>
        /// <param name="parentExpression">The expression containing the tokens.</param>
        /// <param name="baseToken">The 'base' keyword token.</param>
        /// <returns>Returns the name of the member or null if there is no member name.</returns>
        private static Token ExtractBaseClassMemberName(Expression parentExpression, Token baseToken)
        {
            Param.AssertNotNull(parentExpression, "parentExpression");
            Param.AssertNotNull(baseToken, "baseTokenNode");

            Debug.Assert(baseToken.TokenType == TokenType.Base, "Incorrect token type.");

            bool foundMemberAccessSymbol = false;
            for (Token next = baseToken.FindNextToken(); next != null; next = next.FindNextToken())
            {
                if (foundMemberAccessSymbol)
                {
                    if (next.TokenType == TokenType.Literal)
                    {
                        return next;
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    if (next.TokenType == TokenType.OperatorSymbol)
                    {
                        if (next.Is(OperatorType.MemberAccess))
                        {
                            foundMemberAccessSymbol = true;
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return null;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Checks a open bracket for spacing.
        /// </summary>
        /// <param name="token">The token to check.</param>
        private void CheckOpenSquareBracket(Token token)
        {
            Param.AssertNotNull(token, "token");

            // Open brackets should be never be preceded by whitespace.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem != null)
            {
                if (previousItem.LexicalElementType == LexicalElementType.WhiteSpace ||
                    previousItem.LexicalElementType == LexicalElementType.EndOfLine)
                {
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.OpeningSquareBracketsMustBeSpacedCorrectly);
                }
            }

            // Open brackets should never be followed by whitespace.
            LexicalElement nextItem = token.FindNextLexicalElement();
            if (nextItem != null &&
                (nextItem.LexicalElementType == LexicalElementType.WhiteSpace || nextItem.LexicalElementType == LexicalElementType.EndOfLine))
            {
                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.OpeningSquareBracketsMustBeSpacedCorrectly);
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Checks a label colon for spacing.
        /// </summary>
        /// <param name="token">The token to check.</param>
        private void CheckLabelColon(Token token)
        {
            Param.AssertNotNull(token, "token");

            // A colon should always be followed by whitespace, but never preceded by whitespace.
            LexicalElement nextItem = token.FindNextLexicalElement();
            if (nextItem == null)
            {
                if (nextItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                    nextItem.LexicalElementType != LexicalElementType.EndOfLine)
                {
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ColonsMustBeSpacedCorrectly);
                }
            }

            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem != null)
            {
                if (previousItem.LexicalElementType == LexicalElementType.WhiteSpace ||
                    previousItem.LexicalElementType == LexicalElementType.EndOfLine ||
                    previousItem.Is(CommentType.SingleLineComment) ||
                    previousItem.Is(CommentType.MultilineComment))
                {
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ColonsMustBeSpacedCorrectly);
                }
            }
        }
Ejemplo n.º 10
0
        private void CheckUnsafeAccessSymbols(Token token, bool type)
        {
            Param.AssertNotNull(token, "token");
            Param.Ignore(type);

            // In a type declaration, the symbol must have whitespace on the right but
            // not on the left. If this is not a type declaration, the opposite is true.
            if (type)
            {
                // The symbol should be followed by whitespace. It 
                // can also be followed by a closing paren or a closing bracket,
                // or another token of the same type.
                LexicalElement nextItem = token.FindNextLexicalElement();
                if (nextItem != null)
                {
                    if (nextItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                        nextItem.LexicalElementType != LexicalElementType.EndOfLine &&
                        !nextItem.Is(TokenType.OpenParenthesis) &&
                        !nextItem.Is(TokenType.OpenSquareBracket) &&
                        !nextItem.Is(TokenType.CloseParenthesis) &&
                        !nextItem.Is(token.TokenType))
                    {
                        this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.DereferenceAndAccessOfSymbolsMustBeSpacedCorrectly);
                    }
                }

                // The symbol must not be preceded by whitespace.
                LexicalElement previousItem = token.FindPreviousLexicalElement();
                if (previousItem != null)
                {
                    if (previousItem.LexicalElementType == LexicalElementType.WhiteSpace ||
                        previousItem.LexicalElementType == LexicalElementType.EndOfLine ||
                        previousItem.Is(CommentType.SingleLineComment) ||
                        previousItem.Is(CommentType.MultilineComment))
                    {
                        this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.DereferenceAndAccessOfSymbolsMustBeSpacedCorrectly);
                    }
                }
            }
            else
            {
                // The symbol should be preceded by whitespace. It 
                // can also be preceded by an open paren or an open bracket, or
                // another token of the same type.
                LexicalElement previousItem = token.FindPreviousLexicalElement();
                if (previousItem != null)
                {
                    if (previousItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                        previousItem.LexicalElementType != LexicalElementType.EndOfLine &&
                        !previousItem.Is(TokenType.OpenParenthesis) &&
                        !previousItem.Is(TokenType.OpenSquareBracket) &&
                        !previousItem.Is(TokenType.CloseParenthesis) &&
                        !previousItem.Is(token.TokenType))
                    {
                        this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.DereferenceAndAccessOfSymbolsMustBeSpacedCorrectly);
                    }
                }

                // The symbol must not be followed by whitespace.
                LexicalElement nextItem = token.FindNextLexicalElement();
                if (nextItem == null)
                {
                    if (nextItem.LexicalElementType == LexicalElementType.WhiteSpace ||
                        nextItem.LexicalElementType == LexicalElementType.EndOfLine ||
                        nextItem.Is(CommentType.SingleLineComment) ||
                        nextItem.Is(CommentType.MultilineComment))
                    {
                        this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.DereferenceAndAccessOfSymbolsMustBeSpacedCorrectly);
                    }
                }
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Checks a positive sign for spacing.
        /// </summary>
        /// <param name="token">The token to check.</param>
        private void CheckPositiveSign(Token token)
        {
            Param.AssertNotNull(token, "token");

            // A positive sign should be preceded by whitespace. It 
            // can also be preceded by an open paren or an open bracket.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem != null)
            {
                if (previousItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                    previousItem.LexicalElementType != LexicalElementType.EndOfLine &&
                    !previousItem.Is(TokenType.OpenParenthesis) &&
                    !previousItem.Is(TokenType.OpenSquareBracket) &&
                    !previousItem.Is(TokenType.CloseParenthesis))
                {
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.PositiveSignsMustBeSpacedCorrectly);
                }
            }

            LexicalElement nextItem = token.FindNextLexicalElement();
            if (nextItem != null)
            {
                if (nextItem.LexicalElementType == LexicalElementType.WhiteSpace ||
                    nextItem.LexicalElementType == LexicalElementType.EndOfLine ||
                    nextItem.Is(CommentType.SingleLineComment) ||
                    nextItem.Is(CommentType.MultilineComment))
                {
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.PositiveSignsMustBeSpacedCorrectly);
                }
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Checks an increment or decrement sign for spacing.
        /// </summary>
        /// <param name="token">The token to check.</param>
        private void CheckIncrementDecrement(Token token)
        {
            Param.AssertNotNull(token, "token");

            // Increment and decrement symbols should have whitespace on only one side. The non-whitespace
            // side is also allowed to butt up against a bracket or a parenthesis, however.
            bool before = false;
            bool after = false;

            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem == null)
            {
                before = true;
            }
            else
            {
                if (previousItem.LexicalElementType == LexicalElementType.WhiteSpace ||
                    previousItem.LexicalElementType == LexicalElementType.EndOfLine ||
                    previousItem.Is(CommentType.SingleLineComment) ||
                    previousItem.Is(CommentType.MultilineComment))
                {
                    before = true;
                }
            }

            LexicalElement nextItem = token.FindNextLexicalElement();
            if (nextItem == null)
            {
                after = true;
            }
            else
            {
                if (nextItem.LexicalElementType == LexicalElementType.WhiteSpace ||
                    nextItem.LexicalElementType == LexicalElementType.EndOfLine ||
                    nextItem.Is(CommentType.SingleLineComment) ||
                    nextItem.Is(CommentType.MultilineComment))
                {
                    after = true;
                }
            }

            // If there is no whitespace on either side, then make sure that at least one of the sides
            // is touching a square bracket or a parenthesis. The right side of the symbol is also
            // allowed to be up against a comma or a semicolon.
            if (!before && !after)
            {
                if (previousItem != null &&
                    (previousItem.Is(TokenType.OpenSquareBracket) || previousItem.Is(TokenType.OpenParenthesis)))
                {
                    return;
                }

                if (nextItem != null)
                {
                    if (nextItem.Is(TokenType.CloseSquareBracket) ||
                        nextItem.Is(TokenType.CloseParenthesis) ||
                        nextItem.Is(TokenType.Comma) ||
                        nextItem.Is(TokenType.Semicolon))
                    {
                        return;
                    }
                }

                // This is a violation.
                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.IncrementDecrementSymbolsMustBeSpacedCorrectly);
            }
            else if (before && after)
            {
                // There is whitespace on both sides.
                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.IncrementDecrementSymbolsMustBeSpacedCorrectly);
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Checks a member access symbol for spacing.
        /// </summary>
        /// <param name="root">The container to parse.</param>
        /// <param name="token">The token to check.</param>
        private void CheckMemberAccessSymbol(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            // Member access symbols should not have any whitespace on either side.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem == null)
            {
                if (previousItem.LexicalElementType == LexicalElementType.WhiteSpace ||
                    previousItem.LexicalElementType == LexicalElementType.EndOfLine ||
                    previousItem.Is(CommentType.SingleLineComment) ||
                    previousItem.Is(CommentType.MultilineComment))
                {
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.MemberAccessSymbolsMustBeSpacedCorrectly);
                }
            }

            LexicalElement nextItem = token.FindNextLexicalElement();
            if (nextItem == null)
            {
                if (nextItem.LexicalElementType == LexicalElementType.WhiteSpace ||
                    nextItem.LexicalElementType == LexicalElementType.EndOfLine ||
                    nextItem.Is(CommentType.SingleLineComment) ||
                    nextItem.Is(CommentType.MultilineComment))
                {
                    // Make sure the previous token is not the operator keyword.
                    if (previousItem != null)
                    {
                        for (LexicalElement item = previousItem.FindPreviousLexicalElement(); item != null; item = item.FindPreviousLexicalElement())
                        {
                            if (item.Is(TokenType.Operator))
                            {
                                return;
                            }
                            else if (item.LexicalElementType != LexicalElementType.WhiteSpace &&
                                item.LexicalElementType != LexicalElementType.EndOfLine &&
                                !item.Is(CommentType.SingleLineComment) &&
                                !item.Is(CommentType.MultilineComment))
                            {
                                break;
                            }
                        }
                    }

                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.MemberAccessSymbolsMustBeSpacedCorrectly);
                }
            }
        }    
Ejemplo n.º 14
0
        /// <summary>
        /// Checks a nullable type symbol for spacing.
        /// </summary>
        /// <param name="token">The token to check.</param>
        private void CheckNullableTypeSymbol(Token token)
        {
            Param.AssertNotNull(token, "token");

            // Nullable type symbols should never be preceded by whitespace.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem != null &&
                (previousItem.LexicalElementType == LexicalElementType.WhiteSpace || previousItem.LexicalElementType == LexicalElementType.EndOfLine))
            {
                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.NullableTypeSymbolsMustNotBePrecededBySpace);
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Checks a closing attribute bracket for spacing.
        /// </summary>
        /// <param name="token">The token to check.</param>
        private void CheckAttributeTokenCloseBracket(Token token)
        {
            Param.AssertNotNull(token, "token");

            // Closing attribute brackets should be never be preceded by whitespace.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem != null)
            {
                if (previousItem.LexicalElementType == LexicalElementType.WhiteSpace ||
                    previousItem.LexicalElementType == LexicalElementType.EndOfLine)
                {
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingAttributeBracketsMustBeSpacedCorrectly);
                }
            }
        }
Ejemplo n.º 16
0
        private void CheckOpenParen(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            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.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem != null)
            {
                if (previousItem.LexicalElementType == LexicalElementType.WhiteSpace)
                {
                    for (LexicalElement item = previousItem.FindPreviousLexicalElement(); item != null; item = item.FindPreviousLexicalElement())
                    {
                        if (item.LexicalElementType == LexicalElementType.WhiteSpace)
                        {
                            continue;
                        }
                        else if (item.LexicalElementType == LexicalElementType.EndOfLine)
                        {
                            firstOnLine = true;
                            break;
                        }
                        else if (
                            item.Is(TokenType.Case) ||
                            item.Is(TokenType.Catch) ||
                            item.Is(TokenType.CloseSquareBracket) ||
                            item.Is(TokenType.Comma) ||
                            item.Is(TokenType.Equals) ||
                            item.Is(TokenType.Fixed) ||
                            item.Is(TokenType.For) ||
                            item.Is(TokenType.Foreach) ||
                            item.Is(TokenType.From) ||
                            ////item.Is(TokenType.Goto) ||
                            item.Is(TokenType.Group) ||
                            item.Is(TokenType.If) ||
                            item.Is(TokenType.In) ||
                            item.Is(TokenType.Into) ||
                            item.Is(TokenType.Join) ||
                            item.Is(TokenType.Let) ||
                            item.Is(TokenType.Lock) ||
                            item.Is(CommentType.MultilineComment) ||
                            ////item.Is(TokenType.New) ||
                            item.Is(TokenType.Number) ||
                            item.Is(TokenType.OperatorSymbol) ||
                            item.Is(TokenType.OpenCurlyBracket) ||
                            item.Is(TokenType.OrderBy) ||
                            item.Is(TokenType.Return) ||
                            item.Is(TokenType.Select) ||
                            item.Is(TokenType.Semicolon) ||
                            ////item.Is(CommentType.SingleLineComment) ||
                            item.Is(TokenType.Switch) ||
                            item.Is(TokenType.Throw) ||
                            item.Is(TokenType.Using) ||
                            item.Is(TokenType.Where) ||
                            item.Is(TokenType.While) ||
                            item.Is(TokenType.WhileDo) ||
                            item.Is(TokenType.Yield))
                        {
                            break;
                        }
                        else
                        {
                            this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.OpeningParenthesisMustBeSpacedCorrectly);
                        }
                    }
                }
            }

            // Open parens should never be followed by whitespace unless
            // it is the last thing on the line.
            LexicalElement next = token.FindPreviousLexicalElement();
            if (next != null &&
                (next.LexicalElementType == LexicalElementType.WhiteSpace || next.LexicalElementType == LexicalElementType.EndOfLine))
            {
                // Look to see if there is any non whitespace character
                // on this line other than a comment.
                for (LexicalElement item = next.FindNextLexicalElement(); item != null; item = item.FindNextLexicalElement())
                {
                    if (item.LexicalElementType == LexicalElementType.EndOfLine)
                    {
                        lastOnLine = true;
                        break;
                    }
                    else if (item.LexicalElementType != LexicalElementType.WhiteSpace &&
                        !item.Is(CommentType.SingleLineComment) &&
                        !item.Is(CommentType.MultilineComment))
                    {
                        this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.OpeningParenthesisMustBeSpacedCorrectly);
                        break;
                    }
                }
            }

            // Open parens cannot be the only thing on the line.
            if (firstOnLine && lastOnLine)
            {
                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.OpeningParenthesisMustBeSpacedCorrectly);
            }
        }
Ejemplo n.º 17
0
        private void CheckCloseParen(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            // Close parens should never be preceded by whitespace.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem != null &&
                (previousItem.LexicalElementType == LexicalElementType.WhiteSpace || previousItem.LexicalElementType == LexicalElementType.EndOfLine))
            {
                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingParenthesisMustBeSpacedCorrectly);
            }

            // Find out what comes after the closing paren.
            LexicalElement nextItem = token.FindNextLexicalElement();
            LexicalElement nextNextItem = nextItem == null ? null : nextItem.FindNextLexicalElement();

            if (nextItem != null)
            {
                if (token.Parent is CastExpression)
                {
                    // There should not be any whitespace after the closing parenthesis in a cast expression.
                    if (nextItem.LexicalElementType == LexicalElementType.WhiteSpace)
                    {
                        this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingParenthesisMustBeSpacedCorrectly);
                    }
                }
                else if (nextItem.Is(TokenType.LabelColon) || (nextNextItem != null && nextNextItem.Is(TokenType.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;

                    for (LexicalElement item = token.FindPreviousLexicalElement(); item != null; item = item.FindPreviousLexicalElement())
                    {
                        if (item.LexicalElementType == LexicalElementType.EndOfLine)
                        {
                            break;
                        }
                        else if (item.Is(TokenType.Case))
                        {
                            followsCase = true;
                            break;
                        }
                    }

                    if ((followsCase && nextItem.LexicalElementType == LexicalElementType.WhiteSpace) ||
                        (!followsCase && nextItem.LexicalElementType != LexicalElementType.WhiteSpace))
                    {
                        this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingParenthesisMustBeSpacedCorrectly);
                    }
                }
                else if (nextItem.LexicalElementType == LexicalElementType.WhiteSpace)
                {
                    if (nextNextItem != null)
                    {
                        // Make sure that the character just after the whitespace is not a paren, bracket, a comma, or a semicolon.
                        for (LexicalElement item = nextNextItem; item != null; item = item.FindNextLexicalElement())
                        {
                            if (IsAllowedAfterClosingParenthesis(item))
                            {
                                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingParenthesisMustBeSpacedCorrectly);
                            }
                            else if (item.LexicalElementType != LexicalElementType.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 (nextItem.LexicalElementType != LexicalElementType.EndOfLine &&
                        !IsAllowedAfterClosingParenthesis(nextItem))
                    {
                        this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingParenthesisMustBeSpacedCorrectly);
                    }
                }
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Checks a unary symbol for spacing.
        /// </summary>
        /// <param name="token">The token to check.</param>
        private void CheckUnarySymbol(Token token)
        {
            Param.AssertNotNull(token, "token");

            // 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.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem != null)
            {
                if (previousItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                    previousItem.LexicalElementType != LexicalElementType.EndOfLine &&
                    !previousItem.Is(TokenType.OpenParenthesis) &&
                    !previousItem.Is(TokenType.OpenSquareBracket))
                {
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.SymbolsMustBeSpacedCorrectly, token.Text);
                }
            }

            LexicalElement nextItem = token.FindNextLexicalElement();
            if (nextItem == null)
            {
                if (nextItem.LexicalElementType == LexicalElementType.WhiteSpace ||
                    nextItem.LexicalElementType == LexicalElementType.EndOfLine ||
                    nextItem.Is(CommentType.SingleLineComment) ||
                    nextItem.Is(CommentType.MultilineComment))
                {
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.SymbolsMustBeSpacedCorrectly, token.Text);
                }
            }
        }
Ejemplo n.º 19
0
        private void CheckCloseSquareBracket(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            // Close brackets should never be preceded by whitespace.
            LexicalElement previousItem = token.FindNextLexicalElement();
            if (previousItem != null &&
                (previousItem.LexicalElementType == LexicalElementType.WhiteSpace || previousItem.LexicalElementType == LexicalElementType.EndOfLine))
            {
                this.AddViolation(token.FindParentElement(), token.LineNumber, 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.
            LexicalElement nextItem = token.FindNextLexicalElement();
            if (nextItem != null)
            {
                if (nextItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                    nextItem.LexicalElementType != LexicalElementType.EndOfLine &&
                    !nextItem.Is(TokenType.CloseParenthesis) &&
                    !nextItem.Is(TokenType.OpenParenthesis) &&      // someDictionary["Test"]();
                    !nextItem.Is(TokenType.CloseSquareBracket) &&   // someIndexer[someArray[1]] = 2;
                    !nextItem.Is(TokenType.OpenSquareBracket) &&    // someArray[1][2] = 2;
                    !nextItem.Is(TokenType.Semicolon) &&
                    !nextItem.Is(TokenType.Comma) &&
                    !nextItem.Is(TokenType.CloseGenericBracket) &&
                    nextItem.Text != "++" &&
                    nextItem.Text != "--" &&
                    !nextItem.Text.StartsWith(".", StringComparison.Ordinal))
                {
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingSquareBracketsMustBeSpacedCorrectly);
                }

                if (nextItem.LexicalElementType == LexicalElementType.WhiteSpace)
                {
                    // If this is followed by whitespace, make sure that the character just
                    // after the whitespace is not a paren, bracket, comma, or semicolon.
                    for (LexicalElement item = nextItem.FindNextLexicalElement(); item != null; item = item.FindNextLexicalElement())
                    {
                        if (item.Is(TokenType.CloseParenthesis) ||
                            item.Is(TokenType.OpenParenthesis) ||
                            item.Is(TokenType.CloseSquareBracket) ||
                            item.Is(TokenType.OpenSquareBracket) ||
                            item.Is(TokenType.Semicolon) ||
                            item.Is(TokenType.Comma))
                        {
                            this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingSquareBracketsMustBeSpacedCorrectly);
                        }
                        else if (item.LexicalElementType != LexicalElementType.WhiteSpace)
                        {
                            break;
                        }
                    }
                }
            }
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Checks a keyword that should be followed by a space.
        /// </summary>
        /// <param name="token">The token to check.</param>
        private void CheckKeywordWithSpace(Token token)
        {
            Param.AssertNotNull(token, "token");

            // Keywords must be followed by a space before the open parenthesis.
            // Sometimes keywords appear within attributes and are allowed to be
            // followed immediately by an attribute colon.
            LexicalElement temp = token.FindNextLexicalElement();
            if (temp == null ||
                (temp.LexicalElementType != LexicalElementType.WhiteSpace &&
                temp.LexicalElementType != LexicalElementType.EndOfLine &&
                !temp.Is(TokenType.Semicolon) &&
                !temp.Is(TokenType.AttributeColon)))
            {
                this.AddViolation(
                    token.FindParentElement(), 
                    token.LineNumber, 
                    Rules.KeywordsMustBeSpacedCorrectly, 
                    token.Text);
            }
        }
        /// <summary>
        /// Determines whether a matching local variable is contained in the given variable list.
        /// </summary>
        /// <param name="variables">The variable list.</param>
        /// <param name="word">The variable name to check.</param>
        /// <param name="item">The token containing the variable name.</param>
        /// <returns>Returns true if there is a matching local variable.</returns>
        private static bool ContainsVariable(VariableCollection variables, string word, Token item)
        {
            Param.AssertNotNull(variables, "variables");
            Param.AssertValidString(word, "word");
            Param.AssertNotNull(item, "item");

            IVariable variable = variables[word];
            if (variable != null)
            {
                // Make sure the variable appears before the word.
                if (variable.Location.LineNumber < item.LineNumber)
                {
                    return true;
                }
                else if (variable.Location.LineNumber == item.LineNumber)
                {
                    if (variable.Location.StartPoint.IndexOnLine <= item.Location.StartPoint.IndexOnLine)
                    {
                        return true;
                    }
                }
            }

            return false;
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Checks a keyword that should not be followed by a space.
        /// </summary>
        /// <param name="root">The container to parse.</param>
        /// <param name="token">The token to check.</param>
        private void CheckKeywordWithoutSpace(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            // Keywords must not contain any space before the open parenthesis.
            LexicalElement temp = token.FindNextLexicalElement();
            if (temp != null &&
                (temp.LexicalElementType == LexicalElementType.WhiteSpace || temp.LexicalElementType == LexicalElementType.EndOfLine))
            {
                // Make sure the next non-whitespace character is not an open parenthesis.
                for (LexicalElement nextNonWhitespaceItem = temp.FindNextLexicalElement(); nextNonWhitespaceItem != null; nextNonWhitespaceItem = nextNonWhitespaceItem.FindNextLexicalElement())
                {
                    if (nextNonWhitespaceItem.Is(TokenType.OpenParenthesis))
                    {
                        this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.KeywordsMustBeSpacedCorrectly, token.Text);
                        break;
                    }
                    else if (nextNonWhitespaceItem.LexicalElementType != LexicalElementType.WhiteSpace && nextNonWhitespaceItem.LexicalElementType != LexicalElementType.EndOfLine)
                    {
                        break;
                    }
                }
            }
        }
        /// <summary>
        /// Determines whether the given token is preceded by a member access symbol.
        /// </summary>
        /// <param name="literalToken">The token to check.</param>
        /// <returns>Returns true if the token is preceded by a member access symbol.</returns>
        private static bool IsLiteralTokenPrecededByMemberAccessSymbol(Token literalToken)
        {
            Param.AssertNotNull(literalToken, "literalToken");

            // Get the previous non-whitespace item.
            LexicalElement previousItem = ReadabilityRules.GetPreviousNonWhitespaceItem(literalToken);
            if (previousItem != null)
            {
                if (previousItem.Is(OperatorType.MemberAccess) ||
                    previousItem.Is(OperatorType.Pointer) ||
                    previousItem.Is(OperatorType.QualifiedAlias))
                {
                    return true;
                }
            }

            return false;
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Checks the spacing around a 'new' keyword.
        /// </summary>
        /// <param name="root">The token container list.</param>
        /// <param name="token">The token to check.</param>
        private void CheckNewKeywordSpacing(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            // 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.
            LexicalElement temp = token.FindNextLexicalElement();
            if (temp != null)
            {
                if (temp.LexicalElementType == LexicalElementType.WhiteSpace || temp.LexicalElementType == LexicalElementType.EndOfLine)
                {
                    // The keyword is followed by whitespace. Make sure the next non-whitespace character is not an opening bracket.
                    for (LexicalElement nextNonWhitespaceItem = temp.FindNextLexicalElement(); nextNonWhitespaceItem != null; nextNonWhitespaceItem = nextNonWhitespaceItem.FindNextLexicalElement())
                    {
                        if (nextNonWhitespaceItem.Is(TokenType.OpenSquareBracket))
                        {
                            this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.CodeMustNotContainSpaceAfterNewKeywordInImplicitlyTypedArrayAllocation);
                            break;
                        }
                        else if (nextNonWhitespaceItem.LexicalElementType != LexicalElementType.WhiteSpace && nextNonWhitespaceItem.LexicalElementType != LexicalElementType.EndOfLine)
                        {
                            break;
                        }
                    }
                }
                else if (!temp.Is(TokenType.OpenSquareBracket))
                {
                    // The keyword is not followed by whitespace.
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.KeywordsMustBeSpacedCorrectly, token.Text);
                }
            }
        }
        /// <summary>
        /// Checks a word to see if it should start with this. or base.
        /// </summary>
        /// <param name="word">The word text to check.</param>
        /// <param name="item">The word being checked.</param>
        /// <param name="line">The line that the word appears on.</param>
        /// <param name="expression">The expression the word appears within.</param>
        /// <param name="parentElement">The element that contains the word.</param>
        /// <param name="parentClass">The parent class that this element belongs to.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        private void CheckWordUsageAgainstClassMemberRules(
            string word,
            Token item,
            int line,
            Expression expression,
            Element parentElement,
            ClassBase parentClass,
            Dictionary<string, List<Element>> members)
        {
            Param.AssertValidString(word, "word");
            Param.AssertNotNull(item, "item");
            Param.AssertGreaterThanZero(line, "line");
            Param.AssertNotNull(expression, "expression");
            Param.AssertNotNull(parentElement, "parentElement");
            Param.Ignore(parentClass);
            Param.Ignore(members);

            // If there is a local variable with the same name, or if the item we're checking is within the left-hand side
            // of an object initializer expression, then ignore it.
            if (!IsLocalMember(word, item, expression) && !IsObjectInitializerLeftHandSideExpression(expression))
            {
                // Determine if this is a member of our class.
                Element foundMember = null;
                ICollection<Element> classMembers = ReadabilityRules.FindClassMember(word, parentClass, members, false);
                if (classMembers != null)
                {
                    foreach (Element classMember in classMembers)
                    {
                        if (classMember.ContainsModifier(TokenType.Static) ||
                            (classMember.ElementType == ElementType.Field && ((Field)classMember).Const))
                        {
                            // There is a member with a matching name that is static or is a const field. In this case, 
                            // ignore the issue and quit.
                            foundMember = null;
                            break;
                        }
                        else if (classMember.ElementType != ElementType.Class &&
                            classMember.ElementType != ElementType.Struct &&
                            classMember.ElementType != ElementType.Delegate &&
                            classMember.ElementType != ElementType.Enum)
                        {
                            // Found a matching member.
                            if (foundMember == null)
                            {
                                foundMember = classMember;
                            }
                        }
                    }

                    if (foundMember != null)
                    {
                        if (foundMember.ElementType == ElementType.Property)
                        {
                            // If the property's name and type are the same, then this is not a violation.
                            // In this case, the type is being accessed, not the property.
                            Property property = (Property)foundMember;
                            if (property.ReturnType.Text != property.Name)
                            {
                                this.Violation<Token>(
                                    Rules.PrefixLocalCallsWithThis,
                                    new ViolationContext(parentElement, line, word),
                                    this.FixPrefixLocalCallsWithThisViolation,
                                    item);
                            }
                        }
                        else
                        {
                            this.Violation<Token>(
                                Rules.PrefixLocalCallsWithThis,
                                new ViolationContext(parentElement, line, word),
                                this.FixPrefixLocalCallsWithThisViolation,
                                item);
                        }
                    }
                }
            }
        }
Ejemplo n.º 26
0
        private void CheckSemicolonAndComma(Token token)
        {
            Param.AssertNotNull(token, "token");

            bool comma = false;
            if (token.Text == ",")
            {
                comma = true;
            }
            else
            {
                Debug.Assert(token.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[] { "[", "<" };
            string[] close = new string[] { "]", ">" };

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

            bool specialCaseBackwards = true;
            bool specialCaseForwards = true;

            // Work backwards and look for the previous character on this line.
            bool found = false;
            LexicalElement item = token.FindPreviousLexicalElement();
            if (item != null)
            {
                for (int i = 0; i < open.Length; ++i)
                {
                    if (item.Text == open[i])
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    if (item.Text == token.Text)
                    {
                        found = true;
                    }
                    else
                    {
                        specialCaseBackwards = false;
                    }
                }
            }

            if (!found)
            {
                specialCaseBackwards = false;
            }

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

                if (!found)
                {
                    if (item.Text == token.Text)
                    {
                        found = true;
                    }
                    else
                    {
                        specialCaseForwards = false;
                    }
                }
            }

            if (!found)
            {
                specialCaseForwards = false;
            }

            if (!specialCaseBackwards)
            {
                LexicalElement previousItem = token.FindPreviousLexicalElement();

                // Make sure this is not preceded by whitespace.
                if (previousItem != null &&
                    (previousItem.LexicalElementType == LexicalElementType.WhiteSpace || previousItem.LexicalElementType == LexicalElementType.EndOfLine))
                {
                    this.AddViolation(
                        token.FindParentElement(),
                        token.LineNumber, 
                        comma ? Rules.CommasMustBeSpacedCorrectly : Rules.SemicolonsMustBeSpacedCorrectly);
                }
            }

            if (!specialCaseForwards)
            {
                LexicalElement nextItem = token.FindNextLexicalElement();

                // Make sure this is followed by whitespace or a close paren.
                if (nextItem != null &&
                    nextItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                    nextItem.LexicalElementType != LexicalElementType.EndOfLine &&
                    !nextItem.Is(TokenType.CloseParenthesis))
                {
                    this.AddViolation(
                        token.FindParentElement(),
                        token.LineNumber, 
                        comma ? Rules.CommasMustBeSpacedCorrectly : Rules.SemicolonsMustBeSpacedCorrectly);
                }
            }
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Determines whether the statement is declaring a const field or variable.
        /// </summary>
        /// <param name="assignmentOperator">The assignment operator for the variable declaration.</param>
        /// <returns>Returns true if the statement is declaring a const, false otherwise.</returns>
        private static bool IsConstVariableDeclaration(Token assignmentOperator)
        {
            Param.Ignore(assignmentOperator);

            if (assignmentOperator != null && assignmentOperator.Text == "=")
            {
                // Work backwards until we find the keyword const, or have moved past the beginning of the statement.
                Token token = assignmentOperator.FindPreviousToken();

                while (token != null)
                {
                    if (token.TokenType == TokenType.CloseParenthesis ||
                        token.TokenType == TokenType.OpenParenthesis ||
                        token.TokenType == TokenType.OpenCurlyBracket ||
                        token.TokenType == TokenType.CloseCurlyBracket ||
                        token.TokenType == TokenType.Semicolon)
                    {
                        break;
                    }
                    else if (token.TokenType == TokenType.Const)
                    {
                        return true;
                    }

                    token = token.FindPreviousToken();
                }
            }

            return false;
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Checks a symbol for spacing.
        /// </summary>
        /// <param name="root">The container to parse.</param>
        /// <param name="token">The token to check.</param>
        private void CheckSymbol(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            // Symbols should have whitespace on both sides.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem != null &&
                previousItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                previousItem.LexicalElementType != LexicalElementType.EndOfLine)
            {
                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.SymbolsMustBeSpacedCorrectly, token.Text);
            }

            LexicalElement nextItem = token.FindNextLexicalElement();
            if (nextItem != null &&
                nextItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                nextItem.LexicalElementType != LexicalElementType.EndOfLine)
            {
                // Make sure the previous token is not operator.
                if (previousItem != null)
                {
                    for (LexicalElement item = previousItem.FindPreviousLexicalElement(); item != null; item = item.FindPreviousLexicalElement())
                    {
                        if (item.Is(TokenType.Operator))
                        {
                            return;
                        }
                        else if (item.LexicalElementType != LexicalElementType.WhiteSpace &&
                            item.LexicalElementType != LexicalElementType.EndOfLine &&
                            !item.Is(CommentType.SingleLineComment) &&
                            !item.Is(CommentType.MultilineComment) &&
                            item.LexicalElementType != LexicalElementType.PreprocessorDirective)
                        {
                            break;
                        }
                    }
                }

                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.SymbolsMustBeSpacedCorrectly, token.Text);
            }
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Checks a string to determine whether it is using an incorrect empty string notation.
        /// </summary>
        /// <param name="text">The string to check.</param>
        /// <param name="parentElement">The parent element.</param>
        private void CheckEmptyString(Token text, Element parentElement)
        {
            Param.AssertNotNull(text, "text");
            Param.AssertNotNull(parentElement, "parentElement");
            
            Debug.Assert(text.TokenType == TokenType.String, "The token must be a string.");

            if (string.Equals(text.Text, "\"\"", StringComparison.Ordinal) ||
                string.Equals(text.Text, "@\"\"", StringComparison.Ordinal))
            {
                // Look at the previous token. If it is the 'case' keyword, then do not throw this
                // exception. It is illegal to write case: String.Empty and instead case: "" must be written.
                Token previousToken = text.FindPreviousToken();
                if (previousToken == null || (previousToken.TokenType != TokenType.Case && !IsConstVariableDeclaration(previousToken)))
                {
                    this.Violation(
                        Rules.UseStringEmptyForEmptyStrings,
                        new ViolationContext(parentElement, text.LineNumber),
                        (c, o) =>
                        {
                            // Fix the violation.
                            CsDocument document = text.Document;

                            // Create a member access expression which represents "string.Empty".
                            var stringEmpty = document.CreateMemberAccessExpression(document.CreateLiteralExpression("string"), document.CreateLiteralExpression("Empty"));

                            // The parent of the token should be a literal expression.
                            if (text.Parent != null && text.Parent.Is(ExpressionType.Literal))
                            {
                                document.Replace(text.Parent, stringEmpty);
                            }
                            else
                            {
                                Debug.Fail("Unhandled situation");
                            }
                        });
                }
            }
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Checks the operator keyword for spacing.
        /// </summary>
        /// <param name="token">The token to check.</param>
        private void CheckOperatorKeyword(Token token)
        {
            Param.AssertNotNull(token, "token");

            // Operator keywords should be followed by whitespace.
            LexicalElement next = token.FindNextLexicalElement();
            if (next != null && next.LexicalElementType != LexicalElementType.WhiteSpace)
            {
                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.OperatorKeywordMustBeFollowedBySpace);
            }
        }