Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Andrei-Pozolotin/85a1218c2a2353890e4222d6b8eb78db to your computer and use it in GitHub Desktop.
Save Andrei-Pozolotin/85a1218c2a2353890e4222d6b8eb78db to your computer and use it in GitHub Desktop.
Macro-powered structural types
import scala.annotation.StaticAnnotation
import scala.reflect.macros.Macro
import language.experimental.macros
class body(tree: Any) extends StaticAnnotation
trait Macros extends Macro {
import c.universe._
def selFieldImpl = {
val field = c.macroApplication.symbol
val bodyAnn = field.annotations.filter(_.tpe <:< typeOf[body]).head
bodyAnn.scalaArgs.head
}
def mkObjectImpl(xs: c.Tree*) = {
val kvps = xs.toList map { case q"${_}(${Literal(Constant(name: String))}).->[${_}]($value)" => name -> value }
val fields = kvps map { case (k, v) => q"@body($v) def ${TermName(k)} = macro Macros.selFieldImpl" }
q"class Workaround { ..$fields }; new Workaround{}"
}
}
object mkObject {
def apply(xs: Any*) = macro Macros.mkObjectImpl
}
=================
object Test {
def main(args: Array[String]) = {
val foo = mkObject("x" -> "2", "y" -> 3)
println(foo.x)
println(foo.y)
// println(foo.z) => will result in a compilation error
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment