mirror of
https://github.com/darlinghq/darling-objc4.git
synced 2024-11-26 21:50:26 +00:00
151 lines
3.5 KiB
Objective-C
151 lines
3.5 KiB
Objective-C
// TEST_CFLAGS -Wno-deprecated-declarations -Wl,-no_objc_category_merging
|
|
|
|
#include "test.h"
|
|
#include "testroot.i"
|
|
#include <objc/runtime.h>
|
|
|
|
static int state;
|
|
|
|
@protocol Proto
|
|
+(void)classMethod;
|
|
-(void)instanceMethod;
|
|
@end
|
|
|
|
@interface Super : TestRoot <Proto> {
|
|
int i;
|
|
}
|
|
@property int i;
|
|
@end
|
|
|
|
@implementation Super
|
|
@synthesize i;
|
|
|
|
+(void)classMethod {
|
|
state = 1;
|
|
}
|
|
|
|
-(void)instanceMethod {
|
|
state = 3;
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
#if __clang__
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
|
|
#endif
|
|
|
|
@implementation Super (Category)
|
|
|
|
+(void)classMethod {
|
|
state = 2;
|
|
}
|
|
|
|
-(void)instanceMethod {
|
|
state = 4;
|
|
}
|
|
|
|
@end
|
|
|
|
#if __clang__
|
|
#pragma clang diagnostic pop
|
|
#endif
|
|
|
|
|
|
int main()
|
|
{
|
|
Class clone;
|
|
Class cls;
|
|
Method *m1, *m2;
|
|
int i;
|
|
|
|
cls = [Super class];
|
|
clone = objc_duplicateClass(cls, "Super_copy", 0);
|
|
|
|
testassert(clone != cls);
|
|
testassert(object_getClass(clone) == object_getClass(cls));
|
|
testassert(class_getSuperclass(clone) == class_getSuperclass(cls));
|
|
testassert(class_getVersion(clone) == class_getVersion(cls));
|
|
testassert(class_isMetaClass(clone) == class_isMetaClass(cls));
|
|
testassert(class_getIvarLayout(clone) == class_getIvarLayout(cls));
|
|
testassert(class_getWeakIvarLayout(clone) == class_getWeakIvarLayout(cls));
|
|
|
|
// Check method list
|
|
|
|
m1 = class_copyMethodList(cls, NULL);
|
|
m2 = class_copyMethodList(clone, NULL);
|
|
testassert(m1);
|
|
testassert(m2);
|
|
for (i = 0; m1[i] && m2[i]; i++) {
|
|
testassert(m1[i] != m2[i]); // method list must be deep-copied
|
|
testassert(method_getName(m1[i]) == method_getName(m2[i]));
|
|
testassert(method_getImplementation(m1[i]) == method_getImplementation(m2[i]));
|
|
testassert(method_getTypeEncoding(m1[i]) == method_getTypeEncoding(m2[i]));
|
|
}
|
|
testassert(m1[i] == NULL && m2[i] == NULL);
|
|
free(m1);
|
|
free(m2);
|
|
|
|
// Check ivar list
|
|
Ivar *i1 = class_copyIvarList(cls, NULL);
|
|
Ivar *i2 = class_copyIvarList(clone, NULL);
|
|
testassert(i1);
|
|
testassert(i2);
|
|
for (i = 0; i1[i] && i2[i]; i++) {
|
|
testassert(i1[i] == i2[i]); // ivars are not deep-copied
|
|
}
|
|
testassert(i1[i] == NULL && i2[i] == NULL);
|
|
free(i1);
|
|
free(i2);
|
|
|
|
// Check protocol list
|
|
Protocol * __unsafe_unretained *p1 = class_copyProtocolList(cls, NULL);
|
|
Protocol * __unsafe_unretained *p2 = class_copyProtocolList(clone, NULL);
|
|
testassert(p1);
|
|
testassert(p2);
|
|
for (i = 0; p1[i] && p2[i]; i++) {
|
|
testassert(p1[i] == p2[i]); // protocols are not deep-copied
|
|
}
|
|
testassert(p1[i] == NULL && p2[i] == NULL);
|
|
free(p1);
|
|
free(p2);
|
|
|
|
// Check property list
|
|
objc_property_t *o1 = class_copyPropertyList(cls, NULL);
|
|
objc_property_t *o2 = class_copyPropertyList(clone, NULL);
|
|
testassert(o1);
|
|
testassert(o2);
|
|
for (i = 0; o1[i] && o2[i]; i++) {
|
|
testassert(o1[i] == o2[i]); // properties are not deep-copied
|
|
}
|
|
testassert(o1[i] == NULL && o2[i] == NULL);
|
|
free(o1);
|
|
free(o2);
|
|
|
|
// Check method calls
|
|
|
|
state = 0;
|
|
[cls classMethod];
|
|
testassert(state == 2);
|
|
state = 0;
|
|
[clone classMethod];
|
|
testassert(state == 2);
|
|
|
|
// #4511660 Make sure category implementation is still the preferred one
|
|
id obj;
|
|
obj = [cls new];
|
|
state = 0;
|
|
[obj instanceMethod];
|
|
testassert(state == 4);
|
|
RELEASE_VAR(obj);
|
|
|
|
obj = [clone new];
|
|
state = 0;
|
|
[obj instanceMethod];
|
|
testassert(state == 4);
|
|
RELEASE_VAR(obj);
|
|
|
|
succeed(__FILE__);
|
|
}
|