我正在尝试编写一个使用Roslyn修改某些代码的命令行工具。一切似乎都顺利:打开解决方案,更改解决方案,Workspace.TryApplyChanges方法返回true。但是,磁盘上没有更改实际文件。这是怎么回事?下面是我正在使用的顶级代码。
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;
}
}
答案 0 :(得分:3)
我使用您的代码构建了一个简短的程序,并收到了我期望的结果 - 问题似乎存在于SolutionAttributeUpdater.UpdateAttributes方法中。我使用您的base main和UpdateAnnotations方法使用以下实现收到了这些结果:
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;
}
}
在样本溶液中使用以下类进行了测试:
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更新解决方案。
我会假设这两个调用中的任何一个缺失或者根本没有任何更改 - 如果你调用workspace.TryApplyChanges(解决方案),你仍然会收到true作为输出。
请注意,使用root.ReplaceNode()而不是root.ReplaceNodes()的多次调用也可能导致错误,因为只有第一次更新实际用于修改后的文档 - 这可能会让您相信没有任何更改完全取决于实施。