I'm trying to generate a class in a Scala compiler Plugin. I have a trait Test, and need a class TestWrapper, approximately like this:
class TestWrapper(wrapped: Test) extends Test { ... }
I define the constructor parameter like this:
val pName = newTermName("wrapped")
val paramSym = myNewClass.newValueParameter(owner.pos.focus, pName)
paramSym.setInfo(wrapped.tpe).setFlag(SYNTHETIC)
val param = ValDef(paramSym)
and later the ClassDef:
ClassDef(myNewClass, NoMods, List(List(param)), List(Nil),
members, owner.pos)
which receives the parameter. Currently, what I get is:
// 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;
};
The compiler seems to be automatically generating a field with the same name as the parameter. What I don't see is the assignment from the parameter to the field, but I had assumed it was "implicit". I can than instantiate this TestWrapper with a concrete instance of Test, but calling m3 causes an Exception:
java.lang.NoSuchFieldError: wrapped
at test.TestWrapper.m3(Test.scala:1)
...
"wrapped" should in fact be 3 different things:
1) A constructor parameter
2) An class instance field
3) A getter for the class instance field
The output of the compiler shows after all that there is a field:
<synthetic> val wrapped: test.Test = _;
and that it is defined, because of the "= _", as opposed to undefined, when there is no "= ..."
So, what am I missing?
Got it. I needed to add the following line:
Duh!