private static void ChangeType( CodeRefactoringContext context, SemanticModel semanticModel, VariableDeclarationSyntax variableDeclaration) { TypeAnalysisResult result = VariableDeclarationAnalysis.AnalyzeType( variableDeclaration, semanticModel, context.CancellationToken); switch (result) { case TypeAnalysisResult.Explicit: case TypeAnalysisResult.ExplicitButShouldBeImplicit: { context.RegisterRefactoring( "Change type to 'var'", cancellationToken => TypeSyntaxRefactoring.ChangeTypeToImplicitAsync(context.Document, variableDeclaration.Type, cancellationToken)); break; } case TypeAnalysisResult.Implicit: case TypeAnalysisResult.ImplicitButShouldBeExplicit: { ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(variableDeclaration.Type, context.CancellationToken).Type; context.RegisterRefactoring( $"Change type to '{typeSymbol.ToDisplayString(TypeSyntaxRefactoring.SymbolDisplayFormat)}'", cancellationToken => TypeSyntaxRefactoring.ChangeTypeToExplicitAsync(context.Document, variableDeclaration.Type, typeSymbol, cancellationToken)); break; } } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); VariableDeclarationSyntax variableDeclaration = root .FindNode(context.Span, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <VariableDeclarationSyntax>(); if (variableDeclaration == null) { return; } if (variableDeclaration.Type.IsVar) { SemanticModel semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken); if (semanticModel == null) { return; } ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(variableDeclaration.Type).Type; CodeAction codeAction = CodeAction.Create( $"Change type to '{typeSymbol.ToDisplayString(TypeSyntaxRefactoring.SymbolDisplayFormat)}'", cancellationToken => TypeSyntaxRefactoring.ChangeTypeToExplicitAsync(context.Document, variableDeclaration.Type, typeSymbol, cancellationToken), DiagnosticIdentifiers.DeclareExplicitType + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, context.Diagnostics); } }
private static void ChangeTypeAccordingToExpression( CodeRefactoringContext context, SemanticModel semanticModel, VariableDeclarationSyntax variableDeclaration) { if (variableDeclaration.Parent?.IsKind(SyntaxKind.FieldDeclaration) != false) { return; } TypeSyntax type = variableDeclaration.Type; if (type == null) { return; } if (type.IsVar) { return; } if (!type.Span.Contains(context.Span)) { return; } if (variableDeclaration.Variables.Count != 1) { return; } EqualsValueClauseSyntax initializer = variableDeclaration.Variables[0].Initializer; if (initializer == null) { return; } if (initializer.Value == null) { return; } ITypeSymbol initializerTypeSymbol = semanticModel.GetTypeInfo(initializer.Value).Type; if (initializerTypeSymbol == null || initializerTypeSymbol.IsKind(SymbolKind.ErrorType)) { return; } ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(type).ConvertedType; if (!initializerTypeSymbol.Equals(typeSymbol)) { context.RegisterRefactoring( $"Change type to '{initializerTypeSymbol.ToDisplayString(TypeSyntaxRefactoring.SymbolDisplayFormat)}'", cancellationToken => TypeSyntaxRefactoring.ChangeTypeToExplicitAsync(context.Document, variableDeclaration.Type, initializerTypeSymbol, cancellationToken)); } }
private static void ChangeTypeAccordingToExpression( CodeRefactoringContext context, SemanticModel semanticModel, ForEachStatementSyntax forEachStatement) { if (forEachStatement.Type?.IsVar != false) { return; } if (!forEachStatement.Type.Span.Contains(context.Span)) { return; } ForEachStatementInfo forEachInfo = semanticModel.GetForEachStatementInfo(forEachStatement); ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(forEachStatement.Type).ConvertedType; if (forEachInfo.ElementType?.Equals(typeSymbol) != false) { return; } context.RegisterRefactoring( $"Change type to '{forEachInfo.ElementType.ToDisplayString(TypeSyntaxRefactoring.SymbolDisplayFormat)}'", cancellationToken => TypeSyntaxRefactoring.ChangeTypeToExplicitAsync(context.Document, forEachStatement.Type, forEachInfo.ElementType, cancellationToken)); }
private static async Task <Document> UsePredefinedTypeAsync( Document document, SyntaxNode node, ITypeSymbol typeSymbol, CancellationToken cancellationToken) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken); TypeSyntax newType = TypeSyntaxRefactoring.CreateTypeSyntax(typeSymbol) .WithTriviaFrom(node) .WithAdditionalAnnotations(Formatter.Annotation); SyntaxNode newRoot = oldRoot.ReplaceNode(node, newType); return(document.WithSyntaxRoot(newRoot)); }
private static async Task <Document> ChangeDeclaredTypeToExplicitAsync( Document document, TypeSyntax type, ITypeSymbol typeSymbol, CancellationToken cancellationToken) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken); TypeSyntax newType = TypeSyntaxRefactoring.CreateTypeSyntax(typeSymbol) .WithTriviaFrom(type) .WithAdditionalAnnotations(Simplifier.Annotation); SyntaxNode newRoot = oldRoot.ReplaceNode(type, newType); return(document.WithSyntaxRoot(newRoot)); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); ImplicitArrayCreationExpressionSyntax node = root .FindNode(context.Span, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <ImplicitArrayCreationExpressionSyntax>(); if (node == null) { return; } SemanticModel semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken); if (semanticModel == null) { return; } ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(node, context.CancellationToken).Type; if (typeSymbol == null) { return; } var arrayType = TypeSyntaxRefactoring.CreateTypeSyntax(typeSymbol) as ArrayTypeSyntax; if (arrayType == null) { return; } CodeAction codeAction = CodeAction.Create( $"Declare explicit type '{typeSymbol.ToDisplayString(TypeSyntaxRefactoring.SymbolDisplayFormat)}'", cancellationToken => SpecifyExplicitTypeAsync(context.Document, node, arrayType, cancellationToken), DiagnosticIdentifiers.AvoidImplicitArrayCreation + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, context.Diagnostics); }
private static void ChangeType( CodeRefactoringContext context, SemanticModel semanticModel, ForEachStatementSyntax forEachStatement) { TypeSyntax type = forEachStatement.Type; if (type == null || !type.Span.Contains(context.Span)) { return; } TypeAnalysisResult result = ForEachStatementAnalysis.AnalyzeType( forEachStatement, semanticModel, context.CancellationToken); switch (result) { case TypeAnalysisResult.Explicit: { context.RegisterRefactoring( "Change type to 'var'", cancellationToken => TypeSyntaxRefactoring.ChangeTypeToImplicitAsync(context.Document, type, cancellationToken)); break; } case TypeAnalysisResult.ImplicitButShouldBeExplicit: { ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(type, context.CancellationToken).Type; context.RegisterRefactoring( $"Change type to '{typeSymbol.ToDisplayString(TypeSyntaxRefactoring.SymbolDisplayFormat)}'", cancellationToken => TypeSyntaxRefactoring.ChangeTypeToExplicitAsync(context.Document, type, typeSymbol, cancellationToken)); break; } } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); VariableDeclarationSyntax variableDeclaration = root .FindNode(context.Span, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <VariableDeclarationSyntax>(); if (variableDeclaration == null) { return; } if (!variableDeclaration.Type.IsVar) { CodeAction codeAction = CodeAction.Create( "Change type to 'var'", cancellationToken => TypeSyntaxRefactoring.ChangeTypeToImplicitAsync(context.Document, variableDeclaration.Type, cancellationToken), DiagnosticIdentifiers.DeclareImplicitType + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, context.Diagnostics); } }
public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken); YieldStatementSyntax yieldStatement = root .FindNode(context.Span, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <YieldStatementSyntax>(); if (yieldStatement == null) { return; } if (yieldStatement.IsYieldReturn() && yieldStatement.Expression?.Span.Contains(context.Span) == true && context.Document.SupportsSemanticModel) { MemberDeclarationSyntax declaration = GetDeclaration(yieldStatement); if (declaration != null) { TypeSyntax memberType = GetMemberType(declaration); if (memberType != null) { SemanticModel semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken); ITypeSymbol memberTypeSymbol = semanticModel .GetTypeInfo(memberType, context.CancellationToken) .Type; if (memberTypeSymbol.SpecialType != SpecialType.System_Collections_IEnumerable) { ITypeSymbol typeSymbol = semanticModel .GetTypeInfo(yieldStatement.Expression, context.CancellationToken) .Type; if (typeSymbol?.IsKind(SymbolKind.ErrorType) == false && (memberTypeSymbol == null || memberTypeSymbol.IsKind(SymbolKind.ErrorType) || !memberTypeSymbol.IsGenericIEnumerable() || !((INamedTypeSymbol)memberTypeSymbol).TypeArguments[0].Equals(typeSymbol))) { TypeSyntax newType = QualifiedName( ParseName("System.Collections.Generic"), GenericName( Identifier("IEnumerable"), TypeArgumentList( SingletonSeparatedList( TypeSyntaxRefactoring.CreateTypeSyntax(typeSymbol))))); context.RegisterRefactoring( $"Change {GetText(declaration)} type to 'IEnumerable<{typeSymbol.ToDisplayString(TypeSyntaxRefactoring.SymbolDisplayFormat)}>'", cancellationToken => { return(ChangeReturnTypeAsync( context.Document, memberType, newType, cancellationToken)); }); } } } } } }
public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken); ReturnStatementSyntax returnStatement = root .FindNode(context.Span, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <ReturnStatementSyntax>(); if (returnStatement == null) { return; } if (returnStatement.Expression != null && returnStatement.Expression.Span.Contains(context.Span) && context.Document.SupportsSemanticModel) { MemberDeclarationSyntax declaration = GetDeclaration(returnStatement); if (declaration != null) { TypeSyntax memberType = GetMemberType(declaration); if (memberType != null) { SemanticModel semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken); ITypeSymbol memberTypeSymbol = semanticModel .GetTypeInfo(memberType, context.CancellationToken) .Type; if (memberTypeSymbol?.IsKind(SymbolKind.ErrorType) == false) { ITypeSymbol typeSymbol = semanticModel .GetTypeInfo(returnStatement.Expression, context.CancellationToken) .Type; if (typeSymbol?.IsKind(SymbolKind.ErrorType) == false) { if (memberTypeSymbol.SpecialType == SpecialType.System_Boolean && typeSymbol.IsKind(SymbolKind.NamedType)) { var namedTypeSymbol = (INamedTypeSymbol)typeSymbol; if (namedTypeSymbol?.ConstructedFrom.SpecialType == SpecialType.System_Nullable_T && namedTypeSymbol.TypeArguments[0].SpecialType == SpecialType.System_Boolean) { CodeAction codeAction = CodeAction.Create( AddBooleanComparisonRefactoring.Title, cancellationToken => { return(AddBooleanComparisonRefactoring.RefactorAsync( context.Document, returnStatement.Expression, context.CancellationToken)); }); context.RegisterRefactoring(codeAction); } } if (!memberTypeSymbol.Equals(typeSymbol)) { TypeSyntax newType = TypeSyntaxRefactoring.CreateTypeSyntax(typeSymbol); if (newType != null) { CodeAction codeAction = CodeAction.Create( $"Change {GetText(declaration)} type to '{typeSymbol.ToDisplayString(TypeSyntaxRefactoring.SymbolDisplayFormat)}'", cancellationToken => { return(ChangeReturnTypeAsync( context.Document, memberType, newType, cancellationToken)); }); context.RegisterRefactoring(codeAction); } } } } } } } }