/// <summary>
        /// Determines whether a method's parameters share lines or are on different lines.
        /// </summary>
        /// <param name="arguments">The method arguments.</param>
        /// <param name="someParametersShareLine">Returns true if some of the parameters are on the same line.</param>
        /// <param name="someParameterOnDifferentLines">Returns true if some of the parameters are on different lines.</param>
        private static void DetermineMethodParameterPlacementScheme(
            IArgumentList arguments, out bool someParametersShareLine, out bool someParameterOnDifferentLines)
        {
            Param.AssertNotNull(arguments, "arguments");

            someParametersShareLine       = false;
            someParameterOnDifferentLines = false;

            CodeLocation previousArgumentLocation = null;

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

                if (i > 0)
                {
                    if (previousArgumentLocation.StartPoint.LineNumber == argumentLocation.EndPoint.LineNumber)
                    {
                        someParametersShareLine = true;
                    }
                    else
                    {
                        someParameterOnDifferentLines = true;
                    }
                }

                previousArgumentLocation = argumentLocation;
            }
        }
Ejemplo n.º 2
0
                public override void PopulateValue(object target, IArgumentList args, IDiagnostics diags)
                {
                    var arg         = args.GetLastArg(OptionId);
                    var valueString = arg?.Value ?? attribute.DefaultValue;

                    if (valueString is null)
                    {
                        return;
                    }

                    var converter = TypeDescriptor.GetConverter(Property.PropertyType);

                    if (!converter.CanConvertFrom(typeof(string)))
                    {
                        diags.ReportError(
                            "Type converter for option '{0}' cannot convert from '{1}'.",
                            arg.Option.PrefixedName, typeof(string).Name);
                        return;
                    }

                    object value;

                    try {
                        value = converter.ConvertFromInvariantString(valueString);
                    } catch (NotSupportedException) {
                        diags.ReportError("Invalid value '{1}' in '{0}{1}'", arg.Spelling, valueString);
                        return;
                    }

                    Property.SetValue(target, value);
                }
