如何防止 StaticAnnotation 中的类型检查?
How to prevent typecheck in StaticAnnotation?
我正在创建一些宏库,这些宏库从 enclosing
方法的注释中读取一些信息。
@info(foo(bar, baz))
def enclosing() = {
myMacro()
}
这些信息在StaticAnnotation
@info
中编码为foo(bar, baz)
。
foo(bar, baz)
包含myMacro
需要的信息,但是foo(bar, baz)
无法在@info
位置进行类型检查,导致类型检查时出现编译错误foo(bar, baz)
.
我想知道我是否可以创建一个宏 dontTypecheck
来防止 foo(bar, baz)
被类型检查。这样我就可以创建类似的东西:
@info(dontTypecheck {
foo(bar, baz)
})
def enclosing() = {
myMacro()
}
dontTypecheck
宏应该生成一个 Tree
,其中包含未经类型检查的 foo(bar, baz)
。
如何创建 dontTypecheck
宏?
一个想法是使用另一个注释保存信息
class Info[T](t: T) extends scala.annotation.StaticAnnotation {
}
class AnnInfo extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro AnnInfImpl.impl
}
trait AnnotationUtils {
val c: scala.reflect.macros.blackbox.Context
import c.universe._
final def getAnnotation(x: MemberDef) = x.mods.annotations
}
class AnnInfImpl(val c: blackbox.Context) extends AnnotationUtils {
import c.universe._
// edit 1
def impl(annottees: Tree*): Tree = {
annottees.head match {
case x: DefDef =>
// collect value from `@Info(value)`
val info: List[Tree] = getAnnotation(x).collect { case q"new $name ($value)" => value }
val newBody =
q"""
{
val info = ${info.map(e => show(e))}
println(info)// just print it
${x.rhs}
}"""
DefDef(
mods = Modifiers(), //dropMods
name = x.name,
tparams = x.tparams,
vparamss = x.vparamss,
tpt = x.tpt,
rhs = newBody
)
}
}
}
// 测试
class AnnInfoTest {
val a = 1
val b = 2
def f(a: Int, b: Int) = a + b
@Info(f(a, b))
@AnnInfo
def e = ???
}
如果你调用 e
将打印 List(f(a, b))
我正在创建一些宏库,这些宏库从 enclosing
方法的注释中读取一些信息。
@info(foo(bar, baz))
def enclosing() = {
myMacro()
}
这些信息在StaticAnnotation
@info
中编码为foo(bar, baz)
。
foo(bar, baz)
包含myMacro
需要的信息,但是foo(bar, baz)
无法在@info
位置进行类型检查,导致类型检查时出现编译错误foo(bar, baz)
.
我想知道我是否可以创建一个宏 dontTypecheck
来防止 foo(bar, baz)
被类型检查。这样我就可以创建类似的东西:
@info(dontTypecheck {
foo(bar, baz)
})
def enclosing() = {
myMacro()
}
dontTypecheck
宏应该生成一个 Tree
,其中包含未经类型检查的 foo(bar, baz)
。
如何创建 dontTypecheck
宏?
一个想法是使用另一个注释保存信息
class Info[T](t: T) extends scala.annotation.StaticAnnotation {
}
class AnnInfo extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro AnnInfImpl.impl
}
trait AnnotationUtils {
val c: scala.reflect.macros.blackbox.Context
import c.universe._
final def getAnnotation(x: MemberDef) = x.mods.annotations
}
class AnnInfImpl(val c: blackbox.Context) extends AnnotationUtils {
import c.universe._
// edit 1
def impl(annottees: Tree*): Tree = {
annottees.head match {
case x: DefDef =>
// collect value from `@Info(value)`
val info: List[Tree] = getAnnotation(x).collect { case q"new $name ($value)" => value }
val newBody =
q"""
{
val info = ${info.map(e => show(e))}
println(info)// just print it
${x.rhs}
}"""
DefDef(
mods = Modifiers(), //dropMods
name = x.name,
tparams = x.tparams,
vparamss = x.vparamss,
tpt = x.tpt,
rhs = newBody
)
}
}
}
// 测试
class AnnInfoTest {
val a = 1
val b = 2
def f(a: Int, b: Int) = a + b
@Info(f(a, b))
@AnnInfo
def e = ???
}
如果你调用 e
将打印 List(f(a, b))