Ejemplo n.º 1
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(
                    root,
                    context.Span,
                    out SyntaxNode node,
                    predicate: f => f.IsKind(
                        SyntaxKind.VariableDeclaration,
                        SyntaxKind.ForEachStatement,
                        SyntaxKind.Parameter,
                        SyntaxKind.DeclarationPattern,
                        SyntaxKind.DeclarationExpression,
                        SyntaxKind.LocalFunctionStatement)))
            {
                return;
            }

            if (node.IsKind(SyntaxKind.ForEachStatement, SyntaxKind.Parameter, SyntaxKind.DeclarationPattern, SyntaxKind.DeclarationExpression, SyntaxKind.LocalFunctionStatement))
            {
                return;
            }

            var variableDeclaration = (VariableDeclarationSyntax)node;

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.CS0819_ImplicitlyTypedVariablesCannotHaveMultipleDeclarators:
                case CompilerDiagnosticIdentifiers.CS0822_ImplicitlyTypedVariablesCannotBeConstant:
                {
                    if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.UseExplicitTypeInsteadOfVar, context.Document, root.SyntaxTree))
                    {
                        return;
                    }

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

                    TypeSyntax type = variableDeclaration.Type;

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

                    if (typeSymbol?.SupportsExplicitDeclaration() == true)
                    {
                        CodeAction codeAction = CodeActionFactory.ChangeType(context.Document, type, typeSymbol, semanticModel, equivalenceKey: GetEquivalenceKey(diagnostic));

                        context.RegisterCodeFix(codeAction, diagnostic);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0128_LocalVariableOrFunctionIsAlreadyDefinedInThisScope:
                case CompilerDiagnosticIdentifiers.CS0136_LocalOrParameterCannotBeDeclaredInThisScopeBecauseThatNameIsUsedInEnclosingScopeToDefineLocalOrParameter:
                {
                    if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceVariableDeclarationWithAssignment, context.Document, root.SyntaxTree))
                    {
                        return;
                    }

                    if (variableDeclaration.Parent is not LocalDeclarationStatementSyntax localDeclaration)
                    {
                        return;
                    }

                    VariableDeclaratorSyntax variableDeclarator = variableDeclaration.Variables.SingleOrDefault(shouldThrow: false);

                    if (variableDeclarator == null)
                    {
                        break;
                    }

                    ExpressionSyntax value = variableDeclarator.Initializer?.Value;

                    if (value == null)
                    {
                        break;
                    }

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

                    VariableDeclaratorSyntax variableDeclarator2 = FindVariableDeclarator(
                        variableDeclarator.Identifier.ValueText,
                        semanticModel.GetEnclosingSymbolSyntax(localDeclaration.SpanStart, context.CancellationToken));

                    if (variableDeclarator2?.SpanStart < localDeclaration.SpanStart)
                    {
                        CodeAction codeAction = CodeAction.Create(
                            "Replace variable declaration with assignment",
                            ct =>
                            {
                                ExpressionStatementSyntax newNode = CSharpFactory.SimpleAssignmentStatement(
                                    SyntaxFactory.IdentifierName(variableDeclarator.Identifier),
                                    value);

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

                                return(context.Document.ReplaceNodeAsync(localDeclaration, newNode, ct));
                            },
                            GetEquivalenceKey(diagnostic));
                        context.RegisterCodeFix(codeAction, diagnostic);
                    }

                    break;
                }
                }
            }
        }
