Repository navigation
Code generation for Generic Type wrong #1402
Description
Activity
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 theTypeMirrorin 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?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.I mean, if the bean is a singleton, it can have only one instance, so it can have only one T across the app.
@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); }
Sorry, code to complex to get the idea without a context ))
OK, i will create a PR soon.
Oh, I see. Looks like there is a problem with resolving generic, that are not directly defined, e.g. in the extending class
Please, don't rush with PR, look at my comments first. There is nothing you can do with singletons.
Actually, the same problem is here inside a non-generic bean.
Oh, you are talking about handling '''@restservice''', aren't you? But in the case of trivial beans, we can use existing helpers, right?
There are two helpers here:
typeMirrorToJClass: we cannot get theTypeMirrorbecause the type does not exist yet
generifyStaticHelper:JClassis notJGenerifiableSo we should add that narrow solution which i proposed.
I mean the problem arises with a code like this:
@RestService HrRestClient<ConcreteObject> restClient;
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.
The generated
GenericClient_does not exist at the time of annotation processing, so we cannot use itsTypeMirror.@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.
@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).
@WonderCsabo, don't you think, that @gnuhel still should remove a singleton scope?
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.
@Artyomcool @WonderCsabo
So it is a bug? Can I expect a fix soon?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.
Cool thank you
Fixed.
I have this annotated class
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_);