Skip to content

Commit

Permalink
Showing 1 changed file with 209 additions and 209 deletions.
418 changes: 209 additions & 209 deletions core/src/main/java/org/jruby/RubyModule.java
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@
* Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
* Copyright (C) 2006-2007 Miguel Covarrubias <mlcovarrubias@gmail.com>
* Copyright (C) 2007 William N Dortch <bill.dortch@gmail.com>
*
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
@@ -166,12 +166,12 @@ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
return new RubyModule(runtime, klass);
}
};

public static RubyClass createModuleClass(Ruby runtime, RubyClass moduleClass) {
moduleClass.index = ClassIndex.MODULE;
moduleClass.setReifiedClass(RubyModule.class);
moduleClass.kindOf = new RubyModule.JavaClassKindOf(RubyModule.class);

moduleClass.defineAnnotatedMethods(RubyModule.class);
moduleClass.defineAnnotatedMethods(ModuleKernelMethods.class);

@@ -187,19 +187,19 @@ public void checkValidBindTargetFrom(ThreadContext context, RubyModule originMod
}
}
}

public static class ModuleKernelMethods {
@JRubyMethod
public static IRubyObject autoload(IRubyObject recv, IRubyObject arg0, IRubyObject arg1) {
return RubyKernel.autoload(recv, arg0, arg1);
}

@JRubyMethod(name = "autoload?")
public static IRubyObject autoload_p(ThreadContext context, IRubyObject recv, IRubyObject arg0) {
return RubyKernel.autoload_p(context, recv, arg0);
}
}

