From c2f95f795306c4ecf88e45d946b0d522fa7b2b3a Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Mon, 23 Nov 2015 10:48:15 +0100 Subject: [PATCH] Fixed: Runtime method argument functions will now comply to how Objective-C runtime works. --- Objective-J/Runtime.js | 29 +++++++++++++----- .../Preprocessor/BehaviorTests/MethodTest.j | 30 +++++++++++-------- 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/Objective-J/Runtime.js b/Objective-J/Runtime.js index a97fa0e48..2229a6e82 100644 --- a/Objective-J/Runtime.js +++ b/Objective-J/Runtime.js @@ -1020,6 +1020,7 @@ GLOBAL(method_getName) = function(/*Method*/ aMethod) return aMethod.method_name; } +// This will not return correct values if the compiler does not have the option 'IncludeTypeSignatures' GLOBAL(method_copyReturnType) = function(/*Method*/ aMethod) { var types = aMethod.method_types; @@ -1034,25 +1035,37 @@ GLOBAL(method_copyReturnType) = function(/*Method*/ aMethod) return NULL; } +// This will not return correct values for index > 1 if the compiler does not have the option 'IncludeTypeSignatures' GLOBAL(method_copyArgumentType) = function(/*Method*/ aMethod, /*unsigned int*/ index) { - var types = aMethod.method_types; + switch (index) { + case 0: + return "id"; - if (types) - { - var argType = types[index + 1]; + case 1: + return "SEL"; - return argType != NULL ? argType : NULL; + default: + var types = aMethod.method_types; + + if (types) + { + var argType = types[index - 1]; + + return argType != NULL ? argType : NULL; + } + else + return NULL; } - else - return NULL; } +// Returns number of arguments for a method. The first argument is 'self' and the second is the selector. +// Those are followed by the method arguments. So for example it will return 2 for a method with no arguments. GLOBAL(method_getNumberOfArguments) = function(/*Method*/ aMethod) { var types = aMethod.method_types; - return types ? types.length - 1 : ((aMethod.method_name.match(/:/g) || []).length); + return types ? types.length + 1 : ((aMethod.method_name.match(/:/g) || []).length + 2); } GLOBAL(method_getImplementation) = function(/*Method*/ aMethod) diff --git a/Tests/Objective-J/Preprocessor/BehaviorTests/MethodTest.j b/Tests/Objective-J/Preprocessor/BehaviorTests/MethodTest.j index 3d70e07ce..7df299459 100644 --- a/Tests/Objective-J/Preprocessor/BehaviorTests/MethodTest.j +++ b/Tests/Objective-J/Preprocessor/BehaviorTests/MethodTest.j @@ -87,17 +87,17 @@ [self assert:method_getName(method) equals:@"sqrt:"]; } -- (void)testMethodNoArguments +- (void)testMethodNoOfArguments { var method = class_getInstanceMethod(MathClass, @selector(five)); - [self assert:method_getNumberOfArguments(method) equals:0]; + [self assert:method_getNumberOfArguments(method) equals:2]; method = class_getInstanceMethod(MathClass, @selector(multiply:)); - [self assert:method_getNumberOfArguments(method) equals:1]; + [self assert:method_getNumberOfArguments(method) equals:3]; method = class_getInstanceMethod(MathClass, @selector(multiply:with:)); - [self assert:method_getNumberOfArguments(method) equals:2]; + [self assert:method_getNumberOfArguments(method) equals:4]; } - (void)testMethodTypes @@ -113,20 +113,26 @@ var method = class_getInstanceMethod(theClass, @selector(myMethod:)); [self assert:method_copyReturnType(method) equals:@"void" message:@"Return type of method 'myMethod:'"]; - [self assert:method_copyArgumentType(method, 0) equals:@"CPNumber"]; - [self assertTrue:method_copyArgumentType(method, 1) === nil]; - [self assert:method_getNumberOfArguments(method) equals:1]; + [self assert:method_copyArgumentType(method, 0) equals:@"id"]; + [self assert:method_copyArgumentType(method, 1) equals:@"SEL"]; + [self assert:method_copyArgumentType(method, 2) equals:@"CPNumber"]; + [self assertTrue:method_copyArgumentType(method, 3) === nil]; + [self assert:method_getNumberOfArguments(method) equals:3]; method = class_getInstanceMethod(theClass, @selector(myMethod2:)); [self assert:method_copyReturnType(method) equals:@"int" message:@"Return type of method 'myMethod2:'"]; - [self assert:method_copyArgumentType(method, 0) equals:@"float"]; - [self assertTrue:method_copyArgumentType(method, 1) === nil]; - [self assert:method_getNumberOfArguments(method) equals:1]; + [self assert:method_copyArgumentType(method, 0) equals:@"id"]; + [self assert:method_copyArgumentType(method, 1) equals:@"SEL"]; + [self assert:method_copyArgumentType(method, 2) equals:@"float"]; + [self assertTrue:method_copyArgumentType(method, 3) === nil]; + [self assert:method_getNumberOfArguments(method) equals:3]; method = class_getInstanceMethod(theClass, @selector(myMethod3:)); [self assertTrue:method_copyReturnType(method) == nil]; - [self assertTrue:method_copyArgumentType(method, 0) === nil]; - [self assert:method_getNumberOfArguments(method) equals:1]; + [self assert:method_copyArgumentType(method, 0) equals:@"id"]; + [self assert:method_copyArgumentType(method, 1) equals:@"SEL"]; + [self assertTrue:method_copyArgumentType(method, 2) === nil]; + [self assert:method_getNumberOfArguments(method) equals:3]; } @end