99#import " JSBMessageForwarding.h"
1010#import " JSBScriptingSupport.h"
1111
12+ NSString * const JSBInstanceMembersKey = @" instanceMembers" ;
13+ NSString * const JSBStaticMembersKey = @" staticMembers" ;
14+
1215@import JavaScriptCore;
1316@import ObjectiveC;
1417
3639 return propertyName;
3740}
3841
42+ JSValue *propertyForObject (id obj, NSString *propertyName)
43+ {
44+ JSContext *context = [JSBScriptingSupport globalContext ];
45+
46+ JSValue *properties = nil ;
47+
48+ Class cls = object_getClass (obj);
49+ if (class_isMetaClass (cls)) {
50+ properties = context[mangledNameFromClass (obj)][JSBStaticMembersKey];
51+ } else {
52+ properties = context[mangledNameFromClass (cls)][JSBInstanceMembersKey];
53+ }
54+
55+ return properties[propertyName];
56+ }
57+
3958#pragma mark -
4059
4160void invokeSuper (NSInvocation *inv)
@@ -196,7 +215,7 @@ CGFloat tableViewHeightForRowAtIndexPath(id self, SEL _cmd, UITableView *tableVi
196215 JSContext *context = [JSBScriptingSupport globalContext ];
197216
198217 NSString *propertyName = propertyNameFromSelector (_cmd);
199- JSValue *function = context[mangledNameFromClass ([ self class ])][ @" instanceMembers " ][propertyName];
218+ JSValue *function = context[mangledNameFromClass (object_getClass ( self ))][JSBInstanceMembersKey ][propertyName];
200219
201220 if (!function.isUndefined ) {
202221 JSValue *returnValue = [function callWithArguments: @[tableView, indexPath]];
@@ -211,7 +230,7 @@ CGFloat tableViewHeightForHeaderInSection(id self, SEL _cmd, UITableView *tableV
211230 JSContext *context = [JSBScriptingSupport globalContext ];
212231
213232 NSString *propertyName = propertyNameFromSelector (_cmd);
214- JSValue *function = context[mangledNameFromClass ([ self class ])][ @" instanceMembers " ][propertyName];
233+ JSValue *function = context[mangledNameFromClass (object_getClass ( self ))][JSBInstanceMembersKey ][propertyName];
215234
216235 if (!function.isUndefined ) {
217236 JSValue *returnValue = [function callWithArguments: @[tableView, @(section)]];
@@ -226,7 +245,7 @@ CGFloat tableViewHeightForFooterInSection(id self, SEL _cmd, UITableView *tableV
226245 JSContext *context = [JSBScriptingSupport globalContext ];
227246
228247 NSString *propertyName = propertyNameFromSelector (_cmd);
229- JSValue *function = context[mangledNameFromClass ([ self class ])][ @" instanceMembers " ][propertyName];
248+ JSValue *function = context[mangledNameFromClass (object_getClass ( self ))][JSBInstanceMembersKey ][propertyName];
230249
231250 if (!function.isUndefined ) {
232251 JSValue *returnValue = [function callWithArguments: @[tableView, @(section)]];
@@ -238,16 +257,16 @@ CGFloat tableViewHeightForFooterInSection(id self, SEL _cmd, UITableView *tableV
238257
239258#pragma mark -
240259
241- void setupForwardingImplementations (Class targetClass, Class cls, JSValue *functions )
260+ void setupForwardingImplementations (Class targetClass, Class cls, JSValue *instanceFunctions, JSValue *staticFunctions )
242261{
243- unsigned int count = 0 ;
244- Method *methods = class_copyMethodList (cls, &count );
245- for (unsigned int i = 0 ; i < count ; i++) {
246- Method m = methods [i];
247- struct objc_method_description *description = method_getDescription (m );
262+ unsigned int numberOfInstanceMethods = 0 ;
263+ Method *instanceMethods = class_copyMethodList (cls, &numberOfInstanceMethods );
264+ for (unsigned int i = 0 ; i < numberOfInstanceMethods ; i++) {
265+ Method method = instanceMethods [i];
266+ struct objc_method_description *description = method_getDescription (method );
248267
249268 NSString *propertyName = propertyNameFromSelector (description->name );
250- JSValue *function = functions [propertyName];
269+ JSValue *function = instanceFunctions [propertyName];
251270 if (!function.isUndefined ) {
252271 if (strcmp (@encode (NSInteger ), " q" ) == 0 ) { // for 64bit devices
253272 if (description->name == @selector (tableView:heightForRowAtIndexPath: )) {
@@ -274,13 +293,31 @@ void setupForwardingImplementations(Class targetClass, Class cls, JSValue *funct
274293 class_addMethod (targetClass, description->name , _objc_msgForward, description->types );
275294 }
276295 }
277- if (methods) {
278- free (methods);
296+ if (instanceMethods) {
297+ free (instanceMethods);
298+ }
299+
300+ unsigned int numberOfClassMethods = 0 ;
301+ Class metaClass = objc_getMetaClass (class_getName (cls));
302+ Class targetMetaClass = objc_getMetaClass (class_getName (targetClass));
303+ Method *classMethods = class_copyMethodList (metaClass, &numberOfClassMethods);
304+ for (unsigned int i = 0 ; i < numberOfClassMethods; i++) {
305+ Method method = classMethods[i];
306+ struct objc_method_description *description = method_getDescription (method);
307+
308+ NSString *propertyName = propertyNameFromSelector (description->name );
309+ JSValue *function = staticFunctions[propertyName];
310+ if (!function.isUndefined ) {
311+ class_addMethod (targetMetaClass, description->name , _objc_msgForward, description->types );
312+ }
313+ }
314+ if (classMethods) {
315+ free (classMethods);
279316 }
280317
281318 Class superClass = class_getSuperclass (cls);
282319 if (superClass) {
283- setupForwardingImplementations (targetClass, superClass, functions );
320+ setupForwardingImplementations (targetClass, superClass, instanceFunctions, staticFunctions );
284321 }
285322}
286323
@@ -298,7 +335,7 @@ void forwardInvocation(id self, SEL _cmd, NSInvocation *invocation)
298335 context[@" self" ] = self;
299336
300337 NSString *propertyName = propertyNameFromSelector (invocation.selector );
301- JSValue *function = context[ mangledNameFromClass ([ self class ])][ @" instanceMembers " ][ propertyName] ;
338+ JSValue *function = propertyForObject ( self, propertyName) ;
302339
303340 if (!function.isUndefined ) {
304341 NSArray *arguments = extractArguments (invocation);
@@ -313,11 +350,18 @@ void forwardInvocation(id self, SEL _cmd, NSInvocation *invocation)
313350NSMethodSignature *methodSignatureForSelector (id self, SEL _cmd, SEL selector)
314351{
315352 NSMethodSignature *methodSignature = nil ;
353+ Class cls = object_getClass (self);
316354
317- Class cls = [self class ];
318- methodSignature = [cls instanceMethodSignatureForSelector: selector];
319- if (methodSignature) {
320- return methodSignature;
355+ if (class_isMetaClass (cls)) {
356+ methodSignature = [cls instanceMethodSignatureForSelector: selector];
357+ if (methodSignature) {
358+ return methodSignature;
359+ }
360+ } else {
361+ methodSignature = [cls instanceMethodSignatureForSelector: selector];
362+ if (methodSignature) {
363+ return methodSignature;
364+ }
321365 }
322366
323367 NSUInteger numberOfArguments = [[NSStringFromSelector (selector) componentsSeparatedByString: @" :" ] count ] - 1 ;
@@ -326,10 +370,8 @@ void forwardInvocation(id self, SEL _cmd, NSInvocation *invocation)
326370
327371BOOL respondsToSelector (id self, SEL _cmd, SEL selector)
328372{
329- JSContext *context = [JSBScriptingSupport globalContext ];
330-
331373 NSString *propertyName = propertyNameFromSelector (selector);
332- JSValue *value = context[ mangledNameFromClass ([ self class ])][ @" instanceMembers " ][ propertyName] ;
374+ JSValue *function = propertyForObject ( self, propertyName) ;
333375
334- return !value .isUndefined ;
376+ return !function .isUndefined ;
335377}
0 commit comments