Ejemplo n.º 2
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReplaceVariableDeclarationWithAssignment))
            {
                return;
            }

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

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out LocalDeclarationStatementSyntax localDeclaration))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.LocalVariableOrFunctionIsAlreadyDefinedInThisScope:
                case CompilerDiagnosticIdentifiers.LocalOrParameterCannotBeDeclaredInThisScopeBecauseThatNameIsUsedInEnclosingScopeToDefineLocalOrParameter:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReplaceVariableDeclarationWithAssignment))
                    {
                        break;
                    }

                    VariableDeclaratorSyntax variableDeclarator = localDeclaration.Declaration?.SingleVariableOrDefault();

                    if (variableDeclarator == null)
                    {
                        break;
                    }

                    ExpressionSyntax value = variableDeclarator.Initializer?.Value;

                    if (value == null)
                    {
                        break;
                    }

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

                    VariableDeclaratorSyntax variableDeclarator2 = FindVariableDeclarator(
                        variableDeclarator.Identifier.ValueText,
                        semanticModel.GetEnclosingSymbolSyntax(localDeclaration.SpanStart, context.CancellationToken));

                    if (variableDeclarator2?.SpanStart < localDeclaration.SpanStart)
                    {
                        CodeAction codeAction = CodeAction.Create(
                            "Replace variable declaration with assignment",
                            cancellationToken =>
                            {
                                ExpressionStatementSyntax newNode = CSharpFactory.SimpleAssignmentStatement(
                                    SyntaxFactory.IdentifierName(variableDeclarator.Identifier),
                                    value);

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

                                return(context.Document.ReplaceNodeAsync(localDeclaration, newNode, context.CancellationToken));
                            },
                            GetEquivalenceKey(diagnostic));
                        context.RegisterCodeFix(codeAction, diagnostic);
                    }

                    break;
                }
                }
            }
        }
Ejemplo n.º 3
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsAnyCodeFixEnabled(
                    CodeFixIdentifiers.UseExplicitTypeInsteadOfVar,
                    CodeFixIdentifiers.ReplaceVariableDeclarationWithAssignment))
            {
                return;
            }

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

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out VariableDeclarationSyntax variableDeclaration))
            {
                return;
            }

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

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

                    TypeSyntax type = variableDeclaration.Type;

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

                    if (typeSymbol?.SupportsExplicitDeclaration() == true)
                    {
                        CodeAction codeAction = CodeAction.Create(
                            $"Change type to '{SymbolDisplay.GetMinimalString(typeSymbol, semanticModel, type.Span.Start)}'",
                            cancellationToken => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, type, typeSymbol, cancellationToken),
                            GetEquivalenceKey(diagnostic));

                        context.RegisterCodeFix(codeAction, diagnostic);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.LocalVariableOrFunctionIsAlreadyDefinedInThisScope:
                case CompilerDiagnosticIdentifiers.LocalOrParameterCannotBeDeclaredInThisScopeBecauseThatNameIsUsedInEnclosingScopeToDefineLocalOrParameter:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReplaceVariableDeclarationWithAssignment))
                    {
                        return;
                    }

                    if (!(variableDeclaration.Parent is LocalDeclarationStatementSyntax localDeclaration))
                    {
                        return;
                    }

                    VariableDeclaratorSyntax variableDeclarator = variableDeclaration.Variables.SingleOrDefault(shouldthrow: false);

                    if (variableDeclarator == null)
                    {
                        break;
                    }

                    ExpressionSyntax value = variableDeclarator.Initializer?.Value;

                    if (value == null)
                    {
                        break;
                    }

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

                    VariableDeclaratorSyntax variableDeclarator2 = FindVariableDeclarator(
                        variableDeclarator.Identifier.ValueText,
                        semanticModel.GetEnclosingSymbolSyntax(localDeclaration.SpanStart, context.CancellationToken));

                    if (variableDeclarator2?.SpanStart < localDeclaration.SpanStart)
                    {
                        CodeAction codeAction = CodeAction.Create(
                            "Replace variable declaration with assignment",
                            cancellationToken =>
                            {
                                ExpressionStatementSyntax newNode = CSharpFactory.SimpleAssignmentStatement(
                                    SyntaxFactory.IdentifierName(variableDeclarator.Identifier),
                                    value);

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

                                return(context.Document.ReplaceNodeAsync(localDeclaration, newNode, cancellationToken));
                            },
                            GetEquivalenceKey(diagnostic));
                        context.RegisterCodeFix(codeAction, diagnostic);
                    }

                    break;
                }
                }
            }
        }