Пример #1
0
        public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(TransformationContext context, IProgress <Diagnostic> progress, CancellationToken cancellationToken)
        {
            var ogStruct  = (StructDeclarationSyntax)context.ProcessingNode;
            var ogMembers = ogStruct.Members;

            var newStruct = SyntaxFactory.StructDeclaration(ogStruct.Identifier.ValueText + suffix)
                            .WithAttributeLists(ogStruct.AttributeLists)
                            .WithTriviaFrom(ogStruct);
            List <MemberDeclarationSyntax> newMembers = new List <MemberDeclarationSyntax>();

            foreach (var ogMember in ogMembers)
            {
                if (ogMember.RawKind == (int)SyntaxKind.FieldDeclaration)
                {
                    FieldDeclarationSyntax    ogFieldSyntax    = (FieldDeclarationSyntax)ogMember;
                    VariableDeclarationSyntax ogVariableSyntax = ogFieldSyntax.Declaration;
                    TypeSyntax ogType = ogVariableSyntax.Type;
                    VariableDeclarationSyntax newVariableSyntax = ogVariableSyntax.WithType(ArrayType(ogType, SingletonList(ArrayRankSpecifier())));
                    FieldDeclarationSyntax    newFieldSyntax    = ogFieldSyntax.ReplaceNode(ogVariableSyntax, newVariableSyntax);
                    newMembers.Add(newFieldSyntax);
                }
                else
                {
                    newMembers.Add(ogMember);
                }
            }

            newStruct = newStruct.AddMembers(newMembers.ToArray());

            var result = SyntaxFactory.SingletonList <MemberDeclarationSyntax>(newStruct);

            return(Task.FromResult(result));
        }
Пример #2
0
        private static Task <Document> ChangeTypeAndAddAwait(
            Document document,
            SyntaxNode declaration,
            VariableDeclarationSyntax variableDeclaration,
            TypeSyntax type,
            ExpressionSyntax expression,
            ITypeSymbol newTypeSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            AwaitExpressionSyntax newExpression = SyntaxFactory.AwaitExpression(expression).WithTriviaFrom(expression);

            VariableDeclarationSyntax newVariableDeclaration = variableDeclaration.ReplaceNode(expression, newExpression);

            TypeSyntax newType = newTypeSymbol.ToMinimalTypeSyntax(semanticModel, type.SpanStart).WithTriviaFrom(type);

            newVariableDeclaration = newVariableDeclaration.WithType(newType);

            if (!SyntaxInfo.ModifierListInfo(declaration).IsAsync)
            {
                SyntaxNode newDeclaration = declaration
                                            .ReplaceNode(variableDeclaration, newVariableDeclaration)
                                            .InsertModifier(SyntaxKind.AsyncKeyword);

                return(document.ReplaceNodeAsync(declaration, newDeclaration, cancellationToken));
            }

            return(document.ReplaceNodeAsync(variableDeclaration, newVariableDeclaration, cancellationToken));
        }
        private static async Task <Document> ChangeTypeAndAddAwaitAsync(
            Document document,
            VariableDeclarationSyntax variableDeclaration,
            ITypeSymbol typeSymbol,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            ExpressionSyntax initializerValue = variableDeclaration.Variables[0].Initializer.Value;

            AwaitExpressionSyntax newInitializerValue = SyntaxFactory.AwaitExpression(initializerValue)
                                                        .WithTriviaFrom(initializerValue);

            VariableDeclarationSyntax newNode = variableDeclaration.ReplaceNode(initializerValue, newInitializerValue);

            newNode = newNode
                      .WithType(
                CSharpFactory.Type(typeSymbol)
                .WithTriviaFrom(variableDeclaration.Type)
                .WithSimplifierAnnotation());

            SyntaxNode newRoot = oldRoot.ReplaceNode(variableDeclaration, newNode);

            return(document.WithSyntaxRoot(newRoot));
        }
