public static void AnalyzeAddExpression(SyntaxNodeAnalysisContext context) { var addExpression = (BinaryExpressionSyntax)context.Node; if (addExpression.ContainsDiagnostics) { return; } IMethodSymbol methodSymbol = context.SemanticModel.GetMethodSymbol(addExpression, context.CancellationToken); if (!SymbolUtility.IsStringAdditionOperator(methodSymbol)) { return; } ExpressionSyntax expression = GetObjectExpression()?.WalkDownParentheses(); if (expression == null) { return; } if (expression.Kind() == SyntaxKind.AddExpression) { return; } ITypeSymbol typeSymbol = context.SemanticModel.GetTypeSymbol(expression, context.CancellationToken); if (typeSymbol?.IsValueType != true) { return; } DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.AvoidBoxingOfValueType, expression); ExpressionSyntax GetObjectExpression() { ImmutableArray <IParameterSymbol> parameters = methodSymbol.Parameters; if (parameters[0].Type.SpecialType == SpecialType.System_Object) { return(addExpression.Left); } else if (parameters[1].Type.SpecialType == SpecialType.System_Object) { return(addExpression.Right); } else { return(null); } } }
public static bool IsStringConcatenation(BinaryExpressionSyntax addExpression, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { return(addExpression.Kind() == SyntaxKind.AddExpression && SymbolUtility.IsStringAdditionOperator(semanticModel.GetMethodSymbol(addExpression, cancellationToken))); }
public static bool IsFixable( SimpleMemberInvocationExpressionInfo invocationInfo, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { if (invocationInfo.Expression.Kind() == SyntaxKind.BaseExpression) { return(false); } InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocationExpression, cancellationToken); if (SymbolUtility.IsPublicInstanceNonGeneric(methodSymbol, "ToString") && methodSymbol.ReturnType.SpecialType == SpecialType.System_String && !methodSymbol.Parameters.Any()) { INamedTypeSymbol containingType = methodSymbol.ContainingType; if (containingType?.IsReferenceType == true && containingType.SpecialType != SpecialType.System_Enum) { if (containingType.SpecialType == SpecialType.System_String) { return(true); } ExpressionSyntax expression = invocationExpression.WalkUpParentheses(); SyntaxNode parent = expression.Parent; if (parent != null) { SyntaxKind kind = parent.Kind(); if (kind == SyntaxKind.Interpolation) { return(IsNotHidden(methodSymbol, containingType)); } else if (kind == SyntaxKind.AddExpression) { if (!parent.ContainsDiagnostics && IsNotHidden(methodSymbol, containingType)) { var addExpression = (BinaryExpressionSyntax)expression.Parent; if (CSharpUtility.IsStringConcatenation(addExpression, semanticModel, cancellationToken)) { BinaryExpressionSyntax newAddExpression = addExpression.ReplaceNode(expression, invocationInfo.Expression); IMethodSymbol speculativeSymbol = semanticModel.GetSpeculativeMethodSymbol(addExpression.SpanStart, newAddExpression); return(SymbolUtility.IsStringAdditionOperator(speculativeSymbol)); } } } } } } return(false); }