]> git.saurik.com Git - apple/objc4.git/blob - test/getMethod.m
objc4-787.1.tar.gz
[apple/objc4.git] / test / getMethod.m
1 /*
2 TEST_BUILD_OUTPUT
3 .*getMethod.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
4 .*getMethod.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
5 .*getMethod.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
6 .*getMethod.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
7 END
8 */
9
10 #include "test.h"
11 #include "testroot.i"
12 #include <objc/runtime.h>
13 #include <objc/message.h>
14
15 static int state = 0;
16
17 @interface Super : TestRoot @end
18 @implementation Super
19 +(void)classMethod { state = 1; }
20 -(void)instanceMethod { state = 4; }
21 +(void)classMethodSuperOnly { state = 3; }
22 -(void)instanceMethodSuperOnly { state = 6; }
23 @end
24
25 @interface Sub : Super @end
26 @implementation Sub
27 +(void)classMethod { state = 2; }
28 -(void)instanceMethod { state = 5; }
29 @end
30
31 typedef void (*imp_t)(id, SEL);
32
33 int main()
34 {
35 Class Super_cls, Sub_cls;
36 Class buf[10];
37 Method m;
38 SEL sel;
39 IMP imp;
40
41 id bufobj = (__bridge_transfer id)(void*)buf;
42
43 // don't use [Super class] to check laziness handing
44 Super_cls = objc_getClass("Super");
45 Sub_cls = objc_getClass("Sub");
46
47 sel = sel_registerName("classMethod");
48 m = class_getClassMethod(Super_cls, sel);
49 testassert(m);
50 testassert(sel == method_getName(m));
51 imp = method_getImplementation(m);
52 testassert(imp == class_getMethodImplementation(object_getClass(Super_cls), sel));
53 testassert(imp == object_getMethodImplementation(Super_cls, sel));
54 state = 0;
55 (*(imp_t)imp)(Super_cls, sel);
56 testassert(state == 1);
57
58 sel = sel_registerName("classMethod");
59 m = class_getClassMethod(Sub_cls, sel);
60 testassert(m);
61 testassert(sel == method_getName(m));
62 imp = method_getImplementation(m);
63 testassert(imp == class_getMethodImplementation(object_getClass(Sub_cls), sel));
64 testassert(imp == object_getMethodImplementation(Sub_cls, sel));
65 state = 0;
66 (*(imp_t)imp)(Sub_cls, sel);
67 testassert(state == 2);
68
69 sel = sel_registerName("classMethodSuperOnly");
70 m = class_getClassMethod(Sub_cls, sel);
71 testassert(m);
72 testassert(sel == method_getName(m));
73 imp = method_getImplementation(m);
74 testassert(imp == class_getMethodImplementation(object_getClass(Sub_cls), sel));
75 testassert(imp == object_getMethodImplementation(Sub_cls, sel));
76 state = 0;
77 (*(imp_t)imp)(Sub_cls, sel);
78 testassert(state == 3);
79
80 sel = sel_registerName("instanceMethod");
81 m = class_getInstanceMethod(Super_cls, sel);
82 testassert(m);
83 testassert(sel == method_getName(m));
84 imp = method_getImplementation(m);
85 testassert(imp == class_getMethodImplementation(Super_cls, sel));
86 buf[0] = Super_cls;
87 testassert(imp == object_getMethodImplementation(bufobj, sel));
88 state = 0;
89 (*(imp_t)imp)(bufobj, sel);
90 testassert(state == 4);
91
92 sel = sel_registerName("instanceMethod");
93 m = class_getInstanceMethod(Sub_cls, sel);
94 testassert(m);
95 testassert(sel == method_getName(m));
96 imp = method_getImplementation(m);
97 testassert(imp == class_getMethodImplementation(Sub_cls, sel));
98 buf[0] = Sub_cls;
99 testassert(imp == object_getMethodImplementation(bufobj, sel));
100 state = 0;
101 (*(imp_t)imp)(bufobj, sel);
102 testassert(state == 5);
103
104 sel = sel_registerName("instanceMethodSuperOnly");
105 m = class_getInstanceMethod(Sub_cls, sel);
106 testassert(m);
107 testassert(sel == method_getName(m));
108 imp = method_getImplementation(m);
109 testassert(imp == class_getMethodImplementation(Sub_cls, sel));
110 buf[0] = Sub_cls;
111 testassert(imp == object_getMethodImplementation(bufobj, sel));
112 state = 0;
113 (*(imp_t)imp)(bufobj, sel);
114 testassert(state == 6);
115
116 // check class_getClassMethod(cls) == class_getInstanceMethod(cls->isa)
117 sel = sel_registerName("classMethod");
118 testassert(class_getClassMethod(Sub_cls, sel) == class_getInstanceMethod(object_getClass(Sub_cls), sel));
119
120 sel = sel_registerName("nonexistent");
121 testassert(! class_getInstanceMethod(Sub_cls, sel));
122 testassert(! class_getClassMethod(Sub_cls, sel));
123 testassert(class_getMethodImplementation(Sub_cls, sel) == (IMP)&_objc_msgForward);
124 buf[0] = Sub_cls;
125 testassert(object_getMethodImplementation(bufobj, sel) == (IMP)&_objc_msgForward);
126 #if !__arm64__
127 testassert(class_getMethodImplementation_stret(Sub_cls, sel) == (IMP)&_objc_msgForward_stret);
128 testassert(object_getMethodImplementation_stret(bufobj, sel) == (IMP)&_objc_msgForward_stret);
129 #endif
130
131 testassert(! class_getInstanceMethod(NULL, NULL));
132 testassert(! class_getInstanceMethod(NULL, sel));
133 testassert(! class_getInstanceMethod(Sub_cls, NULL));
134 testassert(! class_getClassMethod(NULL, NULL));
135 testassert(! class_getClassMethod(NULL, sel));
136 testassert(! class_getClassMethod(Sub_cls, NULL));
137
138 succeed(__FILE__);
139 }