Пример #4
0
        public override SyntaxNode VisitVariableDeclaration(VariableDeclarationSyntax node)
        {
            if (node.Parent is LocalDeclarationStatementSyntax localDeclarationStatement)
            {
                if (localDeclarationStatement.Modifiers.Any(SyntaxKind.ConstKeyword))
                {
                    return(base.VisitVariableDeclaration(node));
                }
            }
            else if (node.Parent is FieldDeclarationSyntax fieldDeclaration)
            {
                if (fieldDeclaration.Modifiers.Any(SyntaxKind.ConstKeyword))
                {
                    return(base.VisitVariableDeclaration(node));
                }
            }

            /*else if (node.Parent is PropertyDeclarationSyntax)
             * {
             *  var n = node.Parent as PropertyDeclarationSyntax;
             *  if (n.Modifiers.Any(SyntaxKind.ConstKeyword)) return base.VisitVariableDeclaration(node);
             * }*/
            if (node.Ancestors().Any(x => x is LambdaExpressionSyntax || x is ParenthesizedLambdaExpressionSyntax))
            {
                return(base.VisitVariableDeclaration(node));
            }
            if (_variableRewrites.TryGetValue(node, out int clusterID))
            {
                SyntaxNode n = node.WithType(SyntaxFactory.ParseTypeName("Cluster" + clusterID.ToString()));
                Rewrote = true;
                return(n);
            }

            return(base.VisitVariableDeclaration(node));
        }
        private static void ChangeTypeAndAddAwait(
            CodeFixContext context,
            Diagnostic diagnostic,
            ExpressionSyntax expression,
            VariableDeclarationSyntax variableDeclaration,
            TypeSyntax type,
            ITypeSymbol newTypeSymbol,
            SemanticModel semanticModel)
        {
            AwaitExpressionSyntax newExpression = SyntaxFactory.AwaitExpression(expression).WithTriviaFrom(expression);

            VariableDeclarationSyntax newNode = variableDeclaration.ReplaceNode(expression, newExpression);

            TypeSyntax newType = newTypeSymbol.ToMinimalTypeSyntax(semanticModel, type.SpanStart).WithTriviaFrom(type);

            newNode = newNode.WithType(newType);

            string typeName = SymbolDisplay.ToMinimalDisplayString(newTypeSymbol, semanticModel, type.SpanStart, SymbolDisplayFormats.Default);

            CodeAction codeAction = CodeAction.Create(
                $"Change type to '{typeName}' and add await",
                cancellationToken => context.Document.ReplaceNodeAsync(variableDeclaration, newNode, cancellationToken),
                EquivalenceKey.Create(diagnostic, CodeFixIdentifiers.ChangeTypeAccordingToInitializer, "AddAwait"));

            context.RegisterCodeFix(codeAction, diagnostic);
        }
Пример #6
0
        private VariableDeclarationSyntax ConvertToVar(VariableDeclarationSyntax variable)
        {
            var type = SyntaxFactory.IdentifierName("var")
                       .WithLeadingTrivia(variable.Type.GetLeadingTrivia())
                       .WithTrailingTrivia(variable.Type.GetTrailingTrivia());

            return(variable.WithType(type));
        }
        public override SyntaxNode?VisitVariableDeclaration(VariableDeclarationSyntax node)
        {
            if (node.Type.IsVar)
            {
                return(base.VisitVariableDeclaration(node));
            }

            return(base.VisitVariableDeclaration(node.WithType(SyntaxFactory.IdentifierName("var"))));
        }
        public override SyntaxNode VisitVariableDeclaration(VariableDeclarationSyntax node)
        {
            if (node.Type.IdentifierName() == "String")
            {
                return(base.Visit(
                           node.WithType(PredefinedType(Token(SyntaxKind.StringKeyword))
                                         .WithTriviaFrom(node.Type))));
            }

            return(base.VisitVariableDeclaration(node));
        }
Пример #9
0
        public override SyntaxNode VisitVariableDeclaration(VariableDeclarationSyntax node)
        {
            var disagree = disagreements.FirstOrDefault(d => node.Type.ToString().EndsWith(d.TypeName));

            if (disagree != null)
            {
                var repl = node.Type.ToFullString().Replace(disagree.TypeName, disagree.ClassName);
                return(base.VisitVariableDeclaration(node.WithType(SyntaxFactory.ParseTypeName(repl))));
            }

            return(base.VisitVariableDeclaration(node));
        }
        private static Task <Document> RefactorAsync(
            Document document,
            VariableDeclarationSyntax variableDeclaration,
            INamedTypeSymbol typeSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            TypeSyntax type = typeSymbol.ToMinimalTypeSyntax(semanticModel, variableDeclaration.SpanStart);

            VariableDeclarationSyntax newNode = variableDeclaration.WithType(type.WithTriviaFrom(variableDeclaration.Type));

            return(document.ReplaceNodeAsync(variableDeclaration, newNode, cancellationToken));
        }
