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));
        }
Example #5
0
        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));
        }
Example #7
0
        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;
            }
            }
        }
Example #9
0
        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);
            }
        }
Example #10
0
        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));
                                });
                            }
                        }
                    }
                }
            }
        }
Example #11
0
        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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }