scala - 为方法的参数范围提取 ClassSymbols
问题描述
我正在尝试为ClassSymbol
方法的所有类型参数的边界提取 s。
我想出的“解决方案”:
宏注解实现:
@compileTimeOnly("Compile-time only annotation")
class classSyms extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro impl
}
object classSyms {
def impl(c: whitebox.Context)(annottees: c.Tree*) = {
import c.universe._
annottees.toList foreach {
case q"$mods def $templatename[..$typeparams](...$paramss): $tpt = $body" =>
typeparams foreach {
case q"$mods type $name[..$tparams] >: $low <: $high" =>
if (!high.isEmpty) {
//requires FQCN, does not work with imported names
val classSymbol = c.mirror.staticClass(high.toString)
println(classSymbol)
}
}
}
q"..$annottees"
}
}
示例:
package pack.age
trait Test
package another.pack.age
import pack.age._
trait Bar{
@classSyms
def foo[M <: pack.age.Test, T](): Unit //works ok
@classSyms
def baz[M <: Test, T](): Unit //throws scala.ScalaReflectionException: class Test not found.
}
问题在于,将完全限定的类名指定为参数绑定的要求并没有使这个宏实现非常有用(没有人想写这么长的 fqcn 东西,尤其是在名称被导入的情况下)。
ClassSymbol
是否可以通过导入的名称提取?
解决方案
尝试使用c.typecheck
.
代替
val classSymbol = c.mirror.staticClass(high.toString)
和
val classSymbol = c.typecheck(tq"$high", mode = c.TYPEmode).symbol.asClass
推荐阅读
- c# - 尝试分配一个数字并使其递增,但还要保存程序关闭后使用的最后一个数字
- asynchronous - Dart 编程语言的异步功能无法正常工作
- key - 在 GAE 上的 NDB 上自动生成的密钥 ID
- node.js - 导出未命名的模块
- c# - SmtpCommandException:无效的发件人地址 -
- awk - 使用 sed 或 awk 进行计数、groupby
- node.js - Bcrypts 比较和验证功能验证任何密码
- android - 如何在android中使图像中的某些区域可点击
- c# - 在 appSettings.json 中配置 System.Runtime.Caching
- spring - 如何通过 XML 配置在 Task Executor 中设置 Task Decorator?