public static async Task ComputeRefactoringsAsync(RefactoringContext context, ArgumentSyntax argument)
        {
            if (context.IsAnyRefactoringEnabled(RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod))
            {
                ExpressionSyntax expression = argument.Expression;

                if (expression?.IsMissing == false)
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(expression).ConvertedType;

                    if (typeSymbol?.IsErrorType() == false)
                    {
                        IEnumerable <ITypeSymbol> newTypes = DetermineParameterTypeHelper.DetermineParameterTypes(argument, semanticModel, context.CancellationToken)
                                                             .Where(f => !typeSymbol.Equals(f));

                        ModifyExpressionRefactoring.ComputeRefactoring(context, expression, newTypes, semanticModel);
                    }
                }
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceMethodGroupWithLambda))
            {
                await ReplaceMethodGroupWithLambdaRefactoring.ComputeRefactoringAsync(context, argument).ConfigureAwait(false);
            }
        }
Exemple #2
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsAnyCodeFixEnabled(
                    CodeFixIdentifiers.AddOutModifierToArgument,
                    CodeFixIdentifiers.RemoveRefModifier,
                    CodeFixIdentifiers.CreateSingletonArray,
                    CodeFixIdentifiers.AddArgumentList,
                    CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue))
            {
                return;
            }

            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out ArgumentSyntax argument))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.ArgumentMustBePassedWithRefOrOutKeyword:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddOutModifierToArgument))
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Add 'out' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(CSharpFactory.OutKeyword())
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);

                    break;
                }

                case CompilerDiagnosticIdentifiers.ArgumentShouldNotBePassedWithRefOrOutKeyword:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveRefModifier))
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Remove 'ref' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(default(SyntaxToken))
                                                         .PrependToLeadingTrivia(argument.RefOrOutKeyword.GetAllTrivia())
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

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

                case CompilerDiagnosticIdentifiers.CannotConvertArgumentType:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression.Kind() == SyntaxKind.NullLiteralExpression &&
                            argument.Parent is ArgumentListSyntax argumentList)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            ImmutableArray <IParameterSymbol> parameterSymbols = FindParameters(argumentList, semanticModel, context.CancellationToken);

                            if (!parameterSymbols.IsDefault)
                            {
                                int index = argumentList.Arguments.IndexOf(argument);

                                IParameterSymbol parameterSymbol = parameterSymbols[index];

                                ITypeSymbol typeSymbol = parameterSymbol.Type;

                                if (typeSymbol.IsValueType)
                                {
                                    CodeFixRegistrator.ReplaceNullWithDefaultValue(
                                        context,
                                        diagnostic,
                                        expression,
                                        typeSymbol,
                                        semanticModel,
                                        CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue);
                                }
                            }
                        }
                    }

                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddArgumentList))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression.IsKind(
                                SyntaxKind.IdentifierName,
                                SyntaxKind.GenericName,
                                SyntaxKind.SimpleMemberAccessExpression))
                        {
                            InvocationExpressionSyntax invocationExpression = InvocationExpression(
                                expression.WithoutTrailingTrivia(),
                                ArgumentList().WithTrailingTrivia(expression.GetTrailingTrivia()));

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

                            if (semanticModel.GetSpeculativeMethodSymbol(expression.SpanStart, invocationExpression) != null)
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Add argument list",
                                    cancellationToken =>
                                    {
                                        ArgumentSyntax newNode = argument.WithExpression(invocationExpression);

                                        return(context.Document.ReplaceNodeAsync(argument, newNode, cancellationToken));
                                    },
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddArgumentList));

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

                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.CreateSingletonArray))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression?.IsMissing == false)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression);

                            if (typeSymbol?.IsErrorType() == false)
                            {
                                foreach (ITypeSymbol typeSymbol2 in DetermineParameterTypeHelper.DetermineParameterTypes(argument, semanticModel, context.CancellationToken))
                                {
                                    if (!typeSymbol.Equals(typeSymbol2) &&
                                        typeSymbol2 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;
                                    }
                                }
                            }
                        }
                    }

                    break;
                }
                }
            }
        }
