【问题标题】:Does Roslyn expose the compiler-generated yield transformations to the syntax trees?Roslyn 是否将编译器生成的 yield 转换暴露给语法树?
【发布时间】:2014-01-12 20:27:28
【问题描述】:

yield 运算符是由编译器在后台实现的,该编译器生成一个实现符合IEnumerableIEnumerator 的状态机的类。

给定 Roslyn MethodDeclarationSyntax,可以像编译器通常那样创建 ClassDeclarationSyntax 并生成 MoveNext 方法。如果要编写支持yield 运算符的交叉编译器,则这种转换是必要的——首先要重写C# 代码以不使用yield 运算符,然后让交叉编译器从那里获取它。

但是,很明显,由于 Roslyn 可以端到端编译 C# 代码,它必须具有以某种方式执行此转换的逻辑,并且我自己实现此算法并非易事。

我的问题:该逻辑是否以某种方式公开,以便可以利用它来将给定的 MethodDeclarationSyntax 转换为相应的 ClassDeclarationSyntax 迭代器声明?还是它在Emit 阶段被烧毁,因此在SyntaxNodes 中工作时不可用?

【问题讨论】:

  • 根据您的目标,翻译 IL 可能更简单。
  • 没错,但我的交叉编译器是纯 C#->JS 编译器。

标签: yield roslyn


【解决方案1】:

当前的 Roslyn 位将迭代器方法作为代码生成阶段的一部分进行处理。不幸的是,这个阶段大多是不透明的,并且使用了不暴露给公共 API 的内部表示。 Roslyn.Compilers.CSharp.IteratorRewriter 内部类是实现这一点的地方,如果你想深入研究的话。

现在,您必须自己实现它。不过,Roslyn 团队暗示在不久的将来会对公共 CTP 进行更新,其中包含大量的 API 更改,所以请放心,也许下一个版本将具有此功能。

【讨论】:

  • 啊,谢谢你的信息,尤其是指向IteratorRewriter的指针;正如您所说,围绕非语法树 API 编写的逻辑。 (事实上​​,BoundXXX 的一组课程,我希望将来能公开)。
  • 我认为绑定节点不可能成为公共 API,因为我们会希望随着编译器的发展对其进行更改。如果您想要一个交叉编译器,您可能想要编写自己的编译器“代码生成”阶段,该阶段位于执行异步降低阶段之后。
  • @NealGafter 有了开源的 Roslyn,一切都可以成为公共 API,对吧?顺便说一句,出色的工作! :)
  • 我们将那些有意保持某种程度兼容性的部分“公开”。至于其余部分,您可以根据需要将其视为“公共”API,但当它从您下面更改时不要感到惊讶。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-21
  • 2013-12-16
  • 2020-04-07
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
相关资源
最近更新 更多