You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
BasicAnnotationProcessor does not recursively validate superclasses / superinterfaces #660
BasicAnnotationProcessor only validates immediate superclass and superinterfaces. This commit demonstrates the behavior. The first test passes, but the second fails. It's possible to update SuperficialValidation to recursively validate superclasses and superinterfaces. Is this something that BasicAnnotationProcessor should support?
We can add validateElement(t.asElement()) to TYPE_VALIDATING_VISITOR.visitDeclared to recursively validate superclasses, but this would introduce a cycle. To prevent an infinite loop, we can break the cycle by:
a) Maintaining a set of visited elements. Sounds like it could work, but it would be a bit of refactoring.
b) Removing validateType from isValidBaseElement. However, this doesn't actually break the cycle (ie: ClassA self() { return this; } would loop infinitely) so I don't think this would help.
Update ELEMENT_VALIDATING_VISITOR.visitType to call validateElement for each superclass and superinterface. This does not introduce a cycle like (1) since a class or interface cannot extend/implement itself.
@eamonnmcmanus would love to get your thoughts on here. We just had another person report a similar issue in Dagger that appears to be a manifestation of this bug.
Certainly the second approach (just iterate up the hierarchy) is easier to understand and less susceptible to infinite recursion. I would include a test where a class does extend itself, since we're talking about detecting incorrect code here. Probably such a class would never even reach the annotation processing stage, but I'm not sure.
It's possible for a class or interface to inherit from the same interface along more than one path, but it's probably not worth handling that specially since at worst we would just make the same checks more than once.
(Incidentally I'm not particularly expert on this code. AutoValue doesn't use it, because as I recall it doesn't interact well with the round-deferment we do in order to handle references to classes that have not yet been generated but will be.)
Activity
ronshapiro commentedon Aug 23, 2018
I'm not positive, but I think here:
auto/common/src/main/java/com/google/auto/common/SuperficialValidation.java
Line 135 in 9cc04ec
If we also check
validateElement(t.asElement()), I think that should do the full type-hierarchy checking you're looking for.Leland-Takamine commentedon Aug 23, 2018
That's what I was initially thinking as well. The problem is that this will result in a cycle since
isValidBaseElementdoes the inverse:ronshapiro commentedon Aug 23, 2018
It's possible we need to pass some state around for previously visited elements/types. Or we can change isValidBaseElement?
Leland-Takamine commentedon Aug 23, 2018
So to clarify some options:
validateElement(t.asElement())toTYPE_VALIDATING_VISITOR.visitDeclaredto recursively validate superclasses, but this would introduce a cycle. To prevent an infinite loop, we can break the cycle by:a) Maintaining a set of visited elements. Sounds like it could work, but it would be a bit of refactoring.
b) Removing
validateTypefromisValidBaseElement. However, this doesn't actually break the cycle (ie:ClassA self() { return this; }would loop infinitely) so I don't think this would help.ELEMENT_VALIDATING_VISITOR.visitTypeto callvalidateElementfor each superclass and superinterface. This does not introduce a cycle like (1) since a class or interface cannot extend/implement itself.ronshapiro commentedon Nov 1, 2018
@eamonnmcmanus would love to get your thoughts on here. We just had another person report a similar issue in Dagger that appears to be a manifestation of this bug.
ronshapiro commentedon Nov 1, 2018
@Leland-Takamine I tried option 2, but that is also stack-overflowing. Hrm.
eamonnmcmanus commentedon Nov 1, 2018
Certainly the second approach (just iterate up the hierarchy) is easier to understand and less susceptible to infinite recursion. I would include a test where a class does extend itself, since we're talking about detecting incorrect code here. Probably such a class would never even reach the annotation processing stage, but I'm not sure.
It's possible for a class or interface to inherit from the same interface along more than one path, but it's probably not worth handling that specially since at worst we would just make the same checks more than once.
(Incidentally I'm not particularly expert on this code. AutoValue doesn't use it, because as I recall it doesn't interact well with the round-deferment we do in order to handle references to classes that have not yet been generated but will be.)
Leland-Takamine commentedon Nov 13, 2018
@ronshapiro That's surprising - would you mind pushing up a branch with those changes?
Leland-Takamine commentedon May 14, 2019
@eamonnmcmanus @ronshapiro Pushed a PR up - let me know what you think.
TonyTangAndroid commentedon Sep 20, 2021
Is there any plan on how we are to proceed from here? Been keeping on an eye on this issue for a while now.