protected override IParameterSymbol GetParameterSymbolCore(SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            SyntaxNode parent = Node.Parent;

            if (parent?.Kind() != SyntaxKind.CoalesceExpression)
            {
                return(null);
            }

            SimpleAssignmentExpressionInfo simpleAssignment = SyntaxInfo.SimpleAssignmentExpressionInfo(parent.Parent);

            ISymbol leftSymbol = semanticModel.GetSymbol(simpleAssignment.Left, cancellationToken);

            if (leftSymbol?.Kind != SymbolKind.Parameter)
            {
                return(null);
            }

            if (leftSymbol.ContainingSymbol?.Equals(DeclarationSymbol) != true)
            {
                return(null);
            }

            return((IParameterSymbol)leftSymbol);
        }
예제 #2
0
        protected override IParameterSymbol GetParameterSymbolCore(SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            SyntaxNode parent = Node.Parent;

            if (!parent.IsKind(SyntaxKind.CoalesceExpression))
            {
                return(null);
            }

            SimpleAssignmentExpressionInfo simpleAssignment = SyntaxInfo.SimpleAssignmentExpressionInfo(parent.Parent);

            if (!simpleAssignment.Success)
            {
                return(null);
            }

            ISymbol leftSymbol = semanticModel.GetSymbol(simpleAssignment.Left, cancellationToken);

            if (leftSymbol?.Kind != SymbolKind.Parameter)
            {
                return(null);
            }

            if (!SymbolEqualityComparer.Default.Equals(leftSymbol.ContainingSymbol, DeclarationSymbol))
            {
                return(null);
            }

            return((IParameterSymbol)leftSymbol);
        }
예제 #3
0
        public static bool IsFixable(AssignmentExpressionSyntax assignmentExpression)
        {
            SimpleAssignmentExpressionInfo assignmentInfo = SyntaxInfo.SimpleAssignmentExpressionInfo(assignmentExpression);

            if (!assignmentInfo.Success)
            {
                return(false);
            }

            if (assignmentExpression.IsParentKind(SyntaxKind.ObjectInitializerExpression))
            {
                return(false);
            }

            if (!IsFixableBinaryExpression(assignmentInfo.Right.Kind()))
            {
                return(false);
            }

            BinaryExpressionInfo binaryInfo = SyntaxInfo.BinaryExpressionInfo((BinaryExpressionSyntax)assignmentInfo.Right);

            if (!binaryInfo.Success)
            {
                return(false);
            }

            if (!CSharpFactory.AreEquivalent(assignmentInfo.Left, binaryInfo.Left))
            {
                return(false);
            }

            return(true);
        }
