phax / jcodemodel

A heavily extended fork of the com.sun.codemodel (from 2013/09)
Other
93 stars 34 forks source link

Double imports and bad generics when using anonymous inner classes #31

Closed wbrusch closed 8 years ago

wbrusch commented 8 years ago

I have a code generation need where I have an abstract outer class instance with generics that needs to add an instance of the inner class within the anonymous class definition

in codemodel i defined what I was doing with:

AbstractJClass jtype = generator.ref(String.class);
AbstractJClass aspect = generator.ref(ValueHolderInstanceImpl.class);
AbstractJClass abstractFieldClass = generator.ref(AbstractFieldInstanceImpl.class).narrow(jtype);
JDefinedClass basefield = generator.anonymousClass(abstractFieldClass);
JFieldVar apectfield = basefield.field(JMod.PRIVATE, aspect, "_valueHolder_");
JMethod initfield = basefield.method(JMod.PROTECTED, generator.VOID, "_initialize_");
initfield.body().assign(apectfield,JExpr._new(aspect).arg(jtype.dotclass()).arg(JExpr._null()));

The output is:

package impl;

import impl.AbstractFieldInstanceImpl;
import impl.AbstractFieldInstanceImpl;
import impl.ClassInstanceImpl;

public class TestClass1Impl
    extends ClassInstanceImpl
{
    private AbstractFieldInstanceImpl<String>_testField_ = new AbstractFieldInstanceImpl<String>("testField", 0, null) {
        private AbstractFieldInstanceImpl.ValueHolderInstanceImpl _valueHolder_;
        protected void _initialize_() {
            _valueHolder_ = new AbstractFieldInstanceImpl.ValueHolderInstanceImpl(String.class, null);
        }
            //.... more stuff ....
    }
    ;
}

so there are two general issues here:

  1. The generics on of AbstractFieldInstanceImpl.ValueHolderInstanceImpl ie AbstractFieldInstanceImpl<String>.ValueHolderInstanceImpl are getting dropped in the definition above. While I this probably has no code impact, it looks really bad and I would rather not add a @SuppressWarnings({ "rawtypes" }) annotation to remove the warning on the field and another @SuppressWarnings({ "unchecked", "rawtypes" }) on the initialization method. Ideally it should generate too:
    private AbstractFieldInstanceImpl<String>_testField_ = new AbstractFieldInstanceImpl<String>("testField", 0, null) {
        private ValueHolderInstanceImpl _valueHolder_;
        protected void _initialize_() {
            _valueHolder_ = new ValueHolderInstanceImpl(String.class, null);
        }
            //.... more stuff ....
    }
    ;
  1. it is adding two imports of the AbstractFieldInstanceImpl I assume that if I generated another generic subtype it would add another import per subtype.

While all of these are inconsequential and I could fix it all with a second pass generator really quickly it seems that you are actively working on this project and may wish to fix this.

Thanks

phax commented 8 years ago

Thanks for the report - I will take care of it, but at the moment I can't find the time. Please have a little patience :smile:

WonderCsabo commented 8 years ago

@phax actually we also saw this with AndroidAnnotations (the repeated imports), but because of no harm for the compiled code, i forgot to report it. It was before you reworked the imports of classes after my other issues, so it is not a regression because of that.

phax commented 8 years ago

Double imports are fixed now. Was because of the narrowed classes

phax commented 8 years ago

I can't find a solution because than the emitting of a type would depend on the context in which it is emitted. I can suggest the following work around:

    final AbstractJClass aspect = generator.directClass (ValueHolderInstanceImpl.class.getSimpleName ());

Not nice but produces the correct result.