public
Last active

Simple macro-based wrapper example

  • Download Gist
wrapper.scala
Scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
import scala.language.experimental.macros
import scala.reflect.macros.Context
 
object WrapperExample {
def wrap[A](a: A): A = macro wrap_impl[A]
 
def wrap_impl[A: c.WeakTypeTag](c: Context)(a: c.Expr[A]) = {
import c.universe._
 
val wrapped = weakTypeOf[A]
val f = Select(reify(Predef).tree, "println")
 
val methods = wrapped.declarations.collect {
case m: MethodSymbol if !m.isConstructor => DefDef(
Modifiers(Flag.OVERRIDE),
m.name,
Nil, Nil,
TypeTree(),
Block(
Apply(f, c.literal("Calling: " + m.name.decoded).tree :: Nil),
Select(a.tree, m.name)
)
)
}.toList
 
val constructor = DefDef(
Modifiers(), nme.CONSTRUCTOR, Nil, Nil :: Nil, TypeTree(),
Block(
Apply(
Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), Nil
) :: Nil,
c.literalUnit.tree
)
)
 
val anon = c.fresh
 
c.Expr(Block(
ClassDef(Modifiers(Flag.FINAL), newTypeName(anon), Nil,
Template(
List(Ident(wrapped.typeSymbol.name)),
emptyValDef,
constructor :: methods
)
) :: Nil,
Apply(Select(New(Ident(newTypeName(anon))), nme.CONSTRUCTOR), Nil)
))
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.