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);
        }
Exemplo n.º 2
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 ArgumentParameterMapping(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.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);
        }
        public override void Initialize(AnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
                {
                    var invocation = (InvocationExpressionSyntax)c.Node;
                    var methodSymbol = c.SemanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;

                    if (methodSymbol == null ||
                        methodSymbol.ContainingType.SpecialType != SpecialType.System_String ||
                        methodSymbol.Name != "Format")
                    {
                        return;
                    }

                    if (invocation.ArgumentList == null ||
                        invocation.ArgumentList.Arguments.Count == 0)
                    {
                        return;
                    }

                    var lookup = new MethodParameterLookup(invocation, c.SemanticModel);
                    if (!InvocationHasFormatArgument(invocation, lookup))
                    {
                        var formatArgument = invocation.ArgumentList.Arguments
                            .FirstOrDefault(arg => lookup.GetParameterSymbol(arg).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())));
                    }
                },
                SyntaxKind.InvocationExpression);
        }
        internal static bool ArgumentHasDefaultValue(
            MethodParameterLookup.ArgumentParameterMapping argumentMapping,
            SemanticModel semanticModel)
        {
            var argument = argumentMapping.Argument;
            var parameter = argumentMapping.Parameter;

            if (!parameter.HasExplicitDefaultValue)
            {
                return false;
            }

            var defaultValue = parameter.ExplicitDefaultValue;
            var argumentValue = semanticModel.GetConstantValue(argument.Expression);
            return argumentValue.HasValue &&
                object.Equals(argumentValue.Value, defaultValue);
        }
        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);
        }
        public override void Initialize(AnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
                {
                    var methodCall = (InvocationExpressionSyntax) c.Node;
                    var methodParameterLookup = new 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);
        }
Exemplo n.º 8
0
        public override void Initialize(AnalysisContext 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)
                    {
                        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.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 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);
        }
        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);
            }
        }
 private static bool InvocationHasFormatArgument(InvocationExpressionSyntax invocation, MethodParameterLookup lookup)
 {
     return invocation.ArgumentList.Arguments.Any(arg =>
     {
         var param = lookup.GetParameterSymbol(arg);
         return param != null && param.Name.StartsWith("arg", System.StringComparison.Ordinal);
     });
 }
 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);
     });
 }
Exemplo n.º 13
0
        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);
        }