3

Scala コンパイラ プラグインでクラスを生成しようとしています。トレイト 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;
  };

コンパイラは、パラメーターと同じ名前のフィールドを自動的に生成しているようです。パラメーターからフィールドへの割り当てはわかりませんが、それは「暗黙的」であると想定していました。この TestWrapper を Test の具体的なインスタンスでインスタンス化することはできますが、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 = _;

「= ...」がない場合、未定義とは対照的に、「= _」のために定義されていること

それで、私は何が欠けていますか?

4

1 に答える 1

2

とった。次の行を追加する必要がありました。

myNewClass.info.decls.enter(paramSym)

当たり前!

于 2011-10-24T09:40:38.510 に答える