예제 #4
0
        private static void Analyze(
            SyntaxNodeAnalysisContext context,
            SyntaxList <StatementSyntax> statements,
            SingleLocalDeclarationStatementInfo localDeclarationInfo,
            int index,
            ExpressionStatementSyntax expressionStatement)
        {
            SimpleAssignmentExpressionInfo assignment = SyntaxInfo.SimpleAssignmentExpressionInfo(expressionStatement.Expression);

            if (!assignment.Success)
            {
                return;
            }

            if (assignment.Right.Kind() != SyntaxKind.IdentifierName)
            {
                return;
            }

            var identifierName = (IdentifierNameSyntax)assignment.Right;

            string name = localDeclarationInfo.IdentifierText;

            if (!string.Equals(name, identifierName.Identifier.ValueText, StringComparison.Ordinal))
            {
                return;
            }

            VariableDeclaratorSyntax declarator = localDeclarationInfo.Declarator;

            ISymbol localSymbol = context.SemanticModel.GetDeclaredSymbol(declarator, context.CancellationToken);

            if (localSymbol?.IsErrorType() != false)
            {
                return;
            }

            bool isReferenced = IsLocalVariableReferenced(localSymbol, name, assignment.Left, assignment.Left.Span, context.SemanticModel, context.CancellationToken);

            if (!isReferenced &&
                index < statements.Count - 2)
            {
                TextSpan span = TextSpan.FromBounds(statements[index + 2].SpanStart, statements.Last().Span.End);

                isReferenced = IsLocalVariableReferenced(localSymbol, name, localDeclarationInfo.Statement.Parent, span, context.SemanticModel, context.CancellationToken);
            }

            if (isReferenced)
            {
                return;
            }

            if (expressionStatement.SpanOrLeadingTriviaContainsDirectives())
            {
                return;
            }

            ReportDiagnostic(context, localDeclarationInfo, assignment.Right);
        }
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, AssignmentExpressionSyntax assignmentExpression)
        {
            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExpandCompoundAssignmentOperator) &&
                context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(assignmentExpression.OperatorToken) &&
                CSharpFacts.IsCompoundAssignmentExpression(assignmentExpression.Kind()) &&
                SyntaxInfo.AssignmentExpressionInfo(assignmentExpression).Success)
            {
                context.RegisterRefactoring(
                    $"Expand {assignmentExpression.OperatorToken}",
                    ct => ExpandCompoundAssignmentOperatorRefactoring.RefactorAsync(context.Document, assignmentExpression, ct));
            }

            if (context.IsAnyRefactoringEnabled(RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod) &&
                assignmentExpression.IsKind(SyntaxKind.SimpleAssignmentExpression))
            {
                SimpleAssignmentExpressionInfo simpleAssignment = SyntaxInfo.SimpleAssignmentExpressionInfo(assignmentExpression);

                ExpressionSyntax right = simpleAssignment.Right;

                if (simpleAssignment.Success &&
                    right.Span.Contains(context.Span))
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    ITypeSymbol leftSymbol = semanticModel.GetTypeSymbol(simpleAssignment.Left, context.CancellationToken);

                    if (leftSymbol?.IsErrorType() == false)
                    {
                        ITypeSymbol rightSymbol = semanticModel.GetTypeSymbol(right, context.CancellationToken);

                        if (rightSymbol?.IsErrorType() == false &&
                            !leftSymbol.Equals(rightSymbol))
                        {
                            ModifyExpressionRefactoring.ComputeRefactoring(context, right, leftSymbol, semanticModel);
                        }
                    }
                }
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceMethodGroupWithLambda) &&
                context.SupportsSemanticModel)
            {
                await ReplaceMethodGroupWithLambdaRefactoring.ComputeRefactoringAsync(context, assignmentExpression).ConfigureAwait(false);
            }
        }
        private static void AnalyzeCoalesceExpression(SyntaxNodeAnalysisContext context)
        {
            var coalesceExpression = (BinaryExpressionSyntax)context.Node;

            BinaryExpressionInfo binaryExpressionInfo = SyntaxInfo.BinaryExpressionInfo(coalesceExpression, walkDownParentheses: false);

            if (!binaryExpressionInfo.Success)
            {
                return;
            }

            ExpressionSyntax right = binaryExpressionInfo.Right;

            if (!right.IsKind(SyntaxKind.ParenthesizedExpression))
            {
                return;
            }

            var parenthesizedExpression = (ParenthesizedExpressionSyntax)right;

            ExpressionSyntax expression = parenthesizedExpression.Expression;

            if (!expression.IsKind(SyntaxKind.SimpleAssignmentExpression))
            {
                return;
            }

            SimpleAssignmentExpressionInfo assignmentInfo = SyntaxInfo.SimpleAssignmentExpressionInfo((AssignmentExpressionSyntax)expression);

            if (!assignmentInfo.Success)
            {
                return;
            }

            if (!CSharpFactory.AreEquivalent(binaryExpressionInfo.Left, assignmentInfo.Left))
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseCompoundAssignment, coalesceExpression);

            DiagnosticHelpers.ReportToken(context, DiagnosticDescriptors.UseCompoundAssignmentFadeOut, parenthesizedExpression.OpenParenToken);
            DiagnosticHelpers.ReportNode(context, DiagnosticDescriptors.UseCompoundAssignmentFadeOut, assignmentInfo.Left);
            DiagnosticHelpers.ReportToken(context, DiagnosticDescriptors.UseCompoundAssignmentFadeOut, parenthesizedExpression.CloseParenToken);
        }
        private static void AnalyzeSimpleAssignment(SyntaxNodeAnalysisContext context)
        {
            var assignmentExpression = (AssignmentExpressionSyntax)context.Node;

            SimpleAssignmentExpressionInfo assignmentInfo = SyntaxInfo.SimpleAssignmentExpressionInfo(assignmentExpression);

            if (!assignmentInfo.Success)
            {
                return;
            }

            if (assignmentExpression.IsParentKind(SyntaxKind.ObjectInitializerExpression))
            {
                return;
            }

            ExpressionSyntax right = assignmentInfo.Right;

            if (!CanBeReplacedWithCompoundAssignment(right.Kind()))
            {
                return;
            }

            BinaryExpressionInfo binaryInfo = SyntaxInfo.BinaryExpressionInfo((BinaryExpressionSyntax)right);

            if (!binaryInfo.Success)
            {
                return;
            }

            if (!CSharpFactory.AreEquivalent(assignmentInfo.Left, binaryInfo.Left))
            {
                return;
            }

            var binaryExpression = (BinaryExpressionSyntax)right;

            context.ReportDiagnostic(DiagnosticDescriptors.UseCompoundAssignment, assignmentExpression, GetCompoundAssignmentOperatorText(binaryExpression));
            context.ReportNode(DiagnosticDescriptors.UseCompoundAssignmentFadeOut, binaryExpression.Left);
        }
예제 #8
0
        private static async Task <bool> CanRefactorAsync(
            RefactoringContext context,
            PropertyDeclarationSyntax property,
            ExpressionSyntax expression)
        {
            SimpleAssignmentExpressionInfo simpleAssignment = SyntaxInfo.SimpleAssignmentExpressionInfo(expression);

            if (!simpleAssignment.Success)
            {
                return(false);
            }

            if (simpleAssignment.Left.Kind() != SyntaxKind.IdentifierName)
            {
                return(false);
            }

            if (simpleAssignment.Right.Kind() != SyntaxKind.IdentifierName)
            {
                return(false);
            }

            var identifierName = (IdentifierNameSyntax)simpleAssignment.Right;

            if (identifierName.Identifier.ValueText != "value")
            {
                return(false);
            }

            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            return(semanticModel
                   .GetDeclaredSymbol(property, context.CancellationToken)?
                   .ContainingType?
                   .Implements(MetadataNames.System_ComponentModel_INotifyPropertyChanged, allInterfaces: true) == true);
        }
