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

Resolve call targets like Reflection API #722

Merged
merged 3 commits into from
Dec 6, 2021

Conversation

codecholeric
Copy link
Collaborator

Instead of having a complicated JavaMethodCallTarget.resolve() API that returns a Set<JavaMethod> we can follow the same logic as the Reflection API, which always offers one Method matching a certain signature. This should make the vast majority of cases a lot simpler, and for diamond scenarios we are following an established precedence logic. Thus, the argument why method x is chosen in a specific case is a lot simpler ("we just follow the established precedence of the Java Reflection API").

Note that this also fixes a bug in the field resolution logic. Earlier accesses of constants in interfaces of parent classes were not resolved correctly (i.e. if we find a field in an interface it should have precedence).

By mapping the `types` to `rawTypes` we would hide any wrong assumptions that this should always be in sync. I think we should rather find out, if this is the case. Also, meanwhile I found cases, where the `rawTypes` and `types` don't even match 1-2-1 (e.g. generically typed private inner class constructor). So I think it is better to keep exactly what we import from the bytecode and analyze it, if we run into strange cases.

Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
Originally I assumed the order of the interfaces would always be irrelevant for typical architecture tests. However for certain aspects it actually is relevant, e.g. when determining which method a method call should resolve to. Guava's `ImmutableSet` preserves the order, so we do not need to break the API (and in this case a `Set` that keeps the order is equivalent to a `List` since no element can appear more than once anyway).

Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
Instead of having a complicated `JavaMethodCallTarget.resolve()` API that returns a `Set<JavaMethod>` we can follow the same logic as the Reflection API, which always offers one `Method` matching a certain signature. This should make the vast majority of cases a lot simpler, and for diamond scenarios we are following an established precedence logic. Thus, the argument why method x is chosen in a specific case is a lot simpler ("we just follow the established precedence of the Java Reflection API").

Note that this also fixes a bug in the field resolution logic. Earlier accesses of constants in interfaces of parent classes were not resolved correctly (i.e. if we find a field in an interface it should have precedence).

Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
@codecholeric codecholeric force-pushed the resolve-call-targets-like-Reflection-API branch from 4e5a726 to 4c2144d Compare November 29, 2021 07:42
@codecholeric codecholeric merged commit 9958701 into main Dec 6, 2021
@codecholeric codecholeric deleted the resolve-call-targets-like-Reflection-API branch December 6, 2021 05:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants