【问题标题】:Get reified type of symbol after the erasure phase of the Scala 2.9.3 compiler在 Scala 2.9.3 编译器的擦除阶段之后获取具体类型的符号
【发布时间】:2013-09-03 01:12:39
【问题描述】:

我正在编写一个编译器插件,它将 Scala 的一个子集翻译成 C++(忽略这个任务明显的疯狂)。我正在使用一些必须在擦除阶段之后运行的插件。但是,我需要完整的类型信息才能输出有效代码。

例如,对于 Scala;

def foo(f: Type1 => Type2): Unit = { /* Snip */ }

我想输出 C++;

void foo(scala::Function1<Type1, Type2> f) { /* Snip */ }

但是,在擦除阶段之后,foo 看起来像这样:

def foo(f: Function1): Unit = { /* Snip */ }

即,参数f 的泛型类型信息已丢失。我需要以某种方式取回它。有什么建议吗?

回复 cdshines 的评论

这是一个例子:

example.scala

object Example {
  def func(f: Int => Boolean) { }
}

当我编译时;

# scalac -version
Scala compiler version 2.9.3 -- Copyright 2002-2011, LAMP/EPFL
# scalac -Xprint:explicitouter -Xprint:erasure example.scala
[[syntax trees at end of explicitouter]]// Scala source: example.scala
package <empty> {
  final object Example extends java.lang.Object with ScalaObject {
    def this(): object Example = {
      Example.super.this();
      ()
    };
    def func(f: Int => Boolean): Unit = ()
  }
}

[[syntax trees at end of erasure]]// Scala source: example.scala
package <empty> {
  final object Example extends java.lang.Object with ScalaObject {
    def this(): object Example = {
      Example.super.this();
      ()
    };
    def func(f: Function1): Unit = ()
  }
}

注意func的签名变化。 explicitoutererasure 之前的阶段。

【问题讨论】:

  • 您确定要删除吗?你在哪个阶段得到它?我无法用 scala 2.9.3 重现它。
  • @cdshines 我已经回答了这个问题。
  • 我明白了。也许你可以在ClassTags 中传递额外的类型信息?
  • 遗憾的是,ClassTag 在 2.9.3 中不存在。我不确定他们是否会在编译时提供帮助。

标签: c++ scala compiler-construction erasure


【解决方案1】:

这个解决方案是由 scala 语言邮件列表建议的。在导入 scala.tools.nsc.Global 的命名空间的内容中,以下内容将在 erasure 阶段之前恢复方法的类型(更具体地说是 AST 中的 DefDef)。

atPhase(currentRun.erasurePhase) { someDefDef.symbol.tpe }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-14
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    相关资源
    最近更新 更多