예제 #9
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindNode(root, context.Span, out ExpressionSyntax expression))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.CannotImplicitlyConvertTypeExplicitConversionExists:
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    TypeInfo typeInfo = semanticModel.GetTypeInfo(expression, context.CancellationToken);

                    ITypeSymbol type          = typeInfo.Type;
                    ITypeSymbol convertedType = typeInfo.ConvertedType;

                    if ((type is INamedTypeSymbol namedType) &&
                        namedType.IsNullableType())
                    {
                        if (convertedType?.SpecialType == SpecialType.System_Boolean ||
                            AddComparisonWithBooleanLiteralRefactoring.IsCondition(expression))
                        {
                            if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddComparisonWithBooleanLiteral))
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    AddComparisonWithBooleanLiteralRefactoring.GetTitle(expression),
                                    cancellationToken => AddComparisonWithBooleanLiteralRefactoring.RefactorAsync(context.Document, expression, cancellationToken),
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddComparisonWithBooleanLiteral));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }
                        else if (SymbolEqualityComparer.Default.Equals(namedType.TypeArguments[0], convertedType))
                        {
                            if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.UseCoalesceExpression))
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Use coalesce expression",
                                    cancellationToken =>
                                    {
                                        ExpressionSyntax defaultValue = convertedType.GetDefaultValueSyntax(context.Document.GetDefaultSyntaxOptions());

                                        ExpressionSyntax newNode = CoalesceExpression(expression.WithoutTrivia(), defaultValue)
                                                                   .WithTriviaFrom(expression)
                                                                   .Parenthesize()
                                                                   .WithFormatterAnnotation();

                                        return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken));
                                    },
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.UseCoalesceExpression));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeMemberTypeAccordingToReturnExpression) &&
                        expression.IsParentKind(SyntaxKind.ReturnStatement, SyntaxKind.YieldReturnStatement))
                    {
                        ChangeMemberTypeRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddCastExpression))
                    {
                        CodeFixRegistrator.AddCastExpression(context, diagnostic, expression, convertedType, semanticModel);
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeTypeAccordingToInitializer))
                    {
                        ChangeTypeAccordingToInitializerRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.CreateSingletonArray) &&
                        type?.IsErrorType() == false &&
                        !SymbolEqualityComparer.Default.Equals(type, convertedType) &&
                        (convertedType is IArrayTypeSymbol arrayType) &&
                        semanticModel.IsImplicitConversion(expression, arrayType.ElementType))
                    {
                        CodeAction codeAction = CodeAction.Create(
                            "Create singleton array",
                            cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken),
                            GetEquivalenceKey(diagnostic, CodeFixIdentifiers.CreateSingletonArray));

                        context.RegisterCodeFix(codeAction, diagnostic);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ConstantValueCannotBeConverted:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.UseUncheckedExpression))
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Use 'unchecked'",
                        cancellationToken =>
                        {
                            CheckedExpressionSyntax newNode = CSharpFactory.UncheckedExpression(expression.WithoutTrivia());

                            newNode = newNode.WithTriviaFrom(expression);

                            return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.ExpressionBeingAssignedMustBeConstant:
                {
                    SyntaxNode parent = expression.Parent;

                    if (parent?.IsKind(SyntaxKind.EqualsValueClause) != true)
                    {
                        break;
                    }

                    parent = parent.Parent;

                    if (parent?.IsKind(SyntaxKind.VariableDeclarator) != true)
                    {
                        break;
                    }

                    parent = parent.Parent;

                    if (!(parent is VariableDeclarationSyntax variableDeclaration))
                    {
                        break;
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConstModifier) &&
                        variableDeclaration.Parent is LocalDeclarationStatementSyntax localDeclarationStatement)
                    {
                        SyntaxTokenList modifiers = localDeclarationStatement.Modifiers;

                        if (!modifiers.Contains(SyntaxKind.ConstKeyword))
                        {
                            break;
                        }

                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, localDeclarationStatement, SyntaxKind.ConstKeyword);
                    }
                    else if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceConstantWithField) &&
                             variableDeclaration.Variables.Count == 1 &&
                             (variableDeclaration.Parent is FieldDeclarationSyntax fieldDeclaration) &&
                             fieldDeclaration.Modifiers.Contains(SyntaxKind.ConstKeyword))
                    {
                        CodeAction codeAction = CodeAction.Create(
                            ReplaceConstantWithFieldRefactoring.Title,
                            cancellationToken => ReplaceConstantWithFieldRefactoring.RefactorAsync(context.Document, fieldDeclaration, cancellationToken),
                            GetEquivalenceKey(diagnostic));

                        context.RegisterCodeFix(codeAction, diagnostic);
                        break;
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotConvertNullToTypeBecauseItIsNonNullableValueType:
                case CompilerDiagnosticIdentifiers.CannotConvertNullToTypeParameterBecauseItCouldBeNonNullableValueType:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue))
                    {
                        break;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    CodeFixRegistrator.ReplaceNullWithDefaultValue(context, diagnostic, expression, semanticModel);
                    break;
                }

                case CompilerDiagnosticIdentifiers.ResultOfExpressionIsAlwaysConstantSinceValueIsNeverEqualToNull:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConditionThatIsAlwaysEqualToTrueOrFalse))
                    {
                        break;
                    }

                    NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(expression, allowedStyles: NullCheckStyles.ComparisonToNull);

                    if (!nullCheck.Success)
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Remove condition",
                        cancellationToken =>
                        {
                            cancellationToken.ThrowIfCancellationRequested();

                            SyntaxNode newRoot = RemoveCondition(root, expression, nullCheck.Style == NullCheckStyles.NotEqualsToNull);

                            cancellationToken.ThrowIfCancellationRequested();

                            return(Task.FromResult(context.Document.WithSyntaxRoot(newRoot)));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);

                    break;
                }

                case CompilerDiagnosticIdentifiers.OnlyAssignmentCallIncrementDecrementAndNewObjectExpressionsCanBeUsedAsStatement:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveParentheses) &&
                        expression is ParenthesizedExpressionSyntax parenthesizedExpression &&
                        parenthesizedExpression?.IsMissing == false)
                    {
                        CodeAction codeAction = CodeActionFactory.RemoveParentheses(context.Document, parenthesizedExpression, equivalenceKey: GetEquivalenceKey(diagnostic));

                        context.RegisterCodeFix(codeAction, diagnostic);
                        break;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    if (expression.Parent is ArrowExpressionClauseSyntax arrowExpresssionClause)
                    {
                        if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeMemberTypeAccordingToReturnExpression))
                        {
                            break;
                        }

                        ChangeMemberTypeRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                    }
                    else if (expression.Parent is ExpressionStatementSyntax expressionStatement)
                    {
                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddArgumentList) &&
                            expression.IsKind(
                                SyntaxKind.IdentifierName,
                                SyntaxKind.SimpleMemberAccessExpression))
                        {
                            SyntaxNode invocationExpression = InvocationExpression(expression);

                            if (semanticModel.GetSpeculativeMethodSymbol(expression.SpanStart, invocationExpression) != null)
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Add argument list",
                                    cancellationToken => context.Document.ReplaceNodeAsync(expression, invocationExpression, cancellationToken),
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddArgumentList));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }

                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceComparisonWithAssignment) &&
                            expression.IsKind(SyntaxKind.EqualsExpression))
                        {
                            BinaryExpressionInfo info = SyntaxInfo.BinaryExpressionInfo(expression);

                            if (!info.Success)
                            {
                                break;
                            }

                            ITypeSymbol leftTypeSymbol = semanticModel.GetTypeSymbol(info.Left, context.CancellationToken);

                            if (leftTypeSymbol?.IsErrorType() != false)
                            {
                                break;
                            }

                            if (!semanticModel.IsImplicitConversion(info.Right, leftTypeSymbol))
                            {
                                break;
                            }

                            CodeAction codeAction = CodeAction.Create(
                                "Replace comparison with assignment",
                                cancellationToken =>
                                {
                                    AssignmentExpressionSyntax simpleAssignment = SimpleAssignmentExpression(info.Left, info.Right).WithTriviaFrom(expression);
                                    return(context.Document.ReplaceNodeAsync(expression, simpleAssignment, cancellationToken));
                                },
                                GetEquivalenceKey(diagnostic, CodeFixIdentifiers.ReplaceComparisonWithAssignment));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }

                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceConditionalExpressionWithIfElse) &&
                            (expression is ConditionalExpressionSyntax conditionalExpression) &&
                            conditionalExpression.Condition != null)
                        {
                            ExpressionSyntax whenTrue  = conditionalExpression.WhenTrue;
                            ExpressionSyntax whenFalse = conditionalExpression.WhenFalse;

                            if (whenTrue != null &&
                                whenFalse != null &&
                                semanticModel.GetTypeSymbol(whenTrue, context.CancellationToken)?.SpecialType == SpecialType.System_Void &&
                                semanticModel.GetTypeSymbol(whenFalse, context.CancellationToken)?.SpecialType == SpecialType.System_Void)
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Replace ?: with if-else",
                                    cancellationToken =>
                                    {
                                        IfStatementSyntax newNode = IfStatement(
                                            conditionalExpression.Condition.WalkDownParentheses(),
                                            Block(ExpressionStatement(whenTrue)),
                                            ElseClause(Block(ExpressionStatement(whenFalse))));

                                        newNode = newNode
                                                  .WithTriviaFrom(expressionStatement)
                                                  .WithFormatterAnnotation();

                                        return(context.Document.ReplaceNodeAsync(expressionStatement, newNode, cancellationToken));
                                    },
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.ReplaceConditionalExpressionWithIfElse));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }

                        if (semanticModel.GetSymbol(expression, context.CancellationToken)?.IsErrorType() != false)
                        {
                            break;
                        }

                        ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression, context.CancellationToken);

                        if (typeSymbol?.IsErrorType() != false)
                        {
                            break;
                        }

                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.IntroduceLocalVariable) &&
                            !expressionStatement.IsEmbedded())
                        {
                            bool addAwait = typeSymbol.OriginalDefinition.EqualsOrInheritsFromTaskOfT() &&
                                            semanticModel.GetEnclosingSymbol(expressionStatement.SpanStart, context.CancellationToken).IsAsyncMethod();

                            CodeAction codeAction = CodeAction.Create(
                                IntroduceLocalVariableRefactoring.GetTitle(expression),
                                cancellationToken => IntroduceLocalVariableRefactoring.RefactorAsync(context.Document, expressionStatement, typeSymbol, addAwait, semanticModel, cancellationToken),
                                GetEquivalenceKey(diagnostic, CodeFixIdentifiers.IntroduceLocalVariable));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }

                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.IntroduceField))
                        {
                            CodeAction codeAction = CodeAction.Create(
                                $"Introduce field for '{expression}'",
                                cancellationToken => IntroduceFieldRefactoring.RefactorAsync(context.Document, expressionStatement, typeSymbol, semanticModel, cancellationToken),
                                GetEquivalenceKey(diagnostic, CodeFixIdentifiers.IntroduceField));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotImplicitlyConvertType:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceYieldReturnWithForEach) &&
                        expression.IsParentKind(SyntaxKind.YieldReturnStatement))
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        ReplaceYieldReturnWithForEachRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                        break;
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeMemberTypeAccordingToReturnExpression) &&
                        expression.IsParentKind(SyntaxKind.ReturnStatement, SyntaxKind.YieldReturnStatement, SyntaxKind.ArrowExpressionClause))
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        ChangeMemberTypeRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                        break;
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeTypeAccordingToInitializer))
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        CodeFixRegistrationResult result = ChangeTypeAccordingToInitializerRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);

                        if (!result.Success)
                        {
                            RemoveAssignmentOfVoidExpression(context, diagnostic, expression, semanticModel);
                        }

                        break;
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceStringLiteralWithCharacterLiteral) &&
                        expression?.Kind() == SyntaxKind.StringLiteralExpression)
                    {
                        var literalExpression = (LiteralExpressionSyntax)expression;

                        if (literalExpression.Token.ValueText.Length == 1)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            if (semanticModel.GetTypeInfo(expression, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Char)
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Replace string literal with character literal",
                                    cancellationToken => ReplaceStringLiteralWithCharacterLiteralRefactoring.RefactorAsync(context.Document, literalExpression, cancellationToken),
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.ReplaceStringLiteralWithCharacterLiteral));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.UseYieldReturnInsteadOfReturn) &&
                        expression.IsParentKind(SyntaxKind.ReturnStatement))
                    {
                        var returnStatement = (ReturnStatementSyntax)expression.Parent;

                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        ISymbol containingSymbol = semanticModel.GetEnclosingSymbol(returnStatement.SpanStart, context.CancellationToken);

                        if (containingSymbol?.Kind == SymbolKind.Method &&
                            ((IMethodSymbol)containingSymbol).ReturnType.OriginalDefinition.IsIEnumerableOrIEnumerableOfT())
                        {
                            CodeAction codeAction = CodeAction.Create(
                                "Use yield return instead of return",
                                cancellationToken => UseYieldReturnInsteadOfReturnRefactoring.RefactorAsync(context.Document, returnStatement, SyntaxKind.YieldReturnStatement, semanticModel, cancellationToken),
                                GetEquivalenceKey(diagnostic, CodeFixIdentifiers.UseYieldReturnInsteadOfReturn));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.LeftHandSideOfAssignmentMustBeVariablePropertyOrIndexer:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConstModifier))
                    {
                        return;
                    }

                    if (!expression.IsKind(SyntaxKind.IdentifierName))
                    {
                        return;
                    }

                    if (!expression.IsParentKind(SyntaxKind.SimpleAssignmentExpression))
                    {
                        return;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    SymbolInfo symbolInfo = semanticModel.GetSymbolInfo(expression, context.CancellationToken);

                    if (symbolInfo.CandidateReason != CandidateReason.NotAVariable)
                    {
                        return;
                    }

                    if (!(symbolInfo.CandidateSymbols.SingleOrDefault(shouldThrow: false) is ILocalSymbol localSymbol))
                    {
                        return;
                    }

                    if (!localSymbol.IsConst)
                    {
                        return;
                    }

                    SyntaxNode node = localSymbol.GetSyntaxOrDefault(context.CancellationToken);

                    if (!node.IsKind(SyntaxKind.VariableDeclarator))
                    {
                        return;
                    }

                    node = node.Parent;

                    if (!node.IsKind(SyntaxKind.VariableDeclaration))
                    {
                        return;
                    }

                    node = node.Parent;

                    if (!(node is LocalDeclarationStatementSyntax localDeclaration))
                    {
                        return;
                    }

                    SyntaxToken constModifier = localDeclaration.Modifiers.Find(SyntaxKind.ConstKeyword);

                    if (!constModifier.IsKind(SyntaxKind.ConstKeyword))
                    {
                        return;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, localDeclaration, constModifier);

                    break;
                }

                case CompilerDiagnosticIdentifiers.ReadOnlyFieldCannotBeAssignedTo:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeFieldWritable))
                    {
                        break;
                    }

                    SimpleAssignmentExpressionInfo simpleAssignment = SyntaxInfo.SimpleAssignmentExpressionInfo(expression.Parent);

                    if (!simpleAssignment.Success)
                    {
                        return;
                    }

                    if (simpleAssignment.Left != expression)
                    {
                        return;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    SymbolInfo symbolInfo = semanticModel.GetSymbolInfo(expression, context.CancellationToken);

                    if (symbolInfo.CandidateReason != CandidateReason.NotAVariable)
                    {
                        return;
                    }

                    if (!(symbolInfo.CandidateSymbols.SingleOrDefault(shouldThrow: false) is IFieldSymbol fieldSymbol))
                    {
                        return;
                    }

                    if (fieldSymbol.DeclaredAccessibility != Accessibility.Private)
                    {
                        return;
                    }

                    if (!(fieldSymbol.GetSyntax().Parent.Parent is FieldDeclarationSyntax fieldDeclaration))
                    {
                        return;
                    }

                    TypeDeclarationSyntax containingTypeDeclaration = fieldDeclaration.FirstAncestor <TypeDeclarationSyntax>();

                    if (!expression.Ancestors().Any(f => f == containingTypeDeclaration))
                    {
                        return;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(
                        context,
                        diagnostic,
                        fieldDeclaration,
                        SyntaxKind.ReadOnlyKeyword,
                        title: $"Make '{fieldSymbol.Name}' writable");

                    break;
                }
                }
            }
        }
