如何获得 AST 所代表的值的类型?

How does one obtain the type of the value that an AST represents?

我正在尝试编写以下内容:

import scala.reflect.runtime.universe._

val value: Tree = /* some AST */
val tpe = typeOf(value)    // This should be the result type of the AST.
                           // This is pseudocode. What should
                           // actually go on this line?
q"""
type U = $tpe
val v: U = $value
"""

我需要捕获tpe中ASTvalue表示的值的类型,并赋值给U。如何做到这一点?

编辑:为 value 提供类型注释并通过准引号匹配它不是这里的选项。用例是一个 Shapeless extensible record,它具有复杂的类型,例如 String with labelled.KeyTag[1, String] :: Long with labelled.KeyTag[three, Long] :: HNil 对应 val ls = (1 ->> "two") :: ("three" ->> 4L) :: HNil。此外,value AST 是以编程方式生成的,而不是文字。

尝试在q"$mods val $tname: $tpt = $expr"

中使用$tpt
val t: Tree = reify {
  val value: Int = 3
}.tree

val tpe = t match {
  case q"{$mods val $tname: $tpt = $expr; $_}" => tpt
} // Int

https://docs.scala-lang.org/overviews/quasiquotes/syntax-summary.html#definitions

相关问题:

获取一个 ToolBox,用它来进行类型检查 value,并询问带注释的树的类型。

import scala.runtime.reflect.currentMirror
val toolbox = currentMirror.mkToolBox()
val tpe = TypeTree(toolbox.typecheck(value).tpe)

您编写的代码声明您在运行时执行此操作。您在评论中陈述的用例使您看起来像是在编译时宏中。在这种情况下,请在 Context 中使用类似的 typecheck 方法。否则它不会进行类型检查; value 将是错误的 UniverseTree,表示 ToolBox 创建的新编译器实例在当前程序的上下文中运行(恰好是一个编译器),而 Context 表示的反射是关于包含编译器操作的代码的未来上下文。