Example #1
0
        private static bool IsInvocationWithExplicitArray(ArgumentListSyntax argumentList, IMethodSymbol invokedMethodSymbol,
                                                          SemanticModel semanticModel)
        {
            var allParameterMatches = new List <IParameterSymbol>();

            foreach (var argument in argumentList.Arguments)
            {
                if (!MethodParameterLookup.TryGetParameterSymbol(argument, argumentList, invokedMethodSymbol, out var parameter))
                {
                    return(false);
                }

                allParameterMatches.Add(parameter);

                if (!parameter.IsParams)
                {
                    continue;
                }

                var argType = semanticModel.GetTypeInfo(argument.Expression).Type;
                if (!(argType is IArrayTypeSymbol))
                {
                    return(false);
                }
            }

            return(allParameterMatches.Count(p => p.IsParams) == 1);
        }
        private static bool TryGetTypeFromArgumentMappedToFloatType(BinaryExpressionSyntax division, SemanticModel semanticModel,
                                                                    out ITypeSymbol type)
        {
            var argument = division.Parent as ArgumentSyntax;

            if (argument == null)
            {
                type = null;
                return(false);
            }

            var invocation = argument.Parent.Parent as InvocationExpressionSyntax;

            if (invocation == null)
            {
                type = null;
                return(false);
            }

            var lookup = new MethodParameterLookup(invocation, semanticModel);
            IParameterSymbol parameter;

            if (!lookup.TryGetParameterSymbol(argument, out parameter))
            {
                type = null;
                return(false);
            }

            type = parameter.Type;
            return(type.IsAny(KnownType.NonIntegralNumbers));
        }
Example #3
0
        public override void Initialize(AnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var methodCall            = (InvocationExpressionSyntax)c.Node;
                var methodParameterLookup = new 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 (ParameterHasCallerInfoAttribute(argumentMapping))
                    {
                        var argument = argumentMapping.Key;
                        c.ReportDiagnostic(Diagnostic.Create(Rule, argument.GetLocation()));
                    }
                }
            },
                SyntaxKind.InvocationExpression);
        }
Example #4
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var methodCall            = (InvocationExpressionSyntax)c.Node;
                var methodParameterLookup = new MethodParameterLookup(methodCall, c.SemanticModel);
                var argumentMappings      = methodParameterLookup.GetAllArgumentParameterMappings()
                                            .ToList();

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

                foreach (var argumentMapping in argumentMappings.Where(argumentMapping => ArgumentHasDefaultValue(argumentMapping, c.SemanticModel)))
                {
                    var argument  = argumentMapping.Argument;
                    var parameter = argumentMapping.Parameter;
                    c.ReportDiagnostic(Diagnostic.Create(Rule, argument.GetLocation(), parameter.Name));
                }
            },
                SyntaxKind.InvocationExpression);
        }
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var invocation   = (InvocationExpressionSyntax)c.Node;
                var methodSymbol = c.SemanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;

                if (!methodSymbol.IsInType(KnownType.System_String) ||
                    methodSymbol.Name != "Format" ||
                    invocation.HasExactlyNArguments(0))
                {
                    return;
                }

                var lookup = new MethodParameterLookup(invocation, c.SemanticModel);
                if (InvocationHasFormatArgument(invocation, lookup))
                {
                    return;
                }

                var formatArgument = invocation.ArgumentList.Arguments
                                     .FirstOrDefault(arg =>
                {
                    IParameterSymbol parameter;
                    return(lookup.TryGetParameterSymbol(arg, out parameter) &&
                           parameter.Name == "format");
                });
                if (formatArgument == null)
                {
                    return;
                }

                var constValue = c.SemanticModel.GetConstantValue(formatArgument.Expression);
                if (!constValue.HasValue)
                {
                    // we don't report on non-contant format strings
                    return;
                }

                var formatString = constValue.Value as string;
                if (formatString == null)
                {
                    return;
                }

                if (!StringFormatArgumentNumberMismatch.FormatterAcceptsArgumentCount(formatString, 0))
                {
                    ///A more severe issue is already reported by <see cref="StringFormatArgumentNumberMismatch"/>
                    return;
                }

                c.ReportDiagnostic(Diagnostic.Create(Rule, invocation.Expression.GetLocation(),
                                                     ImmutableDictionary <string, string> .Empty.Add(
                                                         FormatStringIndexKey,
                                                         invocation.ArgumentList.Arguments.IndexOf(formatArgument).ToString(CultureInfo.InvariantCulture))));
            },
                SyntaxKind.InvocationExpression);
        }
        private static void CheckToStringInvocationsOnStringAndInStringFormat(SonarAnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var invocation = (InvocationExpressionSyntax)c.Node;

                Location location;
                IMethodSymbol methodSymbol;
                if (!IsArgumentlessToStringCallNotOnBaseExpression(invocation, c.SemanticModel, out location, out methodSymbol))
                {
                    return;
                }

                if (methodSymbol.IsInType(KnownType.System_String))
                {
                    c.ReportDiagnostic(Diagnostic.Create(Rule, location, MessageCallOnString));
                    return;
                }

                ITypeSymbol subExpressionType;
                if (!TryGetExpressionTypeOfOwner(invocation, c.SemanticModel, out subExpressionType) ||
                    subExpressionType.IsValueType)
                {
                    return;
                }

                var stringFormatArgument   = invocation?.Parent as ArgumentSyntax;
                var stringFormatInvocation = stringFormatArgument?.Parent?.Parent as InvocationExpressionSyntax;
                if (stringFormatInvocation == null ||
                    !IsStringFormatCall(c.SemanticModel.GetSymbolInfo(stringFormatInvocation).Symbol as IMethodSymbol))
                {
                    return;
                }

                var parameterLookup = new MethodParameterLookup(stringFormatInvocation, c.SemanticModel);
                IParameterSymbol argParameter;
                if (parameterLookup.TryGetParameterSymbol(stringFormatArgument, out argParameter) &&
                    argParameter.Name.StartsWith("arg", StringComparison.Ordinal))
                {
                    c.ReportDiagnostic(Diagnostic.Create(Rule, location, MessageCompiler));
                }
            },
                SyntaxKind.InvocationExpression);
        }
        private void RaiseOnArrayCovarianceInInvocationExpression(SyntaxNodeAnalysisContext context)
        {
            var invocation            = (InvocationExpressionSyntax)context.Node;
            var methodParameterLookup = new MethodParameterLookup(invocation, context.SemanticModel);

            foreach (var argument in invocation.ArgumentList.Arguments)
            {
                if (!methodParameterLookup.TryGetParameterSymbol(argument, out var parameter) ||
                    parameter.IsParams)
                {
                    continue;
                }

                var typeDerived = context.SemanticModel.GetTypeInfo(argument.Expression).Type;
                if (AreCovariantArrayTypes(typeDerived, parameter.Type))
                {
                    context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, argument.GetLocation()));
                }
            }
        }
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var methodCall            = (InvocationExpressionSyntax)c.Node;
                var methodParameterLookup = new MethodParameterLookup(methodCall, c.SemanticModel);
                var argumentMappings      = methodParameterLookup.GetAllArgumentParameterMappings()
                                            .ToList();

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

                foreach (var argumentMapping in argumentMappings)
                {
                    var parameter = argumentMapping.Parameter;
                    var argument  = argumentMapping.Argument;

                    var callerInfoAttributeDataOnCall = GetCallerInfoAttribute(parameter);
                    if (callerInfoAttributeDataOnCall == null)
                    {
                        continue;
                    }

                    var symbolForArgument = c.SemanticModel.GetSymbolInfo(argument.Expression).Symbol as IParameterSymbol;
                    if (symbolForArgument != null &&
                        object.Equals(callerInfoAttributeDataOnCall.AttributeClass, GetCallerInfoAttribute(symbolForArgument)?.AttributeClass))
                    {
                        continue;
                    }

                    c.ReportDiagnostic(Diagnostic.Create(Rule, argument.GetLocation()));
                }
            },
                SyntaxKind.InvocationExpression);
        }
        private static bool ArgumentsMatchParameters(ArgumentListSyntax argumentList, List <INamedTypeSymbol> argumentTypes,
                                                     IMethodSymbol possibleOtherMethod, SemanticModel semanticModel)
        {
            var matchedParameters = new List <IParameterSymbol>();

            for (int i = 0; i < argumentList.Arguments.Count; i++)
            {
                var argument     = argumentList.Arguments[i];
                var argumentType = argumentTypes[i];
                IParameterSymbol parameter;
                if (!MethodParameterLookup.TryGetParameterSymbol(argument, argumentList, possibleOtherMethod, out parameter))
                {
                    return(false);
                }

                if (argumentType == null)
                {
                    if (!parameter.Type.IsReferenceType)
                    {
                        return(false);
                    }
                }
                else
                {
                    var conversion = semanticModel.ClassifyConversion(argument.Expression, parameter.Type);
                    if (!conversion.IsImplicit)
                    {
                        return(false);
                    }
                }

                matchedParameters.Add(parameter);
            }

            var nonMatchedParameters = possibleOtherMethod.Parameters.Except(matchedParameters);

            return(nonMatchedParameters.All(p => p.HasExplicitDefaultValue));
        }
Example #10
0
        protected sealed override async Task RegisterCodeFixesAsync(SyntaxNode root, CodeFixContext context)
        {
            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 MethodParameterLookup(invocation, semanticModel);
            var argumentMappings      = methodParameterLookup.GetAllArgumentParameterMappings()
                                        .ToList();

            var methodSymbol = methodParameterLookup.MethodSymbol;

            if (methodSymbol == null)
            {
                return;
            }

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

            var reversedMappings = new List <MethodParameterLookup.ArgumentParameterMapping>(argumentMappings);

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

                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 => RemoveArgumentsAsync(context.Document, argumentsCanBeRemovedWithoutNamed, c),
                        TitleRemove),
                    context.Diagnostics);
            }

            var cannotBeRemoved = argumentsWithDefaultValues.Except(argumentsCanBeRemovedWithoutNamed);

            if (cannotBeRemoved.Any())
            {
                context.RegisterCodeFix(
                    CodeAction.Create(
                        TitleRemoveWithNameAdditions,
                        c => RemoveArgumentsAndAddNecessaryNamesAsync(context.Document, invocation.ArgumentList,
                                                                      argumentMappings, argumentsWithDefaultValues, semanticModel, c),
                        TitleRemoveWithNameAdditions),
                    context.Diagnostics);
            }
        }
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var methodCall                = (InvocationExpressionSyntax)c.Node;
                var methodParameterLookup     = new MethodParameterLookup(methodCall, c.SemanticModel);
                var argumentParameterMappings = methodParameterLookup.GetAllArgumentParameterMappings()
                                                .ToDictionary(pair => pair.Argument, pair => pair.Parameter);

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

                    var secondaryLocations = methodSymbol.DeclaringSyntaxReferences
                                             .Select(s => s.GetSyntax())
                                             .OfType <MethodDeclarationSyntax>()
                                             .Select(s => s.Identifier.GetLocation())
                                             .ToList();

                    c.ReportDiagnostic(Diagnostic.Create(Rule, reportLocation,
                                                         additionalLocations: secondaryLocations,
                                                         messageArgs: methodSymbol.Name));
                }
            },
                SyntaxKind.InvocationExpression);
        }
        private static void AnalyzeArguments(SyntaxNodeAnalysisContext analysisContext, ArgumentListSyntax argumentList,
                                             Func <Location> getLocation)
        {
            if (argumentList == null)
            {
                return;
            }

            var methodParameterLookup     = new MethodParameterLookup(argumentList, analysisContext.SemanticModel);
            var argumentParameterMappings = methodParameterLookup.GetAllArgumentParameterMappings()
                                            .ToDictionary(pair => pair.Argument, pair => pair.Parameter);

            var methodSymbol = methodParameterLookup.MethodSymbol;

            if (methodSymbol == null)
            {
                return;
            }

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

            var identifierArguments = GetIdentifierArguments(argumentList);
            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) ||
                    !IdentifierWithSameNameAndTypeExists(parameter))
                {
                    continue;
                }

                if (identifierArgument is PositionalIdentifierArgument positional &&
                    (parameter.IsParams || identifierName == parameterName))
                {
                    continue;
                }

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

                methodCallHasIssue = true;
            }

            if (methodCallHasIssue)
            {
                var secondaryLocations = methodSymbol.DeclaringSyntaxReferences
                                         .Select(s => GetIdentifierLocation(s.GetSyntax()))
                                         .WhereNotNull();

                analysisContext.ReportDiagnosticWhenActive(Diagnostic.Create(rule, getLocation(),
                                                                             additionalLocations: secondaryLocations,
                                                                             messageArgs: methodSymbol.Name));
            }

            bool IdentifierWithSameNameAndTypeExists(IParameterSymbol parameter) =>
            identifierArguments.Any(ia =>
                                    ia.IdentifierName == parameter.Name &&
                                    GetTypeSymbol(ia.ArgumentSyntax.Expression).DerivesOrImplements(parameter.Type));

            ITypeSymbol GetTypeSymbol(SyntaxNode syntaxNode) =>
            analysisContext.SemanticModel.GetTypeInfo(syntaxNode).ConvertedType;
        }
 private static bool InvocationHasFormatArgument(InvocationExpressionSyntax invocation, MethodParameterLookup lookup)
 {
     return(invocation.ArgumentList.Arguments.Any(arg =>
     {
         IParameterSymbol parameter;
         return lookup.TryGetParameterSymbol(arg, out parameter) &&
         parameter.Name.StartsWith("arg", System.StringComparison.Ordinal);
     }));
 }
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var assignment  = (AssignmentExpressionSyntax)c.Node;
                var typeDerived = c.SemanticModel.GetTypeInfo(assignment.Right).Type;
                var typeBase    = c.SemanticModel.GetTypeInfo(assignment.Left).Type;

                if (AreCovariantArrayTypes(typeDerived, typeBase))
                {
                    c.ReportDiagnostic(Diagnostic.Create(Rule, assignment.Right.GetLocation()));
                }
            },
                SyntaxKind.SimpleAssignmentExpression);

            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var variableDeclaration = (VariableDeclarationSyntax)c.Node;
                var typeBase            = c.SemanticModel.GetTypeInfo(variableDeclaration.Type).Type;

                foreach (var variable in variableDeclaration.Variables
                         .Where(syntax => syntax.Initializer != null))
                {
                    var typeDerived = c.SemanticModel.GetTypeInfo(variable.Initializer.Value).Type;

                    if (AreCovariantArrayTypes(typeDerived, typeBase))
                    {
                        c.ReportDiagnostic(Diagnostic.Create(Rule, variable.Initializer.Value.GetLocation()));
                    }
                }
            },
                SyntaxKind.VariableDeclaration);

            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var invocation            = (InvocationExpressionSyntax)c.Node;
                var methodParameterLookup = new MethodParameterLookup(invocation, c.SemanticModel);

                foreach (var argument in invocation.ArgumentList.Arguments)
                {
                    IParameterSymbol parameter;
                    if (!methodParameterLookup.TryGetParameterSymbol(argument, out parameter) ||
                        parameter.IsParams)
                    {
                        continue;
                    }

                    var typeDerived = c.SemanticModel.GetTypeInfo(argument.Expression).Type;
                    if (AreCovariantArrayTypes(typeDerived, parameter.Type))
                    {
                        c.ReportDiagnostic(Diagnostic.Create(Rule, argument.GetLocation()));
                    }
                }
            },
                SyntaxKind.InvocationExpression);

            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var castExpression = (CastExpressionSyntax)c.Node;
                var typeDerived    = c.SemanticModel.GetTypeInfo(castExpression.Expression).Type;
                var typeBase       = c.SemanticModel.GetTypeInfo(castExpression.Type).Type;

                if (AreCovariantArrayTypes(typeDerived, typeBase))
                {
                    c.ReportDiagnostic(Diagnostic.Create(Rule, castExpression.Type.GetLocation()));
                }
            },
                SyntaxKind.CastExpression);
        }
        private static void AnalyzeArguments(SyntaxNodeAnalysisContext analysisContext, ArgumentListSyntax argumentList,
                                             Func <Location> getLocation)
        {
            if (argumentList == null)
            {
                return;
            }

            var methodParameterLookup     = new MethodParameterLookup(argumentList, analysisContext.SemanticModel);
            var argumentParameterMappings = methodParameterLookup.GetAllArgumentParameterMappings()
                                            .ToDictionary(pair => pair.Argument, pair => pair.Parameter);

            var methodSymbol = methodParameterLookup.MethodSymbol;

            if (methodSymbol == null)
            {
                return;
            }

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

            var identifierArguments = GetIdentifierArguments(argumentList);
            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 secondaryLocations = methodSymbol.DeclaringSyntaxReferences
                                         .Select(s => GetIdentifierLocation(s.GetSyntax()))
                                         .WhereNotNull();

                analysisContext.ReportDiagnostic(Diagnostic.Create(rule, getLocation(),
                                                                   additionalLocations: secondaryLocations,
                                                                   messageArgs: methodSymbol.Name));
            }
        }
        public override void Initialize(AnalysisContext context)
        {
            context.RegisterSyntaxNodeAction(
                c =>
                {
                    var assignment = (AssignmentExpressionSyntax) c.Node;
                    var typeDerived = c.SemanticModel.GetTypeInfo(assignment.Right).Type;
                    var typeBase = c.SemanticModel.GetTypeInfo(assignment.Left).Type;

                    if (AreCovariantArrayTypes(typeDerived, typeBase))
                    {
                        c.ReportDiagnostic(Diagnostic.Create(Rule, assignment.Right.GetLocation()));
                    }
                },
                SyntaxKind.SimpleAssignmentExpression);

            context.RegisterSyntaxNodeAction(
                c =>
                {
                    var variableDeclaration = (VariableDeclarationSyntax)c.Node;
                    var typeBase = c.SemanticModel.GetTypeInfo(variableDeclaration.Type).Type;

                    foreach (var variable in variableDeclaration.Variables
                        .Where(syntax => syntax.Initializer != null))
                    {
                        var typeDerived = c.SemanticModel.GetTypeInfo(variable.Initializer.Value).Type;

                        if (AreCovariantArrayTypes(typeDerived, typeBase))
                        {
                            c.ReportDiagnostic(Diagnostic.Create(Rule, variable.Initializer.Value.GetLocation()));
                        }
                    }
                },
                SyntaxKind.VariableDeclaration);

            context.RegisterSyntaxNodeAction(
                c =>
                {
                    var invocation = (InvocationExpressionSyntax)c.Node;
                    var methodParameterLookup = new MethodParameterLookup(invocation, c.SemanticModel);

                    foreach (var argument in invocation.ArgumentList.Arguments)
                    {
                        var parameter = methodParameterLookup.GetParameterSymbol(argument);
                        if (parameter == null)
                        {
                            continue;
                        }

                        if (parameter.IsParams)
                        {
                            continue;
                        }

                        var typeDerived = c.SemanticModel.GetTypeInfo(argument.Expression).Type;
                        if (AreCovariantArrayTypes(typeDerived, parameter.Type))
                        {
                            c.ReportDiagnostic(Diagnostic.Create(Rule, argument.GetLocation()));
                        }
                    }
                },
                SyntaxKind.InvocationExpression);

            context.RegisterSyntaxNodeAction(
                c =>
                {
                    var castExpression = (CastExpressionSyntax) c.Node;
                    var typeDerived = c.SemanticModel.GetTypeInfo(castExpression.Expression).Type;
                    var typeBase = c.SemanticModel.GetTypeInfo(castExpression.Type).Type;

                    if (AreCovariantArrayTypes(typeDerived, typeBase))
                    {
                        c.ReportDiagnostic(Diagnostic.Create(Rule, castExpression.Type.GetLocation()));
                    }
                },
                SyntaxKind.CastExpression);
        }