@Override
public int getNativeTypeIndex() {
return ClassIndex.MODULE;
@@ -250,7 +250,7 @@ public Map<String, ConstantEntry> getConstantMap() {
public synchronized Map<String, ConstantEntry> getConstantMapForWrite() {
return constants == Collections.EMPTY_MAP ? constants = new ConcurrentHashMap<String, ConstantEntry>(4, 0.9f, 1) : constants;
}

/**
* AutoloadMap must be accessed after checking ConstantMap. Checking UNDEF value in constantMap works as a guard.
* For looking up constant, check constantMap first then try to get an Autoload object from autoloadMap.
@@ -259,11 +259,11 @@ public synchronized Map<String, ConstantEntry> getConstantMapForWrite() {
private Map<String, Autoload> getAutoloadMap() {
return autoloads;
}

private synchronized Map<String, Autoload> getAutoloadMapForWrite() {
return autoloads == Collections.EMPTY_MAP ? autoloads = new ConcurrentHashMap<String, Autoload>(4, 0.9f, 1) : autoloads;
}

public void addIncludingHierarchy(IncludedModuleWrapper hierarchy) {
synchronized (getRuntime().getHierarchyLock()) {
Set<RubyClass> oldIncludingHierarchies = includingHierarchies;
@@ -273,7 +273,7 @@ public void addIncludingHierarchy(IncludedModuleWrapper hierarchy) {
}

/** separate path for MetaClass construction
*
*
*/
protected RubyModule(Ruby runtime, RubyClass metaClass, boolean objectSpace) {
super(runtime, metaClass, objectSpace);
@@ -288,20 +288,20 @@ protected RubyModule(Ruby runtime, RubyClass metaClass, boolean objectSpace) {
} else {
cacheEntryFactory = NormalCacheEntryFactory;
}

// set up an invalidator for use in new optimization strategies
methodInvalidator = OptoFactory.newMethodInvalidator(this);
}

/** used by MODULE_ALLOCATOR and RubyClass constructors
*
*
*/
protected RubyModule(Ruby runtime, RubyClass metaClass) {
this(runtime, metaClass, runtime.isObjectSpaceEnabled());
}

/** standard path for Module construction
*
*
*/
protected RubyModule(Ruby runtime) {
this(runtime, runtime.getModule());
@@ -310,16 +310,16 @@ protected RubyModule(Ruby runtime) {
public boolean needsImplementer() {
return getFlag(USER7_F);
}

/** rb_module_new
*
*
*/
public static RubyModule newModule(Ruby runtime) {
return new RubyModule(runtime);
}

/** rb_module_new/rb_define_module_id/rb_name_class/rb_set_class_path
*
*
*/
public static RubyModule newModule(Ruby runtime, String name, RubyModule parent, boolean setParent) {
RubyModule module = newModule(runtime);
@@ -328,7 +328,7 @@ public static RubyModule newModule(Ruby runtime, String name, RubyModule parent,
parent.setConstant(name, module);
return module;
}

// synchronized method per JRUBY-1173 (unsafe Double-Checked Locking)
// FIXME: synchronization is still wrong in CP code
public synchronized void addClassProvider(ClassProvider provider) {
@@ -391,7 +391,7 @@ public RubyModule getParent() {
public void setParent(RubyModule parent) {
this.parent = parent;
}

public Map<String, DynamicMethod> getMethods() {
return this.methods;
}
@@ -402,17 +402,17 @@ public synchronized Map<String, DynamicMethod> getMethodsForWrite() {
this.methods = new ConcurrentHashMap<String, DynamicMethod>(0, 0.9f, 1) :
myMethods;
}

// note that addMethod now does its own put, so any change made to
// functionality here should be made there as well
// functionality here should be made there as well
private void putMethod(String name, DynamicMethod method) {
getMethodsForWrite().put(name, method);

getRuntime().addProfiledMethod(name, method);
}

/**
* Is this module one that in an included one (e.g. an IncludedModuleWrapper).
* Is this module one that in an included one (e.g. an IncludedModuleWrapper).
*/
public boolean isIncluded() {
return false;
@@ -424,7 +424,7 @@ public RubyModule getNonIncludedClass() {

/**
* Get the base name of this class, or null if it is an anonymous class.
*
*
* @return base name of the class
*/
public String getBaseName() {
@@ -474,46 +474,46 @@ private String calculateName() {
// we are anonymous, use anonymous name
return calculateAnonymousName();
}

Ruby runtime = getRuntime();

String name = getBaseName();
RubyClass objectClass = runtime.getObject();

// First, we count the parents
int parentCount = 0;
for (RubyModule p = getParent() ; p != null && p != objectClass ; p = p.getParent()) {
parentCount++;
}

// Allocate a String array for all of their names and populate it
String[] parentNames = new String[parentCount];
int i = parentCount - 1;
int totalLength = name.length() + parentCount * 2; // name length + enough :: for all parents
for (RubyModule p = getParent() ; p != null && p != objectClass ; p = p.getParent(), i--) {
String pName = p.getBaseName();

// This is needed when the enclosing class or module is a singleton.
// In that case, we generated a name such as null::Foo, which broke
// Marshalling, among others. The correct thing to do in this situation
// is to insert the generate the name of form #<Class:01xasdfasd> if
// In that case, we generated a name such as null::Foo, which broke
// Marshalling, among others. The correct thing to do in this situation
// is to insert the generate the name of form #<Class:01xasdfasd> if
// it's a singleton module/class, which this code accomplishes.
if(pName == null) {
cache = false;
pName = p.getName();
}

parentNames[i] = pName;
totalLength += pName.length();
}

// Then build from the front using a StringBuilder
StringBuilder builder = new StringBuilder(totalLength);
for (String parentName : parentNames) {
builder.append(parentName).append("::");
}
builder.append(name);

String fullName = builder.toString();

if (cache) cachedName = fullName;
@@ -533,9 +533,9 @@ private String calculateAnonymousName() {

/**
* Create a wrapper to use for including the specified module into this one.
*
*
* Ruby C equivalent = "include_class_new"
*
*
* @return The module wrapper
*/
@Deprecated
@@ -551,7 +551,7 @@ public IncludedModuleWrapper newIncludeClass(RubyClass superClazz) {
}
/**
* Finds a class that is within the current module (or class).
*
*
* @param name to be found in this module (or class)
* @return the class or null if no such class
*/
@@ -570,7 +570,7 @@ public RubyClass fastGetClass(String internedName) {

/**
* Include a new module in this module or class.
*
*
* @param arg The module to include
*/
public synchronized void includeModule(IRubyObject arg) {
@@ -595,7 +595,7 @@ public synchronized void includeModule(IRubyObject arg) {
invalidateCacheDescendants();
invalidateConstantCacheForModuleInclusion(module);
}

public void defineAnnotatedMethod(Class clazz, String name) {
// FIXME: This is probably not very efficient, since it loads all methods for each call
boolean foundMethod = false;
@@ -609,7 +609,7 @@ public void defineAnnotatedMethod(Class clazz, String name) {
throw new RuntimeException("No JRubyMethod present for method " + name + "on class " + clazz.getName());
}
}

public void defineAnnotatedConstants(Class clazz) {
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : declaredFields) {
@@ -644,7 +644,7 @@ public boolean defineAnnotatedConstant(Field field) {
realVal = getRuntime().getNil();
}


for(String name : names) {
this.setConstant(name, realVal);
}
@@ -656,7 +656,7 @@ public boolean defineAnnotatedConstant(Field field) {
public void defineAnnotatedMethods(Class clazz) {
defineAnnotatedMethodsIndividually(clazz);
}

public static class MethodClumper {
Map<String, List<JavaMethodDescriptor>> annotatedMethods = new HashMap<String, List<JavaMethodDescriptor>>();
Map<String, List<JavaMethodDescriptor>> staticAnnotatedMethods = new HashMap<String, List<JavaMethodDescriptor>>();
@@ -667,7 +667,7 @@ public static class MethodClumper {
Map<String, List<JavaMethodDescriptor>> annotatedMethods2_0 = new HashMap<String, List<JavaMethodDescriptor>>();
Map<String, List<JavaMethodDescriptor>> staticAnnotatedMethods2_0 = new HashMap<String, List<JavaMethodDescriptor>>();
Map<String, List<JavaMethodDescriptor>> allAnnotatedMethods = new HashMap<String, List<JavaMethodDescriptor>>();

public void clump(Class cls) {
Method[] declaredMethods = cls.getDeclaredMethods();
for (Method method: declaredMethods) {
@@ -676,11 +676,11 @@ public void clump(Class cls) {

// skip bridge methods, as generated by JDK8 javac for return-value overloaded methods
if (method.isBridge()) continue;

JavaMethodDescriptor desc = new JavaMethodDescriptor(method);

String name = anno.name().length == 0 ? method.getName() : anno.name()[0];

List<JavaMethodDescriptor> methodDescs;
Map<String, List<JavaMethodDescriptor>> methodsHash = null;
if (desc.isStatic) {
@@ -711,7 +711,7 @@ public void clump(Class cls) {
methodDescs = new ArrayList<JavaMethodDescriptor>();
methodsHash.put(name, methodDescs);
}

methodDescs.add(desc);

// add to general
@@ -761,10 +761,10 @@ public Map<String, List<JavaMethodDescriptor>> getStaticAnnotatedMethods2_0() {
return staticAnnotatedMethods2_0;
}
}

public void defineAnnotatedMethodsIndividually(Class clazz) {
TypePopulator populator;

if (RubyInstanceConfig.FULL_TRACE_ENABLED || RubyInstanceConfig.REFLECTED_HANDLES) {
// we want reflected invokers or need full traces, use default (slow) populator
if (DEBUG) LOG.info("trace mode, using default populator");
@@ -782,10 +782,10 @@ public void defineAnnotatedMethodsIndividually(Class clazz) {
populator = TypePopulator.DEFAULT;
}
}

populator.populate(this, clazz);
}

public boolean defineAnnotatedMethod(String name, List<JavaMethodDescriptor> methods, MethodFactory methodFactory) {
JavaMethodDescriptor desc = methods.get(0);
if (methods.size() == 1) {
@@ -795,15 +795,15 @@ public boolean defineAnnotatedMethod(String name, List<JavaMethodDescriptor> met
if (shouldBindMethod(compatVersion, desc.anno.compat())) {
DynamicMethod dynamicMethod = methodFactory.getAnnotatedMethod(this, methods);
define(this, desc, name, dynamicMethod);

return true;
}

return false;
}
}
public boolean defineAnnotatedMethod(Method method, MethodFactory methodFactory) {

public boolean defineAnnotatedMethod(Method method, MethodFactory methodFactory) {
JRubyMethod jrubyMethod = method.getAnnotation(JRubyMethod.class);

if (jrubyMethod == null) return false;
@@ -818,8 +818,8 @@ public boolean defineAnnotatedMethod(Method method, MethodFactory methodFactory)
}
return false;
}
public boolean defineAnnotatedMethod(String name, JavaMethodDescriptor desc, MethodFactory methodFactory) {

public boolean defineAnnotatedMethod(String name, JavaMethodDescriptor desc, MethodFactory methodFactory) {
JRubyMethod jrubyMethod = desc.anno;

if (jrubyMethod == null) return false;
@@ -867,9 +867,9 @@ public void undef(ThreadContext context, String name) {
throw runtime.newNameError("Undefined method " + name + " for" + s0 + " '" + c.getName() + "'", name);
}
addMethod(name, UndefinedMethod.getInstance());

if (isSingleton()) {
IRubyObject singleton = ((MetaClass)this).getAttached();
IRubyObject singleton = ((MetaClass)this).getAttached();
singleton.callMethod(context, "singleton_method_undefined", runtime.newSymbol(name));
} else {
callMethod(context, "method_undefined", runtime.newSymbol(name));
@@ -893,7 +893,7 @@ public IRubyObject include_p(ThreadContext context, IRubyObject arg) {
return context.runtime.getFalse();
}

// TODO: Consider a better way of synchronizing
// TODO: Consider a better way of synchronizing
public void addMethod(String name, DynamicMethod method) {
testFrozen("class/module");

@@ -938,9 +938,9 @@ public void removeMethod(ThreadContext context, String name) {
invalidateCoreClasses();
invalidateCacheDescendants();
}

if (isSingleton()) {
IRubyObject singleton = ((MetaClass)this).getAttached();
IRubyObject singleton = ((MetaClass)this).getAttached();
singleton.callMethod(context, "singleton_method_removed", runtime.newSymbol(name));
} else {
callMethod(context, "method_removed", runtime.newSymbol(name));
@@ -949,20 +949,20 @@ public void removeMethod(ThreadContext context, String name) {

/**
* Search through this module and supermodules for method definitions. Cache superclass definitions in this class.
*
*
* @param name The name of the method to search for
* @return The method, or UndefinedMethod if not found
*/
*/
public DynamicMethod searchMethod(String name) {
return searchWithCache(name).method;
}

/**
* Search through this module and supermodules for method definitions. Cache superclass definitions in this class.
*
*
* @param name The name of the method to search for
* @return The method, or UndefinedMethod if not found
*/
*/
public CacheEntry searchWithCache(String name) {
CacheEntry entry = cacheHit(name);

@@ -979,12 +979,12 @@ public CacheEntry searchWithCache(String name) {

return method != null ? addToCache(name, method, token) : addToCache(name, UndefinedMethod.getInstance(), token);
}

@Deprecated
public final int getCacheToken() {
return generation;
}

public final int getGeneration() {
return generation;
}
@@ -1003,7 +1003,7 @@ private final Map<String, CacheEntry> getCachedMethodsForWrite() {
this.cachedMethods = new ConcurrentHashMap<String, CacheEntry>(0, 0.75f, 1) :
myCachedMethods;
}

private CacheEntry cacheHit(String name) {
CacheEntry cacheEntry = getCachedMethods().get(name);

@@ -1012,7 +1012,7 @@ private CacheEntry cacheHit(String name) {
return cacheEntry;
}
}

return null;
}

@@ -1024,7 +1024,7 @@ private void invalidateConstantCacheForModuleInclusion(RubyModule module)
}
}
}

protected static abstract class CacheEntryFactory {
public abstract CacheEntry newCacheEntry(String name,DynamicMethod method, int token);

@@ -1133,12 +1133,12 @@ private CacheEntry addToCache(String name, DynamicMethod method, int token) {

return entry;
}

public DynamicMethod searchMethodInner(String name) {
DynamicMethod method = getMethods().get(name);

if (method != null) return method;

return superClass == null ? null : superClass.searchMethodInner(name);
}

@@ -1153,16 +1153,16 @@ public void invalidateCacheDescendants() {

List<Invalidator> invalidators = new ArrayList<Invalidator>();
invalidators.add(methodInvalidator);

synchronized (getRuntime().getHierarchyLock()) {
for (RubyClass includingHierarchy : includingHierarchies) {
includingHierarchy.addInvalidatorsAndFlush(invalidators);
}
}

methodInvalidator.invalidateAll(invalidators);
}

protected void invalidateCoreClasses() {
if (!getRuntime().isBooting()) {
if (this == getRuntime().getFixnum()) {
@@ -1172,11 +1172,11 @@ protected void invalidateCoreClasses() {
}
}
}

public Invalidator getInvalidator() {
return methodInvalidator;
}

public void updateGeneration() {
generationObject = generation = getRuntime().getNextModuleGeneration();
}
@@ -1185,14 +1185,14 @@ public void updateGeneration() {
protected void invalidateCacheDescendantsInner() {
methodInvalidator.invalidate();
}

protected void invalidateConstantCache(String constantName) {
getRuntime().getConstantInvalidator(constantName).invalidate();
}
}

/**
* Search through this module and supermodules for method definitions. Cache superclass definitions in this class.
*
*
* @param name The name of the method to search for
* @return The method, or UndefinedMethod if not found
*/
@@ -1202,7 +1202,7 @@ public DynamicMethod retrieveMethod(String name) {

/**
* Find the given class in this hierarchy, considering modules along the way.
*
*
* @param clazz the class to find
* @return The method, or UndefinedMethod if not found
*/
@@ -1243,25 +1243,25 @@ public synchronized void defineAliases(List<String> aliases, String oldName) {

putMethod(name, new AliasMethod(this, method, oldName));
}

invalidateCoreClasses();
invalidateCacheDescendants();
}

private DynamicMethod searchForAliasMethod(Ruby runtime, String name) {
// JRUBY-2435: Aliasing eval and other "special" methods should display a warning
// We warn because we treat certain method names as "special" for purposes of
// optimization. Hopefully this will be enough to convince people not to alias
// them.
if (SCOPE_CAPTURING_METHODS.contains(name)) {
runtime.getWarnings().warn("`" + name + "' should not be aliased");
}
}

return deepMethodSearch(name, runtime);
}

/** this method should be used only by interpreter or compiler
*
/** this method should be used only by interpreter or compiler
*
*/
public RubyClass defineOrGetClassUnder(String name, RubyClass superClazz) {
// This method is intended only for defining new classes in Ruby code,
@@ -1287,7 +1287,7 @@ public RubyClass defineOrGetClassUnder(String name, RubyClass superClazz) {
// reopen a java class
} else {
if (superClazz == null) superClazz = runtime.getObject();

ObjectAllocator allocator;
if (superClazz == runtime.getObject()) {
if (RubyInstanceConfig.REIFY_RUBY_CLASSES) {
@@ -1300,15 +1300,15 @@ public RubyClass defineOrGetClassUnder(String name, RubyClass superClazz) {
} else {
allocator = superClazz.getAllocator();
}

clazz = RubyClass.newClass(runtime, superClazz, name, allocator, this, true);
}

return clazz;
}

/** this method should be used only by interpreter or compiler
*
/** this method should be used only by interpreter or compiler
*
*/
public RubyModule defineOrGetModuleUnder(String name) {
// This method is intended only for defining new modules in Ruby code
@@ -1321,13 +1321,13 @@ public RubyModule defineOrGetModuleUnder(String name) {
} else if (classProviders != null && (module = searchProvidersForModule(name)) != null) {
// reopen a java module
} else {
module = RubyModule.newModule(runtime, name, this, true);
module = RubyModule.newModule(runtime, name, this, true);
}
return module;
}

/** rb_define_class_under
* this method should be used only as an API to define/open nested classes
* this method should be used only as an API to define/open nested classes
*/
public RubyClass defineClassUnder(String name, RubyClass superClass, ObjectAllocator allocator) {
return getRuntime().defineClassUnder(name, superClass, allocator, this);
@@ -1423,7 +1423,7 @@ public boolean isMethodBound(String name, boolean checkVisibility) {
}
return false;
}

public boolean isMethodBound(String name, boolean checkVisibility, boolean checkRespondTo) {
if (!checkRespondTo) return isMethodBound(name, checkVisibility);
DynamicMethod method = searchMethod(name);
@@ -1510,7 +1510,7 @@ public IRubyObject define_method(ThreadContext context, IRubyObject arg0, Block
// reason for this hack/side-effect is that symbols store their values as raw bytes. We lose encoding
// info so we need to make an entry so any accesses with raw bytes later gets proper symbol.
RubySymbol.newSymbol(runtime, arg0);

if (!block.isGiven()) {
throw getRuntime().newArgumentError("tried to create Proc object without a block");
}
@@ -1520,22 +1520,22 @@ public IRubyObject define_method(ThreadContext context, IRubyObject arg0, Block

// a normal block passed to define_method changes to do arity checking; make it a lambda
proc.getBlock().type = Block.Type.LAMBDA;

newMethod = createProcMethod(name, visibility, proc);

Helpers.addInstanceMethod(this, name, newMethod, visibility, context, runtime);

return proc;
}

@JRubyMethod(name = "define_method", visibility = PRIVATE, reads = VISIBILITY)
public IRubyObject define_method(ThreadContext context, IRubyObject arg0, IRubyObject arg1, Block block) {
Ruby runtime = context.runtime;
IRubyObject body;
String name = TypeConverter.convertToIdentifier(arg0);
DynamicMethod newMethod = null;
Visibility visibility = PUBLIC;

// We need our identifier to be retrievable and creatable as a symbol. This side-effect
// populates this name into our symbol table so it will exist later if needed. The
// reason for this hack/side-effect is that symbols store their values as raw bytes. We lose encoding
@@ -1551,15 +1551,15 @@ public IRubyObject define_method(ThreadContext context, IRubyObject arg0, IRubyO
} else if (arg1 instanceof AbstractRubyMethod) {
AbstractRubyMethod method = (AbstractRubyMethod)arg1;
body = method;

checkValidBindTargetFrom(context, (RubyModule)method.owner(context));

newMethod = method.getMethod().dup();
newMethod.setImplementationClass(this);
} else {
throw runtime.newTypeError("wrong argument type " + arg1.getType().getName() + " (expected Proc/Method)");
}

Helpers.addInstanceMethod(this, name, newMethod, visibility, context, runtime);

return body;
@@ -1575,13 +1575,13 @@ public IRubyObject define_method(ThreadContext context, IRubyObject[] args, Bloc
throw context.runtime.newArgumentError("wrong number of arguments (" + args.length + " for 2)");
}
}

private DynamicMethod createProcMethod(String name, Visibility visibility, RubyProc proc) {
Block block = proc.getBlock();
block.getBinding().getFrame().setKlazz(this);
block.getBinding().getFrame().setName(name);
block.getBinding().setMethod(name);

StaticScope scope = block.getBody().getStaticScope();

// for zsupers in define_method (blech!) we tell the proc scope to act as the "argument" scope
@@ -1600,7 +1600,7 @@ private DynamicMethod createProcMethod(String name, Visibility visibility, RubyP

@Deprecated
public IRubyObject executeUnder(ThreadContext context, org.jruby.runtime.callback.Callback method, IRubyObject[] args, Block block) {
context.preExecuteUnder(this, block);
context.preExecuteUnder(this, this, block);
try {
return method.execute(this, args, block);
} finally {
@@ -1635,7 +1635,7 @@ protected IRubyObject cloneMethods(RubyModule clone) {
// Do not clone cached methods
// FIXME: MRI copies all methods here
if (method.getImplementationClass() == realType || method.isUndefined()) {

// A cloned method now belongs to a new class. Set it.
// TODO: Make DynamicMethod immutable
DynamicMethod clonedMethod = method.dup();
@@ -1648,7 +1648,7 @@ protected IRubyObject cloneMethods(RubyModule clone) {
}

/** rb_mod_init_copy
*
*
*/
@JRubyMethod(name = "initialize_copy", required = 1, visibility = Visibility.PRIVATE)
@Override
@@ -1702,7 +1702,7 @@ public RubyArray included_modules(ThreadContext context) {
public RubyArray ancestors(ThreadContext context) {
return context.runtime.newArray(getAncestorList());
}

@Deprecated
public RubyArray ancestors() {
return getRuntime().newArray(getAncestorList());
@@ -1747,7 +1747,7 @@ public RubyFixnum hash() {
@JRubyMethod(name = "to_s")
@Override
public IRubyObject to_s() {
if(isSingleton()){
if(isSingleton()){
IRubyObject attached = ((MetaClass)this).getAttached();
StringBuilder buffer = new StringBuilder("#<Class:");
if (attached != null) { // FIXME: figure out why we getService null sometimes
@@ -1881,15 +1881,15 @@ public IRubyObject initialize(ThreadContext context, Block block) {

return getRuntime().getNil();
}

public void addReadWriteAttribute(ThreadContext context, String name) {
addAccessor(context, name.intern(), PUBLIC, true, true);
}

public void addReadAttribute(ThreadContext context, String name) {
addAccessor(context, name.intern(), PUBLIC, true, false);
}

public void addWriteAttribute(ThreadContext context, String name) {
addAccessor(context, name.intern(), PUBLIC, false, true);
}
@@ -1903,12 +1903,12 @@ public IRubyObject attr(ThreadContext context, IRubyObject[] args) {

// Check the visibility of the previous frame, which will be the frame in which the class is being eval'ed
Visibility visibility = context.getCurrentVisibility();

addAccessor(context, args[0].asJavaString().intern(), visibility, true, writeable);

return getRuntime().getNil();
}

@JRubyMethod(name = "attr", rest = true, visibility = PRIVATE, reads = VISIBILITY, compat = RUBY1_9)
public IRubyObject attr19(ThreadContext context, IRubyObject[] args) {
Ruby runtime = context.runtime;
@@ -1926,7 +1926,7 @@ public IRubyObject attr19(ThreadContext context, IRubyObject[] args) {
public IRubyObject attr_reader(IRubyObject[] args) {
return attr_reader(getRuntime().getCurrentContext(), args);
}

/** rb_mod_attr_reader
*
*/
@@ -1983,9 +1983,9 @@ public IRubyObject attr_accessor(ThreadContext context, IRubyObject[] args) {
}

/**
* Get a list of all instance methods names of the provided visibility unless not is true, then
* Get a list of all instance methods names of the provided visibility unless not is true, then
* getService all methods which are not the provided
*
*
* @param args passed into one of the Ruby instance_method methods
* @param visibility to find matching instance methods against
* @param not if true only find methods not matching supplied visibility
@@ -2086,7 +2086,7 @@ public RubyArray private_instance_methods19(IRubyObject[] args) {
@JRubyMethod(name = "append_features", required = 1, visibility = PRIVATE)
public RubyModule append_features(IRubyObject module) {
if (!(module instanceof RubyModule)) {
// MRI error message says Class, even though Module is ok
// MRI error message says Class, even though Module is ok
throw getRuntime().newTypeError(module,getRuntime().getClassClass());
}
((RubyModule) module).includeModule(this);
@@ -2168,7 +2168,7 @@ public IRubyObject mix(ThreadContext context, IRubyObject mod, IRubyObject hash0
} else {
throw runtime.newTypeError(hash0, runtime.getHash());
}

for (Map.Entry entry : (Set<Map.Entry<Object, Object>>)methodNames.directEntrySet()) {
String name = entry.getValue().toString();
if (methods.containsKey(entry.getValue().toString())) {
@@ -2272,7 +2272,7 @@ public IRubyObject method_removed(ThreadContext context, IRubyObject nothing) {
public IRubyObject method_undefined(ThreadContext context, IRubyObject nothing) {
return context.runtime.getNil();
}

@JRubyMethod(name = "method_defined?", required = 1)
public RubyBoolean method_defined_p(ThreadContext context, IRubyObject symbol) {
return isMethodBound(symbol.asJavaString(), true) ? context.runtime.getTrue() : context.runtime.getFalse();
@@ -2291,7 +2291,7 @@ public IRubyObject protected_method_defined(ThreadContext context, IRubyObject s

return context.runtime.newBoolean(!method.isUndefined() && method.getVisibility() == PROTECTED);
}

@JRubyMethod(name = "private_method_defined?", required = 1)
public IRubyObject private_method_defined(ThreadContext context, IRubyObject symbol) {
DynamicMethod method = searchMethod(symbol.asJavaString());
@@ -2393,8 +2393,8 @@ public static RubyModule unmarshalFrom(UnmarshalStream input) throws java.io.IOE
}

/* Module class methods */
/**

/**
* Return an array of nested modules or classes.
*/
@JRubyMethod(name = "nesting", reads = FrameField.SCOPE, meta = true)
@@ -2403,11 +2403,11 @@ public static RubyArray nesting(ThreadContext context, IRubyObject recv, Block b
RubyModule object = runtime.getObject();
StaticScope scope = context.getCurrentScope().getStaticScope();
RubyArray result = runtime.newArray();

for (StaticScope current = scope; current.getModule() != object; current = current.getPreviousCRefScope()) {
result.append(current.getModule());
}

return result;
}

@@ -2416,12 +2416,12 @@ public static RubyArray nesting(ThreadContext context, IRubyObject recv, Block b
* this module/class. Inspects the hierarchy to ensure the same module isn't
* included twice, and selects an appropriate insertion point for each incoming
* module.
*
*
* @param baseModule The module to include, along with any modules it itself includes
*/
private void doIncludeModule(RubyModule baseModule) {
List<RubyModule> modulesToInclude = gatherModules(baseModule);

RubyModule currentInclusionPoint = this;
ModuleLoop: for (RubyModule nextModule : modulesToInclude) {
checkForCyclicInclude(nextModule);
@@ -2449,10 +2449,10 @@ private void doIncludeModule(RubyModule baseModule) {
currentInclusionPoint = proceedWithInclude(currentInclusionPoint, nextModule);
}
}

/**
* Is the given class a wrapper for the specified module?
*
*
* @param theClass The class to inspect
* @param theModule The module we're looking for
* @return true if the class is a wrapper for the module, false otherwise
@@ -2466,7 +2466,7 @@ private boolean doesTheClassWrapTheModule(RubyClass theClass, RubyModule theModu
* Gather all modules that would be included by including the given module.
* The resulting list contains the given module and its (zero or more)
* module-wrapping superclasses.
*
*
* @param baseModule The base module from which to aggregate modules
* @return A list of all modules that would be included by including the given module
*/
@@ -2484,7 +2484,7 @@ private List<RubyModule> gatherModules(RubyModule baseModule) {
/**
* Actually proceed with including the specified module above the given target
* in a hierarchy. Return the new module wrapper.
*
*
* @param insertAbove The hierarchy target above which to include the wrapped module
* @param moduleToInclude The module to wrap and include
* @return The new module wrapper resulting from this include
@@ -2494,20 +2494,20 @@ private RubyModule proceedWithInclude(RubyModule insertAbove, RubyModule moduleT
// IncludedModuleWrapper, so there's no need to fish out the delegate. But just
// in case the logic should change later, let's do it anyway
RubyClass wrapper = new IncludedModuleWrapper(getRuntime(), insertAbove.getSuperClass(), moduleToInclude.getNonIncludedClass());

// if the insertion point is a class, update subclass lists
if (insertAbove instanceof RubyClass) {
RubyClass insertAboveClass = (RubyClass)insertAbove;

// if there's a non-null superclass, we're including into a normal class hierarchy;
// update subclass relationships to avoid stale parent/child relationships
if (insertAboveClass.getSuperClass() != null) {
insertAboveClass.getSuperClass().replaceSubclass(insertAboveClass, wrapper);
}

wrapper.addSubclass(insertAboveClass);
}

insertAbove.setSuperClass(wrapper);
insertAbove = insertAbove.getSuperClass();
return insertAbove;
@@ -2577,7 +2577,7 @@ public IRubyObject remove_class_variable19(ThreadContext context, IRubyObject na
public RubyArray class_variables(ThreadContext context) {
Ruby runtime = context.runtime;
RubyArray ary = runtime.newArray();

Collection<String> names = classVariablesCommon();
ary.addAll(names);
return ary;
@@ -2587,7 +2587,7 @@ public RubyArray class_variables(ThreadContext context) {
public RubyArray class_variables19(ThreadContext context) {
Ruby runtime = context.runtime;
RubyArray ary = runtime.newArray();

Collection<String> names = classVariablesCommon();
for (String name : names) {
ary.add(runtime.newSymbol(name));
@@ -2706,18 +2706,18 @@ private boolean hasConstantInHierarchy(final String name) {
}
return false;
}

/**
* Base implementation of Module#const_missing, throws NameError for specific missing constant.
*
*
* @param rubyName The constant name which was found to be missing
* @return Nothing! Absolutely nothing! (though subclasses might choose to return something)
*/
@JRubyMethod(name = "const_missing", required = 1)
public IRubyObject const_missing(ThreadContext context, IRubyObject rubyName, Block block) {
Ruby runtime = context.runtime;
String name;

if (this != runtime.getObject()) {
name = getName() + "::" + rubyName.asJavaString();
} else {
@@ -2733,7 +2733,7 @@ public RubyArray constants(ThreadContext context) {
RubyArray array = runtime.newArray();
Collection<String> constantNames = constantsCommon(runtime, true, true);
array.addAll(constantNames);

return array;
}

@@ -2746,13 +2746,13 @@ public RubyArray constants19(ThreadContext context) {
public RubyArray constants19(ThreadContext context, IRubyObject allConstants) {
return constantsCommon19(context, false, allConstants.isTrue());
}

public RubyArray constantsCommon19(ThreadContext context, boolean replaceModule, boolean allConstants) {
Ruby runtime = context.runtime;
RubyArray array = runtime.newArray();

Collection<String> constantNames = constantsCommon(runtime, replaceModule, allConstants, false);

for (String name : constantNames) {
array.add(runtime.newSymbol(name));
}
@@ -2844,9 +2844,9 @@ private void setConstantVisibility(ThreadContext context, String name, boolean h

/**
* Set the named class variable to the given value, provided taint and freeze allow setting it.
*
*
* Ruby C equivalent = "rb_cvar_set"
*
*
* @param name The variable name to set
* @param value The value to set it to
*/
@@ -2857,7 +2857,7 @@ public IRubyObject setClassVar(String name, IRubyObject value) {
return module.storeClassVariable(name, value);
}
} while ((module = module.getSuperClass()) != null);

return storeClassVariable(name, value);
}

@@ -2868,9 +2868,9 @@ public IRubyObject fastSetClassVar(final String internedName, final IRubyObject

/**
* Retrieve the specified class variable, searching through this module, included modules, and supermodules.
*
*
* Ruby C equivalent = "rb_cvar_get"
*
*
* @param name The name of the variable to retrieve
* @return The variable's value, or throws NameError if not found
*/
@@ -2893,9 +2893,9 @@ public IRubyObject fastGetClassVar(String internedName) {

/**
* Is class var defined?
*
*
* Ruby C equivalent = "rb_cvar_defined"
*
*
* @param name The class var to determine "is defined?"
* @return true if true, false if false
*/
@@ -2912,7 +2912,7 @@ public boolean isClassVarDefined(String name) {
public boolean fastIsClassVarDefined(String internedName) {
return isClassVarDefined(internedName);
}

/** rb_mod_remove_cvar
*
* @deprecated - use {@link #removeClassVariable(String)}
@@ -2956,14 +2956,14 @@ public IRubyObject getConstantAtSpecial(String name) {
} else {
value = fetchConstant(name);
}

return value == UNDEF ? resolveUndefConstant(name) : value;
}

public IRubyObject getConstantAt(String name) {
return getConstantAt(name, true);
}

public IRubyObject getConstantAt(String name, boolean includePrivate) {
IRubyObject value = fetchConstant(name, includePrivate);

@@ -2977,7 +2977,7 @@ public IRubyObject fastGetConstantAt(String internedName) {

/**
* Retrieve the named constant, invoking 'const_missing' should that be appropriate.
*
*
* @param name The constant to retrieve
* @return The value for the constant, or null if not found
*/
@@ -3043,7 +3043,7 @@ public IRubyObject getConstantFrom(String name) {

return value != null ? value : getConstantFromConstMissing(name);
}

@Deprecated
public IRubyObject fastGetConstantFrom(String internedName) {
return getConstantFrom(internedName);
@@ -3080,7 +3080,7 @@ public IRubyObject getConstantFromNoConstMissing(String name, boolean includePri
}
return null;
}

@Deprecated
public IRubyObject fastGetConstantFromNoConstMissing(String internedName) {
return getConstantFromNoConstMissing(internedName);
@@ -3149,7 +3149,7 @@ private IRubyObject setConstantCommon(String name, IRubyObject value, boolean wa
}

invalidateConstantCache(name);

// if adding a module under a constant name, set that module's basename to the constant name
if (value instanceof RubyModule) {
RubyModule module = (RubyModule)value;
@@ -3165,7 +3165,7 @@ private IRubyObject setConstantCommon(String name, IRubyObject value, boolean wa
public IRubyObject fastSetConstant(String internedName, IRubyObject value) {
return setConstant(internedName, value);
}

/** rb_define_const
*
*/
@@ -3182,7 +3182,7 @@ public void defineConstant(String name, IRubyObject value) {

// Fix for JRUBY-1339 - search hierarchy for constant
/** rb_const_defined_at
*
*
*/
public boolean isConstantDefined(String name) {
assert IdUtil.isConstant(name);
@@ -3255,12 +3255,12 @@ private RaiseException cannotRemoveError(String id) {
//
////////////////// INTERNAL MODULE VARIABLE API METHODS ////////////////
//

/**
* Behaves similarly to {@link #getClassVar(String)}. Searches this
* class/module <em>and its ancestors</em> for the specified internal
* variable.
*
*
* @param name the internal variable name
* @return the value of the specified internal variable if found, else null
* @see #setInternalModuleVariable(String, IRubyObject)
@@ -3276,7 +3276,7 @@ public boolean hasInternalModuleVariable(final String name) {
* Behaves similarly to {@link #getClassVar(String)}. Searches this
* class/module <em>and its ancestors</em> for the specified internal
* variable.
*
*
* @param name the internal variable name
* @return the value of the specified internal variable if found, else null
* @see #setInternalModuleVariable(String, IRubyObject)
@@ -3293,8 +3293,8 @@ public IRubyObject searchInternalModuleVariable(final String name) {
/**
* Behaves similarly to {@link #setClassVar(String, IRubyObject)}. If the
* specified internal variable is found in this class/module <em>or an ancestor</em>,
* it is set where found. Otherwise it is set in this module.
*
* it is set where found. Otherwise it is set in this module.
*
* @param name the internal variable name
* @param value the internal variable value
* @see #searchInternalModuleVariable(String)
@@ -3375,7 +3375,7 @@ private Map<String,IRubyObject> getClassVariablesForWriteAtomic() {
protected Map<String, IRubyObject> getClassVariablesForRead() {
return classVariables;
}

public boolean hasClassVariable(String name) {
assert IdUtil.isClassVariable(name);
return getClassVariablesForRead().containsKey(name);
@@ -3420,7 +3420,7 @@ public List<String> getClassVariableNameList() {

protected static final String ERR_INSECURE_SET_CLASS_VAR = "Insecure: can't modify class variable";
protected static final String ERR_FROZEN_CVAR_TYPE = "class/module ";

protected final String validateClassVariable(String name) {
if (IdUtil.isValidClassVariableName(name)) {
return name;
@@ -3430,7 +3430,7 @@ protected final String validateClassVariable(String name) {

protected final void ensureClassVariablesSettable() {
Ruby runtime = getRuntime();

if (!isFrozen()) {
return;
}
@@ -3484,7 +3484,7 @@ public IRubyObject fastFetchConstant(String internedName) {
public IRubyObject storeConstant(String name, IRubyObject value) {
assert IdUtil.isConstant(name) : name + " is not a valid constant name";
assert value != null : "value is null";

ensureConstantsSettable();
return constantTableStore(name, value);
}
@@ -3500,7 +3500,7 @@ public IRubyObject deleteConstant(String name) {
ensureConstantsSettable();
return constantTableRemove(name);
}

@Deprecated
public List<Variable<IRubyObject>> getStoredConstantList() {
return null;
@@ -3526,14 +3526,14 @@ public Collection<String> getConstantNames(boolean includePrivate) {
}

HashSet<String> publicNames = new HashSet<String>(getConstantMap().size());

for (Map.Entry<String, ConstantEntry> entry : getConstantMap().entrySet()) {
if (entry.getValue().hidden) continue;
publicNames.add(entry.getKey());
}
return publicNames;
}

protected final String validateConstant(String name) {
if (getRuntime().is1_9() ?
IdUtil.isValidConstantName19(name) :
@@ -3550,7 +3550,7 @@ protected final void ensureConstantsSettable() {
protected boolean constantTableContains(String name) {
return getConstantMap().containsKey(name);
}

protected IRubyObject constantTableFetch(String name) {
ConstantEntry entry = getConstantMap().get(name);
if (entry == null) return null;
@@ -3560,7 +3560,7 @@ protected IRubyObject constantTableFetch(String name) {
protected ConstantEntry constantEntryFetch(String name) {
return getConstantMap().get(name);
}

protected IRubyObject constantTableStore(String name, IRubyObject value) {
Map<String, ConstantEntry> constMap = getConstantMapForWrite();
boolean hidden = false;
@@ -3571,13 +3571,13 @@ protected IRubyObject constantTableStore(String name, IRubyObject value) {
constMap.put(name, new ConstantEntry(value, hidden));
return value;
}

protected IRubyObject constantTableRemove(String name) {
ConstantEntry entry = getConstantMapForWrite().remove(name);
if (entry == null) return null;
return entry.value;
}

/**
* Define an autoload. ConstantMap holds UNDEF for the name as an autoload marker.
*/
@@ -3588,7 +3588,7 @@ protected void defineAutoload(String name, IAutoloadMethod loadMethod) {
getAutoloadMapForWrite().put(name, new Autoload(loadMethod));
}
}

/**
* Extract an Object which is defined by autoload thread from autoloadMap and define it as a constant.
*/
@@ -3617,7 +3617,7 @@ public IRubyObject getAutoloadConstant(String name) {
}
return autoload.getConstant(getRuntime().getCurrentContext());
}

/**
* Set an Object as a defined constant in autoloading.
*/
@@ -3632,14 +3632,14 @@ private void setAutoloadConstant(String name, IRubyObject value) {
storeConstant(name, value);
}
}

/**
* Removes an Autoload object from autoloadMap. ConstantMap must be updated before calling this.
*/
private void removeAutoload(String name) {
getAutoloadMapForWrite().remove(name);
}

protected String getAutoloadFile(String name) {
Autoload autoload = getAutoloadMap().get(name);
if (autoload != null) {
@@ -3677,7 +3677,7 @@ private static void define(RubyModule module, JavaMethodDescriptor desc, String
AnnotationHelper.addMethodNamesToSet(scopeAwareMethods, jrubyMethod, simpleName);
ASTInspector.SCOPE_AWARE_METHODS.addAll(scopeAwareMethods);
}

RubyModule singletonClass;

if (jrubyMethod.meta()) {
@@ -3742,7 +3742,7 @@ private static void define(RubyModule module, JavaMethodDescriptor desc, String
}
}
}

@Deprecated
public IRubyObject initialize(Block block) {
return initialize(getRuntime().getCurrentContext());
@@ -3762,7 +3762,7 @@ public IRubyObject initialize(Block block) {
* an anonymous class.
*/
protected String baseName;

/**
* The cached anonymous class name, since it never changes and has a nonzero
* cost to calculate.
@@ -3787,15 +3787,15 @@ public ConstantEntry(IRubyObject value, boolean hidden) {
this.value = value;
this.hidden = hidden;
}

public ConstantEntry dup() {
return new ConstantEntry(value, hidden);
}
}

/**
* Objects for holding autoload state for the defined constant.
*
*
* 'Module#autoload' creates this object and stores it in autoloadMap.
* This object can be shared with multiple threads so take care to change volatile and synchronized definitions.
*/
@@ -3825,28 +3825,28 @@ IRubyObject getConstant(ThreadContext ctx) {
return getValue();
}
// This method needs to be synchronized for removing Autoload
// from autoloadMap when it's loaded.
// from autoloadMap when it's loaded.
getLoadMethod().load(ctx.runtime);
}
return getValue();
}

// Update an object for the constant if the caller is the autoloading thread.
boolean setConstant(ThreadContext ctx, IRubyObject newValue) {
synchronized(ctxLock) {
boolean isSelf = isSelf(ctx);

if (isSelf) value = newValue;

return isSelf;
}
}

// Returns an object for the constant defined by autoload.
IRubyObject getValue() {
return value;
}

// Returns the assigned feature.
String getFile() {
return getLoadMethod().file();
@@ -3860,15 +3860,15 @@ private boolean isSelf(ThreadContext rhs) {
return ctx != null && ctx.getThread() == rhs.getThread();
}
}

/**
* Set whether this class is associated with (i.e. a proxy for) a normal
* Java class or interface.
*/
public void setJavaProxy(boolean javaProxy) {
this.javaProxy = javaProxy;
}

/**
* Get whether this class is associated with (i.e. a proxy for) a normal
* Java class or interface.
@@ -3892,11 +3892,11 @@ public boolean getCacheProxy() {
public void setCacheProxy(boolean cacheProxy) {
setFlag(USER0_F, cacheProxy);
}

/**
* Visit all interpreted methods in this module (and superclasses, if this
* is a class with superclasses) using the given visitor.
*
*
* @param visitor the visitor to use
*/
public void visitInterpretedMethods(NodeVisitor visitor) {
@@ -3910,7 +3910,7 @@ public void visitInterpretedMethods(NodeVisitor visitor) {
}
}
}

public Set<String> discoverInstanceVariables() {
HashSet<String> set = new HashSet();
RubyModule cls = this;
@@ -3919,7 +3919,7 @@ public Set<String> discoverInstanceVariables() {
MethodData methodData = method.getMethodData();
set.addAll(methodData.getIvarNames());
}

if (cls instanceof RubyClass) {
cls = ((RubyClass)cls).getSuperClass();
} else {
@@ -3931,7 +3931,7 @@ public Set<String> discoverInstanceVariables() {

/**
* Visit methods contained in the specified class using the given visitor.
*
*
* @param visitor the visitor to use
* @param mod the module/class whose methods to visit
*/
@@ -3982,7 +3982,7 @@ public void defineMethod(String name, org.jruby.runtime.callback.Callback method
} else if (runtime.is2_0() && ("respond_to_missing?".equals(name) || "initialize_clone".equals(name) || "initialize_dup".equals(name))) {
visibility = Visibility.PRIVATE;
}

addMethod(name, new org.jruby.internal.runtime.methods.FullFunctionCallbackMethod(this, method, visibility));
}

@@ -3995,7 +3995,7 @@ public void defineFastMethod(String name, org.jruby.runtime.callback.Callback me
} else if (runtime.is2_0() && ("respond_to_missing?".equals(name) || "initialize_clone".equals(name) || "initialize_dup".equals(name))) {
visibility = Visibility.PRIVATE;
}

addMethod(name, new org.jruby.internal.runtime.methods.SimpleCallbackMethod(this, method, visibility));
}

@@ -4054,7 +4054,7 @@ public void defineFastPublicModuleFunction(String name, org.jruby.runtime.callba
defineFastMethod(name, method);
getSingletonClass().defineFastMethod(name, method);
}

private volatile Map<String, Autoload> autoloads = Collections.EMPTY_MAP;
private volatile Map<String, DynamicMethod> methods = Collections.EMPTY_MAP;
protected Map<String, CacheEntry> cachedMethods = Collections.EMPTY_MAP;
@@ -4073,7 +4073,7 @@ public void defineFastPublicModuleFunction(String name, org.jruby.runtime.callba
/**
* The index of this class in the ClassIndex. Only non-zero for native JRuby
* classes that have a corresponding entry in ClassIndex.
*
*
* @see ClassIndex
*/
public int index;
@@ -4095,10 +4095,10 @@ public void defineFastPublicModuleFunction(String name, org.jruby.runtime.callba
}
CLASSVARS_UPDATER = updater;
}

// Invalidator used for method caches
protected final Invalidator methodInvalidator;

/** Whether this class proxies a normal Java class */
private boolean javaProxy = false;
}

0 comments on commit aaf1681

Please sign in to comment.