コード例 #1
0
            public CompilationUnitSyntax TransformRoot(CompilationUnitSyntax root)
            {
                root = root.ReplaceNodes(_nodeToAnnotations.Keys, (originalNode, rewrittenNode) =>
                {
                    var ret = rewrittenNode.WithAdditionalAnnotations(_nodeToAnnotations[originalNode]);

                    return(ret);
                });

                foreach (var kvp in _annotationToTransformation)
                {
                    Dictionary <SyntaxNode, SyntaxNode> originalNodeMap = new Dictionary <SyntaxNode, SyntaxNode>();
                    foreach (var originalNodeKvp in _originalNodeLookup)
                    {
                        var        annotatedNodes = root.GetAnnotatedNodes(originalNodeKvp.Key).ToList();
                        SyntaxNode annotatedNode  = annotatedNodes.SingleOrDefault();
                        if (annotatedNode != null)
                        {
                            originalNodeMap[annotatedNode] = originalNodeKvp.Value;
                        }
                    }

                    var syntaxAnnotation = kvp.Key;
                    var transformation   = kvp.Value;
                    var nodesToTransform = root.GetAnnotatedNodes(syntaxAnnotation);
                    root = transformation(root, nodesToTransform, originalNodeMap);
                }

                return(root);
            }
コード例 #2
0
        public CodeTemplateBuilder SetParameters()
        {
            var parameterListNode = _template.GetAnnotatedNodes("ParameterList").First();

            _template = _template.ReplaceNode(parameterListNode, SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList(_parameters)));
            return(this);
        }
コード例 #3
0
        /// <summary>
        /// Registers a change performed by the code fix.
        /// </summary>
        /// <param name="original">Original <see cref="CSharpSyntaxNode"/> that is begin replaced by the <paramref name="updated"/> node.</param>
        /// <param name="updated"><see cref="CSharpSyntaxNode"/> to replace the <paramref name="original"/> node with.</param>
        public void RegisterChange(CSharpSyntaxNode original, CSharpSyntaxNode updated)
        {
            SyntaxTree old = Root.SyntaxTree;

            Root        = Root.ReplaceNode(original, updated);
            Compilation = Compilation.ReplaceSyntaxTree(old, Root.SyntaxTree);
            Document    = Document.WithSyntaxRoot(Root);
            Node        = Root.GetAnnotatedNodes(_annotation).OfType <T>().First();

            if (_semanticModel is not null)
            {
                _semanticModel = null;
            }
        }
コード例 #4
0
 private CodeFixExecutionContext(
     Diagnostic diagnostic,
     Document document,
     CompilationUnitSyntax root,
     T node,
     CSharpCompilation compilation,
     CancellationToken cancellationToken)
 {
     _annotation       = new();
     Diagnostic        = diagnostic;
     CancellationToken = cancellationToken;
     Root           = root.ReplaceNode(node, node.WithAdditionalAnnotations(_annotation));
     Compilation    = compilation.ReplaceSyntaxTree(root.SyntaxTree, Root.SyntaxTree);
     Document       = document.WithSyntaxRoot(Root);
     Node           = Root.GetAnnotatedNodes(_annotation).OfType <T>().First();
     _semanticModel = null;
 }
