使用 Roslyn 更改文件 [英] Change files using Roslyn

查看:35
本文介绍了使用 Roslyn 更改文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个命令行工具,使用 Roslyn 修改一些代码.一切似乎都很顺利:解决方案已打开,解决方案已更改,Workspace.TryApplyChanges 方法返回 true.但是,磁盘上的实际文件没有更改.这是怎么回事?下面是我使用的顶级代码.

I'm trying to write a command line tool that modifies some code using Roslyn. Everything seems to go well: the solution is opened, the solution is changed, the Workspace.TryApplyChanges method returns true. However no actual files are changed on disk. What's up? Below is the top level code I'm using.

static void Main(string[] args)
{
    var solutionPath = args[0];
    UpdateAnnotations(solutionPath).Wait();
}

static async Task<bool> UpdateAnnotations(string solutionPath)
{
    using (var workspace = MSBuildWorkspace.Create())
    {
        var solution = await workspace.OpenSolutionAsync(solutionPath);
        var newSolution = await SolutionAttributeUpdater.UpdateAttributes(solution);
        var result = workspace.TryApplyChanges(newSolution);
        Console.WriteLine(result);
        return result;
    }
}

推荐答案

我使用您的代码构建了一个简短的程序并收到了我预期的结果 - 问题似乎存在于 SolutionAttributeUpdater.UpdateAttributes 方法中.我使用以下实现与您的基本 main 和 UpdateAnnotations-methods 收到了这些结果:

I constructed a short program using your code and received the results I expected - the problem appears to reside within the SolutionAttributeUpdater.UpdateAttributes method. I received these results using the following implementation with your base main and UpdateAnnotations-methods:

public class SolutionAttributeUpdater
{
    public static async Task<Solution> UpdateAttributes(Solution solution)
    {
        foreach (var project in solution.Projects)
        {
            foreach (var document in project.Documents)
            {
                var syntaxTree = await document.GetSyntaxTreeAsync();
                var root = syntaxTree.GetRoot();

                var descentants = root.DescendantNodes().Where(curr => curr is AttributeListSyntax).ToList();
                if (descentants.Any())
                {
                    var attributeList = SyntaxFactory.AttributeList(
                        SyntaxFactory.SingletonSeparatedList(
                            SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("Cookies"), SyntaxFactory.AttributeArgumentList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.AttributeArgument(
                                    SyntaxFactory.LiteralExpression(
                                                                SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(@"Sample"))
                                    )})))));
                    root = root.ReplaceNodes(descentants, (node, n2) => attributeList);
                    solution = solution.WithDocumentSyntaxRoot(document.Id, root);
                }
            }
        }
        return solution;
    }
}

使用示例解决方案中的以下类对其进行了测试:

It was tested using the following class in the sample solution:

public class SampleClass<T>
{
    [DataMember("Id")]
    public int Property { get; set; }
    [DataMember("Id")]
    public void DoStuff()
    {
        DoStuff();
    }
}

结果如下:

public class SampleClass<T>
{
[Cookies("Sample")]        public int Property { get; set; }
[Cookies("Sample")]        public void DoStuff()
    {
        DoStuff();
    }
}

如果您查看 UpdateAttributes 方法,我必须用 ReplaceNodes 替换节点并通过调用 WithDocumentSyntaxRoot 更新解决方案.

If you take a look at the UpdateAttributes method I had to replace the nodes with ReplaceNodes and updated the solution by calling WithDocumentSyntaxRoot.

我会假设这两个调用中的任何一个丢失或根本没有任何更改 - 如果您调用 workspace.TryApplyChanges(solution) 您仍然会收到 true 作为输出.

I would assume that either one of those two calls is missing or that nothing was changed at all - if you call workspace.TryApplyChanges(solution) you would still receive true as an Output.

请注意,使用多次调用 root.ReplaceNode() 而不是 root.ReplaceNodes() 也会导致错误,因为实际上只有第一次更新用于修改后的文档 - 这可能会让您相信没有任何变化完全取决于实现.

Note that using multiple calls of root.ReplaceNode() instead of root.ReplaceNodes() can also result in an error since only the first update is actually used for the modified document - which might lead you to believe that nothing has changed at all, depending on the implementation.

这篇关于使用 Roslyn 更改文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