Merge pull request #2794 from mrcarlberg/initialize_missing_on_custom_root_class

Fixed: the class method +initialize was always sent even if the root class did not implement it.
This commit is contained in:
Alexandre Wilhelm authored and GitHub committed 2019-04-03 15:07:59 -07:00
commit 091025a304
2 files changed
+69 -16

No files matched your search

+5 -3
View File
@@ -504,9 +504,11 @@ var _class_initialize = function(/*Class*/ aClass)
meta.objj_msgSend3 = objj_msgSendFast3;
aClass.method_msgSend = aClass.method_dtable;
meta.method_msgSend = meta.method_dtable;
var metaMethodDTable = meta.method_msgSend = meta.method_dtable,
initializeImp = metaMethodDTable["initialize"];
meta.objj_msgSend0(aClass, "initialize");
if (initializeImp)
initializeImp(aClass, "initialize");
CHANGEINFO(meta, CLS_INITIALIZED, CLS_INITIALIZING);
}
@@ -583,7 +585,7 @@ GLOBAL(_objj_forward) = function(self, _cmd)
if (implementation)
return implementation(self, SEL_doesNotRecognizeSelector_, _cmd);
throw class_getName(isa) + " does not implement doesNotRecognizeSelector:. Did you forget a superclass for " + class_getName(isa) + "?";
throw class_getName(isa) + " does not implement doesNotRecognizeSelector: when sending " + sel_getName(_cmd) + ". Did you forget a superclass for " + class_getName(isa) + "?";
};
// I think this forward:: may need to be a common method, instead of defined in CPObject.
+64 -13
View File
@@ -13,6 +13,38 @@
@end
@implementation RootClassWithInitialize
{
}
+ (id)alloc
{
return class_createInstance(self);
}
+ (void)initialize
{
throw "Initialize";
}
@end
@implementation RootClassWithInitialize2
{
}
+ (id)alloc
{
return class_createInstance(self);
}
+ (void)initialize
{
throw "Initialize";
}
@end
@implementation RootClassWithDoesNotRecognizeSelector
{
}
@@ -24,7 +56,7 @@
- (void)doesNotRecognizeSelector:(SEL)aSelector
{
throw "ERROR";
throw "ERROR: " + sel_getName(aSelector);
}
@end
@@ -40,10 +72,6 @@
Class isa;
}
+ (void)initialize
{
}
+ (id)alloc
{
return class_createInstance(self);
@@ -88,10 +116,6 @@
{
}
+ (void)initialize
{
}
+ (id)alloc
{
return class_createInstance(self);
@@ -176,7 +200,7 @@ var GlobalMethodDispatchTest;
}
catch (anException)
{
[self assert:anException equals:"RootClass does not implement doesNotRecognizeSelector:. Did you forget a superclass for RootClass?"];
[self assert:anException equals:"RootClass does not implement doesNotRecognizeSelector: when sending doesNotExist. Did you forget a superclass for RootClass?"];
}
}
@@ -190,7 +214,34 @@ var GlobalMethodDispatchTest;
}
catch (anException)
{
[self assert:anException equals:"RootClass does not implement doesNotRecognizeSelector:. Did you forget a superclass for RootClass?"];
[self assert:anException equals:"RootClass does not implement doesNotRecognizeSelector: when sending doesNotExist. Did you forget a superclass for RootClass?"];
}
}
- (void)test_RootClassWithInitialize_class_initialize
{
try
{
[RootClassWithInitialize doesNotExist];
}
catch (anException)
{
[self assert:anException equals:"Initialize"];
}
}
- (void)test_RootClassWithInitialize_instance_initialize
{
// Here we create a new instance with Runtime function to not trigger the +initialize method.
// We also have to use a fresh new class or the +initialize method would have already been triggered.
var object = class_createInstance(RootClassWithInitialize2);
try
{
[object doesNotExist];
}
catch (anException)
{
[self assert:anException equals:"Initialize"];
}
}
@@ -202,7 +253,7 @@ var GlobalMethodDispatchTest;
}
catch (anException)
{
[self assert:anException equals:"ERROR"];
[self assert:anException equals:"ERROR: doesNotExist"];
}
}
@@ -216,7 +267,7 @@ var GlobalMethodDispatchTest;
}
catch (anException)
{
[self assert:anException equals:"ERROR"];
[self assert:anException equals:"ERROR: doesNotExist"];
}
}