コード例 #5
0
        private async Task <Document> ReplaceStringWithLocalizerFormat(Document document, LiteralExpressionSyntax litDecl, CancellationToken cancellationToken)
        {
            try
            {
                //Get the details of the ID to use
                currentProject = ProjectsManager.projects[document.Project.Name];
                newIDKey       = currentProject.LocalizerSettings.NextTag;
                newValue       = litDecl.ToString();

                if (newValue.StartsWith("\""))
                {
                    newValue = newValue.Substring(1);
                }
                if (newValue.EndsWith("\""))
                {
                    newValue = newValue.Substring(0, newValue.Length - 1);
                }

                //Get the document
                var root = await document.GetSyntaxRootAsync(cancellationToken);

                CompilationUnitSyntax newroot = (CompilationUnitSyntax)root;

                SyntaxNode replacedNode;
                try
                {
                    //Set up the call to Localizer.Format
                    IdentifierNameSyntax         localizer    = SyntaxFactory.IdentifierName("Localizer");
                    IdentifierNameSyntax         format       = SyntaxFactory.IdentifierName("Format");
                    MemberAccessExpressionSyntax memberaccess = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, localizer, format);

                    ArgumentSyntax arg = SyntaxFactory.Argument(SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(newIDKey)));
                    SeparatedSyntaxList <ArgumentSyntax> argList = SyntaxFactory.SeparatedList(new[] { arg });

                    SyntaxAnnotation syntaxAnnotation = new SyntaxAnnotation("LocalizerFormat");

                    SyntaxNode writecall =
                        SyntaxFactory.InvocationExpression(memberaccess,
                                                           SyntaxFactory.ArgumentList(argList)

                                                           ).WithAdditionalAnnotations(syntaxAnnotation).WithTriviaFrom(litDecl);


                    newroot = newroot.ReplaceNode(litDecl, (SyntaxNode)writecall);

                    //get the changed node back from teh updated document root
                    replacedNode = newroot.GetAnnotatedNodes(syntaxAnnotation).Single();
                }
                catch (Exception ex)
                {
                    OutputManager.WriteErrorEx(ex, "Unable to compile the Localizer call. Refactor cancelled.");
                    return(null);
                }

                try
                {
                    //find the Trivial that marks the end of this line
                    bool         foundEOL   = false;
                    SyntaxNode   objToCheck = replacedNode;
                    SyntaxTrivia objEOL     = SyntaxFactory.Comment(" ");

                    //This look works upwards through the structure by parent to get bigger bits of the
                    // syntax tree to find the first EOL after the replaced Node
                    while (!foundEOL)
                    {
                        //Go up one level
                        objToCheck = objToCheck.Parent;

                        //If we found it get out
                        if (FindEOLAfter(objToCheck, replacedNode.FullSpan.End, ref objEOL))
                        {
                            foundEOL = true;
                        }

                        //If we just checked the whole document then stop looping
                        if (objToCheck == root)
                        {
                            break;
                        }
                    }

                    //If we found the EOL Trivia then insert the new comment before it
                    if (foundEOL)
                    {
                        var tabs    = SyntaxFactory.Whitespace("\t\t");
                        var comment = SyntaxFactory.Comment("// " + newIDKey + " = " + newValue);
                        List <SyntaxTrivia> lineComment = new List <SyntaxTrivia>();
                        lineComment.Add(tabs);
                        lineComment.Add(comment);

                        newroot = newroot.InsertTriviaBefore(objEOL, lineComment);
                    }
                }
                catch (Exception ex)
                {
                    OutputManager.WriteErrorEx(ex, "Unable to add comment to end of line. Add it manually if you like.");
                }


                try {
                    //Make sure the file has a usings so the short name works
                    if (!newroot.Usings.Any(u => u.Name.GetText().ToString() == "KSP.Localization"))
                    {
                        newroot = newroot.AddUsings(SyntaxFactory.UsingDirective(SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("KSP"), SyntaxFactory.IdentifierName("Localization"))));
                    }
                }
                catch (Exception ex)
                {
                    OutputManager.WriteErrorEx(ex, "Unable to add usings line to head of file. Add it manually.");
                }

                //Now convert it to the document to send it back
                try
                {
                    var result = document.WithSyntaxRoot(newroot);

                    return(result);
                }
                catch (Exception ex)
                {
                    OutputManager.WriteErrorEx(ex, "Unable to rewrite the document. Refactor cancelled.");
                    return(null);
                }
            }
            catch (Exception ex)
            {
                OutputManager.WriteErrorEx(ex, "General error refactoring the token. Refactor cancelled.");
            }

            return(null);
        }
コード例 #6
0
        private CompilationUnitSyntax ReplacePlaceholder(CompilationUnitSyntax template, SyntaxNode syntax)
        {
            var returnValueNode = template.GetAnnotatedNodes("SyntaxPlaceholder").First();

            return(template.ReplaceNode(returnValueNode, syntax));
        }
コード例 #7
0
 public static SyntaxNode FindNodeById(this CompilationUnitSyntax syntax, ulong id)
 {
     return(syntax.GetAnnotatedNodes("Id")              // syntax.GetAnnotatedNodes(new SyntaxAnnotation("Id", assignmentNode.Id.ToString())) does not work!
            .Where(node => node.GetAnnotations("Id").First().Data.Equals(id.ToString())).First());
 }