-
-
Notifications
You must be signed in to change notification settings - Fork 921
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
Allow public methods from non-public superclasses to bind #6199
Allow public methods from non-public superclasses to bind #6199
Conversation
One question I have about this... should we instead just allow all public methods from any class to bind on that class now? The reason we don't bind anything if there's no "local" method is because it expects to see the method on a superclass. However since the superclass is non-public we don't bind any of its methods. The reason we don't bind public methods from non-public classes is because they can't be invoked directly on that class. For example, there are non-public implementations of Iterator within each JDK collection class; we don't want to bind the version of the method that can't be seen, so we bind the interface method which can. |
At least one JI spec fails so there's some work to do here. |
That is something I wanted in the past. The Java classes simply have Java semantics in terms of taking a reflected method and calling it. Internal types (such as |
Well let's give it a try and see how CI shakes out. The problem I expect we'll see is when you have a non-public implementation of a public interface. Instead of only binding the interface form of the method, we'll bind the implementation that's associated with the non-public class. Since that class is not public, we can't dispatch to the implementation and things break. I've pushed the commit so we can see everything that breaks, but I think this example illustrates it:
|
Amazingly, that changed passed! But my example case still stands. Apparently we are not testing it! |
83c5a48
to
c39b3e0
Compare
6e3f06c
to
4370c49
Compare
The existing logic will never bind any methods declared on a non- public superclass, but this is incorrect behavior if the subclass is public. A public subclass will expose public methods from any superclass, regardless of the superclass's visibility, so we need to also bind those methods. There are four changes here: * Allow methods to be gathered from superclasses if the superclass is public or the target class is public. * Allow those methods to be bound even if there's no definition on the target class (no so-called "local method") * Consider methods equivalent if parent method's return type is the same or a superclass of the child method's return type. * Only replace a child method with an equivalent parent method if the parent method's class is public. This fixes jruby#6197
4370c49
to
1ba9980
Compare
An additional two changes were needed:
This fixes the additional failure calling StringBuilder methods that are also defined and public on the package-visible AbstractStringBuilder class. A method like |
Looks like this is finally green. The changes have been squashed into a single commit that describes the key four changes made here. It may still be warranted to start simply using Class#getMethods and binding everything it returns to each class, rather than doing the more complicated parent walk we do now, but I'll merge this. |
The existing logic will never bind any methods declared on a non-
public superclass, but this is incorrect behavior if the subclass
is public. A public subclass will expose public methods from any
superclass, regardless of the superclass's visibility, so we need
to also bind those methods.
There are two changes here:
target class is public.
the target class (no so-called "local method")
This fixes #6197