我正在尝试在 Scala 编译器插件中生成一个类。我有一个 trait Test,需要一个 TestWrapper 类,大致如下:
class TestWrapper(wrapped: Test) extends Test { ... }
我这样定义构造函数参数:
val pName = newTermName("wrapped")
val paramSym = myNewClass.newValueParameter(owner.pos.focus, pName)
paramSym.setInfo(wrapped.tpe).setFlag(SYNTHETIC)
val param = ValDef(paramSym)
以及后来的 ClassDef:
ClassDef(myNewClass, NoMods, List(List(param)), List(Nil),
members, owner.pos)
它接收参数。目前,我得到的是:
// Scala source: Test.scala
[[syntax trees at end of generatewrappers]]
package test {
<synthetic> class TestWrapper extends Object with test.Test {
<synthetic> val wrapped: test.Test = _;
def this(wrapped: test.Test): test.TestWrapper = {
TestWrapper.super.this();
()
};
<synthetic> def m3: Int = TestWrapper.this.wrapped.m3;
};
编译器似乎会自动生成一个与参数同名的字段。我没有看到从参数到字段的分配,但我认为它是“隐式的”。我可以用一个具体的 Test 实例来实例化这个 TestWrapper,但是调用 m3 会导致异常:
java.lang.NoSuchFieldError: wrapped
at test.TestWrapper.m3(Test.scala:1)
...
“包装”实际上应该是 3 个不同的东西:
1) A constructor parameter
2) An class instance field
3) A getter for the class instance field
毕竟编译器的输出显示有一个字段:
<synthetic> val wrapped: test.Test = _;
并且它是定义的,因为“= _”,而不是未定义,当没有“= ...”时
那么,我错过了什么?