private void ComputeCodeFix( CodeFixContext context, Diagnostic diagnostic, VariableDeclaratorSyntax variableDeclarator, ISymbol symbol, SemanticModel semanticModel) { if (symbol is IMethodSymbol methodSymbol) { ImmutableArray <IParameterSymbol> parameters = methodSymbol.Parameters; if (parameters.Length <= 16) { ITypeSymbol returnType = methodSymbol.ReturnType; if (SupportsExplicitDeclaration(returnType, parameters)) { INamedTypeSymbol typeSymbol = ConstructActionOrFunc(returnType, parameters, semanticModel); var variableDeclaration = (VariableDeclarationSyntax)variableDeclarator.Parent; CodeAction codeAction = CodeActionFactory.ChangeType( context.Document, variableDeclaration.Type, typeSymbol, semanticModel, equivalenceKey: GetEquivalenceKey(diagnostic, SymbolDisplay.ToDisplayString(typeSymbol))); context.RegisterCodeFix(codeAction, diagnostic); } } } }
internal static async Task ChangeTypeAsync( RefactoringContext context, ForEachStatementSyntax forEachStatement) { TypeSyntax type = forEachStatement.Type; if (type?.Span.Contains(context.Span) != true) { return; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeAnalysis analysis = CSharpTypeAnalysis.AnalyzeType(forEachStatement, semanticModel); if (analysis.IsExplicit) { if (analysis.SupportsImplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar)) { context.RegisterRefactoring(CodeActionFactory.ChangeTypeToVar(context.Document, type, equivalenceKey: RefactoringIdentifiers.ChangeExplicitTypeToVar)); } if (!forEachStatement.ContainsDiagnostics && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeTypeAccordingToExpression)) { ChangeTypeAccordingToExpression(context, forEachStatement, semanticModel); } } else if (analysis.SupportsExplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType)) { context.RegisterRefactoring(CodeActionFactory.ChangeType(context.Document, type, analysis.Symbol, semanticModel, equivalenceKey: RefactoringIdentifiers.ChangeVarToExplicitType)); } }
private static void ChangeTypeAccordingToExpression( RefactoringContext context, ForEachStatementSyntax forEachStatement, SemanticModel semanticModel) { ForEachStatementInfo info = semanticModel.GetForEachStatementInfo(forEachStatement); ITypeSymbol elementType = info.ElementType; if (elementType?.IsErrorType() != false) { return; } Conversion conversion = info.ElementConversion; if (conversion.IsIdentity) { return; } if (!conversion.IsImplicit) { return; } context.RegisterRefactoring(CodeActionFactory.ChangeType(context.Document, forEachStatement.Type, elementType, semanticModel, equivalenceKey: RefactoringIdentifiers.ChangeTypeAccordingToExpression)); }
public static async Task ComputeRefactoringsAsync( RefactoringContext context, DeclarationExpressionSyntax declarationExpression) { if (declarationExpression.Type?.Span.Contains(context.Span) == true && context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ChangeExplicitTypeToVar, RefactoringIdentifiers.ChangeVarToExplicitType)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeAnalysis analysis = CSharpTypeAnalysis.AnalyzeType(declarationExpression, semanticModel, context.CancellationToken); if (analysis.IsExplicit) { if (analysis.SupportsImplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar)) { context.RegisterRefactoring(CodeActionFactory.ChangeTypeToVar(context.Document, declarationExpression.Type, equivalenceKey: RefactoringIdentifiers.ChangeExplicitTypeToVar)); } } else if (analysis.SupportsExplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType)) { TypeSyntax type = declarationExpression.Type; var localSymbol = (ILocalSymbol)semanticModel.GetDeclaredSymbol(declarationExpression.Designation, context.CancellationToken); ITypeSymbol typeSymbol = localSymbol.Type; context.RegisterRefactoring(CodeActionFactory.ChangeType(context.Document, type, typeSymbol, semanticModel, equivalenceKey: RefactoringIdentifiers.ChangeVarToExplicitType)); } } }
public sealed 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.ForEachStatement, SyntaxKind.ForEachVariableStatement, SyntaxKind.DeclarationExpression))) { return; } Document document = context.Document; Diagnostic diagnostic = context.Diagnostics[0]; SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeSyntax type; ITypeSymbol typeSymbol; switch (node) { case ForEachStatementSyntax forEachStatement: { type = forEachStatement.Type; typeSymbol = semanticModel.GetTypeSymbol(type, context.CancellationToken); break; } case ForEachVariableStatementSyntax forEachVariableStatement: { var declarationExpression = (DeclarationExpressionSyntax)forEachVariableStatement.Variable; type = declarationExpression.Type; typeSymbol = semanticModel.GetTypeSymbol(declarationExpression, context.CancellationToken); break; } case DeclarationExpressionSyntax declarationExpression: { type = declarationExpression.Type; typeSymbol = semanticModel.GetTypeSymbol(declarationExpression, context.CancellationToken); break; } default: { throw new InvalidOperationException(); } } CodeAction codeAction = CodeActionFactory.ChangeType(document, type, typeSymbol, semanticModel, equivalenceKey: GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); }
private void RegisterCodeFix(CodeFixContext context, TypeSyntax type, ITypeSymbol typeSymbol, SemanticModel semanticModel) { foreach (Diagnostic diagnostic in context.Diagnostics) { CodeAction codeAction = CodeActionFactory.ChangeType(context.Document, type, typeSymbol, semanticModel, equivalenceKey: GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } }
public static CodeFixRegistrationResult ChangeType( CodeFixContext context, Diagnostic diagnostic, TypeSyntax type, ITypeSymbol newTypeSymbol, SemanticModel semanticModel, string additionalKey = null) { CodeAction codeAction = CodeActionFactory.ChangeType(context.Document, type, newTypeSymbol, semanticModel, equivalenceKey: EquivalenceKey.Create(diagnostic, additionalKey)); context.RegisterCodeFix(codeAction, diagnostic); return(new CodeFixRegistrationResult(true)); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf(root, context.Span, out ForEachStatementSyntax forEachStatement)) { return; } Diagnostic diagnostic = context.Diagnostics[0]; SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeSyntax type = forEachStatement.Type; ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, context.CancellationToken); CodeAction codeAction = CodeActionFactory.ChangeType(context.Document, type, typeSymbol, semanticModel, equivalenceKey: GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); }
private static void ChangeTypeAccordingToExpression( RefactoringContext context, VariableDeclarationSyntax variableDeclaration, ITypeSymbol typeSymbol, SemanticModel semanticModel) { foreach (VariableDeclaratorSyntax variableDeclarator in variableDeclaration.Variables) { ExpressionSyntax value = variableDeclarator.Initializer?.Value; if (value == null) { return; } Conversion conversion = semanticModel.ClassifyConversion(value, typeSymbol); if (conversion.IsIdentity) { return; } if (!conversion.IsImplicit) { return; } } ITypeSymbol newTypeSymbol = semanticModel.GetTypeSymbol(variableDeclaration.Variables[0].Initializer.Value, context.CancellationToken); if (newTypeSymbol == null) { return; } context.RegisterRefactoring(CodeActionFactory.ChangeType(context.Document, variableDeclaration.Type, newTypeSymbol, semanticModel, equivalenceKey: RefactoringIdentifiers.ChangeTypeAccordingToExpression)); }
public static void ChangeTypeOrReturnType( CodeFixContext context, Diagnostic diagnostic, SyntaxNode node, ITypeSymbol newTypeSymbol, SemanticModel semanticModel, string additionalKey = null) { if (newTypeSymbol.IsErrorType()) { return; } TypeSyntax type = CSharpUtility.GetTypeOrReturnType(node); if (type == null) { return; } CodeAction codeAction = CodeActionFactory.ChangeType(context.Document, type, newTypeSymbol, semanticModel, equivalenceKey: EquivalenceKey.Create(diagnostic, additionalKey)); context.RegisterCodeFix(codeAction, diagnostic); }
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 static async Task ComputeRefactoringsAsync(RefactoringContext context, VariableDeclarationSyntax variableDeclaration) { TypeSyntax type = variableDeclaration.Type; if (type?.Span.Contains(context.Span) == true && context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ChangeExplicitTypeToVar, RefactoringIdentifiers.ChangeVarToExplicitType, RefactoringIdentifiers.ChangeTypeAccordingToExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeAnalysis analysis = CSharpTypeAnalysis.AnalyzeType(variableDeclaration, semanticModel, context.CancellationToken); if (analysis.IsExplicit) { if (analysis.SupportsImplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar)) { context.RegisterRefactoring(CodeActionFactory.ChangeTypeToVar(context.Document, type, equivalenceKey: RefactoringIdentifiers.ChangeExplicitTypeToVar)); } if (!variableDeclaration.ContainsDiagnostics && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeTypeAccordingToExpression)) { ChangeTypeAccordingToExpression(context, variableDeclaration, analysis.Symbol, semanticModel); } } else if (analysis.SupportsExplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType)) { ITypeSymbol typeSymbol = analysis.Symbol; VariableDeclaratorSyntax variableDeclarator = variableDeclaration.Variables.SingleOrDefault(shouldThrow: false); if (variableDeclarator?.Initializer?.Value != null) { if (typeSymbol.OriginalDefinition.EqualsOrInheritsFromTaskOfT()) { Func <CancellationToken, Task <Document> > createChangedDocument = DocumentRefactoringFactory.ChangeTypeAndAddAwait( context.Document, variableDeclaration, variableDeclarator, typeSymbol, semanticModel, context.CancellationToken); if (createChangedDocument != null) { ITypeSymbol typeArgument = ((INamedTypeSymbol)typeSymbol).TypeArguments[0]; context.RegisterRefactoring( $"Change type to '{SymbolDisplay.ToMinimalDisplayString(typeArgument, semanticModel, type.SpanStart)}' and add 'await'", createChangedDocument, EquivalenceKey.Join(RefactoringIdentifiers.ChangeVarToExplicitType, "AddAwait")); } } typeSymbol = semanticModel.GetTypeSymbol(variableDeclarator.Initializer.Value, context.CancellationToken); if (typeSymbol != null) { context.RegisterRefactoring(CodeActionFactory.ChangeType(context.Document, type, typeSymbol, semanticModel, equivalenceKey: RefactoringIdentifiers.ChangeVarToExplicitType)); } } } } }