Пример #11
0
        private async Task <Document> ChangeToFunc(Document document, VariableDeclarationSyntax variableDeclaration, CancellationToken cancellationToken)
        {
            // Change the variable declaration
            var newDeclaration = variableDeclaration.WithType(SyntaxFactory.ParseTypeName("System.Func<System.Threading.Tasks.Task>").WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation)
                                                              .WithLeadingTrivia(variableDeclaration.Type.GetLeadingTrivia()).WithTrailingTrivia(variableDeclaration.Type.GetTrailingTrivia()));

            var oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var newRoot     = oldRoot.ReplaceNode(variableDeclaration, newDeclaration);
            var newDocument = document.WithSyntaxRoot(newRoot);

            // Return document with transformed tree.
            return(newDocument);
        }
            SyntaxNode ConvertToVar(VariableDeclarationSyntax node)
            {
                if (node.Parent is LocalDeclarationStatementSyntax == false)
                {
                    return(null);
                }
                if ((node.Parent as LocalDeclarationStatementSyntax).IsConst)
                {
                    return(null);
                }
                if (node.Type is IdentifierNameSyntax varIdentifierNameSyntax)
                {
                    if (varIdentifierNameSyntax.Identifier.ValueText == VarKeyword)
                    {
                        return(null);
                    }
                }

                if (node.Variables.Count > 1)
                {
                    return(null);
                }

                var variable = node.Variables.First();

                if (variable.Initializer == null)
                {
                    return(null);
                }

                var typeOfInitializer = projectItemDetails.SemanticModel.GetTypeInfo(variable.Initializer.Value);

                var typeOfTypeDef = projectItemDetails.SemanticModel.GetTypeInfo(node.Type);

                if (typeOfInitializer.Type == typeOfTypeDef.Type)
                {
                    node =
                        node
                        .WithType(
                            SyntaxFactory.ParseTypeName(VarKeyword)
                            .WithTrailingTrivia(SyntaxFactory.Space)
                            .WithLeadingTrivia(node.Type.GetLeadingTrivia())
                            );
                }

                return(base.VisitVariableDeclaration(node));
            }
Пример #13
0
        private async Task <Solution> UseImplicitTyping(
            Document document, VariableDeclarationSyntax declaration, CancellationToken cancellationToken)
        {
            var typeSyntax = SyntaxFactory.ParseTypeName("var");

            var newDeclaration = declaration
                                 .WithType(typeSyntax)
                                 .WithLeadingTrivia(declaration.GetLeadingTrivia())
                                 .WithTrailingTrivia(declaration.GetTrailingTrivia());

            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            syntaxRoot = syntaxRoot.ReplaceNode(declaration, newDeclaration);

            syntaxRoot = syntaxRoot.Format();

            return(document.WithSyntaxRoot(syntaxRoot).Project.Solution);
        }
Пример #14
0
        private VariableDeclarationSyntax TryReplace(VariableDeclarationSyntax declaration)
        {
            var variable = declaration.Variables.First();

            if (variable.Initializer != null)
            {
                var t1 = SemanticModel.GetTypeInfo(variable.Initializer.Value);
                var t2 = SemanticModel.GetTypeInfo(declaration.Type);

                if (t1.Type != null && t2.Type != null && t1.Type.ToString() == t2.Type.ToString())
                {
                    Altered = true;
                    var type = SyntaxFactory.IdentifierName("var")
                               .WithLeadingTrivia(declaration.Type.GetLeadingTrivia())
                               .WithTrailingTrivia(declaration.Type.GetTrailingTrivia());
                    return(declaration.WithType(type));
                }
            }
            return(declaration);
        }
        private static async Task <Document> ChangeTypeAndAddAwaitAsync(
            Document document,
            VariableDeclarationSyntax variableDeclaration,
            ITypeSymbol typeSymbol,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            TypeSyntax type = variableDeclaration.Type;

            ExpressionSyntax value = variableDeclaration.Variables[0].Initializer.Value;

            AwaitExpressionSyntax newInitializerValue = SyntaxFactory.AwaitExpression(value)
                                                        .WithTriviaFrom(value);

            VariableDeclarationSyntax newNode = variableDeclaration.ReplaceNode(value, newInitializerValue);

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            newNode = newNode.WithType(
                typeSymbol.ToMinimalTypeSyntax(semanticModel, type.SpanStart).WithTriviaFrom(type));

            return(await document.ReplaceNodeAsync(variableDeclaration, newNode, cancellationToken).ConfigureAwait(false));
        }
        private static Task <Document> RefactorAsync(
            Document document,
            SingleLocalDeclarationStatementInfo localInfo,
            TypeSyntax type,
            CancellationToken cancellationToken)
        {
            LocalDeclarationStatementSyntax localStatement = localInfo.Statement;

            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(localStatement);

            int index = statementsInfo.IndexOf(localStatement);

            VariableDeclaratorSyntax declarator = localInfo.Declarator;

            VariableDeclaratorSyntax newDeclarator = declarator.WithInitializer(null);

            VariableDeclarationSyntax newDeclaration = localInfo.Declaration.ReplaceNode(declarator, newDeclarator);

            if (type != null)
            {
                newDeclaration = newDeclaration.WithType(type.WithTriviaFrom(newDeclaration.Type));
            }

            LocalDeclarationStatementSyntax newLocalStatement = localStatement
                                                                .WithDeclaration(newDeclaration)
                                                                .WithTrailingTrivia(NewLine())
                                                                .WithFormatterAnnotation();

            ExpressionStatementSyntax assignmentStatement = SimpleAssignmentStatement(IdentifierName(localInfo.Identifier), localInfo.Initializer.Value)
                                                            .WithTrailingTrivia(localStatement.GetTrailingTrivia())
                                                            .WithFormatterAnnotation();

            StatementsInfo newStatementsInfo = statementsInfo
                                               .Insert(index + 1, assignmentStatement)
                                               .ReplaceAt(index, newLocalStatement);

            return(document.ReplaceStatementsAsync(statementsInfo, newStatementsInfo, cancellationToken));
        }
Пример #17
0
        private async Task <Solution> UseExplicitTyping(
            Document document,
            VariableDeclarationSyntax declaration, ITypeSymbol variableType,
            CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var typeName = variableType.ToMinimalDisplayString(semanticModel, declaration.SpanStart);

            var typeSyntax = SyntaxFactory.ParseTypeName(typeName);

            var newDeclaration = declaration
                                 .WithType(typeSyntax)
                                 .WithLeadingTrivia(declaration.GetLeadingTrivia())
                                 .WithTrailingTrivia(declaration.GetTrailingTrivia());

            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            syntaxRoot = syntaxRoot.ReplaceNode(declaration, newDeclaration);

            syntaxRoot = syntaxRoot.Format();

            return(document.WithSyntaxRoot(syntaxRoot).Project.Solution);
        }
