我正在创建一个代码修复程序,它会转换检测到的方法public
的访问修饰符。实现很简单:删除所有现有的访问修饰符并在前面添加public
。然后我替换节点并返回解决方案。
然而,这会产生一个如下所示的修饰符列表:publicvirtual void Method()
。在粘贴彼此的修改器之上,该行代码被错误地缩进。它看起来像这样:
[TestClass]
public class MyClass
{
[TestMethod]
publicvirtual void Method()
{
}
}
因此,作为解决方案,我会格式化代码。使用
var formattedMethod = Formatter.Format(newMethod,
newMethod.Modifiers.Span,
document.Project.Solution.Workspace,
document.Project.Solution.Workspace.Options);
我可以格式化修饰符,但它们仍然错误地缩进:
[TestClass]
public class MyClass
{
[TestMethod]
public virtual void Method()
{
}
}
我认为这是因为琐事,但是使用原始方法的主要琐事预先设置格式化方法并没有什么不同。我想避免格式化整个文档,因为这不是格式化整个文档的操作。
此代码修复的完整相关实现:
private Task<Solution> MakePublicAsync(Document document, SyntaxNode root, MethodDeclarationSyntax method)
{
var removableModifiers = new[]
{
SyntaxFactory.Token(SyntaxKind.InternalKeyword),
SyntaxFactory.Token(SyntaxKind.ProtectedKeyword),
SyntaxFactory.Token(SyntaxKind.PrivateKeyword)
};
var modifierList = new SyntaxTokenList()
.Add(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
.AddRange(method.Modifiers.Where(x => !removableModifiers.Select(y => y.RawKind).Contains(x.RawKind)));
var newMethod = method.WithModifiers(modifierList);
var formattedMethod = Formatter.Format(newMethod, newMethod.Modifiers.Span, document.Project.Solution.Workspace, document.Project.Solution.Workspace.Options);
var newRoot = root.ReplaceNode(method, formattedMethod.WithLeadingTrivia(method.GetLeadingTrivia()));
var newDocument = document.WithSyntaxRoot(newRoot);
return Task.FromResult(newDocument.Project.Solution);
}
答案 0 :(得分:2)
不要手动调用Formatter.Format
,只需将Formatter.Annotation
放在固定节点上,CodeFix引擎就会自动为您调用它。
问题是您需要在树的根上调用Format
,但是要指定要格式化的树的范围,否则格式化程序将在上运行树你传入,没有来自其父母的上下文。
答案 1 :(得分:0)
问题是我在字符串表示中缩进了我的测试,如下所示:
var original = @"
using System;
using System.Text;
namespace ConsoleApplication1
{
class MyClass
{
void Method(Nullable<int> myVar = 5)
{
}
}
}";
正如您所看到的,左边距和实际代码之间仍然有一个标签。显然,Roslyn格式化程序无法处理这种情况(诚然,这不是常见情况)。
在不同的情况下,您可能对格式化程序感兴趣,这就是我接受凯文答案的原因。