Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.
This repository was archived by the owner on Feb 26, 2023. It is now read-only.

Code generation for Generic Type wrong #1402

Description

@gnuhel

I have this annotated class

@EBean(scope = EBean.Scope.Singleton)
public class HrWebServiceTask<T> extends Task<HrRequest, HrResponse<T>> {

    @RestService
    HrRestClient<T> restClient;

    @Override
    protected HrResponse<T> run(HrRequest request) throws Exception {
        return restClient.doRequest(request);
    }
}

and it generates following code

private void init_() { restClient = new HrRestClient<T>_(context_); rootContext = context_; createTaskRegistry(); }

I get a compiler error for the code at restClient = new HrRestClient<T>_(context_);
Shouldn't it be

restClient = new HrRestClient_<T>(context_);

Activity

  1. WonderCsabo commented on May 8, 2015

    @WonderCsabo
    Member

    This is indeed a bug, thanks for reporting!

    @Artyomcool, i think we cannot solve this by just calling APTCodeModelHeper.typeMirrorToJClass(), because the generated type is not yet present, so we cannot get the TypeMirror in the first place. I think it is impossible to add type arguments to the constructor call, is it? So we just should use the raw constructor?

  2. Artyomcool commented on May 8, 2015

    @Artyomcool

    Sorry, but the code makes no sence for me. This been is a singleton, right? So, who is supposed to define the T? AA just can't do that.
    But the same problem could be faced with simple beans too. In this case we will be able to resolve a type, I think.

  3. Artyomcool commented on May 8, 2015

    @Artyomcool

    I mean, if the bean is a singleton, it can have only one instance, so it can have only one T across the app.

  4. WonderCsabo commented on May 8, 2015

    @WonderCsabo
    Member

    @Artyomcool i quickly created this, WDYT?

    TypeMirror fieldTypeMirror = element.asType();
    TypeMirror erasedFieldTypeMirror = processingEnv.getTypeUtils().erasure(fieldTypeMirror);
    String interfaceName = erasedFieldTypeMirror.toString();
    
    String generatedClassName = interfaceName + classSuffix();
    
    JClass clazz = refClass(generatedClassName);
    
    DeclaredType type = (DeclaredType) fieldTypeMirror;
    
    for (TypeMirror param : type.getTypeArguments()) {
        JClass paramClass = codeModelHelper.typeMirrorToJClass(param, holder);
        clazz = clazz.narrow(paramClass);
    }
  5. Artyomcool commented on May 8, 2015

    @Artyomcool

    Sorry, code to complex to get the idea without a context ))

  6. WonderCsabo commented on May 8, 2015

    @WonderCsabo
    Member

    OK, i will create a PR soon.

  7. Artyomcool commented on May 8, 2015

    @Artyomcool

    Oh, I see. Looks like there is a problem with resolving generic, that are not directly defined, e.g. in the extending class

  8. Artyomcool commented on May 8, 2015

    @Artyomcool

    Please, don't rush with PR, look at my comments first. There is nothing you can do with singletons.

  9. WonderCsabo commented on May 8, 2015

    @WonderCsabo
    Member

    Actually, the same problem is here inside a non-generic bean.

  10. Artyomcool commented on May 8, 2015

    @Artyomcool

    Oh, you are talking about handling '''@restservice''', aren't you? But in the case of trivial beans, we can use existing helpers, right?

  11. WonderCsabo commented on May 8, 2015

    @WonderCsabo
    Member

    There are two helpers here:

    typeMirrorToJClass: we cannot get the TypeMirror because the type does not exist yet
    generifyStaticHelper: JClass is not JGenerifiable

    So we should add that narrow solution which i proposed.

    I mean the problem arises with a code like this:

    @RestService
    HrRestClient<ConcreteObject> restClient;
  12. Artyomcool commented on May 8, 2015

    @Artyomcool

    What exactly type is not exists? There is a problem with your solution:

    @SomeComponent
    class A extends B<SomeType> { ... }
    
    class B<T> {
      @RestService
      SomeGenericField<T> field;
    }
    

    I'm not sure (i havn't reach a pc yet), but your solution shouldn't work.

  13. WonderCsabo commented on May 8, 2015

    @WonderCsabo
    Member

    The generated GenericClient_ does not exist at the time of annotation processing, so we cannot use its TypeMirror.

  14. gnuhel commented on May 8, 2015

    @gnuhel
    Author

    @Artyomcool
    you are right with Singleton. I haven't thought about it. But you can remove (scope = EBean.Scope.Singleton)

    or should I use @RestService HrRestClient_<T> restClient; instead?

    I can only try it on Monday again.

  15. WonderCsabo commented on May 8, 2015

    @WonderCsabo
    Member

    @gnuhel You are using it right. The generation has a bug, but i think i have a fix already. You should never reference the generated types only if there is no other solution (for example in manifest, or generated shared preferences).

  16. Artyomcool commented on May 8, 2015

    @Artyomcool

    @WonderCsabo, don't you think, that @gnuhel still should remove a singleton scope?

  17. WonderCsabo commented on May 8, 2015

    @WonderCsabo
    Member

    or should I use @restservice HrRestClient_ restClient; instead?

    i was responding to this question only. Yeah, the singleton scope does not make sense in this case, because nobody can substitute the type parameter.

  18. gnuhel commented on May 8, 2015

    @gnuhel
    Author

    @Artyomcool @WonderCsabo
    So it is a bug? Can I expect a fix soon?

  19. WonderCsabo commented on May 8, 2015

    @WonderCsabo
    Member

    it is a bug, as i wrote 4 hours ago and also check out the label. 😉 If you are really eager to see it, you can build this (WIP) branch. Hopefully this will be merged soon, so you can use it in a SNAPSHOT release, but i cannot see now when it will be fixed in a next stable release.

  20. gnuhel commented on May 8, 2015

    @gnuhel
    Author

    Cool thank you

  21. self-assigned this
    on Jun 9, 2015
  22. WonderCsabo commented on Jun 10, 2015

    @WonderCsabo
    Member

    Fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions