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