Scala演示文稿编译器locateTree方法 [英] Scala presentation compiler locateTree method

查看:106
本文介绍了Scala演示文稿编译器locateTree方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用scala表示编译器API,或者更确切地说,它是locateTree方法来获取某些源代码的AST,然后通过showRaw(ast)调用获取其原始表示,但是结果似乎是与我的预期相比有所不同.例如

I've been using scala presentation compiler API, or to be more exact it's locateTree method to get AST of some piece of source code, and then get its raw representation via showRaw(ast) call, but the result seems to be different compared to what I expected. For instance

val tree = q"final def x = 1"
println(showRaw(tree))

输出DefDef(Modifiers(FINAL), TermName("x"), List(), List(), TypeTree(), Literal(Constant(1))),而在同一源上对表示编译器的调用将生成DefDef(Modifiers(32, , List()), x, List(), List(), TypeTree(), Literal(Constant(1)))(注意x不在TermName中包装,并且在Modifiers参数列表中存在差异).为什么会发生这种情况,如何在演示文稿编译器上强制执行类似的行为?

Outputs DefDef(Modifiers(FINAL), TermName("x"), List(), List(), TypeTree(), Literal(Constant(1))), while a call to presentation compiler on the same source produces DefDef(Modifiers(32, , List()), x, List(), List(), TypeTree(), Literal(Constant(1))) (notice that x is not wrapped in TermName and difference in Modifiers parameter list). Why does this happen and how can I enforce similar behaviour on presentation compiler?

修改:scala版本为2.11.8

scala version is 2.11.8

推荐答案

树的类型不同,因此必须使用正确的show:

The trees are typed differently, so you have to use the correct show:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_60).
Type in expressions for evaluation. Or try :help.

scala> import scala.tools.nsc._
import scala.tools.nsc._

scala> val ss = new Settings(println)
ss: scala.tools.nsc.Settings =
Settings {
  -d = .
}

scala> val g = new interactive.Global(ss, new reporters.ConsoleReporter(ss), "testing")
g: scala.tools.nsc.interactive.Global = scala.tools.nsc.interactive.Global@4c6007fb

scala> val tt = g.newUnitParser("final def x = 1").parseStats
tt: List[g.syntaxAnalyzer.global.Tree] = List(final def x = 1)

scala> reflect.runtime.universe.show(tt.head)
res0: String = final def x = 1

scala> reflect.runtime.universe.showRaw(tt.head)
res1: String = DefDef(Modifiers(32, , List()), x, List(), List(), TypeTree(), Literal(Constant(1)))

scala> g.showRaw(tt)
res2: String = List(DefDef(Modifiers(FINAL), TermName("x"), List(), List(), TypeTree(), Literal(Constant(1))))

res1处没有类型安全性,因此您不会意识到树是来自不同的宇宙.

There is no type safety at res1, so you don't realize the tree is from a different universe.

由于位置注释,树的修饰符略有不同:

The trees are slightly different in modifiers because of position annotations:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_60).
Type in expressions for evaluation. Or try :help.

scala> import scala.tools.nsc._
import scala.tools.nsc._

scala> val ss = new Settings(println)
ss: scala.tools.nsc.Settings =
Settings {
  -d = .
}

scala> new interactive.Global(ss, new reporters.ConsoleReporter(ss), "testing")
res0: scala.tools.nsc.interactive.Global = scala.tools.nsc.interactive.Global@4c6007fb

scala> val cc = res0
cc: scala.tools.nsc.interactive.Global = scala.tools.nsc.interactive.Global@4c6007fb

scala> val tt = cc.newUnitParser("final def x = 1").parseStats
tt: List[cc.syntaxAnalyzer.global.Tree] = List(final def x = 1)

scala> val cc.DefDef(mods, nam, ps, vs, tpt, rhs) = tt.head
mods: cc.Modifiers = Modifiers(final, , Map(32 -> RangePosition(<console>, 0, 0, 4), 72 -> RangePosition(<console>, 6, 6, 8)))
nam: cc.TermName = x
ps: List[cc.TypeDef] = List()
vs: List[List[cc.ValDef]] = List()
tpt: cc.Tree = <type ?>
rhs: cc.Tree = 1

相对于:

scala> import reflect.runtime._, universe._
import reflect.runtime._
import universe._

scala> val DefDef(mods, nam, ps, vs, tpt, rhs) = q"final def x = 1"
mods: reflect.runtime.universe.Modifiers = Modifiers(final, , Map())
nam: reflect.runtime.universe.TermName = x
ps: List[reflect.runtime.universe.TypeDef] = List()
vs: List[List[reflect.runtime.universe.ValDef]] = List()
tpt: reflect.runtime.universe.Tree = <type ?>
rhs: reflect.runtime.universe.Tree = 1

事实证明,annotations仅显示显式的:

It turns out that annotations shows only explicit ones:

scala> mods.annotations
res13: List[reflect.runtime.universe.Tree] = List()

值得一提的是,该文档showRaw用于检查而不是用于施工.

Worth mentioning that the doc says that showRaw is for inspection rather than construction.

这篇关于Scala演示文稿编译器locateTree方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