I created a macro annotation to be used together with another macro to transform case classes into records with dynamic, typed method dispatching.
https://github.com/DeliteEPFL/virtualization-lms-core/blob/macrovirt/src/common/RecordsAnnot.scala
trait T {
@mRecord
case class Region(key: Int)
}
will be transformed into
trait T {
type Region = Record {
val r_regionkey: Rep[Int]
}
def Region(key: Rep[Int], name: Rep[String], comment: Rep[String]): Rep[Region] =
Record (r_regionkey = key) //another macro, but does not really matter
}
The problem is that those are 2 definitions which have to be put in the place of one which I didn't manage to do. When you do:
q"$typedef ; $metdef"
you will end up with a Block()
and thus the definitions are local, the workaround I do right now is:
q"object O {$typedef ; $metdef}"
and then
@mRecord
case class Region(key: Int)
import O._
which is not the cleanest as you need unique object names, the IDE will highlight O._
as non existent and other issues.
splicing only works if you known the surrounding context, which is not the case for macro annotations...
val body = q"$typedef ; $metdef"
q"""trait T { $body }""" //created a block inside the body
q"""trait T { ..$body }""" //this will lift the block and add the defintions to the body directly
Thanks for any pointer. Cedric