Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: d19a3c99e4cf
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 9af87db589f7
Choose a head ref
  • 5 commits
  • 14 files changed
  • 2 contributors

Commits on Nov 6, 2014

  1. Copy the full SHA
    b7910ac View commit details
  2. gross hacks

    tduehr committed Nov 6, 2014
    Copy the full SHA
    dd2ea65 View commit details
  3. one more tweak

    tduehr committed Nov 6, 2014
    Copy the full SHA
    a734f10 View commit details
  4. Copy the full SHA
    6713a8c View commit details
  5. Merge branch 'tduehr-prepend_current'

    Lands most remaining capabilities of Module#prepend.
    headius committed Nov 6, 2014
    Copy the full SHA
    9af87db View commit details
17 changes: 8 additions & 9 deletions core/src/main/java/org/jruby/IncludedModule.java
Original file line number Diff line number Diff line change
@@ -34,11 +34,6 @@ public void setMetaClass(RubyClass newRubyClass) {
throw new UnsupportedOperationException("An included class is only a wrapper for a module");
}

@Override
public void addMethod(String name, DynamicMethod method) {
throw new UnsupportedOperationException("An included class is only a wrapper for a module");
}

public void setMethods(Map newMethods) {
throw new UnsupportedOperationException("An included class is only a wrapper for a module");
}
@@ -48,12 +43,16 @@ public String getName() {
return origin.getName();
}

