我期待有效地实现以下方法:Roslyn:枚举确切的标记+琐事跨越单一源代码行?
IEnumerable<ColoredSpan> GetSyntaxHighlightedSpansOnLine(int lineNumber);
我有一个Document
,SourceText
,SyntaxTree
等。假设ColoredSpan
是一些颜色和字符串的元组(或其他来源char
s)。对于例如第三行这段代码:
namespace Foo
{ /* Badly formatted coment...
which continues here... */ class Bar : public IBaz // TODO: rename classes
{
...
我期待与文本交付枚举的结果:
" ", "which continues here... */", " ", "class", " ", "Bar", " ",
":", " ", "public", " ", "IBaz", " ", "// TODO: rename classes", "\r\n"
注意包含空格和评论琐事,和部分多评论。
Another answer指向派生CSharpSyntaxWalker来遍历AST的整个部分,但不能有效地限制遍历单行节点的方法。在每行的基础上,这是不高效的,我不能轻易地确定例如Roslyn“trivia”(例如多行注释)返回。它也返回重叠的节点(例如命名空间)。
我试图code as in this answer,一拉:
var lineSpan = sf.GetText().Lines[lineNumber].Span;
var nodes = syntaxTree.GetRoot()
.DescendantNodes()
.Where(x => x.Span.IntersectsWith(lineSpan))
但这返回整个子树AST,前序遍历,而这又是低效的,并且还返回重叠节点(例如命名空间),并且不处理琐事。其他样本适用于整个文档/脚本。我还咨询了接近零的API文档。
代码分析API是否有效地允许这样做?或者为了实现这个方法,我是否需要提前遍历整个AST,并存储一个我自己设计的主观庞大并行内存消耗的数据结构,如this answer?
不完全确定我们应该在这里添加哪些文档该代码与我们在Visual Studio中使用的代码相同,但是有一些缓存是我们在其上面的。缓存问题很棘手,说实话,如果不知道该场景,很难回答。 –
@JasonMalinowski这是超级安慰,谢谢 - 至少在这里的正确线条。虽然我们可以看到Roslyn代码非常棒,但评论很少,所以很难从实现中推导出API合约,所以很难知道其中的API是按照预期编写的,而不是滥用API /吠叫错误的树/为未来的自我创造糟糕的表现问题。顺便提一下,在Roslyn概述wiki中看到提及语法突出显示和分类器会很高兴。但我真的应该在Github上提出这样的建议。 –