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);
                }
            }
        }
示例#2
0
 public static bool IsStringConcatenation(BinaryExpressionSyntax addExpression, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(addExpression.Kind() == SyntaxKind.AddExpression &&
            SymbolUtility.IsStringAdditionOperator(semanticModel.GetMethodSymbol(addExpression, cancellationToken)));
 }
示例#3
0
        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);
        }