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; } } } }
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; } } } }
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; } } } }