예제 #10
0
        public static async Task ComputeRefactoringAsync(
            RefactoringContext context,
            PropertyDeclarationSyntax property)
        {
            AccessorDeclarationSyntax setter = property.Setter();

            if (setter == null)
            {
                return;
            }

            ExpressionSyntax expression = GetExpression();

            if (expression == null)
            {
                return;
            }

            SimpleAssignmentExpressionInfo simpleAssignment = SyntaxInfo.SimpleAssignmentExpressionInfo(expression);

            if (!simpleAssignment.Success)
            {
                return;
            }

            if (!simpleAssignment.Left.IsKind(SyntaxKind.IdentifierName))
            {
                return;
            }

            if (!(simpleAssignment.Right is IdentifierNameSyntax identifierName))
            {
                return;
            }

            if (identifierName.Identifier.ValueText != "value")
            {
                return;
            }

            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            INamedTypeSymbol containingType = semanticModel
                                              .GetDeclaredSymbol(property, context.CancellationToken)?
                                              .ContainingType;

            if (containingType == null)
            {
                return;
            }

            if (!containingType.Implements(MetadataNames.System_ComponentModel_INotifyPropertyChanged, allInterfaces: true))
            {
                return;
            }

            IMethodSymbol methodSymbol = SymbolUtility.FindMethodThatRaisePropertyChanged(containingType, expression.SpanStart, semanticModel);

            if (methodSymbol == null)
            {
                return;
            }

            Document document = context.Document;

            context.RegisterRefactoring(
                "Notify when property change",
                ct => RefactorAsync(document, property, methodSymbol.Name, ct),
                RefactoringIdentifiers.NotifyWhenPropertyChange);

            ExpressionSyntax GetExpression()
            {
                BlockSyntax body = setter.Body;

                if (body != null)
                {
                    if (body.Statements.SingleOrDefault(shouldThrow: false) is ExpressionStatementSyntax expressionStatement)
                    {
                        return(expressionStatement.Expression);
                    }
                }
                else
                {
                    return(setter.ExpressionBody?.Expression);
                }

                return(null);
            }
        }
