0

I'm using APIs to reconstruct the scala AST during compiling.

I want to change an "Apply" AST like

a(1)

into an "Assign and Return" Block

{

val newvalue = a(1)

newvalue

}

And here's my code for generating a new value in 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)

In the code, "a" is the Apply AST

I do this change after scala compiler phase "packageobjects", the transformation of AST tree can be finished, but it always gets stuck after that. I guess the problem lies in the symbol for the "newvalue", because it works if I use an existing symbol of a existing value, instead of creating a new one by myself.

Thanks.

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
user5279007
  • 255
  • 2
  • 6
  • Please reedit your question. – luoluo Aug 29 '15 at 04:03
  • @luoluo Thank you for viewing my question. Can you check whether I've make it clear now? Basically, in the AST tree of a scala program, when I find a function A calls another function B as its return value, I want to first assign the call of B to a new value, and then use this new value as the return value of A. Could you please tell me how to do it? – user5279007 Aug 29 '15 at 05:11

1 Answers1

0

Figure it out! Yet another problem will occur when function call "a" returns "Unit", in this case when I use "newvalue" as return, it report a type mismatch error:

error: java.lang.AssertionError: assertion failed: Can't convert from UNIT to REF(class BoxedUnit) in unit hello.scala at source-/Users/shiyu/Scala/FinalDataFlow/src/print/hello.scala,line-347,offset=13999

But my code below works under other cases. In the code "d" is DefDef AST node of a function definition, "a" is the Apply AST node of the tail function call at the end of "d", and "b" is the right hand side Block of "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))
user5279007
  • 255
  • 2
  • 6