Exemple #3
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out IdentifierNameSyntax identifierName))
            {
                return;
            }

            Document          document          = context.Document;
            CancellationToken cancellationToken = context.CancellationToken;

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.UseOfUnassignedLocalVariable:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.InitializeLocalVariableWithDefaultValue))
                    {
                        return;
                    }

                    SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                    if (!(semanticModel.GetSymbol(identifierName, cancellationToken) is ILocalSymbol localSymbol))
                    {
                        break;
                    }

                    ITypeSymbol typeSymbol = localSymbol.Type;

                    if (typeSymbol.Kind == SymbolKind.ErrorType)
                    {
                        break;
                    }

                    if (!(localSymbol.GetSyntax(cancellationToken) is VariableDeclaratorSyntax variableDeclarator))
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        $"Initialize '{identifierName.Identifier.ValueText}' with default value",
                        ct =>
                        {
                            SyntaxToken identifier = variableDeclarator.Identifier;

                            var variableDeclaration = (VariableDeclarationSyntax)variableDeclarator.Parent;

                            ExpressionSyntax value = typeSymbol.GetDefaultValueSyntax(variableDeclaration.Type.WithoutTrivia(), document.GetDefaultSyntaxOptions());

                            if (value.IsKind(SyntaxKind.DefaultExpression) &&
                                document.SupportsLanguageFeature(CSharpLanguageFeature.DefaultLiteral))
                            {
                                value = CSharpFactory.DefaultLiteralExpression().WithTriviaFrom(value);
                            }

                            EqualsValueClauseSyntax newEqualsValue = EqualsValueClause(value)
                                                                     .WithLeadingTrivia(TriviaList(Space))
                                                                     .WithTrailingTrivia(identifier.TrailingTrivia);

                            VariableDeclaratorSyntax newNode = variableDeclarator
                                                               .WithInitializer(newEqualsValue)
                                                               .WithIdentifier(identifier.WithoutTrailingTrivia());

                            return(document.ReplaceNodeAsync(variableDeclarator, newNode, ct));
                        },
                        GetEquivalenceKey(diagnostic));

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

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

                    if (!(identifierName.Parent is ArgumentSyntax argument))
                    {
                        break;
                    }

                    if (argument.RefOrOutKeyword.Kind() != SyntaxKind.OutKeyword)
                    {
                        break;
                    }

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

                    foreach (ITypeSymbol typeSymbol in DetermineParameterTypeHelper.DetermineParameterTypes(argument, semanticModel, cancellationToken))
                    {
                        if (typeSymbol.Kind == SymbolKind.TypeParameter)
                        {
                            continue;
                        }

                        string typeName = SymbolDisplay.ToMinimalDisplayString(typeSymbol, semanticModel, identifierName.SpanStart, SymbolDisplayFormats.DisplayName);

                        CodeAction codeAction = CodeAction.Create(
                            $"Add variable type '{typeName}'",
                            ct =>
                            {
                                DeclarationExpressionSyntax newNode = DeclarationExpression(
                                    typeSymbol.ToTypeSyntax(),
                                    SingleVariableDesignation(identifierName.Identifier.WithoutTrivia()).WithLeadingTrivia(Space));

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

                                return(document.ReplaceNodeAsync(identifierName, newNode, ct));
                            },
                            GetEquivalenceKey(diagnostic, typeName));

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

                    break;
                }
                }
            }
        }
Exemple #4
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsAnyCodeFixEnabled(
                    CodeFixIdentifiers.InitializeLocalVariableWithDefaultValue,
                    CodeFixIdentifiers.AddVariableType))
            {
                return;
            }

            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out IdentifierNameSyntax identifierName))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.UseOfUnassignedLocalVariable:
                {
                    CodeAction codeAction = CodeAction.Create(
                        $"Initialize '{identifierName.Identifier.ValueText}' with default value",
                        cancellationToken => RefactorAsync(context.Document, identifierName, cancellationToken),
                        GetEquivalenceKey(diagnostic));

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

                case CompilerDiagnosticIdentifiers.NameDoesNotExistInCurrentContext:
                {
                    if (!(identifierName.Parent is ArgumentSyntax argument))
                    {
                        break;
                    }

                    if (argument.RefOrOutKeyword.Kind() != SyntaxKind.OutKeyword)
                    {
                        break;
                    }

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

                    foreach (ITypeSymbol typeSymbol in DetermineParameterTypeHelper.DetermineParameterTypes(argument, semanticModel, context.CancellationToken))
                    {
                        if (typeSymbol.Kind == SymbolKind.TypeParameter)
                        {
                            continue;
                        }

                        string typeName = SymbolDisplay.GetMinimalString(typeSymbol, semanticModel, identifierName.SpanStart);

                        CodeAction codeAction = CodeAction.Create(
                            $"Add variable type '{typeName}'",
                            cancellationToken =>
                            {
                                DeclarationExpressionSyntax newNode = DeclarationExpression(
                                    ParseName(typeName),
                                    SingleVariableDesignation(identifierName.Identifier.WithoutTrivia()).WithLeadingTrivia(Space));

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

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

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

                    break;
                }
                }
            }
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsAnyCodeFixEnabled(
                    CodeFixIdentifiers.AddOutModifierToArgument,
                    CodeFixIdentifiers.RemoveRefModifier,
                    CodeFixIdentifiers.CreateSingletonArray))
            {
                return;
            }

            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out ArgumentSyntax argument))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.ArgumentMustBePassedWithOutKeyword:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddOutModifierToArgument))
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Add 'out' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(CSharpFactory.OutKeyword())
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, context.CancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);

                    break;
                }

                case CompilerDiagnosticIdentifiers.ArgumentMayNotBePassedWithRefKeyword:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveRefModifier))
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Remove 'ref' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(default(SyntaxToken))
                                                         .PrependToLeadingTrivia(argument.RefOrOutKeyword.GetLeadingAndTrailingTrivia())
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, context.CancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

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

                case CompilerDiagnosticIdentifiers.CannotConvertArgumentType:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddOutModifierToArgument))
                    {
                        return;
                    }

                    ExpressionSyntax expression = argument.Expression;

                    if (expression?.IsMissing == false)
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression);

                        if (typeSymbol?.IsErrorType() == false)
                        {
                            foreach (ITypeSymbol typeSymbol2 in DetermineParameterTypeHelper.DetermineParameterTypes(argument, semanticModel, context.CancellationToken))
                            {
                                if (!typeSymbol.Equals(typeSymbol2) &&
                                    typeSymbol2.IsArrayType())
                                {
                                    var arrayType = (IArrayTypeSymbol)typeSymbol2;

                                    if (semanticModel.IsImplicitConversion(expression, arrayType.ElementType))
                                    {
                                        CodeAction codeAction = CodeAction.Create(
                                            "Create singleton array",
                                            cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken),
                                            GetEquivalenceKey(diagnostic));

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

                    break;
                }
                }
            }
        }
Exemple #6
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out ArgumentSyntax argument))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.ArgumentMustBePassedWithRefOrOutKeyword:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddOutModifierToArgument))
                    {
                        return;
                    }

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

                    IParameterSymbol parameter = semanticModel.DetermineParameter(argument, allowCandidate: true, cancellationToken: context.CancellationToken);

                    if (parameter == null)
                    {
                        return;
                    }

                    SyntaxToken refOrOutKeyword = default;

                    if (parameter.RefKind == RefKind.Out)
                    {
                        refOrOutKeyword = Token(SyntaxKind.OutKeyword);
                    }
                    else if (parameter.RefKind == RefKind.Ref)
                    {
                        refOrOutKeyword = Token(SyntaxKind.RefKeyword);
                    }
                    else
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        $"Add '{SyntaxFacts.GetText(refOrOutKeyword.Kind())}' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(refOrOutKeyword)
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

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

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

                    CodeAction codeAction = CodeAction.Create(
                        "Remove 'ref' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(default(SyntaxToken))
                                                         .PrependToLeadingTrivia(argument.RefOrOutKeyword.GetAllTrivia())
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

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

                case CompilerDiagnosticIdentifiers.CannotConvertArgumentType:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression.Kind() == SyntaxKind.NullLiteralExpression &&
                            argument.Parent is ArgumentListSyntax argumentList)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            ImmutableArray <IParameterSymbol> parameterSymbols = FindParameters(argumentList, semanticModel, context.CancellationToken);

                            if (!parameterSymbols.IsDefault)
                            {
                                int index = argumentList.Arguments.IndexOf(argument);

                                IParameterSymbol parameterSymbol = parameterSymbols[index];

                                ITypeSymbol typeSymbol = parameterSymbol.Type;

                                if (typeSymbol.IsValueType)
                                {
                                    CodeFixRegistrator.ReplaceNullWithDefaultValue(
                                        context,
                                        diagnostic,
                                        expression,
                                        typeSymbol,
                                        CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue);
                                }
                            }
                        }
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddArgumentList))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression.IsKind(
                                SyntaxKind.IdentifierName,
                                SyntaxKind.GenericName,
                                SyntaxKind.SimpleMemberAccessExpression))
                        {
                            InvocationExpressionSyntax invocationExpression = InvocationExpression(
                                expression.WithoutTrailingTrivia(),
                                ArgumentList().WithTrailingTrivia(expression.GetTrailingTrivia()));

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

                            if (semanticModel.GetSpeculativeMethodSymbol(expression.SpanStart, invocationExpression) != null)
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Add argument list",
                                    cancellationToken =>
                                    {
                                        ArgumentSyntax newNode = argument.WithExpression(invocationExpression);

                                        return(context.Document.ReplaceNodeAsync(argument, newNode, cancellationToken));
                                    },
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddArgumentList));

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

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.CreateSingletonArray))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression?.IsMissing == false)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression);

                            if (typeSymbol?.IsErrorType() == false)
                            {
                                foreach (ITypeSymbol typeSymbol2 in DetermineParameterTypeHelper.DetermineParameterTypes(argument, semanticModel, context.CancellationToken))
                                {
                                    if (!typeSymbol.Equals(typeSymbol2) &&
                                        typeSymbol2 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;
                                    }
                                }
                            }
                        }
                    }

                    break;
                }

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

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

                    SymbolInfo symbolInfo = semanticModel.GetSymbolInfo(argument.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 (!argument.Ancestors().Any(f => f == containingTypeDeclaration))
                    {
                        return;
                    }

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

                    break;
                }
                }
            }
        }
