Пример #1
0
        public override void Initialize(AnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var methodCall            = (InvocationExpressionSyntax)c.Node;
                var methodParameterLookup = new ArrayCovariance.MethodParameterLookup(methodCall, c.SemanticModel);
                var argumentMappings      = methodCall.ArgumentList.Arguments.Select(argument =>
                                                                                     new KeyValuePair <ArgumentSyntax, IParameterSymbol>(argument,
                                                                                                                                         methodParameterLookup.GetParameterSymbol(argument)))
                                            .ToList();

                var methodSymbol = methodParameterLookup.MethodSymbol;
                if (methodSymbol == null)
                {
                    return;
                }

                foreach (var argumentMapping in argumentMappings)
                {
                    if (ArgumentHasDefaultValue(argumentMapping, c.SemanticModel))
                    {
                        var argument  = argumentMapping.Key;
                        var parameter = argumentMapping.Value;
                        c.ReportDiagnostic(Diagnostic.Create(Rule, argument.GetLocation(), parameter.Name));
                    }
                }
            },
                SyntaxKind.InvocationExpression);
        }
Пример #2
0
        public override void Initialize(AnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
                {
                    var methodCall = (InvocationExpressionSyntax) c.Node;
                    var methodParameterLookup = new ArrayCovariance.MethodParameterLookup(methodCall, c.SemanticModel);
                    var argumentMappings = methodCall.ArgumentList.Arguments.Select(argument =>
                        new KeyValuePair<ArgumentSyntax, IParameterSymbol>(argument,
                            methodParameterLookup.GetParameterSymbol(argument)))
                        .ToList();

                    var methodSymbol = methodParameterLookup.MethodSymbol;
                    if (methodSymbol == null)
                    {
                        return;
                    }

                    foreach (var argumentMapping in argumentMappings)
                    {
                        if (ArgumentHasDefaultValue(argumentMapping, c.SemanticModel))
                        {
                            var argument = argumentMapping.Key;
                            var parameter = argumentMapping.Value;
                            c.ReportDiagnostic(Diagnostic.Create(Rule, argument.GetLocation(), parameter.Name));
                        }
                    }
                },
                SyntaxKind.InvocationExpression);
        }
        public override void Initialize(AnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var methodCall                = (InvocationExpressionSyntax)c.Node;
                var methodParameterLookup     = new ArrayCovariance.MethodParameterLookup(methodCall, c.SemanticModel);
                var argumentParameterMappings = methodCall.ArgumentList.Arguments.Select(argument =>
                                                                                         new KeyValuePair <ArgumentSyntax, IParameterSymbol>(argument,
                                                                                                                                             methodParameterLookup.GetParameterSymbol(argument)))
                                                .ToDictionary(pair => pair.Key, pair => pair.Value);

                var methodSymbol = methodParameterLookup.MethodSymbol;

                if (methodSymbol == null)
                {
                    return;
                }

                var parameterNames = argumentParameterMappings.Values
                                     .Select(symbol => symbol.Name)
                                     .Distinct()
                                     .ToList();

                var identifierArguments = GetIdentifierArguments(methodCall);
                var identifierNames     = identifierArguments
                                          .Select(p => p.IdentifierName)
                                          .ToList();

                if (!parameterNames.Intersect(identifierNames).Any())
                {
                    return;
                }

                var methodCallHasIssue = false;

                for (var i = 0; !methodCallHasIssue && i < identifierArguments.Count; i++)
                {
                    var identifierArgument = identifierArguments[i];
                    var identifierName     = identifierArgument.IdentifierName;
                    var parameter          = argumentParameterMappings[identifierArgument.ArgumentSyntax];
                    var parameterName      = parameter.Name;

                    if (string.IsNullOrEmpty(identifierName) ||
                        !parameterNames.Contains(identifierName))
                    {
                        continue;
                    }

                    var positional = identifierArgument as PositionalIdentifierArgument;
                    if (positional != null &&
                        (parameter.IsParams ||
                         !identifierNames.Contains(parameterName) ||
                         identifierName == parameterName))
                    {
                        continue;
                    }

                    var named = identifierArgument as NamedIdentifierArgument;
                    if (named != null &&
                        (!identifierNames.Contains(named.DeclaredName) || named.DeclaredName == named.IdentifierName))
                    {
                        continue;
                    }

                    methodCallHasIssue = true;
                }

                if (methodCallHasIssue)
                {
                    var memberAccess   = methodCall.Expression as MemberAccessExpressionSyntax;
                    var reportLocation = memberAccess == null
                            ? methodCall.Expression.GetLocation()
                            : memberAccess.Name.GetLocation();

                    c.ReportDiagnostic(Diagnostic.Create(Rule, reportLocation,
                                                         methodSymbol.Name));
                }
            },
                SyntaxKind.InvocationExpression);
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            var diagnostic = context.Diagnostics.First();
            var invocation = GetInvocation(root, diagnostic.Location.SourceSpan);
            if (invocation == null)
            {
                return;
            }

            var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken);
            var methodParameterLookup = new ArrayCovariance.MethodParameterLookup(invocation, semanticModel);
            var argumentMappings = invocation.ArgumentList.Arguments
                .Select(argument =>
                    new KeyValuePair<ArgumentSyntax, IParameterSymbol>(argument,
                        methodParameterLookup.GetParameterSymbol(argument)))
                .ToList();

            var methodSymbol = methodParameterLookup.MethodSymbol;
            if (methodSymbol == null)
            {
                return;
            }

            var argumentsWithDefaultValues = new List<ArgumentSyntax>();
            var argumentsCanBeRemovedWithoutNamed = new List<ArgumentSyntax>();
            var canBeRemovedWithoutNamed = true;

            var reversedMappings =
                ((IEnumerable<KeyValuePair<ArgumentSyntax, IParameterSymbol>>) argumentMappings).Reverse();
            foreach (var argumentMapping in reversedMappings)
            {
                var argument = argumentMapping.Key;

                if (RedundantArgument.ArgumentHasDefaultValue(argumentMapping, semanticModel))
                {
                    argumentsWithDefaultValues.Add(argument);

                    if (canBeRemovedWithoutNamed)
                    {
                        argumentsCanBeRemovedWithoutNamed.Add(argument);
                    }
                }
                else
                {
                    if (argument.NameColon == null)
                    {
                        canBeRemovedWithoutNamed = false;
                    }
                }
            }

            if (argumentsCanBeRemovedWithoutNamed.Any())
            {
                context.RegisterCodeFix(
                    CodeAction.Create(
                        TitleRemove,
                        c => RemoveArguments(context.Document, argumentsCanBeRemovedWithoutNamed, c),
                        TitleRemove),
                    context.Diagnostics);
            }

            var cannotBeRemoved = argumentsWithDefaultValues.Except(argumentsCanBeRemovedWithoutNamed);
            if (cannotBeRemoved.Any())
            {
                context.RegisterCodeFix(
                    CodeAction.Create(
                        TitleRemoveWithNameAdditions,
                        c => RemoveArgumentsAndAddNecessaryNames(context.Document, invocation.ArgumentList,
                                argumentMappings, argumentsWithDefaultValues, semanticModel, c),
                        TitleRemoveWithNameAdditions),
                    context.Diagnostics);
            }
        }
        public override void Initialize(AnalysisContext context)
        {
            context.RegisterSyntaxNodeAction(
                c =>
                {
                    var methodCall = (InvocationExpressionSyntax) c.Node;
                    var methodParameterLookup = new ArrayCovariance.MethodParameterLookup(methodCall, c.SemanticModel);
                    var argumentParameterMappings = methodCall.ArgumentList.Arguments.Select(argument =>
                        new KeyValuePair<ArgumentSyntax, IParameterSymbol>(argument,
                            methodParameterLookup.GetParameterSymbol(argument)))
                        .ToDictionary(pair => pair.Key, pair => pair.Value);
                    
                    var methodSymbol = methodParameterLookup.MethodSymbol;

                    if (methodSymbol == null)
                    {
                        return;
                    }
                    
                    var parameterNames = argumentParameterMappings.Values
                        .Select(symbol => symbol.Name)
                        .Distinct()
                        .ToList();
                    
                    var identifierArguments = GetIdentifierArguments(methodCall);
                    var identifierNames = identifierArguments
                        .Select(p => p.IdentifierName)
                        .ToList();

                    if (!parameterNames.Intersect(identifierNames).Any())
                    {
                        return;
                    }

                    var methodCallHasIssue = false;

                    for (var i = 0; !methodCallHasIssue && i < identifierArguments.Count; i++)
                    {
                        var identifierArgument = identifierArguments[i];
                        var identifierName = identifierArgument.IdentifierName;
                        var parameter = argumentParameterMappings[identifierArgument.ArgumentSyntax];
                        var parameterName = parameter.Name;

                        if (string.IsNullOrEmpty(identifierName) ||
                            !parameterNames.Contains(identifierName))
                        {
                            continue;
                        }

                        var positional = identifierArgument as PositionalIdentifierArgument;
                        if (positional != null &&
                            (parameter.IsParams ||
                             !identifierNames.Contains(parameterName) ||
                             identifierName == parameterName))
                        {
                            continue;
                        }

                        var named = identifierArgument as NamedIdentifierArgument;
                        if (named != null &&
                            (!identifierNames.Contains(named.DeclaredName) || named.DeclaredName == named.IdentifierName))
                        {
                            continue;
                        }

                        methodCallHasIssue = true;
                    }

                    if (methodCallHasIssue)
                    {
                        var memberAccess = methodCall.Expression as MemberAccessExpressionSyntax;
                        var reportLocation = memberAccess == null
                            ? methodCall.Expression.GetLocation()
                            : memberAccess.Name.GetLocation();

                        c.ReportDiagnostic(Diagnostic.Create(Rule, reportLocation,
                            methodSymbol.Name));
                    }
                },
                SyntaxKind.InvocationExpression);
        }
