我正在尝试编写一个宏,它接受一个带有java bean接口和case类的类,并创建一对用于在它们之间进行映射的方法.
我试图检查每个属性的类型是否匹配,但java bean中的类型是例如java.lang.Long,case类中的类型是scala.Long.
我的问题是,给定这些2的c.universe.Type对象,有没有办法测试它们之间是否存在隐式转换?即测试我是否可以将一个传递给一个期望另一个的方法.
我有点被以下(宏注释)情况阻止.假设我有一个被调用的注释@factory
,它旨在为apply
相应的伴随对象中的带注释的特征生成一个方法.例如,鉴于trait A
:
@factory
trait A {
val a1: Int
}
Run Code Online (Sandbox Code Playgroud)
要生成的预期代码如下:
object A extends Factory[A] {
def apply(_a1: Int) = new A {
val a1 = _a1
}
}
Run Code Online (Sandbox Code Playgroud)
现在假设我们有一个特征B
,它继承自A
:
@factory
trait B extends A {
val b1: String
}
Run Code Online (Sandbox Code Playgroud)
这应该产生:
object B extends Factory[B] {
def apply(_a1: Int, _b1: String) = new B {
val a1 = _a1
val b1 = _b1
}
}
Run Code Online (Sandbox Code Playgroud)
在后一种情况下,我需要知道存在哪些属性A
, …
当注释的参数是常量时,我获得了成功,例如:
@Annotation(2)
class AnnotatedClass
Run Code Online (Sandbox Code Playgroud)
因为我可以通过以下方式获取宏中的值impl
:
c.prefix.tree match {
case Apply(_, List(Literal(Constant(x)))) => x.toInt
}
Run Code Online (Sandbox Code Playgroud)
但是当注释的参数不是常数时,我很难过,比如:
object Obj {val n = 2}
@Annotation(Obj.n)
class AnnotatedClass
Run Code Online (Sandbox Code Playgroud)
在假开始类似这样的问题,我可以匹配c.prefix.tree
一次拉出名称Obj
和n
,但我如何获得的价值Obj.n
?