Как получить тип значения, которое представляет AST? - PullRequest
0 голосов
/ 23 апреля 2019

Я пытаюсь написать следующее:

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
"""

Мне нужно захватить тип значения, представленного AST value в tpe, и присвоить его U.Как это сделать?

Редактировать: Давать аннотацию типа для value и сопоставлять ее с помощью квазиквот здесь не вариант.Вариант использования - расширяемая запись Shapeless , которая имеет сложные типы, такие как String with labelled.KeyTag[1, String] :: Long with labelled.KeyTag[three, Long] :: HNil для чего-то вроде val ls = (1 ->> "two") :: ("three" ->> 4L) :: HNil.Кроме того, value AST генерируется программно, а не буквально.

Ответы [ 2 ]

2 голосов
/ 23 апреля 2019

Получите ToolBox, используйте его для проверки типа value и запросите аннотированное дерево для его типа.

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

Код, который вы написали, утверждает, что вы делаете это во время выполнения.Вариант использования, который вы указали в своем комментарии, создает впечатление, что вы находитесь в макросе времени компиляции.В этом случае используйте аналогичный метод typecheck в вашем Context.В противном случае он не будет проверяться;value будет Tree от неправильного Universe, представляя тот факт, что новый экземпляр компилятора, созданный ToolBox, работает в контексте текущей программы (которая оказывается компилятором), а отражениеContext - это весь будущий контекст кода, которым манипулирует содержащийся компилятор.

0 голосов
/ 23 апреля 2019

Попробуйте использовать $tpt в q"$mods val $tname: $tpt = $expr"

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 / обзоры / квазицитаты / syntax-summary.html # определения

Связанный вопрос: Как использовать квазицитаты для получения типа значения?

...