Пример #18
0
        private SyntaxNode handleError(SyntaxNode node, out SyntaxNode oldNode, Diagnostic error, SemanticModel model)
        {
            oldNode = null;
            if (error.Severity != DiagnosticSeverity.Error)
            {
                return(null);
            }

            oldNode = node.FindNode(error.Location.SourceSpan);
            if (oldNode == null || oldNode.ToString() == "void")
            {
                oldNode = null;
                return(null);
            }

            //td: !!! error manager
            switch (error.Id)
            {
            case "CS0246":
            {
                //type not found
                string typeName = oldNode.ToString();

                if (oldNode is GenericNameSyntax)
                {
                    GenericNameSyntax syntax = (GenericNameSyntax)oldNode;
                    typeName = syntax.Identifier.ToString();
                }

                switch (typeName)
                {
                case "function": return(FunctionType(oldNode));

                default:
                {
                    var currType = oldNode.Ancestors().OfType <ClassDeclarationSyntax>().FirstOrDefault();
                    if (currType == null)
                    {
                        break;
                    }

                    IEnumerable <Typedef> tdefs = GetTypeInfo <Typedef>(currType.Identifier.ToString(), "typedefs");

                    if (tdefs != null)
                    {
                        var TypeName = oldNode.ToString();
                        foreach (var typedef in tdefs)
                        {
                            if (typedef.Name == TypeName)
                            {
                                return(typedef.Type);
                            }
                        }
                    }
                    break;
                }
                }

                break;
            }

            case "CS0815":
            {
                if (oldNode is VariableDeclaratorSyntax)
                {
                    VariableDeclaratorSyntax            decl   = (VariableDeclaratorSyntax)oldNode;
                    ParenthesizedLambdaExpressionSyntax lambda = (ParenthesizedLambdaExpressionSyntax)decl.Initializer.Value;

                    var arguments     = lambda.ParameterList.Parameters;
                    var funcArguments = new List <TypeSyntax>();
                    foreach (var arg in arguments)
                    {
                        if (arg.Type == null || arg.Type.IsMissing)
                        {
                            return(oldNode);    //can't recover
                        }
                        funcArguments.Add(arg.Type);
                    }

                    var         returnStatements = lambda.Body.DescendantNodes().OfType <ReturnStatementSyntax>();
                    ITypeSymbol returnType       = null;
                    bool        returns          = false;
                    foreach (var rs in returnStatements)
                    {
                        returns |= rs.Expression != null;

                        ITypeSymbol type = model.GetSpeculativeTypeInfo(rs.Expression.SpanStart, rs.Expression, SpeculativeBindingOption.BindAsExpression).Type;
                        if (type == null)
                        {
                            return(oldNode);    //can't recover
                        }
                        if (returnType == null)
                        {
                            returnType = type;
                        }
                        else if (type != returnType)
                        {
                            returnType = null;
                            break;
                        }
                    }

                    TypeSyntax resultType;
                    if (!returns)
                    {
                        resultType = SyntaxFactory.GenericName("Action").
                                     WithTypeArgumentList(SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(
                                                                                             funcArguments)));
                    }
                    else
                    {
                        string returnTypeName = "object";
                        if (returnType != null)
                        {
                            returnTypeName = returnType.Name;
                        }

                        funcArguments.Add(SyntaxFactory.ParseTypeName(returnTypeName));
                        resultType = SyntaxFactory.GenericName("Func").
                                     WithTypeArgumentList(SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(
                                                                                             funcArguments)));
                    }


                    oldNode = oldNode.Parent;
                    VariableDeclarationSyntax declaration = (VariableDeclarationSyntax)oldNode;

                    return(declaration.WithType(resultType));
                }

                break;
            }
            }

            return(oldNode);
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            MemberDeclarationSyntax memberDeclaration,
            ITypeSymbol typeSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            TypeSyntax newType = typeSymbol.ToMinimalTypeSyntax(semanticModel, memberDeclaration.SpanStart);

            switch (memberDeclaration.Kind())
            {
            case SyntaxKind.MethodDeclaration:
            {
                var methodDeclaration = (MethodDeclarationSyntax)memberDeclaration;

                MethodDeclarationSyntax newNode = methodDeclaration.WithReturnType(newType.WithTriviaFrom(methodDeclaration.ReturnType));

                return(await document.ReplaceNodeAsync(methodDeclaration, newNode, cancellationToken).ConfigureAwait(false));
            }

            case SyntaxKind.PropertyDeclaration:
            {
                var propertyDeclaration = (PropertyDeclarationSyntax)memberDeclaration;

                PropertyDeclarationSyntax newNode = propertyDeclaration.WithType(newType.WithTriviaFrom(propertyDeclaration.Type));

                return(await document.ReplaceNodeAsync(propertyDeclaration, newNode, cancellationToken).ConfigureAwait(false));
            }

            case SyntaxKind.IndexerDeclaration:
            {
                var indexerDeclaration = (IndexerDeclarationSyntax)memberDeclaration;

                IndexerDeclarationSyntax newNode = indexerDeclaration.WithType(newType.WithTriviaFrom(indexerDeclaration.Type));

                return(await document.ReplaceNodeAsync(indexerDeclaration, newNode, cancellationToken).ConfigureAwait(false));
            }

            case SyntaxKind.EventDeclaration:
            {
                var eventDeclaration = (EventDeclarationSyntax)memberDeclaration;

                EventDeclarationSyntax newNode = eventDeclaration.WithType(newType.WithTriviaFrom(eventDeclaration.Type));

                return(await document.ReplaceNodeAsync(eventDeclaration, newNode, cancellationToken).ConfigureAwait(false));
            }

            case SyntaxKind.EventFieldDeclaration:
            {
                var eventDeclaration = (EventFieldDeclarationSyntax)memberDeclaration;

                VariableDeclarationSyntax declaration = eventDeclaration.Declaration;
                VariableDeclaratorSyntax  declarator  = declaration.Variables.First();

                EventFieldDeclarationSyntax newNode = eventDeclaration.WithDeclaration(declaration.WithType(newType.WithTriviaFrom(declaration.Type)));

                return(await document.ReplaceNodeAsync(eventDeclaration, newNode, cancellationToken).ConfigureAwait(false));
            }

            default:
            {
                Debug.Fail(memberDeclaration.Kind().ToString());
                return(document);
            }
            }
        }
