From ad1a15faaa31584fb6898fcd52c3b62be9c35960 Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Tue, 10 Nov 2015 11:29:52 +0100 Subject: [PATCH 1/8] New: Added runtime functions 'method_copyReturnType' and 'method_copyArgumentType'. --- Objective-J/Runtime.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Objective-J/Runtime.js b/Objective-J/Runtime.js index 2c07e2154..99bde2448 100644 --- a/Objective-J/Runtime.js +++ b/Objective-J/Runtime.js @@ -1025,6 +1025,18 @@ GLOBAL(method_getTypes) = function(/*Method*/ aMethod) return aMethod.method_types; } +GLOBAL(method_copyReturnType) = function(/*Method*/ aMethod) +{ + var types = aMethod.method_types; + return types ? types[0] : NULL; +} + +GLOBAL(method_copyArgumentType) = function(/*Method*/ aMethod, /*unsigned int*/ index) +{ + var types = aMethod.method_types; + return types ? types[index + 1] : NULL; +} + GLOBAL(method_getImplementation) = function(/*Method*/ aMethod) { return aMethod.method_imp; From 920daf7fde55385414d1f46e1f32483f75e9daa5 Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Tue, 10 Nov 2015 11:30:29 +0100 Subject: [PATCH 2/8] Fixed: Marked function 'method_getTypes' as deprecated --- Objective-J/Runtime.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Objective-J/Runtime.js b/Objective-J/Runtime.js index 99bde2448..9188017c2 100644 --- a/Objective-J/Runtime.js +++ b/Objective-J/Runtime.js @@ -1020,8 +1020,11 @@ GLOBAL(method_getName) = function(/*Method*/ aMethod) return aMethod.method_name; } +// FIXME: This function is deprecated and should be removed in a future release +// Please use 'method_copyReturnType' or 'method_copyArgumentType' GLOBAL(method_getTypes) = function(/*Method*/ aMethod) { + console.warn("Runtime function 'method_getTypes' is deprecated. Please use function 'method_copyReturnType' or 'method_copyArgumentType'"); return aMethod.method_types; } From e4560df62fa231327d5a50328d5f0216d6a878f8 Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Tue, 10 Nov 2015 11:31:04 +0100 Subject: [PATCH 3/8] Fixed: Use correct property in decorator --- Objective-J/Debug.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objective-J/Debug.js b/Objective-J/Debug.js index 532afc6f2..d8583f634 100644 --- a/Objective-J/Debug.js +++ b/Objective-J/Debug.js @@ -185,7 +185,7 @@ GLOBAL(objj_typecheck_decorator) = function(msgSend) if (!aReceiver) return msgSend.apply(this, arguments); - var types = aReceiver.isa.method_dtable[aSelector].types; + var types = aReceiver.isa.method_dtable[aSelector].method_types; for (var i = 2; i < arguments.length; i++) { try From 3e0a6ea2cf2056a2fcc8b67b92dbd128f87ac9d9 Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Fri, 20 Nov 2015 14:52:53 +0100 Subject: [PATCH 4/8] Fixed: Return NULL when out of bounce --- Objective-J/Runtime.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Objective-J/Runtime.js b/Objective-J/Runtime.js index 9188017c2..3b816d4ca 100644 --- a/Objective-J/Runtime.js +++ b/Objective-J/Runtime.js @@ -1031,13 +1031,29 @@ GLOBAL(method_getTypes) = function(/*Method*/ aMethod) GLOBAL(method_copyReturnType) = function(/*Method*/ aMethod) { var types = aMethod.method_types; - return types ? types[0] : NULL; + + if (types) + { + var argType = types[0]; + + return argType != NULL ? argType : NULL; + } + else + return NULL; } GLOBAL(method_copyArgumentType) = function(/*Method*/ aMethod, /*unsigned int*/ index) { var types = aMethod.method_types; - return types ? types[index + 1] : NULL; + + if (types) + { + var argType = types[index + 1]; + + return argType != NULL ? argType : NULL; + } + else + return NULL; } GLOBAL(method_getImplementation) = function(/*Method*/ aMethod) From d0fd53a2ca4f85a39406a4c4eb6063ea70d525b7 Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Fri, 20 Nov 2015 14:53:46 +0100 Subject: [PATCH 5/8] Added: Function method_getNumberOfArguments --- Objective-J/Runtime.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Objective-J/Runtime.js b/Objective-J/Runtime.js index 3b816d4ca..d435455e0 100644 --- a/Objective-J/Runtime.js +++ b/Objective-J/Runtime.js @@ -1056,6 +1056,13 @@ GLOBAL(method_copyArgumentType) = function(/*Method*/ aMethod, /*unsigned int*/ return NULL; } +GLOBAL(method_getNumberOfArguments) = function(/*Method*/ aMethod) +{ + var types = aMethod.method_types; + + return types ? types.length - 1 : ((aMethod.method_name.match(/:/g) || []).length); +} + GLOBAL(method_getImplementation) = function(/*Method*/ aMethod) { return aMethod.method_imp; From 141d737ca5fbe1c7b650e7cda25fc9b7a545f535 Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Fri, 20 Nov 2015 14:54:11 +0100 Subject: [PATCH 6/8] Fixed: Removed old function instead of mark it deprecated --- Objective-J/Runtime.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Objective-J/Runtime.js b/Objective-J/Runtime.js index d435455e0..a97fa0e48 100644 --- a/Objective-J/Runtime.js +++ b/Objective-J/Runtime.js @@ -1020,14 +1020,6 @@ GLOBAL(method_getName) = function(/*Method*/ aMethod) return aMethod.method_name; } -// FIXME: This function is deprecated and should be removed in a future release -// Please use 'method_copyReturnType' or 'method_copyArgumentType' -GLOBAL(method_getTypes) = function(/*Method*/ aMethod) -{ - console.warn("Runtime function 'method_getTypes' is deprecated. Please use function 'method_copyReturnType' or 'method_copyArgumentType'"); - return aMethod.method_types; -} - GLOBAL(method_copyReturnType) = function(/*Method*/ aMethod) { var types = aMethod.method_types; From 58aeb2e40f6da4e22344065bf79b7136fd1af342 Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Fri, 20 Nov 2015 14:54:23 +0100 Subject: [PATCH 7/8] Fixed: Add test cases --- .../Preprocessor/BehaviorTests/MethodTest.j | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/Tests/Objective-J/Preprocessor/BehaviorTests/MethodTest.j b/Tests/Objective-J/Preprocessor/BehaviorTests/MethodTest.j index 99aef883b..3d70e07ce 100644 --- a/Tests/Objective-J/Preprocessor/BehaviorTests/MethodTest.j +++ b/Tests/Objective-J/Preprocessor/BehaviorTests/MethodTest.j @@ -80,4 +80,53 @@ [self assert:-6 equals:[testClass void:10 in:4]]; } +- (void)testMethodName +{ + var method = class_getInstanceMethod(MathClass, @selector(sqrt:)); + + [self assert:method_getName(method) equals:@"sqrt:"]; +} + +- (void)testMethodNoArguments +{ + var method = class_getInstanceMethod(MathClass, @selector(five)); + + [self assert:method_getNumberOfArguments(method) equals:0]; + + method = class_getInstanceMethod(MathClass, @selector(multiply:)); + [self assert:method_getNumberOfArguments(method) equals:1]; + + method = class_getInstanceMethod(MathClass, @selector(multiply:with:)); + [self assert:method_getNumberOfArguments(method) equals:2]; +} + +- (void)testMethodTypes +{ + var theClass = objj_allocateClassPair(CPObject, RAND() + ""); + + objj_registerClassPair(theClass); + class_addMethod(theClass, @"myMethod:", function() { }, ["void", "CPNumber"]); + class_addMethod(theClass, @"myMethod2:", function() { }, ["int", "float"]); + class_addMethod(theClass, @"myMethod3:", function() { }); + [theClass new]; + + 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]; + + 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]; + + 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]; +} + @end From c2f95f795306c4ecf88e45d946b0d522fa7b2b3a Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Mon, 23 Nov 2015 10:48:15 +0100 Subject: [PATCH 8/8] 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