Exemple #7
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out ExpressionSyntax expression, getInnermostNodeForTie: false))
            {
                return;
            }

            if (expression.Parent is not ArgumentSyntax argument ||
                argument.Expression != expression)
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            switch (diagnostic.Id)
            {
            case CompilerDiagnosticIdentifiers.CS1503_CannotConvertArgumentType:
            {
                if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue, document, root.SyntaxTree) &&
                    expression.Kind() == SyntaxKind.NullLiteralExpression &&
                    argument.Parent is ArgumentListSyntax argumentList)
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    ImmutableArray <IParameterSymbol> parameterSymbols = FindParameters(argumentList, semanticModel, context.CancellationToken);

                    if (!parameterSymbols.IsDefault)
                    {
                        int index = argumentList.Arguments.IndexOf(argument);

                        IParameterSymbol parameterSymbol = parameterSymbols[index];

                        ITypeSymbol typeSymbol = parameterSymbol.Type;

                        if (typeSymbol.IsValueType)
                        {
                            CodeFixRegistrator.ReplaceNullWithDefaultValue(
                                context,
                                diagnostic,
                                expression,
                                typeSymbol,
                                CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue);
                        }
                    }
                }

                if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddArgumentList, document, root.SyntaxTree) &&
                    expression.IsKind(
                        SyntaxKind.IdentifierName,
                        SyntaxKind.GenericName,
                        SyntaxKind.SimpleMemberAccessExpression))
                {
                    InvocationExpressionSyntax invocationExpression = InvocationExpression(
                        expression.WithoutTrailingTrivia(),
                        ArgumentList().WithTrailingTrivia(expression.GetTrailingTrivia()));

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

                    if (semanticModel.GetSpeculativeMethodSymbol(expression.SpanStart, invocationExpression) != null)
                    {
                        CodeAction codeAction = CodeAction.Create(
                            "Add argument list",
                            ct =>
                            {
                                ArgumentSyntax newNode = argument.WithExpression(invocationExpression);

                                return(document.ReplaceNodeAsync(argument, newNode, ct));
                            },
                            GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddArgumentList));

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

                if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.CreateSingletonArray, document, root.SyntaxTree) &&
                    expression?.IsMissing == false)
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression);

                    if (typeSymbol?.IsErrorType() == false)
                    {
                        foreach (ITypeSymbol typeSymbol2 in DetermineParameterTypeHelper.DetermineParameterTypes(argument, semanticModel, context.CancellationToken))
                        {
                            if (!SymbolEqualityComparer.Default.Equals(typeSymbol, typeSymbol2) &&
                                typeSymbol2 is IArrayTypeSymbol arrayType &&
                                semanticModel.IsImplicitConversion(expression, arrayType.ElementType))
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Create singleton array",
                                    ct => CreateSingletonArrayRefactoring.RefactorAsync(document, expression, arrayType.ElementType, semanticModel, ct),
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.CreateSingletonArray));

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

                break;
            }
            }
        }