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