在Scala编译器插件中为合成类定义构造函数参数?

时间:2011-10-23 14:26:51

标签: scala parameters constructor synthetic

我正在尝试在Scala编译器插件中生成一个类。我有一个特质测试,需要一个类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 = _;

并且它被定义,因为“= _”,而不是未定义,当没有“= ...”

那么,我错过了什么?

1 个答案:

答案 0 :(得分:2)

知道了。我需要添加以下行:

myNewClass.info.decls.enter(paramSym)

咄!