Trees$Literal(反射)在 Scala 2.13.0-M3 中移动了吗?

Did Trees$Literal (reflection) move in Scala 2.13.0-M3?

我收到以下 2.13.0-M3 编译器错误:类型 Trees$Literal 不是包 scala.reflect.internal

的成员

这在 2.11 和 2.12 下编译得很好。在 2.13.0-M3 中,我得到了标题中的错误。这改变了吗?损坏的完整代码行示例如下:

// Extract MapName annotation if present
val optionalMapName = member.annotations.find(_.tree.tpe =:= typeOf[MapName])
.map { index =>
  index.tree.children(1).productElement(1)
   .asInstanceOf[scala.reflect.internal.Trees$Literal].value().value
 }.asInstanceOf[Option[String]]

我不知道为什么这在以前有效而在 2.13.0-M3 中不再有效,但 Trees$Literal 是一种实现细节。这就是编译器对内部 classes 的名称进行编码的方式。您可以引用 class 的实际 Scala 类型是类型投影 Trees#Literal

所以可能会起作用的是

const.asInstanceOf[scala.reflect.internal.Trees#Literal].value.value

我猜你的代码中的 value() 曾经有效,因为编译器不再将 Trees$Literal 识别为 Scala 类型,并且在 Java 中所有方法都有一个参数列表。 Scala def foo 编译为方法 带有 参数列表,但编译器可以在特定于 Scala 的元数据中查看它是否是没有参数列表的方法。 A(非本地)val 编译为一个字段 一个方法。

顺便说一句,尽管这可能很有趣,但我认为您实际上不需要为此强制转换为内部 API。您可以简单地进行模式匹配以从文字常量中获取值。 LiteralConstantscala.reflect.runtime.universec.universe 导入(c 是宏上下文):

val Literal(Constant(value: String)) = const

const match {
  case Literal(Constant(value: String)) => value
}