我正在使用API在编译期间重建scala AST。
我想更改“应用”AST,如
a(1)
进入“分配和返回”块
{
val newvalue = a(1)
newvalue
}
这是我在AST中生成新值的代码:
val newVal : Tree = gen.mkPatDef(Typed(Ident(newTermName("newvalue")), returnType), a)(new FreshNameCreator("newvalue"))(0)
val newSymbol = newVal.symbol.newValue(newTermName("newvalue"), a.pos, 0)
newVal.setSymbol(newSymbol)
newVal.setType(a.tpe)
newVal.symbol.setName(newTermName("newvalue"))
newVal.symbol.setInfo(a.tpe)
在代码中,“a”是Apply AST
我在scala编译阶段“packageobjects”之后做了这个改变,AST树的转换可以完成,但是之后它总是被卡住了。我想问题在于“newvalue”的符号,因为如果我使用现有值的现有符号,而不是自己创建一个新符号,它就有效。
感谢。
答案 0 :(得分:0)
搞清楚!当函数调用“a”返回“Unit”时会出现另一个问题,在这种情况下,当我使用“newvalue”作为返回时,它会报告类型不匹配错误:
错误:java.lang.AssertionError:断言失败:无法在源代码单元hello.scala中将UNIT转换为REF(类BoxedUnit) - / Users / shiyu / Scala / FinalDataFlow / src / print / hello.scala ,线路347,偏移量= 13999
但我的代码在其他情况下可以使用。在代码“d”中是函数定义的DefDef AST节点,“a”是“d”末尾的尾函数调用的Apply AST节点,“b”是“d”的右侧块。
val newVal = ValDef(Modifiers(0), newTermName("newvalue"), d.tpt, treeCopy.Apply(a, a.fun, a.args))
val newSymbol = a.symbol.newValue(newTermName("newvalue"), a.pos, 0)
newSymbol.owner = d.symbol
newVal.setSymbol(newSymbol)
newVal.symbol.setName(newTermName("newvalue"))
newVal.symbol.setInfo(a.tpe)
newVal.setType(a.tpe)
val newIdent = Ident(newVal.symbol)
newIdent.setType(a.tpe)
treeCopy.DefDef(d, mods, name, tparams, vparamss, tpt, treeCopy.Block(rhs, b.stats ::: List(newVal), newIdent))