Skip to content

Instantly share code, notes, and snippets.

@travisbrown
Created December 7, 2012 16:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save travisbrown/4234441 to your computer and use it in GitHub Desktop.
Save travisbrown/4234441 to your computer and use it in GitHub Desktop.
Simple macro-based wrapper example
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)
))
}
}
@xeno-by
Copy link

xeno-by commented Dec 8, 2012

@xeno-by
Copy link

xeno-by commented Dec 8, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment