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 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); }
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); } }