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