Skip to content
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

Recursive supertype and superinterface validation #733

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Leland-Takamine
Copy link

Fixes #660

This change adds recursive validation for supertypes and superinterfaces to SuperficialValidation.

@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here (e.g. I signed it!) and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@Leland-Takamine
Copy link
Author

I signed it!

@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

@ronshapiro
Copy link
Contributor

I'll try to run this through google-wide presubmit to check if anything breaks.

return isValidBaseElement(e)
&& validateElements(e.getTypeParameters())
&& validateTypes(e.getInterfaces())
&& validateType(e.getSuperclass());
&& validateType(superclass)
&& e.getInterfaces().stream().map(MoreTypes::asElement).allMatch(SuperficialValidation::validateElement)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want, e -> validateElement(e) is a little shorter than the method reference

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would prefer to leave as is - e conflicts with the existing method parameter and the IDE produces a warning with the lambda.

@ronshapiro
Copy link
Contributor

ronshapiro commented May 16, 2019

Unfortunately this is introducing some cycles. Here's a repro:

@Component
class Foo extends java.lang.ref.Reference {}

Looks like there's a cycle between java.lang.ref.Reference and java.lang.ref.ReferenceQueue.

I'm going to think more, but I think we may want to use something like com.google.common.graph.Traverser instead so that we can ensure we never infinitely recur.

When I ran this through google's global tests, the test framework failed it's smoke tests with a 50% failure rate. Seems like enough things refer to java.lang.Thread that in turn refers to Reference. So it wouldn't even run more than a few hundred tests

@Leland-Takamine
Copy link
Author

@ronshapiro Would it be sufficient to just keep track of visited Elements and skip those we've already seen?

@ronshapiro
Copy link
Contributor

We could try that. I think passing those around may be icky, so that's why I suggested Traverser, which can handle that for us. It abstracts "given this isntance, these are the other things that need to be checked" from "check this individual thing".

@Leland-Takamine
Copy link
Author

Wouldn't we need to handle cycles manually when building to graph in order to leverage Traverser?

@Leland-Takamine
Copy link
Author

Wouldn't we need to handle cycles manually when building to graph in order to leverage Traverser?

Ah never mind - I see now that Traverser.forGraph accepts a function not a graph.

@Leland-Takamine
Copy link
Author

Updated to handle cycles by keeping track of visited Elements at the instance level. This requires making all internal logic non-static. Public static API is unchanged.

@Leland-Takamine
Copy link
Author

@ronshapiro Mind taking another look?

@ronshapiro
Copy link
Contributor

I'll send this through our tests again and report back

@ronshapiro
Copy link
Contributor

I'm seeing a few cases of this come up now:

java.lang.IllegalArgumentException: <nulltype> cannot be represented as a Class<?>.

From within

SuperficialValidation$3.defaultAction

@Leland-Takamine
Copy link
Author

@ronshapiro Are you able to track down which tests are failing? I'd like to figure out a repro case so I can write a test for that.

@ronshapiro
Copy link
Contributor

ronshapiro commented May 23, 2019 via email

@Leland-Takamine
Copy link
Author

@ronshapiro I've taken a look at the code but I'm still unclear on how we'd be visiting a null type. It would be really helpful to see the failing tests to help debug.

@Leland-Takamine
Copy link
Author

Ping on this :)

@raghsriniv raghsriniv added P3 type=enhancement Make an existing feature better labels Oct 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes P3 type=enhancement Make an existing feature better
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BasicAnnotationProcessor does not recursively validate superclasses / superinterfaces
4 participants