0

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

cedric
  • 351
  • 4
  • 13
  • Where is the expanded `type` and `def` supposed to live? There's no way that I know of that allows you to annotate a class member (other than a constructor parameter) and change the structure of the actual class itself. The way I've worked around this was using a annotation to mark the inner entity (your case class), and a macro annotation on the parent object/class to do the expansion for the children that are marked with the first annotation. Similar in concept to: http://stackoverflow.com/questions/33279472/use-scala-macros-to-generate-methods/33294530#33294530 – Michael Zajac Nov 14 '15 at 14:50
  • good question! They should be included inside a trait or something, but I agree that this context is not known to the local macro annotation. However I do not want to add a macro annotation on the enclosing class as I do not want this behavior to be applied to all my case classes inside the given trait... – cedric Nov 16 '15 at 18:54
  • It doesn't have to apply to all case classes within the trait, just the ones with the second marker annotation. It's not ideal, but an idea. – Michael Zajac Nov 16 '15 at 22:25

0 Answers0