Пример #1
0
        /// <summary>
        /// Checks a method or method invocation to ensure that the closing bracket is
        /// on the same line as the last parameter.
        /// </summary>
        /// <param name="element">
        /// The element containing the expression.
        /// </param>
        /// <param name="parameterListTokens">
        /// The tokens that form the parameter list.
        /// </param>
        /// <param name="openingBracketNode">
        /// The opening bracket.
        /// </param>
        /// <param name="closingBracketType">
        /// The type of the closing bracket.
        /// </param>
        /// <param name="arguments">
        /// The arguments to the method.
        /// </param>
        private void CheckMethodClosingBracket(
            CsElement element, CsTokenList parameterListTokens, Node <CsToken> openingBracketNode, CsTokenType closingBracketType, IArgumentList arguments)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterListTokens, "parameterListTokens");
            Param.AssertNotNull(openingBracketNode, "openingBracket");
            Param.Ignore(closingBracketType);
            Param.AssertNotNull(arguments, "arguments");

            // Find the closing bracket.
            Node <CsToken> closingBracketNode = null;

            for (Node <CsToken> tokenNode = parameterListTokens.Last; tokenNode != null; tokenNode = tokenNode.Previous)
            {
                if (tokenNode.Value.CsTokenType == closingBracketType)
                {
                    closingBracketNode = tokenNode;
                    break;
                }
            }

            if (closingBracketNode != null)
            {
                if (arguments.Count == 0)
                {
                    // The closing bracket must be on the same line as the opening bracket.
                    if (openingBracketNode.Value.LineNumber != closingBracketNode.Value.LineNumber)
                    {
                        // If the brackets are not on the same line, determine if this is because there are comments
                        // between the brackets.
                        int commentLineSpan = MeasureCommentLinesBetween(openingBracketNode, closingBracketNode, false);

                        if (openingBracketNode.Value.LineNumber + commentLineSpan != closingBracketNode.Value.LineNumber)
                        {
                            this.AddViolation(element, closingBracketNode.Value.LineNumber, Rules.ClosingParenthesisMustBeOnLineOfOpeningParenthesis);
                        }
                    }
                }
                else
                {
                    // The closing bracket must be on the same line as the end of the last method argument.
                    int lastArgumentEndLine = arguments.Location(arguments.Count - 1).EndPoint.LineNumber;
                    if (lastArgumentEndLine != closingBracketNode.Value.LineNumber)
                    {
                        int commentLineSpan = MeasureCommentLinesBetween(arguments.Tokens(arguments.Count - 1).Last, closingBracketNode, false);

                        if (lastArgumentEndLine + commentLineSpan != closingBracketNode.Value.LineNumber)
                        {
                            this.AddViolation(element, closingBracketNode.Value.LineNumber, Rules.ClosingParenthesisMustBeOnLineOfLastParameter);
                        }
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Checks the positioning of method parameters which are split across multiple lines.
        /// </summary>
        /// <param name="element">
        /// The element.
        /// </param>
        /// <param name="arguments">
        /// The method arguments.
        /// </param>
        /// <param name="openingBracketNode">
        /// The opening bracket token.
        /// </param>
        /// <param name="friendlyTypeText">
        /// The friendly type text to use in reporting violations.
        /// </param>
        private void CheckSplitMethodArgumentList(CsElement element, IArgumentList arguments, Node <CsToken> openingBracketNode, string friendlyTypeText)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(arguments, "arguments");
            Param.AssertNotNull(openingBracketNode, "openingBracketNode");

            Node <CsToken> previousComma = null;
            bool           commaOnSameLineAsPreviousParameterViolation = false;

            for (int i = 0; i < arguments.Count; ++i)
            {
                CodeLocation location          = arguments.Location(i);
                int          argumentStartLine = location.LineNumber;

                CsTokenList tokens = arguments.Tokens(i);

                // Some types of parameters or arguments are not allowed to span across multiple lines.
                if (location.LineSpan > 1 && !arguments.MaySpanMultipleLines(i))
                {
                    this.AddViolation(element, argumentStartLine, Rules.ParameterMustNotSpanMultipleLines);
                }

                if (i == 0)
                {
                    // The first argument must start on the line after the opening bracket
                    if (argumentStartLine != openingBracketNode.Value.LineNumber + 1)
                    {
                        int commentLineSpan = MeasureCommentLinesAfter(openingBracketNode);

                        if (argumentStartLine != openingBracketNode.Value.LineNumber + commentLineSpan + 1)
                        {
                            this.AddViolation(element, argumentStartLine, Rules.SplitParametersMustStartOnLineAfterDeclaration, friendlyTypeText);
                        }
                    }
                }
                else
                {
                    // The parameter must begin on the line after the previous comma.
                    Debug.Assert(previousComma != null, "The previous comma should have been set.");
                    if (!commaOnSameLineAsPreviousParameterViolation)
                    {
                        if (argumentStartLine != previousComma.Value.LineNumber + 1)
                        {
                            int commentLineSpan = MeasureCommentLinesAfter(previousComma);

                            if (argumentStartLine != previousComma.Value.LineNumber + commentLineSpan + 1)
                            {
                                this.AddViolation(element, argumentStartLine, Rules.ParameterMustFollowComma);
                            }
                        }
                    }
                }

                commaOnSameLineAsPreviousParameterViolation = false;

                // Find the comma after the token list.
                if (i < arguments.Count - 1)
                {
                    for (Node <CsToken> tokenNode = tokens.Last.Next; tokenNode != null; tokenNode = tokenNode.Next)
                    {
                        if (tokenNode.Value.CsTokenType == CsTokenType.Comma)
                        {
                            previousComma = tokenNode;

                            // The comma must be on the same line as the previous parameter.
                            if (previousComma.Value.LineNumber != location.EndPoint.LineNumber)
                            {
                                int commentLineSpan = MeasureCommentLinesBetween(tokens.Last, previousComma, false);

                                if (previousComma.Value.LineNumber != location.EndPoint.LineNumber + commentLineSpan)
                                {
                                    this.AddViolation(element, tokenNode.Value.LineNumber, Rules.CommaMustBeOnSameLineAsPreviousParameter);
                                    commaOnSameLineAsPreviousParameterViolation = true;
                                }
                            }

                            break;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Checks the positioning of method parameters which are split across multiple lines.
        /// </summary>
        /// <param name="element">
        /// The element.
        /// </param>
        /// <param name="arguments">
        /// The method arguments.
        /// </param>
        /// <param name="openingBracketNode">
        /// The opening bracket token.
        /// </param>
        /// <param name="friendlyTypeText">
        /// The friendly type text to use in reporting violations.
        /// </param>
        private void CheckSplitMethodArgumentList(CsElement element, IArgumentList arguments, Node<CsToken> openingBracketNode, string friendlyTypeText)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(arguments, "arguments");
            Param.AssertNotNull(openingBracketNode, "openingBracketNode");

            Node<CsToken> previousComma = null;
            bool commaOnSameLineAsPreviousParameterViolation = false;

            for (int i = 0; i < arguments.Count; ++i)
            {
                CodeLocation location = arguments.Location(i);
                int argumentStartLine = location.LineNumber;

                CsTokenList tokens = arguments.Tokens(i);

                // Some types of parameters or arguments are not allowed to span across multiple lines.
                if (location.LineSpan > 1 && !arguments.MaySpanMultipleLines(i))
                {
                    this.AddViolation(element, argumentStartLine, Rules.ParameterMustNotSpanMultipleLines);
                }

                if (i == 0)
                {
                    // The first argument must start on the line after the opening bracket
                    if (argumentStartLine != openingBracketNode.Value.LineNumber + 1)
                    {
                        int commentLineSpan = MeasureCommentLinesAfter(openingBracketNode);

                        if (argumentStartLine != openingBracketNode.Value.LineNumber + commentLineSpan + 1)
                        {
                            this.AddViolation(element, argumentStartLine, Rules.SplitParametersMustStartOnLineAfterDeclaration, friendlyTypeText);
                        }
                    }
                }
                else
                {
                    // The parameter must begin on the line after the previous comma.
                    Debug.Assert(previousComma != null, "The previous comma should have been set.");
                    if (!commaOnSameLineAsPreviousParameterViolation)
                    {
                        if (argumentStartLine != previousComma.Value.LineNumber + 1)
                        {
                            int commentLineSpan = MeasureCommentLinesAfter(previousComma);

                            if (argumentStartLine != previousComma.Value.LineNumber + commentLineSpan + 1)
                            {
                                this.AddViolation(element, argumentStartLine, Rules.ParameterMustFollowComma);
                            }
                        }
                    }
                }

                commaOnSameLineAsPreviousParameterViolation = false;

                // Find the comma after the token list.
                if (i < arguments.Count - 1)
                {
                    for (Node<CsToken> tokenNode = tokens.Last.Next; tokenNode != null; tokenNode = tokenNode.Next)
                    {
                        if (tokenNode.Value.CsTokenType == CsTokenType.Comma)
                        {
                            previousComma = tokenNode;

                            // The comma must be on the same line as the previous parameter.
                            if (previousComma.Value.LineNumber != location.EndPoint.LineNumber)
                            {
                                int commentLineSpan = MeasureCommentLinesBetween(tokens.Last, previousComma, false);

                                if (previousComma.Value.LineNumber != location.EndPoint.LineNumber + commentLineSpan)
                                {
                                    this.AddViolation(element, tokenNode.Value.LineNumber, Rules.CommaMustBeOnSameLineAsPreviousParameter);
                                    commaOnSameLineAsPreviousParameterViolation = true;
                                }
                            }

                            break;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Checks a method or method invocation to ensure that the closing bracket is
        /// on the same line as the last parameter.
        /// </summary>
        /// <param name="element">
        /// The element containing the expression.
        /// </param>
        /// <param name="parameterListTokens">
        /// The tokens that form the parameter list.
        /// </param>
        /// <param name="openingBracketNode">
        /// The opening bracket.
        /// </param>
        /// <param name="closingBracketType">
        /// The type of the closing bracket.
        /// </param>
        /// <param name="arguments">
        /// The arguments to the method.
        /// </param>
        private void CheckMethodClosingBracket(
            CsElement element, CsTokenList parameterListTokens, Node<CsToken> openingBracketNode, CsTokenType closingBracketType, IArgumentList arguments)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterListTokens, "parameterListTokens");
            Param.AssertNotNull(openingBracketNode, "openingBracket");
            Param.Ignore(closingBracketType);
            Param.AssertNotNull(arguments, "arguments");

            // Find the closing bracket.
            Node<CsToken> closingBracketNode = null;
            for (Node<CsToken> tokenNode = parameterListTokens.Last; tokenNode != null; tokenNode = tokenNode.Previous)
            {
                if (tokenNode.Value.CsTokenType == closingBracketType)
                {
                    closingBracketNode = tokenNode;
                    break;
                }
            }

            if (closingBracketNode != null)
            {
                if (arguments.Count == 0)
                {
                    // The closing bracket must be on the same line as the opening bracket.
                    if (openingBracketNode.Value.LineNumber != closingBracketNode.Value.LineNumber)
                    {
                        // If the brackets are not on the same line, determine if this is because there are comments
                        // between the brackets.
                        int commentLineSpan = MeasureCommentLinesBetween(openingBracketNode, closingBracketNode, false);

                        if (openingBracketNode.Value.LineNumber + commentLineSpan != closingBracketNode.Value.LineNumber)
                        {
                            this.AddViolation(element, closingBracketNode.Value.LineNumber, Rules.ClosingParenthesisMustBeOnLineOfOpeningParenthesis);
                        }
                    }
                }
                else
                {
                    // The closing bracket must be on the same line as the end of the last method argument.
                    int lastArgumentEndLine = arguments.Location(arguments.Count - 1).EndPoint.LineNumber;
                    if (lastArgumentEndLine != closingBracketNode.Value.LineNumber)
                    {
                        int commentLineSpan = MeasureCommentLinesBetween(arguments.Tokens(arguments.Count - 1).Last, closingBracketNode, false);

                        if (lastArgumentEndLine + commentLineSpan != closingBracketNode.Value.LineNumber)
                        {
                            this.AddViolation(element, closingBracketNode.Value.LineNumber, Rules.ClosingParenthesisMustBeOnLineOfLastParameter);
                        }
                    }
                }
            }
        }