Ejemplo n.º 3
0
        /// <summary>
        /// Checks the placement and formatting of parameters to a method invocation or a method declaration.
        /// </summary>
        /// <param name="element">
        /// The element.
        /// </param>
        /// <param name="parameterListTokens">
        /// The tokens that form the parameter list.
        /// </param>
        /// <param name="methodArguments">
        /// The arguments or parameters to the method.
        /// </param>
        /// <param name="methodStartLineNumber">
        /// The line number on which the method begins.
        /// </param>
        /// <param name="openBracketType">
        /// The type of the parameter list opening bracket.
        /// </param>
        /// <param name="closeBracketType">
        /// The type of the parameter list closing bracket.
        /// </param>
        /// <param name="friendlyTypeText">
        /// The text to use for violations.
        /// </param>
        private void CheckParameters(
            CsElement element,
            CsTokenList parameterListTokens,
            IArgumentList methodArguments,
            int methodStartLineNumber,
            CsTokenType openBracketType,
            CsTokenType closeBracketType,
            string friendlyTypeText)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterListTokens, "parameterListTokens");
            Param.AssertNotNull(methodArguments, "methodArguments");
            Param.AssertGreaterThanZero(methodStartLineNumber, "methodStartLineNumber");
            Param.Ignore(openBracketType);
            Param.Ignore(closeBracketType);

            Node <CsToken> openingBracketNode = this.CheckMethodOpeningBracket(element, parameterListTokens, openBracketType, friendlyTypeText);

            if (openingBracketNode != null)
            {
                this.CheckMethodClosingBracket(element, parameterListTokens, openingBracketNode, closeBracketType, methodArguments);

                if (methodArguments.Count > 0)
                {
                    this.CheckMethodArgumentList(element, methodArguments, openingBracketNode, methodStartLineNumber, friendlyTypeText);
                }
            }
        }
        /// <summary>
        /// Checks the placement and formatting of parameters to a method invocation or a method declaration.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="parameterList">The argument list.</param>
        /// <param name="methodArguments">The arguments or parameters to the method.</param>
        /// <param name="methodStartLineNumber">The line number on which the method begins.</param>
        /// <param name="openBracketType">The type of the argument list opening bracket.</param>
        /// <param name="closeBracketType">The type of the argument list closing bracket.</param>
        private void CheckParameters(
            Element element,
            CodeUnit parameterList,
            IArgumentList methodArguments,
            int methodStartLineNumber,
            TokenType openBracketType,
            TokenType closeBracketType)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterList, "parameterList");
            Param.AssertNotNull(methodArguments, "methodArguments");
            Param.AssertGreaterThanZero(methodStartLineNumber, "methodStartLineNumber");
            Param.Ignore(openBracketType);
            Param.Ignore(closeBracketType);

            OpenBracketToken openingBracket = this.CheckMethodOpeningBracket(element, parameterList, openBracketType);

            if (openingBracket != null)
            {
                this.CheckMethodClosingBracket(element, parameterList, openingBracket, closeBracketType, methodArguments);

                if (methodArguments.Count > 0)
                {
                    this.CheckMethodArgumentList(element, parameterList, methodArguments, openingBracket, methodStartLineNumber);
                }
            }
        }
 /// <summary>
 /// use one arg.
 /// </summary>
 /// <param name="args"></param>
 public static void UseOne(this IArgumentList args)
 {
     if (args == null)
     {
         throw new ArgumentNullException(nameof(args));
     }
     args.Use(1);
 }
 /// <summary>
 /// Check if all argument are used.
 /// </summary>
 /// <param name="args"></param>
 /// <returns></returns>
 public static bool IsAllUsed(this IArgumentList args)
 {
     if (args == null)
     {
         throw new ArgumentNullException(nameof(args));
     }
     return(args.Argv.Count == args.UsedArgvCount);
 }
 public static string[] GetUnusedArguments(this IArgumentList args)
 {
     if (args == null)
     {
         throw new ArgumentNullException(nameof(args));
     }
     return(args.Argv.Skip(args.UsedArgvCount).ToArray());
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FunctionCallExpression"/> class.
 /// </summary>
 /// <param name="identifier">The identifier.</param>
 /// <param name="argumentList">The argument list.</param>
 /// <exception cref="System.ArgumentNullException">argumentList or identifier</exception>
 public FunctionCallExpression(IIdentifier identifier, IArgumentList argumentList)
 {
     if (argumentList == null)
         throw new ArgumentNullException("argumentList");
     if (identifier == null)
         throw new ArgumentNullException("identifier");
     this.ArgumentList = argumentList;
     this.Identifier = identifier;
 }
Ejemplo n.º 9
0
        public static T UnknownArguments <T>([NotNull] this IArgumentList argv)
        {
            if (argv == null)
            {
                throw new ArgumentNullException(nameof(argv));
            }
            var args = argv.GetUnusedArguments();

            throw new ArgumentsException($"Unknown Arguments: ({string.Join(", ", args)})");
        }
Ejemplo n.º 10
0
 public SettingsNotFoundHighlighting(
     ICSharpArgumentsOwner argumentsOwner,
     IArgumentList argumentList,
     string key,
     string type)
 {
     _argumentsOwner = argumentsOwner;
     _argumentList   = argumentList;
     ToolTip         = $"{type} {key} wasn't found in configuration files";
 }
Ejemplo n.º 11
0
                public override void PopulateValue(object target, IArgumentList args, IDiagnostics diags)
                {
                    if (!args.HasArg(OptionId) && !attribute.HasDefaultValue)
                    {
                        return;
                    }

                    bool value = args.GetFlag(OptionId, attribute.DefaultValue);

                    Property.SetValue(target, value);
                }
Ejemplo n.º 12
0
        public IKaVEList <ISimpleExpression> GetArgumentList(IArgumentList argumentListParam, IList <IStatement> body)
        {
            var args = Lists.NewList <ISimpleExpression>();

            foreach (var arg in argumentListParam.Arguments)
            {
                var argExpr = ToSimpleExpression(arg.Value, body) ?? new UnknownExpression();
                args.Add(argExpr);
            }
            return(args);
        }
Ejemplo n.º 13
0
        internal override void PopulateValue(
            IMemberRef target, int optionId, IArgumentList args)
        {
            if (!args.HasArg(optionId))
            {
                return;
            }

            var converter = TypeDescriptor.GetConverter(target.ValueType);
            var value     = args.GetLastArgValue(optionId, DefaultValue);

            target.SetValue(converter.ConvertFromInvariantString(value));
        }
Ejemplo n.º 14
0
        public static bool HasBurstProhibitedArguments([NotNull] IArgumentList argumentList)
        {
            foreach (var argument in argumentList.Arguments)
            {
                var matchingParameterType = argument.MatchingParameter?.Type;

                if (matchingParameterType != null && !IsBurstPermittedType(matchingParameterType))
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 15
0
        public void ParseSeparate(string prefix, string name, string arg)
        {
            OptTable optTable = new OptTableBuilder()
                                .AddSeparate(1, prefix, name)
                                .CreateTable();
            var args = new[] { prefix + name, arg };

            IArgumentList al = optTable.ParseArgs(args, out var missing);

            Assert.Equal(0, missing.ArgIndex);
            Assert.Equal(0, missing.ArgCount);
            Assert.Equal(1, al.Count);
            Assert.Equal(optTable.MakeArg(1, prefix + name, 0, arg), al[0], argComparer);
        }
Ejemplo n.º 16
0
        public void ParseSeparateMissingArg()
        {
            OptTable optTable = new OptTableBuilder()
                                .AddSeparate(1, "-", "opt")
                                .CreateTable();
            var args = new[] { "-opt", "v1", "-opt" };

            IArgumentList al = optTable.ParseArgs(args, out var missing);

            Assert.Equal(2, missing.ArgIndex);
            Assert.Equal(1, missing.ArgCount);
            Assert.Equal(1, al.Count);
            Assert.Equal(optTable.MakeArg(1, "-opt", 0, "v1"), al[0], argComparer);
        }
Ejemplo n.º 17
0
        public void ParseMultiArg(string prefix, string name, string[] extraArgs)
        {
            OptTable optTable = new OptTableBuilder()
                                .AddMultiArg(1, prefix, name, extraArgs.Length)
                                .CreateTable();
            var args = new[] { prefix + name }.Concat(extraArgs).ToArray();

            IArgumentList al = optTable.ParseArgs(args, out var missing);

            Assert.Equal(0, missing.ArgIndex);
            Assert.Equal(0, missing.ArgCount);
            Assert.Equal(1, al.Count);
            Assert.Equal(optTable.MakeArg(1, prefix + name, 0, extraArgs), al[0], argComparer);
        }
Ejemplo n.º 18
0
        public void ParseRemainingArgs(string prefix, string name)
        {
            OptTable optTable = new OptTableBuilder()
                                .AddRemainingArgs(1, prefix, name)
                                .CreateTable();
            var args = new[] { prefix + name, prefix + name, "value", "-flag" };

            IArgumentList al = optTable.ParseArgs(args, out var missing);

            Assert.Equal(0, missing.ArgIndex);
            Assert.Equal(0, missing.ArgCount);
            Assert.Equal(1, al.Count);
            Assert.Equal(optTable.MakeArg(1, prefix + name, 0, prefix + name, "value", "-flag"), al[0], argComparer);
        }
Ejemplo n.º 19
0
        public void ParseOption(string prefix, string name, int argCount)
        {
            var      opt      = new StubOption(1, prefix, name);
            OptTable optTable = new OptTableBuilder()
                                .Add(opt)
                                .CreateTable();
            var args = Enumerable.Repeat(prefix + name, argCount).ToList();

            IArgumentList al = optTable.ParseArgs(args, out var missing);

            Assert.Equal(new MissingArgs(), missing);
            Assert.Equal(args.Count, al.Count);
            Assert.Equal(opt.CreatedArgs, al);
        }
        public Action <ITextControl> FillCurrentParameterWithMock(string shortName,
                                                                  IArgumentList argumentList,
                                                                  IObjectCreationExpression selectedElement,
                                                                  int parameterNumber,
                                                                  ICSharpContextActionDataProvider dataProvider)
        {
            var             argument = dataProvider.ElementFactory.CreateArgument(ParameterKind.VALUE, dataProvider.ElementFactory.CreateExpression($"{shortName}.Object"));
            ICSharpArgument arg;
            var             shouldRemoveEndComma = true;

            if (argumentList.Arguments.Count <= 1)
            {
                arg = selectedElement.AddArgumentAfter(argument, null);
            }
            else if (parameterNumber != 0)
            {
                arg = selectedElement.AddArgumentAfter(argument, argumentList.Arguments[parameterNumber - 1]);
            }
            else
            {
                arg = selectedElement.AddArgumentBefore(argument, argumentList.Arguments[1]);
                shouldRemoveEndComma = false;
            }

            var argumentRange = arg.GetDocumentRange();

            // Remove last comma Hack!
            return(textControl =>
            {
                TextRange range;

                if (shouldRemoveEndComma)
                {
                    range = new TextRange(argumentRange.EndOffset.Offset, argumentRange.EndOffset.Offset + 1);
                }
                else
                {
                    range = new TextRange(argumentRange.StartOffset.Offset - 2, argumentRange.StartOffset.Offset);
                }

                var text = textControl.Document.GetText(range);

                if (text.Contains(","))
                {
                    textControl.Document.DeleteText(range);
                }
            });
        }
Ejemplo n.º 21
0
        public void ParseJoinedMultiplePrefixes()
        {
            OptTable optTable = new OptTableBuilder()
                                .AddJoined(1, new[] { "-", "--", "/" }, "opt=")
                                .CreateTable();
            var args = new[] { "--opt=value1", "/opt=value2", "-opt=value3" };

            IArgumentList al = optTable.ParseArgs(args, out var missing);

            Assert.Equal(0, missing.ArgIndex);
            Assert.Equal(0, missing.ArgCount);
            Assert.Equal(3, al.Count);
            Assert.Equal(optTable.MakeArg(1, "--opt=", 0, "value1"), al[0], argComparer);
            Assert.Equal(optTable.MakeArg(1, "/opt=", 1, "value2"), al[1], argComparer);
            Assert.Equal(optTable.MakeArg(1, "-opt=", 2, "value3"), al[2], argComparer);
        }
Ejemplo n.º 22
0
        public void ParseFlagMultiplePrefixes()
        {
            OptTable optTable = new OptTableBuilder()
                                .AddFlag(1, new[] { "-", "--", "/" }, "opt")
                                .CreateTable();
            var args = new[] { "--opt", "/opt", "-opt" };

            IArgumentList al = optTable.ParseArgs(args, out var missing);

            Assert.Equal(0, missing.ArgIndex);
            Assert.Equal(0, missing.ArgCount);
            Assert.Equal(3, al.Count);
            Assert.Equal(optTable.MakeArg(1, "--opt", 0), al[0], argComparer);
            Assert.Equal(optTable.MakeArg(1, "/opt", 1), al[1], argComparer);
            Assert.Equal(optTable.MakeArg(1, "-opt", 2), al[2], argComparer);
        }
Ejemplo n.º 23
0
        public void ParseMultiArgMissingArgs(
            string prefix, string name, int argCount, string[] preArgs, string[] postArgs)
        {
            OptTable optTable = new OptTableBuilder()
                                .AddUnknown(1)
                                .AddMultiArg(2, prefix, name, argCount)
                                .CreateTable();
            var args = preArgs.Concat(new[] { prefix + name }).Concat(postArgs).ToArray();

            IArgumentList al = optTable.ParseArgs(args, out var missing);

            Assert.Equal(preArgs.Length, missing.ArgIndex);
            Assert.Equal(argCount - postArgs.Length, missing.ArgCount);
            Assert.Equal(preArgs.Length, al.Count);
            Assert.True(al.All(a => a.Option.Id == 1));
        }
Ejemplo n.º 24
0
        public void ParseMixed()
        {
            OptTable optTable = new OptTableBuilder()
                                .AddFlag(1, "-", "a")
                                .AddJoined(2, "-", "a=")
                                .CreateTable();
            var args = new[] { "-a=123", "-a" };

            IArgumentList al = optTable.ParseArgs(args, out var missing);

            Assert.Equal(0, missing.ArgIndex);
            Assert.Equal(0, missing.ArgCount);
            Assert.Equal(2, al.Count);
            Assert.Equal(optTable.MakeArg(2, "-a=", 0, "123"), al[0], argComparer);
            Assert.Equal(optTable.MakeArg(1, "-a", 1), al[1], argComparer);
        }
        public static bool TryGetNextArgument(this IArgumentList args, out string value)
        {
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            if (args.Argv.Count == args.UsedArgvCount)
            {
                value = null;
                return(false);
            }
            else
            {
                value = args.Argv[args.UsedArgvCount];
                return(true);
            }
        }
Ejemplo n.º 26
0
        public List <string> Parse(IReadOnlyList <string> arguments)
        {
            var optTable = builder.CreateTable();

            IArgumentList al = optTable.ParseArgs(arguments, out _);

            foreach (var arg in al)
            {
                if (!actions.TryGetValue(arg.Option.Id, out var tuple))
                {
                    continue;
                }

                tuple.Item1(arg.Value);
            }

            return(al.Matching(UnknownId).Select(a => a.Value).ToList());
        }
Ejemplo n.º 27
0
        internal override void PopulateValue(IMemberRef target, int optionId, IArgumentList args)
        {
            if (!args.HasArg(optionId))
            {
                return;
            }

            var values = args.GetAllArgValues(optionId);

            if (target.CanWrite)
            {
                target.SetValue(ConvertCollection(values, target.ValueType));
            }
            else if (target.CanRead)
            {
                throw new NotImplementedException();
            }
        }
Ejemplo n.º 28
0
        public IArgumentList Parse(IReadOnlyList <string> args)
        {
            SealOptTable();

            IArgumentList al = OptTable.ParseArgs(args, out _);

            foreach (var info in infos)
            {
                var attribute = info.Member.MemberInfo.GetCustomAttribute <OptionAttribute>();
                if (attribute == null)
                {
                    continue;
                }

                attribute.PopulateValue(info.Member, info.OptionId, al);
            }

            return(al);
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Checks the argument list to a method or method invocation to ensure that the arguments are
        /// positioned correctly.
        /// </summary>
        /// <param name="element">
        /// The element containing the expression.
        /// </param>
        /// <param name="arguments">
        /// The arguments to the method.
        /// </param>
        /// <param name="openingBracketNode">
        /// The opening bracket token.
        /// </param>
        /// <param name="methodLineNumber">
        /// The line number on which the method begins.
        /// </param>
        /// <param name="friendlyTypeText">
        /// The text to use for the type in reporting violations.
        /// </param>
        private void CheckMethodArgumentList(CsElement element, IArgumentList arguments, Node <CsToken> openingBracketNode, int methodLineNumber, string friendlyTypeText)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(arguments, "arguments");
            Param.AssertNotNull(openingBracketNode, "openingBracketNode");
            Param.AssertGreaterThanZero(methodLineNumber, "methodLineNumber");

            // Determine whether all of the parameters are on the same line as one another.
            bool someParametersShareLine;
            bool someParameterOnDifferentLines;

            DetermineMethodParameterPlacementScheme(arguments, out someParametersShareLine, out someParameterOnDifferentLines);

            // All parameters must either be on the same line, or each parameter must begin on its own line.
            if (someParametersShareLine && someParameterOnDifferentLines)
            {
                this.AddViolation(element, methodLineNumber, Rules.ParametersMustBeOnSameLineOrSeparateLines, friendlyTypeText);
            }

            // Determine whether all of the parameters are on the same line as one another.
            if (someParameterOnDifferentLines)
            {
                this.CheckSplitMethodArgumentList(element, arguments, openingBracketNode, friendlyTypeText);
            }
            else if (arguments.Count > 0)
            {
                // The first argument must start on the same line as the opening bracket, or
                // on the line after it.
                int firstArgumentStartLine = arguments.Location(0).LineNumber;

                if (firstArgumentStartLine != openingBracketNode.Value.LineNumber && firstArgumentStartLine != openingBracketNode.Value.LineNumber + 1)
                {
                    int commentLineSpan = MeasureCommentLinesAfter(openingBracketNode);

                    if (firstArgumentStartLine != openingBracketNode.Value.LineNumber + commentLineSpan + 1)
                    {
                        this.AddViolation(element, firstArgumentStartLine, Rules.ParameterListMustFollowDeclaration);
                    }
                }
            }
        }
Ejemplo n.º 30
0
        internal override void PopulateValue(
            IMemberRef target, int optionId, IArgumentList args)
        {
            if (!args.HasArg(optionId))
            {
                return;
            }

            bool allowMultiple =
                typeof(ICollection <string>).IsAssignableFrom(target.ValueType) ||
                typeof(ICollection).IsAssignableFrom(target.ValueType);

            if (allowMultiple)
            {
                target.SetValue(args.GetAllArgValues(optionId));
            }
            else
            {
                target.SetValue(args.GetLastArgValue(optionId));
            }
        }
Ejemplo n.º 31
0
        public void ParseJoinedMultiple()
        {
            OptTable optTable = new OptTableBuilder()
                                .AddJoined(1, "-", "aaaa")
                                .AddJoined(2, new[] { "-", "--" }, "aaa")
                                .AddJoined(3, "-", "a")
                                .AddJoined(4, "--", "aa")
                                .CreateTable();
            var args = new[] { "--aaa1", "--aa2", "-aaaaa", "-a4", "-aaa5" };

            IArgumentList al = optTable.ParseArgs(args, out var missing);

            Assert.Equal(0, missing.ArgIndex);
            Assert.Equal(0, missing.ArgCount);
            Assert.Equal(5, al.Count);
            Assert.Equal(optTable.MakeArg(2, "--aaa", 0, "1"), al[0], argComparer);
            Assert.Equal(optTable.MakeArg(4, "--aa", 1, "2"), al[1], argComparer);
            Assert.Equal(optTable.MakeArg(1, "-aaaa", 2, "a"), al[2], argComparer);
            Assert.Equal(optTable.MakeArg(3, "-a", 3, "4"), al[3], argComparer);
            Assert.Equal(optTable.MakeArg(2, "-aaa", 4, "5"), al[4], argComparer);
        }
        /// <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;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Checks the argument list to a method or method invocation to ensure that the arguments are 
        /// positioned correctly.
        /// </summary>
        /// <param name="element">The element containing the expression.</param>
        /// <param name="parameterList">The element's argument list.</param>
        /// <param name="arguments">The arguments to the method.</param>
        /// <param name="openingBracket">The opening bracket token.</param>
        /// <param name="methodLineNumber">The line number on which the method begins.</param>
        private void CheckMethodArgumentList(Element element, CodeUnit parameterList, IArgumentList arguments, OpenBracketToken openingBracket, int methodLineNumber)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterList, "parameterList");
            Param.AssertNotNull(arguments, "arguments");
            Param.AssertNotNull(openingBracket, "openingBracket");
            Param.AssertGreaterThanZero(methodLineNumber, "methodLineNumber");

            // Determine whether all of the parameters are on the same line as one another.
            bool someParametersShareLine;
            bool someParameterOnDifferentLines;

            DetermineMethodParameterPlacementScheme(
                arguments, out someParametersShareLine, out someParameterOnDifferentLines);

            // All parameters must either be on the same line, or each argument must begin on its own line.
            if (someParametersShareLine && someParameterOnDifferentLines)
            {
                this.AddViolation(
                    element,
                    methodLineNumber,
                    Rules.ParametersMustBeOnSameLineOrSeparateLines,
                    element.FriendlyTypeText);
            }

            // Determine whether all of the parameters are on the same line as one another.
            if (someParameterOnDifferentLines)
            {
                this.CheckSplitMethodArgumentList(element, parameterList, arguments, openingBracket);
            }
            else if (arguments.Count > 0)
            {
                // The first argument must start on the same line as the opening bracket, or 
                // on the line after it.
                int firstArgumentStartLine = arguments.Location(0).LineNumber;

                if (firstArgumentStartLine != openingBracket.LineNumber &&
                    firstArgumentStartLine != openingBracket.LineNumber + 1)
                {
                    int commentLineSpan = MeasureCommentLinesAfter(openingBracket);

                    if (firstArgumentStartLine != openingBracket.LineNumber + commentLineSpan + 1)
                    {
                        this.AddViolation(element, firstArgumentStartLine, Rules.ParameterListMustFollowDeclaration);
                    }
                }
            }
        }
        /// <summary>
        /// Checks a method or method invocation to ensure that the closing bracket is
        /// on the same line as the last argument.
        /// </summary>
        /// <param name="element">The element containing the expression.</param>
        /// <param name="parameterList">The argument list.</param>
        /// <param name="openingBracket">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(
            Element element, CodeUnit parameterList, OpenBracketToken openingBracket, TokenType closingBracketType, IArgumentList arguments)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterList, "parameterList");
            Param.AssertNotNull(openingBracket, "openingBracket");
            Param.Ignore(closingBracketType);
            Param.AssertNotNull(arguments, "arguments");

            // Find the closing bracket.
            CloseBracketToken closingBracket = null;

            Token next = parameterList.FindNextSiblingToken();
            if (next != null && next.Is(closingBracketType))
            {
                closingBracket = (CloseBracketToken)next;
            }

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

                        if (openingBracket.LineNumber + commentLineSpan != closingBracket.LineNumber)
                        {
                            this.AddViolation(element, closingBracket.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 != closingBracket.LineNumber)
                    {
                        int commentLineSpan = MeasureCommentLinesBetween(arguments.Argument(arguments.Count - 1).FindLastDescendentToken(), closingBracket, false);

                        if (lastArgumentEndLine + commentLineSpan != closingBracket.LineNumber)
                        {
                            this.AddViolation(element, closingBracket.LineNumber, Rules.ClosingParenthesisMustBeOnLineOfLastParameter);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Checks the placement and formatting of parameters to a method invocation or a method declaration.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="parameterList">The argument list.</param>
        /// <param name="methodArguments">The arguments or parameters to the method.</param>
        /// <param name="methodStartLineNumber">The line number on which the method begins.</param>
        /// <param name="openBracketType">The type of the argument list opening bracket.</param>
        /// <param name="closeBracketType">The type of the argument list closing bracket.</param>
        private void CheckParameters(
            Element element,
            CodeUnit parameterList,
            IArgumentList methodArguments,
            int methodStartLineNumber,
            TokenType openBracketType,
            TokenType closeBracketType)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterList, "parameterList");
            Param.AssertNotNull(methodArguments, "methodArguments");
            Param.AssertGreaterThanZero(methodStartLineNumber, "methodStartLineNumber");
            Param.Ignore(openBracketType);
            Param.Ignore(closeBracketType);

            OpenBracketToken openingBracket = this.CheckMethodOpeningBracket(element, parameterList, openBracketType);

            if (openingBracket != null)
            {
                this.CheckMethodClosingBracket(element, parameterList, openingBracket, closeBracketType, methodArguments);

                if (methodArguments.Count > 0)
                {
                    this.CheckMethodArgumentList(element, parameterList, methodArguments, openingBracket, methodStartLineNumber);
                }
            }
        }
        /// <summary>
        /// Determines whether a method's parameters share lines or are on different lines.
        /// </summary>
        /// <param name="arguments">The method arguments.</param>
        /// <param name="someParametersShareLine">Returns true if some of the parameters are on the same line.</param>
        /// <param name="someParameterOnDifferentLines">Returns true if some of the parameters are on different lines.</param>
        private static void DetermineMethodParameterPlacementScheme(
            IArgumentList arguments, out bool someParametersShareLine, out bool someParameterOnDifferentLines)
        {
            Param.AssertNotNull(arguments, "arguments");

            someParametersShareLine = false;
            someParameterOnDifferentLines = false;

            CodeLocation previousArgumentLocation = null;
            for (int i = 0; i < arguments.Count; ++i)
            {
                CodeLocation argumentLocation = arguments.Location(i);

                if (i > 0)
                {
                    if (previousArgumentLocation.StartPoint.LineNumber == argumentLocation.EndPoint.LineNumber)
                    {
                        someParametersShareLine = true;
                    }
                    else
                    {
                        someParameterOnDifferentLines = true;
                    }
                }

                previousArgumentLocation = argumentLocation;
            }
        }
        /// <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);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Checks the placement and formatting of parameters to a method invocation or a method declaration.
        /// </summary>
        /// <param name="element">
        /// The element.
        /// </param>
        /// <param name="parameterListTokens">
        /// The tokens that form the parameter list.
        /// </param>
        /// <param name="methodArguments">
        /// The arguments or parameters to the method.
        /// </param>
        /// <param name="methodStartLineNumber">
        /// The line number on which the method begins.
        /// </param>
        /// <param name="openBracketType">
        /// The type of the parameter list opening bracket.
        /// </param>
        /// <param name="closeBracketType">
        /// The type of the parameter list closing bracket.
        /// </param>
        /// <param name="friendlyTypeText">
        /// The text to use for violations.
        /// </param>
        private void CheckParameters(
            CsElement element, 
            CsTokenList parameterListTokens, 
            IArgumentList methodArguments, 
            int methodStartLineNumber, 
            CsTokenType openBracketType, 
            CsTokenType closeBracketType, 
            string friendlyTypeText)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterListTokens, "parameterListTokens");
            Param.AssertNotNull(methodArguments, "methodArguments");
            Param.AssertGreaterThanZero(methodStartLineNumber, "methodStartLineNumber");
            Param.Ignore(openBracketType);
            Param.Ignore(closeBracketType);

            Node<CsToken> openingBracketNode = this.CheckMethodOpeningBracket(element, parameterListTokens, openBracketType, friendlyTypeText);

            if (openingBracketNode != null)
            {
                this.CheckMethodClosingBracket(element, parameterListTokens, openingBracketNode, closeBracketType, methodArguments);

                if (methodArguments.Count > 0)
                {
                    this.CheckMethodArgumentList(element, methodArguments, openingBracketNode, methodStartLineNumber, friendlyTypeText);
                }
            }
        }
        /// <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;
                        }
                    }
                }
            }
        }