如何访问父 class params 文字?
How to access parent class params literals?
使用 Scala 2.x 宏,如何在定义子 classes 时访问传递给父 classes 的文字,通常使用如下 ADT:
sealed abstract class Base(val s: String, val i: Int)
object Base {
case object A extends Base("a", 1)
case object B extends Base("b", 2)
case class C(override val s: String) extends Base(s, 3)
}
对于对象 A,我想知道参数值是文字 "a"
和 1
。
对于对象 B,我想知道参数值是文字 "b"
和 2
.
对于案例 class C,我想知道第二个参数是文字 3
.
如何使用 Scala 2.x 宏完成此操作?
经过大量调查并从 bwmcadams / 中获得灵感
supreme-macro-adventure,看起来一个解决方案是基于 Macro Paradise 的组合和创建 @ADT
注释。
宏天堂 提供了一种机制来扩展 ADT 上的注释以重写它们,感谢 macroTransform
功能。
import scala.annotation.{compileTimeOnly, StaticAnnotation}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context
@compileTimeOnly("enable macro paradise to expand macro annotations")
class ADT extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro ADT.impl
}
object ADT {
def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._
val trees = annottees.map(_.tree)
val rewritten = trees match {
case (cd: ClassDef) :: q"object $name { ..$body }" :: Nil =>
$body match {
case q"case object $name extends $_($literal, $_)" :: tail =>
[...]
}
case _ =>
trees
}
c.Expr[Any](q"{..$rewritten}")
}
}
在准引号的帮助下,可以导航 $body
和模式匹配不同的情况以访问传递给父级 class(此处 $literal
)的参数。最后,一个returns重写的ADT。
使用 Scala 2.x 宏,如何在定义子 classes 时访问传递给父 classes 的文字,通常使用如下 ADT:
sealed abstract class Base(val s: String, val i: Int)
object Base {
case object A extends Base("a", 1)
case object B extends Base("b", 2)
case class C(override val s: String) extends Base(s, 3)
}
对于对象 A,我想知道参数值是文字 "a"
和 1
。
对于对象 B,我想知道参数值是文字 "b"
和 2
.
对于案例 class C,我想知道第二个参数是文字 3
.
如何使用 Scala 2.x 宏完成此操作?
经过大量调查并从 bwmcadams / 中获得灵感
supreme-macro-adventure,看起来一个解决方案是基于 Macro Paradise 的组合和创建 @ADT
注释。
宏天堂 提供了一种机制来扩展 ADT 上的注释以重写它们,感谢 macroTransform
功能。
import scala.annotation.{compileTimeOnly, StaticAnnotation}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context
@compileTimeOnly("enable macro paradise to expand macro annotations")
class ADT extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro ADT.impl
}
object ADT {
def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._
val trees = annottees.map(_.tree)
val rewritten = trees match {
case (cd: ClassDef) :: q"object $name { ..$body }" :: Nil =>
$body match {
case q"case object $name extends $_($literal, $_)" :: tail =>
[...]
}
case _ =>
trees
}
c.Expr[Any](q"{..$rewritten}")
}
}
在准引号的帮助下,可以导航 $body
和模式匹配不同的情况以访问传递给父级 class(此处 $literal
)的参数。最后,一个returns重写的ADT。