Определить параметр конструктора для синтетического класса в плагине компилятора Scala? - PullRequest
3 голосов
/ 23 октября 2011

Я пытаюсь создать класс в плагине компилятора 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 = _;

и что оно определено из-за "= _", в отличие от неопределенного, когда нет "= ..."

Итак, что мне не хватает?

1 Ответ

2 голосов
/ 24 октября 2011

Понял.Мне нужно было добавить следующую строку:

myNewClass.info.decls.enter(paramSym)

Дух!

...