예제 #11
0
        internal static bool IsFixable(
            IndexerDeclarationSyntax indexerDeclaration,
            AccessorDeclarationSyntax accessor,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            switch (accessor.Kind())
            {
            case SyntaxKind.GetAccessorDeclaration:
            {
                ExpressionSyntax expression = GetGetAccessorExpression(accessor);

                if (expression?.IsKind(SyntaxKind.ElementAccessExpression) != true)
                {
                    return(false);
                }

                var elementAccess = (ElementAccessExpressionSyntax)expression;

                if (elementAccess.Expression?.IsKind(SyntaxKind.BaseExpression) != true)
                {
                    return(false);
                }

                if (elementAccess.ArgumentList == null)
                {
                    return(false);
                }

                IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(indexerDeclaration, cancellationToken);

                if (propertySymbol == null)
                {
                    return(false);
                }

                IPropertySymbol overriddenProperty = propertySymbol.OverriddenProperty;

                if (overriddenProperty == null)
                {
                    return(false);
                }

                ISymbol symbol = semanticModel.GetSymbol(elementAccess, cancellationToken);

                return(overriddenProperty.Equals(symbol) &&
                       CheckParameters(indexerDeclaration.ParameterList, elementAccess.ArgumentList, semanticModel, cancellationToken) &&
                       CheckDefaultValues(propertySymbol.Parameters, overriddenProperty.Parameters));
            }

            case SyntaxKind.SetAccessorDeclaration:
            {
                ExpressionSyntax expression = GetSetAccessorExpression(accessor);

                SimpleAssignmentExpressionInfo assignment = SyntaxInfo.SimpleAssignmentExpressionInfo(expression);

                if (!assignment.Success)
                {
                    return(false);
                }

                if (assignment.Left.Kind() != SyntaxKind.ElementAccessExpression)
                {
                    return(false);
                }

                var elementAccess = (ElementAccessExpressionSyntax)assignment.Left;

                if (elementAccess.Expression?.IsKind(SyntaxKind.BaseExpression) != true)
                {
                    return(false);
                }

                if (elementAccess.ArgumentList == null)
                {
                    return(false);
                }

                if (assignment.Right.Kind() != SyntaxKind.IdentifierName)
                {
                    return(false);
                }

                var identifierName = (IdentifierNameSyntax)assignment.Right;

                if (identifierName.Identifier.ValueText != "value")
                {
                    return(false);
                }

                IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(indexerDeclaration, cancellationToken);

                if (propertySymbol == null)
                {
                    return(false);
                }

                IPropertySymbol overriddenProperty = propertySymbol.OverriddenProperty;

                if (overriddenProperty == null)
                {
                    return(false);
                }

                ISymbol symbol = semanticModel.GetSymbol(elementAccess, cancellationToken);

                return(overriddenProperty.Equals(symbol) &&
                       CheckParameters(indexerDeclaration.ParameterList, elementAccess.ArgumentList, semanticModel, cancellationToken) &&
                       CheckDefaultValues(propertySymbol.Parameters, overriddenProperty.Parameters));
            }

            case SyntaxKind.UnknownAccessorDeclaration:
            {
                return(false);
            }

            default:
            {
                Debug.Fail(accessor.Kind().ToString());
                return(false);
            }
            }
        }