// XXX ??? maybe not getNonIncludedClass()
@Override
protected boolean isSame(RubyModule module) {
return origin.isSame(module.getNonIncludedClass());
public RubyModule getNonIncludedClass() {
return origin;
}


// @Override
// public RubyModule getNonPrependedClass() {
// return origin;
// }

/**
* We don't want to reveal ourselves to Ruby code, so origin this
* operation.
161 changes: 152 additions & 9 deletions core/src/main/java/org/jruby/IncludedModuleWrapper.java
Original file line number Diff line number Diff line change
@@ -33,10 +33,13 @@
package org.jruby;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.builtin.Variable;

@@ -56,6 +59,7 @@ public class IncludedModuleWrapper extends IncludedModule {
public IncludedModuleWrapper(Ruby runtime, RubyClass superClass, RubyModule origin) {
super(runtime, superClass, origin);
origin.addIncludingHierarchy(this);
if (origin.methodLocation != origin) this.methodLocation = origin.methodLocation;
}

/**
@@ -66,7 +70,7 @@ public IncludedModuleWrapper(Ruby runtime, RubyClass superClass, RubyModule orig
*/
@Override
@Deprecated
public IncludedModule newIncludeClass(RubyClass superClass) {
public IncludedModuleWrapper newIncludeClass(RubyClass superClass) {
IncludedModuleWrapper includedModule = new IncludedModuleWrapper(getRuntime(), superClass, getNonIncludedClass());

// include its parent (and in turn that module's parents)
@@ -77,29 +81,135 @@ public IncludedModule newIncludeClass(RubyClass superClass) {
return includedModule;
}

@Override
public void addMethod(String name, DynamicMethod method) {
throw new UnsupportedOperationException("An included class is only a wrapper for a module");
}

public void setMethods(Map newMethods) {
throw new UnsupportedOperationException("An included class is only a wrapper for a module");
}

public RubyModule getDelegate() {
return origin;
}

// @Override
// protected DynamicMethod searchMethodCommon(String name) {
// DynamicMethod method = null;
// RubyModule topModule = origin.getMethodLocation().getSuperClass();
//
// for(RubyModule module = origin; module != null; module = module.getSuperClass()) {
// method = module.searchMethodCommon(name);
// if (method != null) return method;
// }
//
// return null;
// }

// @Override
// public void populateInstanceMethodNames(Set<String> seen, RubyArray ary, final Visibility visibility, boolean not, boolean useSymbols, boolean includeSuper) {
// origin.populateInstanceMethodNames(seen, ary, visibility, not, useSymbols, true);
// }

@Override
public RubyModule findImplementer(RubyModule clazz) {
RubyModule retVal = null;
RubyModule topModule = origin.getMethodLocation().getSuperClass();

if (this == clazz) return this;

for (RubyModule module = origin; module != null; module = module.getSuperClass()) {
if (module.isSame(clazz.getNonIncludedClass())) {
retVal = module.getSuperClass() == null ? this : module;
break;
}

if (module.hasModuleInHierarchy(clazz)) {
retVal = module.findImplementer(clazz);
if (retVal != null) {
retVal = retVal.getSuperClass() != null ? retVal : this;
break;
}

for(RubyModule current = module.getNonIncludedClass(); current != this && current != null; current = current.getSuperClass()) {
if (current.isSame(clazz)) {
return current.getSuperClass() == null ? module : current;
}
}
break;
}
}

return retVal;
}

// @Override
// public boolean hasModuleInPrepends(RubyModule type) {
// for (RubyModule module = origin; module != null; module = module.getSuperClass()) {
// if (module.getNonIncludedClass() == type.getNonIncludedClass() || (module.isIncluded() && module.hasModuleInHierarchy(type)))
// return true;
// }
//
// return false;
// }

@Override
public boolean hasModuleInHierarchy(RubyModule type) {
for (RubyModule module = origin; module != null; module = module.getSuperClass()) {
if (module.getNonIncludedClass() == type.getNonIncludedClass() || (module.isIncluded() && module.hasModuleInHierarchy(type)))
return true;
}

return false;
}

@Override
public IRubyObject fetchConstant(String name, boolean includePrivate) {
RubyModule topModule = origin.getMethodLocation().getSuperClass();
for (RubyModule module = origin; module != null; module = module.getSuperClass()) {
IRubyObject value = module.fetchConstant(name, includePrivate);

if (value != null) {
return value == UNDEF ? resolveUndefConstant(name) : value;
}
}
return null;
}

// @Override
// protected boolean hasConstantInHierarchy(final String name) {
// for (RubyModule module = origin; module != null; module = module.getSuperClass()) {
// if (module.hasConstant(name))
// return true;
// }
// return false;
// }

@Override
public boolean isIncluded() {
return true;
}

@Override
public Map<String, DynamicMethod> getMethods() {
return origin.methodLocation.getMethods();
public boolean isPrepended() {
return origin.hasPrepends();
}

// XXX ??? maybe not getNonIncludedClass()
@Override
public Map<String, DynamicMethod> getMethodsForWrite() {
return origin.methodLocation.getMethodsForWrite();
protected boolean isSame(RubyModule module) {
return origin.isSame(module.getDelegate());
}

@Override
public RubyModule getMethodLocation() {
return origin.getMethodLocation();
public Map<String, DynamicMethod> getMethods() {
return origin.getMethods();
}

@Override
public RubyModule getNonIncludedClass() {
return origin;
public Map<String, DynamicMethod> getMethodsForWrite() {
return origin.getMethodsForWrite();
}

@Override
@@ -177,13 +287,46 @@ public List<String> getStoredConstantNameList() {
@Override
public Collection<String> getConstantNames() {
return origin.getConstantNames();
// Collection<String> names = new HashSet<String>(origin.getConstantMap().size());
// RubyModule topModule = origin.getMethodLocation().getSuperClass();
//
// for (RubyModule module = origin; module != null; module = module.getSuperClass()) {
// module.getConstantNamesInner(names);
// }
//
// return names;
}

// @Override
// public void getConstantNamesInner(Collection<String> names) {
// RubyModule topModule = origin.getMethodLocation().getSuperClass();
// for (RubyModule module = origin; module != null; module = module.getSuperClass()) {
// module.getConstantNamesInner(names);
// }
// }

@Override
public Collection<String> getConstantNames(boolean includePrivate) {
return origin.getConstantNames(includePrivate);
// Collection<String> names = new HashSet<String>(origin.getConstantMap().size());
// RubyModule topModule = origin.getMethodLocation().getSuperClass();
//
// for (RubyModule module = origin; module != null; module = module.getSuperClass()) {
// module.getConstantNamesInner(names, includePrivate);
// }
//
// return names;
}

// @Override
// public void getConstantNamesInner(Collection<String> names, boolean includePrivate) {
// RubyModule topModule = origin.getMethodLocation().getSuperClass();
//
// for (RubyModule module = origin; module != null; module = module.getSuperClass()) {
// module.getConstantNamesInner(names, includePrivate);
// }
// }

@Override
public IRubyObject getAutoloadConstant(String name) {
return origin.getAutoloadConstant(name);
Loading