-
-
Notifications
You must be signed in to change notification settings - Fork 353
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
review fix: Invalid use of type access generics #1454
review fix: Invalid use of type access generics #1454
Conversation
For me it looks like a SubstitutionVisitor problem: apparently it tries to substitute |
The o is in the map because there is a bug in if (getTemplateParameterType(ref.getFactory()).isSubtypeOf(ref.getType())) { which returns true on Object ... I am going to fix it too, but it was tooooo late yesterday. |
I though that too (see my branch with fix of SubstitutionVisitor), but later I found that other type access is handled correctly by pretty printer. So may be this one should be also fixed on pretty printer. |
I added PR #1461, which fixes this problem. |
d6cc5f4
to
2effdf2
Compare
After rebase it fails on new template Parameter contract "when Parameter is proxy then it's type must be a String". But how to define this template, without removing the constraint? public class TypeReferenceClassAccessTemplate extends ExtensionTemplate {
Object o;
$Type$ someMethod($Type$ param) {
o = $Type$.out;
o = $Type$.currentTimeMillis();
o = $Type$.class;
o = o instanceof $Type$;
Supplier<Long> p = $Type$::currentTimeMillis;
return new $Type$();
}
@Local
public TypeReferenceClassAccessTemplate(CtTypeReference<?> typeRef) {
this.typeRef = typeRef;
}
@Parameter("$Type$")
CtTypeReference<?> typeRef;
@Local
static class $Type$ {
static final String out = "";
static long currentTimeMillis(){
return 0;
}
}
public static class Example<T> {
static final String out = "";
static long currentTimeMillis(){
return 0;
}
}
}
So it seems to me like these new constrains introduced by @monperrus in |
@pvojtechovsky do you agree that this one could be closed now? |
I think it cannot be closed. The origin problem is different and still exists. There was conflict with template implementation. I will check how it behaves now when templates are fixed. I will let you know |
2effdf2
to
1416ee5
Compare
My comment above from 1 Aug is still relevant: the template Parameter contract "when Parameter is proxy then it's type must be a String" is too strict and avoids to implement such templates. |
So if I'm trying to sum up, here we are in a special case because what you want to use inside a parameter is not a reference to a field of the template, neither a name to rename field/methods, but a type to be able to generate automatically some codes using different types. So, we have three cases:
So, why do we need a proxy on the CtTypeReference: can't we make an exception if the type of the template parameter is a I tend to agree with you on relaxing the constraint, I just need to see an example with the usage of CtTypeReference with and without a proxy to really see how it can be used. |
See /src/test/java/spoon/test/template/testclasses/NtonCodeTemplate.java @Parameter
CtTypeReference<?> _TargetType_; |
In this case it is not possible because @Parameter
CtTypeReference<?> $Type$; will be in conflict with @Local
static class $Type$ {...} So I see no good way how to implement such template without relaxing that template parameter constraint. |
Ok I'm still trying to explain the problem, in order to be sure I fully understand its limit and to explain in documentation why there are exceptions in using template parameters: We cannot template a class name with a CtTypeReference and use it in the same time because the template wouldn't be compilable: it breaks the first rule of Spoon template which is "a template should be correctly typed and compilable". Then we have to use a proxy parameter on CtTypeReference to solve this problem. So the constraint is:
|
yes it is correct.
... and it should exists an element inside the template with the proxyname ... |
1416ee5
to
a889a8d
Compare
a889a8d
to
45304b1
Compare
I have fixed the next problem found by this PR in #1535. Now this PR finally fails on the main problem of this PR. Spoon prints actual type arguments in class access: List<Object>.class And main question of this PR: Is it problem of pretty printer or SubstitutionVisitor?
WDYT? |
45304b1
to
4b1e9d8
Compare
4b1e9d8
to
a86f75d
Compare
a86f75d
to
81313da
Compare
I have fixed that problem on DJPP side, because I believe it is it's responsibility to print correctly the sources independently on CtTypeReference has generics or not. |
it seems there are two independent fixes here: the one with forceWildcardGenerics and the ones with modifying the preconditions of ignoreGenerics. Correct? Is the bug specific to using the template engine or can it happen in a regular situation? |
yes, both are related to use of generics
it is not related to template engine. Client can came into same problems by manipulating of AST too. Anyway these problems can be fixed by two ways |
Thanks @pvojtechovsky ! |
Here is the failing test, which shows that Spoon prints actual type arguments in class access:
List<Object>.class
Is it problem of pretty printer or SubstitutionVisitor?