| Method from org.jruby.RubyClass Detail: |
public synchronized void addSubclass(RubyClass subclass) {
if (subclasses == null) subclasses = new WeakHashSet< RubyClass >();
subclasses.add(subclass);
}
|
public IRubyObject allocate() {
if (superClass == null) throw runtime.newTypeError("can't instantiate uninitialized class");
IRubyObject obj = allocator.allocate(runtime, this);
if (obj.getMetaClass().getRealClass() != getRealClass()) throw runtime.newTypeError("wrong instance allocation");
return obj;
}
|
public static void checkInheritable(IRubyObject superClass) {
if (!(superClass instanceof RubyClass)) {
throw superClass.getRuntime().newTypeError("superclass must be a Class (" + superClass.getMetaClass() + " given)");
}
if (((RubyClass)superClass).isSingleton()) {
throw superClass.getRuntime().newTypeError("can't make subclass of virtual class");
}
}
|
public static RubyClass createBootstrapClass(Ruby runtime,
String name,
RubyClass superClass,
ObjectAllocator allocator) {
RubyClass obj;
if (superClass == null ) { // boot the Object class
obj = new RubyClass(runtime);
obj.marshal = DEFAULT_OBJECT_MARSHAL;
} else { // boot the Module and Class classes
obj = new RubyClass(runtime, superClass);
}
obj.setAllocator(allocator);
obj.setBaseName(name);
return obj;
}
boot_defclass
Create an initial Object meta class before Module and Kernel dependencies have
squirreled themselves together. |
public static void createClassClass(Ruby runtime,
RubyClass classClass) {
classClass.index = ClassIndex.CLASS;
classClass.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
return obj instanceof RubyClass;
}
};
classClass.undefineMethod("module_function");
classClass.undefineMethod("append_features");
classClass.undefineMethod("extend_object");
classClass.defineAnnotatedMethods(RubyClass.class);
// This is a non-standard method; have we decided to start extending Ruby?
//classClass.defineFastMethod("subclasses", callbackFactory.getFastOptMethod("subclasses"));
// FIXME: for some reason this dispatcher causes a VerifyError...
//classClass.dispatcher = callbackFactory.createDispatcher(classClass);
}
|
public ObjectAllocator getAllocator() {
return allocator;
}
|
public Ruby getClassRuntime() {
return runtime;
}
|
public final ObjectMarshal getMarshal() {
return marshal;
}
|
public int getNativeTypeIndex() {
return ClassIndex.CLASS;
}
|
public RubyClass getRealClass() {
return this;
}
|
public void inherit(RubyClass superClazz) {
if (superClazz == null) superClazz = getRuntime().getObject();
superClazz.invokeInherited(getRuntime().getCurrentContext(), superClazz, this);
}
rb_class_inherited (reversed semantics!) |
public IRubyObject inherited(ThreadContext context,
IRubyObject arg) {
return context.getRuntime().getNil();
}
|
public IRubyObject initialize(IRubyObject[] args,
Block block) {
if (superClass != null) {
throw getRuntime().newTypeError("already initialized class");
}
IRubyObject superObject;
if (args.length == 0) {
superObject = getRuntime().getObject();
} else {
superObject = args[0];
checkInheritable(superObject);
}
RubyClass superClazz = (RubyClass) superObject;
superClass = superClazz;
allocator = superClazz.allocator;
makeMetaClass(superClazz.getMetaClass());
marshal = superClazz.marshal;
superClazz.addSubclass(this);
super.initialize(block);
inherit(superClazz);
return this;
}
|
public IRubyObject initialize_copy(IRubyObject original) {
if (superClass != null) throw runtime.newTypeError("already initialized class");
if (original instanceof MetaClass) throw getRuntime().newTypeError("can't copy singleton class");
super.initialize_copy(original);
allocator = ((RubyClass)original).allocator;
return this;
}
|
public IRubyObject invoke(ThreadContext context,
IRubyObject self,
String name,
IRubyObject[] args,
CallType callType,
Block block) {
assert args != null;
DynamicMethod method = searchMethod(name);
if (method.isUndefined() || (!name.equals("method_missing") && !method.isCallableFrom(context.getFrameSelf(), callType))) {
return RuntimeHelpers.callMethodMissing(context, self, method, name, args, context.getFrameSelf(), callType, block);
}
return method.call(context, self, this, name, args, block);
}
|
public IRubyObject invoke(ThreadContext context,
IRubyObject self,
String name,
IRubyObject arg,
CallType callType,
Block block) {
DynamicMethod method = searchMethod(name);
if (method.isUndefined() || (!name.equals("method_missing") && !method.isCallableFrom(context.getFrameSelf(), callType))) {
return RuntimeHelpers.callMethodMissing(context, self, method, name,
new IRubyObject[] {arg}, context.getFrameSelf(), callType, block);
}
return method.call(context, self, this, name, arg, block);
}
|
public IRubyObject invoke(ThreadContext context,
IRubyObject self,
int methodIndex,
String name,
IRubyObject[] args,
CallType callType,
Block block) {
if (context.getRuntime().hasEventHooks()) return invoke(context, self, name, args, callType, block);
return dispatcher.callMethod(context, self, this, methodIndex, name, args, callType, block);
}
|
public IRubyObject invokeInherited(ThreadContext context,
IRubyObject self,
IRubyObject subclass) {
DynamicMethod method = getMetaClass().searchMethod("inherited");
if (method.isUndefined()) {
return RuntimeHelpers.callMethodMissing(context, self, method, "inherited",
new IRubyObject[] {subclass}, context.getFrameSelf(), CallType.FUNCTIONAL, Block.NULL_BLOCK);
}
return method.call(context, self, getMetaClass(), "inherited", subclass, Block.NULL_BLOCK);
}
|
public boolean isClass() {
return true;
}
|
public boolean isModule() {
return false;
}
|
public boolean isSingleton() {
return false;
}
|
public RubyClass makeMetaClass(RubyClass superClass) {
if (isSingleton()) { // could be pulled down to RubyClass in future
MetaClass klass = new MetaClass(getRuntime(), superClass); // rb_class_boot
setMetaClass(klass);
klass.setAttached(this);
klass.setMetaClass(klass);
klass.setSuperClass(getSuperClass().getRealClass().getMetaClass());
return klass;
} else {
return super.makeMetaClass(superClass);
}
}
|
public final void marshal(Object obj,
MarshalStream marshalStream) throws IOException {
getMarshal().marshalTo(getRuntime(), obj, this, marshalStream);
}
|
public static void marshalTo(RubyClass clazz,
MarshalStream output) throws IOException {
output.registerLinkTarget(clazz);
output.writeString(MarshalStream.getPathFromClass(clazz));
}
|
public static RubyClass newClass(Ruby runtime,
RubyClass superClass) {
if (superClass == runtime.getClassClass()) throw runtime.newTypeError("can't make subclass of Class");
if (superClass.isSingleton()) throw runtime.newTypeError("can't make subclass of virtual class");
return new RubyClass(runtime, superClass);
}
|
public static RubyClass newClass(Ruby runtime,
RubyClass superClass,
String name,
ObjectAllocator allocator,
RubyModule parent,
boolean setParent) {
RubyClass clazz = newClass(runtime, superClass);
clazz.setBaseName(name);
clazz.setAllocator(allocator);
clazz.makeMetaClass(superClass.getMetaClass());
if (setParent) clazz.setParent(parent);
parent.setConstant(name, clazz);
clazz.inherit(superClass);
return clazz;
}
rb_class_new/rb_define_class_id/rb_name_class/rb_set_class_path |
public IRubyObject newInstance(ThreadContext context,
IRubyObject[] args,
Block block) {
IRubyObject obj = allocate();
obj.callMethod(context, "initialize", args, block);
return obj;
}
|
public void setAllocator(ObjectAllocator allocator) {
this.allocator = allocator;
}
|
public final void setMarshal(ObjectMarshal marshal) {
this.marshal = marshal;
}
|
public Collection subclasses(boolean includeDescendants) {
if (subclasses != null) {
Collection< RubyClass > mine = new ArrayList< RubyClass >(subclasses);
if (includeDescendants) {
for (RubyClass i: subclasses) {
mine.addAll(i.subclasses(includeDescendants));
}
}
return mine;
} else {
return Collections.EMPTY_LIST;
}
}
|
public IRubyObject subclasses(ThreadContext context,
IRubyObject[] args) {
boolean recursive = false;
if (args.length == 1) {
if (args[0] instanceof RubyBoolean) {
recursive = args[0].isTrue();
} else {
context.getRuntime().newTypeError(args[0], context.getRuntime().fastGetClass("Boolean"));
}
}
return RubyArray.newArray(context.getRuntime(), subclasses(recursive)).freeze(context);
}
|
public IRubyObject superclass(ThreadContext context) {
RubyClass superClazz = superClass;
if (superClazz == null) throw context.getRuntime().newTypeError("uninitialized class");
if (isSingleton()) superClazz = metaClass;
while (superClazz != null && superClazz.isIncluded()) superClazz = superClazz.superClass;
return superClazz != null ? superClazz : context.getRuntime().getNil();
}
Return the real super class of this class.
rb_class_superclass |
public final Object unmarshal(UnmarshalStream unmarshalStream) throws IOException {
return getMarshal().unmarshalFrom(getRuntime(), this, unmarshalStream);
}
|
public static RubyClass unmarshalFrom(UnmarshalStream input) throws IOException {
String name = RubyString.byteListToString(input.unmarshalString());
RubyClass result = UnmarshalStream.getClassFromPath(input.getRuntime(), name);
input.registerLinkTarget(result);
return result;
}
|