Пример #6
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            var diagnostic = context.Diagnostics.First();
            var invocation = GetInvocation(root, diagnostic.Location.SourceSpan);

            if (invocation == null)
            {
                return;
            }

            var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken);

            var methodParameterLookup = new ArrayCovariance.MethodParameterLookup(invocation, semanticModel);
            var argumentMappings      = invocation.ArgumentList.Arguments
                                        .Select(argument =>
                                                new KeyValuePair <ArgumentSyntax, IParameterSymbol>(argument,
                                                                                                    methodParameterLookup.GetParameterSymbol(argument)))
                                        .ToList();

            var methodSymbol = methodParameterLookup.MethodSymbol;

            if (methodSymbol == null)
            {
                return;
            }

            var argumentsWithDefaultValues        = new List <ArgumentSyntax>();
            var argumentsCanBeRemovedWithoutNamed = new List <ArgumentSyntax>();
            var canBeRemovedWithoutNamed          = true;

            var reversedMappings =
                ((IEnumerable <KeyValuePair <ArgumentSyntax, IParameterSymbol> >)argumentMappings).Reverse();

            foreach (var argumentMapping in reversedMappings)
            {
                var argument = argumentMapping.Key;

                if (RedundantArgument.ArgumentHasDefaultValue(argumentMapping, semanticModel))
                {
                    argumentsWithDefaultValues.Add(argument);

                    if (canBeRemovedWithoutNamed)
                    {
                        argumentsCanBeRemovedWithoutNamed.Add(argument);
                    }
                }
                else if (argument.NameColon == null)
                {
                    canBeRemovedWithoutNamed = false;
                }
            }

            if (argumentsCanBeRemovedWithoutNamed.Any())
            {
                context.RegisterCodeFix(
                    CodeAction.Create(
                        TitleRemove,
                        c => RemoveArguments(context.Document, argumentsCanBeRemovedWithoutNamed, c),
                        TitleRemove),
                    context.Diagnostics);
            }

            var cannotBeRemoved = argumentsWithDefaultValues.Except(argumentsCanBeRemovedWithoutNamed);

            if (cannotBeRemoved.Any())
            {
                context.RegisterCodeFix(
                    CodeAction.Create(
                        TitleRemoveWithNameAdditions,
                        c => RemoveArgumentsAndAddNecessaryNames(context.Document, invocation.ArgumentList,
                                                                 argumentMappings, argumentsWithDefaultValues, semanticModel, c),
                        TitleRemoveWithNameAdditions),
                    context.Diagnostics);
            }
        }