예제 #12
0
        internal static bool IsFixable(
            PropertyDeclarationSyntax propertyDeclaration,
            AccessorDeclarationSyntax accessor,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            switch (accessor.Kind())
            {
            case SyntaxKind.GetAccessorDeclaration:
            {
                ExpressionSyntax expression = GetGetAccessorExpression(accessor);

                if (expression?.IsKind(SyntaxKind.SimpleMemberAccessExpression) != true)
                {
                    return(false);
                }

                var memberAccess = (MemberAccessExpressionSyntax)expression;

                if (memberAccess.Expression?.IsKind(SyntaxKind.BaseExpression) != true)
                {
                    return(false);
                }

                SimpleNameSyntax simpleName = memberAccess.Name;

                IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken);

                if (propertySymbol == null)
                {
                    return(false);
                }

                IPropertySymbol overriddenProperty = propertySymbol.OverriddenProperty;

                if (overriddenProperty == null)
                {
                    return(false);
                }

                ISymbol symbol = semanticModel.GetSymbol(simpleName, cancellationToken);

                return(overriddenProperty.Equals(symbol));
            }

            case SyntaxKind.SetAccessorDeclaration:
            {
                ExpressionSyntax expression = GetSetAccessorExpression(accessor);

                SimpleAssignmentExpressionInfo assignment = SyntaxInfo.SimpleAssignmentExpressionInfo(expression);

                if (!assignment.Success)
                {
                    return(false);
                }

                if (assignment.Left.Kind() != SyntaxKind.SimpleMemberAccessExpression)
                {
                    return(false);
                }

                var memberAccess = (MemberAccessExpressionSyntax)assignment.Left;

                if (memberAccess.Expression?.IsKind(SyntaxKind.BaseExpression) != true)
                {
                    return(false);
                }

                if (assignment.Right.Kind() != SyntaxKind.IdentifierName)
                {
                    return(false);
                }

                var identifierName = (IdentifierNameSyntax)assignment.Right;

                if (identifierName.Identifier.ValueText != "value")
                {
                    return(false);
                }

                SimpleNameSyntax simpleName = memberAccess.Name;

                if (simpleName == null)
                {
                    return(false);
                }

                IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken);

                if (propertySymbol == null)
                {
                    return(false);
                }

                IPropertySymbol overriddenProperty = propertySymbol.OverriddenProperty;

                if (overriddenProperty == null)
                {
                    return(false);
                }

                ISymbol symbol = semanticModel.GetSymbol(simpleName, cancellationToken);

                return(overriddenProperty.Equals(symbol));
            }

            case SyntaxKind.UnknownAccessorDeclaration:
            {
                return(false);
            }

            default:
            {
                Debug.Fail(accessor.Kind().ToString());
                return(false);
            }
            }
        }
        private static void AnalyzeSimpleAssignment(SyntaxNodeAnalysisContext context)
        {
            var assignmentExpression = (AssignmentExpressionSyntax)context.Node;

            SimpleAssignmentExpressionInfo assignmentInfo = SyntaxInfo.SimpleAssignmentExpressionInfo(assignmentExpression);

            if (!assignmentInfo.Success)
            {
                return;
            }

            if (assignmentExpression.IsParentKind(SyntaxKind.ObjectInitializerExpression))
            {
                return;
            }

            ExpressionSyntax right = assignmentInfo.Right;

            if (!CanBeReplacedWithCompoundAssignment(right.Kind()))
            {
                return;
            }

            BinaryExpressionInfo binaryInfo = SyntaxInfo.BinaryExpressionInfo((BinaryExpressionSyntax)right);

            if (!binaryInfo.Success)
            {
                return;
            }

            if (!CSharpFactory.AreEquivalent(assignmentInfo.Left, binaryInfo.Left))
            {
                return;
            }

            var binaryExpression = (BinaryExpressionSyntax)right;

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseCompoundAssignment, assignmentExpression, GetCompoundAssignmentOperatorText(binaryExpression));
            DiagnosticHelpers.ReportNode(context, DiagnosticDescriptors.UseCompoundAssignmentFadeOut, binaryExpression.Left);

            bool CanBeReplacedWithCompoundAssignment(SyntaxKind kind)
            {
                switch (kind)
                {
                case SyntaxKind.AddExpression:
                case SyntaxKind.SubtractExpression:
                case SyntaxKind.MultiplyExpression:
                case SyntaxKind.DivideExpression:
                case SyntaxKind.ModuloExpression:
                case SyntaxKind.BitwiseAndExpression:
                case SyntaxKind.ExclusiveOrExpression:
                case SyntaxKind.BitwiseOrExpression:
                case SyntaxKind.LeftShiftExpression:
                case SyntaxKind.RightShiftExpression:
                    return(true);

                case SyntaxKind.CoalesceExpression:
                    return(((CSharpCompilation)context.Compilation).LanguageVersion >= LanguageVersion.CSharp8);

                default:
                    return(false);
                }
            }
        }
        public static void ComputeRefactorings(
            RefactoringContext context,
            InitializerExpressionSyntax initializer,
            SemanticModel semanticModel)
        {
            Debug.Assert(initializer.IsKind(SyntaxKind.ObjectInitializerExpression, SyntaxKind.WithInitializerExpression), initializer.Kind().ToString());

            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(initializer.Parent, context.CancellationToken);

            if (typeSymbol?.IsErrorType() != false)
            {
                return;
            }

            if (typeSymbol.IsAnonymousType)
            {
                return;
            }

            int position = initializer.OpenBraceToken.Span.End;

            ImmutableArray <ISymbol> symbols = semanticModel.LookupSymbols(position, typeSymbol);

            if (!symbols.Any())
            {
                return;
            }

            SeparatedSyntaxList <ExpressionSyntax> expressions = initializer.Expressions;

            if (expressions.Any())
            {
                var initializedPropertyNames = new HashSet <string>();

                foreach (ExpressionSyntax expression in expressions)
                {
                    Debug.Assert(expression.IsKind(SyntaxKind.SimpleAssignmentExpression), expression.Kind().ToString());

                    if (expression.IsKind(SyntaxKind.SimpleAssignmentExpression))
                    {
                        SimpleAssignmentExpressionInfo assignmentInfo = SyntaxInfo.SimpleAssignmentExpressionInfo((AssignmentExpressionSyntax)expression);

                        if (assignmentInfo.Success)
                        {
                            ExpressionSyntax left = assignmentInfo.Left;

                            Debug.Assert(left.IsKind(SyntaxKind.IdentifierName), left.Kind().ToString());

                            if (left is IdentifierNameSyntax identifierName)
                            {
                                initializedPropertyNames.Add(identifierName.Identifier.ValueText);
                            }
                        }
                    }
                }

                Dictionary <string, IPropertySymbol> namesToProperties = null;

                foreach (ISymbol symbol in symbols)
                {
                    if (initializedPropertyNames.Contains(symbol.Name))
                    {
                        continue;
                    }

                    IPropertySymbol propertySymbol = GetInitializableProperty(symbol, position, semanticModel);

                    if (propertySymbol == null)
                    {
                        continue;
                    }

                    if (namesToProperties != null)
                    {
                        if (namesToProperties.ContainsKey(propertySymbol.Name))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        namesToProperties = new Dictionary <string, IPropertySymbol>();
                    }

                    namesToProperties.Add(propertySymbol.Name, propertySymbol);
                }

                if (namesToProperties != null)
                {
                    Document document = context.Document;

                    context.RegisterRefactoring(
                        "Initialize all properties",
                        ct =>
                    {
                        IEnumerable <IPropertySymbol> propertySymbols = namesToProperties.Select(f => f.Value);
                        return(RefactorAsync(document, initializer, propertySymbols, initializeToDefault: false, ct));
                    },
                        RefactoringDescriptors.AddAllPropertiesToInitializer);
                }
            }
            else if (HasAccessiblePropertySetter())
            {
                Document document = context.Document;

                context.RegisterRefactoring(
                    "Initialize all properties",
                    ct =>
                {
                    IEnumerable <IPropertySymbol> propertySymbols = GetInitializableProperties(initializer, symbols, semanticModel);
                    return(RefactorAsync(document, initializer, propertySymbols, initializeToDefault: false, ct));
                },
                    RefactoringDescriptors.AddAllPropertiesToInitializer);
            }

            bool HasAccessiblePropertySetter()
            {
                foreach (ISymbol symbol in symbols)
                {
                    if (GetInitializableProperty(symbol, position, semanticModel) != null)
                    {
                        return(true);
                    }
                }

                return(false);
            }
        }
