Last active
January 28, 2016 07:41
-
-
Save squito/7094987 to your computer and use it in GitHub Desktop.
code samples to go along w/ a blog post on macros
imranrashid.com/posts/learning-scala-macros/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val addedTrait = Select(Select(Select( | |
Select(Ident(newTermName("com")), newTermName("imranrashid")), | |
newTermName("oleander")),newTermName("macros")), | |
newTypeName("SimpleTrait")) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait SimpleTrait { | |
def x: Int | |
def y: Float | |
} | |
@FillTraitDefs class Foo extends SimpleTrait {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait SomeData { | |
def x: Int | |
def y: Float | |
def z: Float | |
} | |
trait OtherData { | |
def a: Float | |
def b: Int | |
} | |
@ByteBufferBacked(classOf[SomeData]) class SomeDataImpl | |
@ByteBufferBacked(classOf[OtherData]) class OtherDataImpl |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class FillTraitDefs extends StaticAnnotation { | |
def macroTransform(annottees: Any*) = macro SimpleTraitImpl.addDefs | |
} | |
object SimpleTraitImpl { | |
def addDefs(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { | |
import c.universe._ | |
val inputs = annottees.map(_.tree).toList | |
val newDefDefs = List( | |
DefDef(Modifiers(), newTermName("x"), List(), List(), TypeTree(), Literal(Constant(5))), | |
DefDef(Modifiers(), newTermName("y"), List(), List(), TypeTree(), Literal(Constant(7.0f))) | |
) | |
val modDefs = inputs map {tree => tree match { | |
case ClassDef(mods, name, something, template) => | |
val q = template match { | |
case Template(superMaybe, emptyValDef, defs) => | |
Template(superMaybe, emptyValDef, defs ++ newDefDefs) | |
case y => | |
y | |
} | |
ClassDef(mods, name, something, q) | |
case x => | |
x | |
}} | |
val result = c.Expr(Block(modDefs, Literal(Constant()))) | |
result | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class B(bb: ByteBuffer) extends A { | |
def x = bb.getInt(0) | |
def y = bb.getFloat(4) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val classdef = q"""class Foo extends A with B with C {}""" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val q"class $cname extends $parent with ..$traits { ..$body }" = classdef |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
scala> q"def x = 5" | |
res3: reflect.runtime.universe.DefDef = def x = 5 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val q"class $ignore extends $addedType" = | |
q"class Foo extends com.imranrashid.oleander.macros.SimpleTrait" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import language.experimental.macros | |
import reflect.macros.Context | |
import scala.annotation.StaticAnnotation | |
import scala.reflect.runtime.{universe => ru} | |
import ru._ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
scala> ru.showRaw{ru.reify{def x = 5}} | |
res11: String = Expr(Block(List(DefDef(Modifiers(), newTermName("x"), List(), List(), TypeTree(), Literal(Constant(5)))), Literal(Constant(())))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val newDefDefs = reify { | |
def x = 5 | |
def y = 7.0f | |
}.tree match { case Block(defs, _) => defs} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import language.experimental.macros | |
import reflect.macros.Context | |
import scala.annotation.StaticAnnotation | |
import scala.reflect.runtime.{universe => ru} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// AST of defining a val | |
scala> ru.showRaw{ru.reify{val x = 5}} | |
res1: String = Expr(Block(List(ValDef(Modifiers(), newTermName("x"), TypeTree(), Literal(Constant(5)))), Literal(Constant(())))) | |
// AST for defining a class | |
scala> ru.showRaw{ru.reify{class B}} | |
res2: String = Expr(Block(List(ClassDef(Modifiers(), newTypeName("B"), List(), Template(List(Ident(newTypeName("AnyRef"))), emptyValDef, List(DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(())))))))), Literal(Constant(())))) | |
// AST for defining a class with a templated parent -- but showRaw is wrong here! | |
scala> ru.showRaw{ru.reify{class B extends collection.mutable.Seq[String]}} | |
res7: String = Expr(Block(List(ClassDef(Modifiers(), newTypeName("B"), List(), Template(List(AppliedTypeTree(Ident(scala.collection.mutable.Seq), List(Select(Ident(scala.Predef), newTypeName("String"))))), emptyValDef, List(DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(())))))))), Literal(Constant(())))) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait A { | |
def x: Int | |
def y: Float | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment