Skip to content

Instantly share code, notes, and snippets.

@travisbrown
Created December 10, 2012 10:55
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save travisbrown/4249936 to your computer and use it in GitHub Desktop.
Save travisbrown/4249936 to your computer and use it in GitHub Desktop.
Instantiating a trait with a type member in a macro
/** Instantiating a trait with a type member in a macro.
*
* Complete working example by Travis Brown for this Stack Overflow question:
* http://stackoverflow.com/q/13795490/334519
*/
import scala.language.existentials
import scala.language.experimental.macros
trait TypeBuilder { type fieldType }
object TypeMemberExample {
import scala.reflect.macros.Context
def builderWithType[T]: TypeBuilder = macro builderWithType_impl[T]
def builderWithType_impl[T: c.WeakTypeTag](c: Context) = {
import c.universe._
val fieldMemberType: Type = c.weakTypeOf[T]
val anon = newTypeName(c.fresh)
c.Expr(
Block(
ClassDef(
Modifiers(Flag.FINAL),
anon,
Nil,
Template(
Ident(newTypeName("TypeBuilder")) :: Nil,
emptyValDef,
List(
constructor(c),
TypeDef(
Modifiers(),
newTypeName("fieldType"),
Nil,
TypeTree(fieldMemberType)
)
)
)
),
Apply(Select(New(Ident(anon)), nme.CONSTRUCTOR), Nil)
)
)
}
def constructor(c: Context) = {
import c.universe._
DefDef(
Modifiers(),
nme.CONSTRUCTOR,
Nil,
Nil :: Nil,
TypeTree(),
Block(
Apply(
Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR),
Nil
)
)
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment