Skip to content

Commit

Permalink
Use prepended origin for visibility calculations.
Browse files Browse the repository at this point in the history
This fixes issues in the ActiveRecord suite with "load_records"
could not be found. That method lived in ActiveRecord::Relation
module. The root cause of this problem is still a bit unclear,
but basically we end up with visibility check trying to compare
the prepended version of Relation with a non-prepended version. I
have been unable to reproduce it without Rails, though.

Say the original Relation module is X. All methods in X know they
live in X. When a new module Y gets prepended into X, X's methods
must be relocated to a new PrependedModule entry added above the
old X in the hierarchy, and their "implementationClass" used for
superclass calculation gets set to the new PrependedModule.

If we use the implementationClass to calculate visibility, we now
have a problem; walking a hierarchy will only find the old X (now
the faux prepend base of all X's), while implementationClass will
point at the PrependedModule shim. By using the PrependedModule's
origin here, we continue to do visibility comparisons against the
original X object rather than against the prepended shim.
  • Loading branch information
headius committed Nov 5, 2016
1 parent 6a436e9 commit 9eaa1bd
Showing 1 changed file with 3 additions and 0 deletions.
Expand Up @@ -33,6 +33,7 @@
import java.lang.reflect.Method;
import java.util.Arrays;
import org.jruby.MetaClass;
import org.jruby.PrependedModule;
import org.jruby.RubyModule;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
Expand Down Expand Up @@ -281,6 +282,8 @@ protected static RubyModule calculateProtectedClass(RubyModule cls) {
// For visibility we need real meta class and not anonymous one from class << self
if (cls instanceof MetaClass) cls = ((MetaClass) cls).getRealClass();

if (cls instanceof PrependedModule) cls = ((PrependedModule) cls).getNonIncludedClass();

return cls;
}

Expand Down

0 comments on commit 9eaa1bd

Please sign in to comment.