格式化方法签名会丢失缩进
Formatting a method signature loses indentation
我正在创建一个代码修复程序,它可以转换检测到的方法的访问修饰符 public
。实现很简单:删除所有现有的访问修饰符并在前面添加 public
。之后我替换了节点和 return 解决方案。
然而,这会导致修饰符列表如下所示: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);
}
无需手动调用 Formatter.Format
,只需将 Formatter.Annotation
放在您的固定节点上,CodeFix 引擎就会自动为您调用它。
问题是你需要在树的根上调用Format
,但是要指定你想要格式化的树的跨度,否则格式化程序会在[=17=上运行 ]只是 您传入的树,没有来自其父级的上下文。
问题是我在字符串表示本身中缩进了我的测试,如下所示:
var original = @"
using System;
using System.Text;
namespace ConsoleApplication1
{
class MyClass
{
void Method(Nullable<int> myVar = 5)
{
}
}
}";
如您所见,左边距和实际代码之间仍然有一个制表符。显然 Roslyn 格式化程序无法处理这种情况(诚然,这种情况并不常见)。
不过在与此不同的情况下,您可能对格式化程序感兴趣,这就是为什么我会接受凯文的回答。
我正在创建一个代码修复程序,它可以转换检测到的方法的访问修饰符 public
。实现很简单:删除所有现有的访问修饰符并在前面添加 public
。之后我替换了节点和 return 解决方案。
然而,这会导致修饰符列表如下所示: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);
}
无需手动调用 Formatter.Format
,只需将 Formatter.Annotation
放在您的固定节点上,CodeFix 引擎就会自动为您调用它。
问题是你需要在树的根上调用Format
,但是要指定你想要格式化的树的跨度,否则格式化程序会在[=17=上运行 ]只是 您传入的树,没有来自其父级的上下文。
问题是我在字符串表示本身中缩进了我的测试,如下所示:
var original = @"
using System;
using System.Text;
namespace ConsoleApplication1
{
class MyClass
{
void Method(Nullable<int> myVar = 5)
{
}
}
}";
如您所见,左边距和实际代码之间仍然有一个制表符。显然 Roslyn 格式化程序无法处理这种情况(诚然,这种情况并不常见)。
不过在与此不同的情况下,您可能对格式化程序感兴趣,这就是为什么我会接受凯文的回答。