예제 #15
0
        protected override bool IsFixableStatement(
            StatementSyntax statement,
            string name,
            ITypeSymbol typeSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (statement.SpanOrLeadingTriviaContainsDirectives())
            {
                return(false);
            }

            if (!(statement is ExpressionStatementSyntax expressionStatement))
            {
                return(false);
            }

            SimpleAssignmentExpressionInfo assignmentInfo = SyntaxInfo.SimpleAssignmentExpressionInfo(expressionStatement.Expression);

            if (!assignmentInfo.Success)
            {
                return(false);
            }

            if (name != (assignmentInfo.Left as IdentifierNameSyntax)?.Identifier.ValueText)
            {
                return(false);
            }

            MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo(assignmentInfo.Right);

            if (!invocationInfo.Success)
            {
                return(false);
            }

            if (!(WalkDownMethodChain(invocationInfo).Expression is IdentifierNameSyntax identifierName))
            {
                return(false);
            }

            if (name != identifierName.Identifier.ValueText)
            {
                return(false);
            }

            if (!semanticModel.TryGetMethodInfo(invocationInfo.InvocationExpression, out MethodInfo methodInfo, cancellationToken))
            {
                return(false);
            }

            if (!methodInfo.ReturnType.Equals(typeSymbol))
            {
                return(false);
            }

            if (IsReferenced(invocationInfo.InvocationExpression, identifierName, name, semanticModel, cancellationToken))
            {
                return(false);
            }

            return(true);
        }
        public override bool IsFixableStatement(
            StatementSyntax statement,
            string name,
            ITypeSymbol typeSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (statement.SpanOrLeadingTriviaContainsDirectives())
            {
                return(false);
            }

            if (statement is not ExpressionStatementSyntax expressionStatement)
            {
                return(false);
            }

            SimpleAssignmentExpressionInfo assignmentInfo = SyntaxInfo.SimpleAssignmentExpressionInfo(expressionStatement.Expression);

            if (!assignmentInfo.Success)
            {
                return(false);
            }

            if (name != (assignmentInfo.Left as IdentifierNameSyntax)?.Identifier.ValueText)
            {
                return(false);
            }

            SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(assignmentInfo.Right);

            if (!invocationInfo.Success)
            {
                return(false);
            }

            if (WalkDownMethodChain(invocationInfo).Expression is not IdentifierNameSyntax identifierName)
            {
                return(false);
            }

            if (name != identifierName.Identifier.ValueText)
            {
                return(false);
            }

            IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocationInfo.InvocationExpression, cancellationToken);

            if (methodSymbol == null)
            {
                return(false);
            }

            if (!SymbolEqualityComparer.Default.Equals(methodSymbol.ReturnType, typeSymbol))
            {
                return(false);
            }

            if (IsReferenced(invocationInfo.InvocationExpression, identifierName, name, semanticModel, cancellationToken))
            {
                return(false);
            }

            return(true);
        }