/// <summary>
        /// Checks the positioning of method parameters which are split across multiple lines.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="parameterList">The argument list.</param>
        /// <param name="arguments">The method arguments.</param>
        /// <param name="openingBracket">The opening bracket token.</param>
        private void CheckSplitMethodArgumentList(Element element, CodeUnit parameterList, IArgumentList arguments, OpenBracketToken openingBracket)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterList, "parameterList");
            Param.AssertNotNull(arguments, "arguments");
            Param.AssertNotNull(openingBracket, "openingBracket");

            Token previousComma = null;
            bool  commaOnSameLineAsPreviousParameterViolation = false;

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

                CodeUnit argument = arguments.Argument(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 != openingBracket.LineNumber + 1)
                    {
                        int commentLineSpan = MeasureCommentLinesAfter(openingBracket);

                        if (argumentStartLine != openingBracket.LineNumber + commentLineSpan + 1)
                        {
                            this.AddViolation(element, argumentStartLine, Rules.SplitParametersMustStartOnLineAfterDeclaration, element.FriendlyTypeText);
                        }
                    }
                }
                else
                {
                    // The argument 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.LineNumber + 1)
                        {
                            int commentLineSpan = MeasureCommentLinesAfter(previousComma);

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

                commaOnSameLineAsPreviousParameterViolation = false;

                // Find the comma after the token list.
                if (i < arguments.Count - 1)
                {
                    Token lastTokenInArgument = argument.FindLastDescendentToken();
                    if (lastTokenInArgument != null)
                    {
                        for (Token token = lastTokenInArgument.FindNextDescendentTokenOf(parameterList); token != null; token = token.FindNextDescendentTokenOf(parameterList))
                        {
                            if (token.TokenType == TokenType.Comma)
                            {
                                previousComma = token;

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

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

                                break;
                            }
                        }
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Checks the placement of curly brackets within the given item.
        /// </summary>
        /// <param name="item">The item containing the brackets to check.</param>
        /// <param name="parentElement">The element containing the brackets.</param>
        /// <param name="parentStatement">The statement containing the brackets, if any.</param>
        /// <param name="openBracket">The opening curly bracket within the token list.</param>
        /// <param name="allowAllOnOneLine">Indicates whether the brackets are allowed to be all on one line.</param>
        private void CheckBracketPlacement(
            CodeUnit item,
            Element parentElement,
            Statement parentStatement,
            OpenBracketToken openBracket,
            bool allowAllOnOneLine)
        {
            Param.AssertNotNull(item, "item");
            Param.AssertNotNull(parentElement, "parentElement");
            Param.Ignore(parentStatement);
            Param.AssertNotNull(openBracket, "openBracket");
            Param.Ignore(allowAllOnOneLine);

            if (openBracket.MatchingBracket != null &&
                !openBracket.Generated &&
                !openBracket.MatchingBracket.Generated)
            {
                // Check if the two brackets are on the same line as each other.
                if (openBracket.LineNumber == openBracket.MatchingBracket.LineNumber)
                {
                    // This is an error if the brackets are not allowed to be all on the same line.
                    if (!allowAllOnOneLine)
                    {
                        // Statements within constructor initializers are allowed to be all on the same line
                        // since sometimes this is the only way to write the statement.
                        if (parentStatement == null)
                        {
                            this.AddViolation(parentElement, openBracket.LineNumber, Rules.ElementMustNotBeOnSingleLine, parentElement.FriendlyTypeText);
                        }
                        else if (parentStatement.StatementType != StatementType.ConstructorInitializer)
                        {
                            this.AddViolation(parentElement, openBracket.LineNumber, Rules.StatementMustNotBeOnSingleLine);
                        }
                    }
                    else
                    {
                        // The brackets are only allowed to be on the same line if the entire statement is on the same line.
                        Token first = item.FindFirstDescendentToken();
                        Token last  = item.FindLastDescendentToken();

                        if (first != null && last != null && first.LineNumber != last.LineNumber)
                        {
                            this.AddViolation(parentElement, openBracket.LineNumber, Rules.CurlyBracketsForMultiLineStatementsMustNotShareLine, GetOpeningOrClosingBracketText(openBracket));
                        }
                    }
                }
                else
                {
                    // The brackets are on different lines. Both brackets must be on a line all by themselves.
                    if (LayoutRules.BracketSharesLine(openBracket, false))
                    {
                        this.AddViolation(parentElement, openBracket.LineNumber, Rules.CurlyBracketsForMultiLineStatementsMustNotShareLine, GetOpeningOrClosingBracketText(openBracket));
                    }

                    if (LayoutRules.BracketSharesLine(openBracket.MatchingBracket, true))
                    {
                        this.AddViolation(parentElement, openBracket.MatchingBracket.LineNumber, Rules.CurlyBracketsForMultiLineStatementsMustNotShareLine, GetOpeningOrClosingBracketText(openBracket.MatchingBracket));
                    }
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Checks the placement of curly brackets within the given item.
        /// </summary>
        /// <param name="item">The item containing the brackets to check.</param>
        /// <param name="parentElement">The element containing the brackets.</param>
        /// <param name="parentStatement">The statement containing the brackets, if any.</param>
        /// <param name="openBracket">The opening curly bracket within the token list.</param>
        /// <param name="allowAllOnOneLine">Indicates whether the brackets are allowed to be all on one line.</param>
        private void CheckBracketPlacement(
            CodeUnit item,
            Element parentElement, 
            Statement parentStatement, 
            OpenBracketToken openBracket, 
            bool allowAllOnOneLine)
        {
            Param.AssertNotNull(item, "item");
            Param.AssertNotNull(parentElement, "parentElement");
            Param.Ignore(parentStatement);
            Param.AssertNotNull(openBracket, "openBracket");
            Param.Ignore(allowAllOnOneLine);

            if (openBracket.MatchingBracket != null &&
                !openBracket.Generated && 
                !openBracket.MatchingBracket.Generated)
            {
                // Check if the two brackets are on the same line as each other.
                if (openBracket.LineNumber == openBracket.MatchingBracket.LineNumber)
                {
                    // This is an error if the brackets are not allowed to be all on the same line.
                    if (!allowAllOnOneLine)
                    {
                        // Statements within constructor initializers are allowed to be all on the same line
                        // since sometimes this is the only way to write the statement.
                        if (parentStatement == null)
                        {
                            this.AddViolation(parentElement, openBracket.LineNumber, Rules.ElementMustNotBeOnSingleLine, parentElement.FriendlyTypeText);
                        }
                        else if (parentStatement.StatementType != StatementType.ConstructorInitializer)
                        {
                            this.AddViolation(parentElement, openBracket.LineNumber, Rules.StatementMustNotBeOnSingleLine);
                        }
                    }
                    else
                    {
                        // The brackets are only allowed to be on the same line if the entire statement is on the same line.
                        Token first = item.FindFirstDescendentToken();
                        Token last = item.FindLastDescendentToken();

                        if (first != null && last != null && first.LineNumber != last.LineNumber)
                        {
                            this.AddViolation(parentElement, openBracket.LineNumber, Rules.CurlyBracketsForMultiLineStatementsMustNotShareLine, GetOpeningOrClosingBracketText(openBracket));
                        }
                    }
                }
                else
                {
                    // The brackets are on different lines. Both brackets must be on a line all by themselves.
                    if (LayoutRules.BracketSharesLine(openBracket, false))
                    {
                        this.AddViolation(parentElement, openBracket.LineNumber, Rules.CurlyBracketsForMultiLineStatementsMustNotShareLine, GetOpeningOrClosingBracketText(openBracket));
                    }

                    if (LayoutRules.BracketSharesLine(openBracket.MatchingBracket, true))
                    {
                        this.AddViolation(parentElement, openBracket.MatchingBracket.LineNumber, Rules.CurlyBracketsForMultiLineStatementsMustNotShareLine, GetOpeningOrClosingBracketText(openBracket.MatchingBracket));
                    }
                }
            }
        }