Пример #20
0
 public static VariableDeclarationSyntax ToRef(this VariableDeclarationSyntax declaration, bool @readonly = false) =>
 declaration
 .WithType(declaration.Type.ToRef(@readonly))
 .WithVariables(declaration.Variables
            SyntaxNode ConvertToVar(VariableDeclarationSyntax node)
            {
                if (node.Parent is LocalDeclarationStatementSyntax == false)
                {
                    return(null);
                }
                if ((node.Parent as LocalDeclarationStatementSyntax).IsConst)
                {
                    return(null);
                }

                if (node.Type is IdentifierNameSyntax varIdentifierNameSyntax)
                {
                    if (varIdentifierNameSyntax.Identifier.ValueText == VarKeyword)
                    {
                        return(null);
                    }
                }

                if (node.Variables.Count > 1)
                {
                    return(null);
                }

                var variable = node.Variables.FirstOrDefault();

                if (variable.Initializer == null)
                {
                    return(null);
                }

                var typeOfInitializer = SemanticModel.GetTypeInfo(variable.Initializer.Value);

                var typeOfTypeDef = SemanticModel.GetTypeInfo(node.Type);

                if (typeOfInitializer.Type?.Name == typeOfTypeDef.Type?.Name)
                {
                    if (isReportOnlyMode)
                    {
                        var lineSpan = node.GetFileLinePosSpan();

                        AddReport(new ChangesReport(node)
                        {
                            LineNumber = lineSpan.StartLinePosition.Line,
                            Column     = lineSpan.StartLinePosition.Character,
                            Message    = "Should Convert To Var",
                            Generator  = nameof(SimplifyVariableDeclarations)
                        });
                    }

                    node =
                        node
                        .WithType(
                            SyntaxFactory.ParseTypeName(VarKeyword)
                            .WithTrailingTrivia(SyntaxFactory.Space)
                            .WithLeadingTrivia(node.Type.GetLeadingTrivia())
                            );
                }

                return(base.VisitVariableDeclaration(node));
            }
Пример #22
0
        public static void ChangeMemberDeclarationType(
            CodeFixContext context,
            Diagnostic diagnostic,
            MemberDeclarationSyntax memberDeclaration,
            ITypeSymbol typeSymbol,
            SemanticModel semanticModel,
            string additionalKey = null)
        {
            if (typeSymbol.IsErrorType())
            {
                return;
            }

            Document document = context.Document;

            string typeName = SymbolDisplay.ToMinimalDisplayString(typeSymbol, semanticModel, memberDeclaration.SpanStart, SymbolDisplayFormats.Default);

            string title = (memberDeclaration.IsKind(SyntaxKind.MethodDeclaration))
                ? $"Change return type to '{typeName}'"
                : $"Change type to '{typeName}'";

            CodeAction codeAction = CodeAction.Create(
                title,
                cancellationToken => RefactorAsync(cancellationToken),
                EquivalenceKey.Create(diagnostic, additionalKey));

            context.RegisterCodeFix(codeAction, diagnostic);

            Task <Document> RefactorAsync(CancellationToken cancellationToken)
            {
                TypeSyntax newType = typeSymbol.ToMinimalTypeSyntax(semanticModel, memberDeclaration.SpanStart);

                switch (memberDeclaration.Kind())
                {
                case SyntaxKind.MethodDeclaration:
                {
                    var methodDeclaration = (MethodDeclarationSyntax)memberDeclaration;

                    MethodDeclarationSyntax newNode = methodDeclaration.WithReturnType(newType.WithTriviaFrom(methodDeclaration.ReturnType));

                    return(document.ReplaceNodeAsync(methodDeclaration, newNode, cancellationToken));
                }

                case SyntaxKind.PropertyDeclaration:
                {
                    var propertyDeclaration = (PropertyDeclarationSyntax)memberDeclaration;

                    PropertyDeclarationSyntax newNode = propertyDeclaration.WithType(newType.WithTriviaFrom(propertyDeclaration.Type));

                    return(document.ReplaceNodeAsync(propertyDeclaration, newNode, cancellationToken));
                }

                case SyntaxKind.IndexerDeclaration:
                {
                    var indexerDeclaration = (IndexerDeclarationSyntax)memberDeclaration;

                    IndexerDeclarationSyntax newNode = indexerDeclaration.WithType(newType.WithTriviaFrom(indexerDeclaration.Type));

                    return(document.ReplaceNodeAsync(indexerDeclaration, newNode, cancellationToken));
                }

                case SyntaxKind.EventDeclaration:
                {
                    var eventDeclaration = (EventDeclarationSyntax)memberDeclaration;

                    EventDeclarationSyntax newNode = eventDeclaration.WithType(newType.WithTriviaFrom(eventDeclaration.Type));

                    return(document.ReplaceNodeAsync(eventDeclaration, newNode, cancellationToken));
                }

                case SyntaxKind.EventFieldDeclaration:
                {
                    var eventDeclaration = (EventFieldDeclarationSyntax)memberDeclaration;

                    VariableDeclarationSyntax declaration = eventDeclaration.Declaration;

                    EventFieldDeclarationSyntax newNode = eventDeclaration.WithDeclaration(declaration.WithType(newType.WithTriviaFrom(declaration.Type)));

                    return(document.ReplaceNodeAsync(eventDeclaration, newNode, cancellationToken));
                }

                default:
                {
                    Debug.Fail(memberDeclaration.Kind().ToString());
                    return(Task.FromResult(document));
                }
                }
            }
        }
Пример #23
0
        private static async Task <Document> MakeConstAsync(Document document, LocalDeclarationStatementSyntax localDeclaration, CancellationToken cancellationToken)
        {
            // Remove the leading trivia from the local declaration.
            SyntaxToken      firstToken    = localDeclaration.GetFirstToken();
            SyntaxTriviaList leadingTrivia = firstToken.LeadingTrivia;
            LocalDeclarationStatementSyntax trimmedLocal = localDeclaration.ReplaceToken(
                firstToken, firstToken.WithLeadingTrivia(SyntaxTriviaList.Empty));

            // Create a const token with the leading trivia.
            SyntaxToken constToken = SyntaxFactory.Token(leadingTrivia, SyntaxKind.ConstKeyword, SyntaxFactory.TriviaList(SyntaxFactory.ElasticMarker));

            // Insert the const token into the modifiers list, creating a new modifiers list.
            SyntaxTokenList newModifiers = trimmedLocal.Modifiers.Insert(0, constToken);

            // If the type of declaration is 'var', create a new type name for the
            // type inferred for 'var'.
            VariableDeclarationSyntax variableDeclaration = localDeclaration.Declaration;
            TypeSyntax variableTypeName = variableDeclaration.Type;

            if (variableTypeName.IsVar)
            {
                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                // Special case: Ensure that 'var' isn't actually an alias to another type
                // (e.g. using var = System.String).
                IAliasSymbol aliasInfo = semanticModel.GetAliasInfo(variableTypeName, cancellationToken);
                if (aliasInfo == null)
                {
                    // Retrieve the type inferred for var.
                    ITypeSymbol type = semanticModel.GetTypeInfo(variableTypeName, cancellationToken).ConvertedType;

                    // Special case: Ensure that 'var' isn't actually a type named 'var'.
                    if (type.Name != "var")
                    {
                        // Create a new TypeSyntax for the inferred type. Be careful
                        // to keep any leading and trailing trivia from the var keyword.
                        TypeSyntax typeName = SyntaxFactory.ParseTypeName(type.ToDisplayString())
                                              .WithLeadingTrivia(variableTypeName.GetLeadingTrivia())
                                              .WithTrailingTrivia(variableTypeName.GetTrailingTrivia());

                        // Add an annotation to simplify the type name.
                        TypeSyntax simplifiedTypeName = typeName.WithAdditionalAnnotations(Simplifier.Annotation);

                        // Replace the type in the variable declaration.
                        variableDeclaration = variableDeclaration.WithType(simplifiedTypeName);
                    }
                }
            }

            // Produce the new local declaration.
            LocalDeclarationStatementSyntax newLocal = trimmedLocal.WithModifiers(newModifiers)
                                                       .WithDeclaration(variableDeclaration);

            // Add an annotation to format the new local declaration.
            LocalDeclarationStatementSyntax formattedLocal = newLocal.WithAdditionalAnnotations(Formatter.Annotation);

            // Replace the old local declaration with the new local declaration.
            SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            SyntaxNode newRoot = root.ReplaceNode(localDeclaration, formattedLocal);

            // Return document with transformed tree.
            return(document.WithSyntaxRoot(newRoot));
        }