Scala 基于宏的注解复用
Scala macro-based annotation reuse
考虑一个基于 Scala 宏的注释,例如 @memoise from macmemo。注释需要两个参数:最大缓存大小和生存时间,例如,
@memoize(maxSize = 20000, expiresAfter = 2 hours)
假设您想要创建一个等同于 @memoize(maxSize = Int.MaxValue, expiresAfter = 100 days)
的 @cacheall
注释,以减少样板文件并具有单点参数化。
是否有针对此类重用的标准模式?显然,
class cacheall extends memoize(Int.MaxValue, 100 days)
由于宏中的编译时参数解析,将无法运行。
标准模式是让你的注解成为一个宏注解,被扩展时会打开带有必要参数的必要注解。
import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
class cacheall extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro cacheallMacro.impl
}
object cacheallMacro {
def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = {
import c.universe._
val memoize = q"""
new _root_.com.softwaremill.macmemo.memoize(
_root_.scala.Int.MaxValue, {
import _root_.scala.concurrent.duration._
100.days
})"""
annottees match {
case q"${mods: Modifiers} def $tname[..$tparams](...$paramss): $tpt = $expr" :: _ =>
q"${mods.mapAnnotations(memoize :: _)} def $tname[..$tparams](...$paramss): $tpt = $expr"
}
}
}
考虑一个基于 Scala 宏的注释,例如 @memoise from macmemo。注释需要两个参数:最大缓存大小和生存时间,例如,
@memoize(maxSize = 20000, expiresAfter = 2 hours)
假设您想要创建一个等同于 @memoize(maxSize = Int.MaxValue, expiresAfter = 100 days)
的 @cacheall
注释,以减少样板文件并具有单点参数化。
是否有针对此类重用的标准模式?显然,
class cacheall extends memoize(Int.MaxValue, 100 days)
由于宏中的编译时参数解析,将无法运行。
标准模式是让你的注解成为一个宏注解,被扩展时会打开带有必要参数的必要注解。
import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
class cacheall extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro cacheallMacro.impl
}
object cacheallMacro {
def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = {
import c.universe._
val memoize = q"""
new _root_.com.softwaremill.macmemo.memoize(
_root_.scala.Int.MaxValue, {
import _root_.scala.concurrent.duration._
100.days
})"""
annottees match {
case q"${mods: Modifiers} def $tname[..$tparams](...$paramss): $tpt = $expr" :: _ =>
q"${mods.mapAnnotations(memoize :: _)} def $tname[..$tparams](...$paramss): $tpt = $expr"
}
}
}