]> git.saurik.com Git - cycript.git/commitdiff
Fix the implementation of cy$toJSON for primitives.
authorJay Freeman (saurik) <saurik@saurik.com>
Thu, 13 Sep 2012 09:02:06 +0000 (02:02 -0700)
committerJay Freeman (saurik) <saurik@saurik.com>
Thu, 13 Sep 2012 09:08:17 +0000 (02:08 -0700)
ObjectiveC/Library.mm
todo.txt

index a113779c0beafbbc092d0ad705da238f62c7dbcc..e3b8917ea6d914140b6d16ea67014087d54f6b09 100644 (file)
@@ -394,7 +394,7 @@ JSObjectRef CYMakeInstance(JSContextRef context, id object, bool transient) {
 - (JSValueRef) cy$valueOfInContext:(JSContextRef)context;
 - (JSType) cy$JSType;
 
-- (NSObject *) cy$toJSON:(NSString *)key;
+- (JSValueRef) cy$toJSON:(NSString *)key inContext:(JSContextRef)context;
 - (NSString *) cy$toCYON:(bool)objective;
 
 - (bool) cy$hasProperty:(NSString *)name;
@@ -538,12 +538,6 @@ struct PropertyAttributes {
 };
 #endif
 
-#ifdef __APPLE__
-NSObject *NSCFType$cy$toJSON(id self, SEL sel, NSString *key) {
-    return [(NSString *) CFCopyDescription((CFTypeRef) self) autorelease];
-}
-#endif
-
 #ifndef __APPLE__
 @interface CYWebUndefined : NSObject {
 }
@@ -572,8 +566,6 @@ NSObject *NSCFType$cy$toJSON(id self, SEL sel, NSString *key) {
 
 - (id) initWithJSObject:(JSObjectRef)object inContext:(JSContextRef)context;
 
-- (NSObject *) cy$toJSON:(NSString *)key;
-
 - (NSUInteger) count;
 - (id) objectForKey:(id)key;
 - (NSEnumerator *) keyEnumerator;
@@ -788,10 +780,6 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
     return kJSTypeBoolean;
 }
 
-- (NSObject *) cy$toJSON:(NSString *)key {
-    return self;
-}
-
 - (NSString *) cy$toCYON:(bool)objective {
     NSString *value([self boolValue] ? @"true" : @"false");
     return objective ? value : [NSString stringWithFormat:@"@%@", value];
@@ -949,10 +937,6 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
     return kJSTypeNumber;
 }
 
-- (NSObject *) cy$toJSON:(NSString *)key {
-    return self;
-}
-
 - (NSString *) cy$toCYON:(bool)objective {
     NSString *value([self cy$JSType] != kJSTypeBoolean ? [self stringValue] : [self boolValue] ? @"true" : @"false");
     return objective ? value : [NSString stringWithFormat:@"@%@", value];
@@ -971,15 +955,15 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
     return kJSTypeNull;
 }
 
-- (NSObject *) cy$toJSON:(NSString *)key {
-    return self;
-}
-
 - (NSString *) cy$toCYON:(bool)objective {
     NSString *value(@"null");
     return objective ? value : [NSString stringWithFormat:@"@%@", value];
 }
 
+- (JSValueRef) cy$valueOfInContext:(JSContextRef)context { CYObjectiveTry_(context) {
+    return CYJSNull(context);
+} CYObjectiveCatch }
+
 @end
 /* }}} */
 /* Bridge: NSObject {{{ */
@@ -989,6 +973,10 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
     return self;
 }
 
+- (JSValueRef) cy$toJSON:(NSString *)key inContext:(JSContextRef)context {
+    return [self cy$valueOfInContext:context];
+}
+
 - (JSValueRef) cy$valueOfInContext:(JSContextRef)context { CYObjectiveTry_(context) {
     return NULL;
 } CYObjectiveCatch }
@@ -997,12 +985,8 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
     return kJSTypeObject;
 }
 
-- (NSObject *) cy$toJSON:(NSString *)key {
-    return [self description];
-}
-
 - (NSString *) cy$toCYON:(bool)objective {
-    return [[self cy$toJSON:@""] cy$toCYON:objective];
+    return [[self description] cy$toCYON:objective];
 }
 
 - (bool) cy$hasProperty:(NSString *)name {
@@ -1033,12 +1017,8 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
 /* Bridge: NSProxy {{{ */
 @implementation NSProxy (Cycript)
 
-- (NSObject *) cy$toJSON:(NSString *)key {
-    return [self description];
-}
-
 - (NSString *) cy$toCYON:(bool)objective {
-    return [[self cy$toJSON:@""] cy$toCYON:objective];
+    return [[self description] cy$toCYON:objective];
 }
 
 @end
@@ -1054,10 +1034,6 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
     return kJSTypeString;
 }
 
-- (NSObject *) cy$toJSON:(NSString *)key {
-    return self;
-}
-
 - (NSString *) cy$toCYON:(bool)objective {
     std::ostringstream str;
     if (!objective)
@@ -1124,10 +1100,6 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
     return kJSTypeUndefined;
 }
 
-- (NSObject *) cy$toJSON:(NSString *)key {
-    return self;
-}
-
 - (NSString *) cy$toCYON {
     NSString *value(@"undefined");
     return value; // XXX: maybe use the below code, adding @undefined?
@@ -1191,18 +1163,6 @@ JSValueRef CYCastJSValue(JSContextRef context, NSObject *value) { CYPoolTry {
     [super dealloc];
 } CYObjectiveCatch }
 
-- (NSObject *) cy$toJSON:(NSString *)key { CYObjectiveTry {
-    JSValueRef toJSON(CYGetProperty(context_, object_, toJSON_s));
-    if (!CYIsCallable(context_, toJSON))
-        return [super cy$toJSON:key];
-    else {
-        JSValueRef arguments[1] = {CYCastJSValue(context_, key)};
-        JSValueRef value(CYCallAsFunction(context_, (JSObjectRef) toJSON, object_, 1, arguments));
-        // XXX: do I really want an NSNull here?!
-        return CYCastNSObject(NULL, context_, value) ?: [NSNull null];
-    }
-} CYObjectiveCatch }
-
 - (NSString *) cy$toCYON:(bool)objective { CYObjectiveTry {
     CYPool pool;
     JSValueRef exception(NULL);
@@ -2400,6 +2360,7 @@ static JSValueRef Instance_callAsFunction_toJSON(JSContextRef context, JSObjectR
         return NULL;
 
     Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(_this)));
+    id value(internal->GetValue());
 
     CYPoolTry {
         NSString *key;
@@ -2407,8 +2368,13 @@ static JSValueRef Instance_callAsFunction_toJSON(JSContextRef context, JSObjectR
             key = nil;
         else
             key = CYCastNSString(NULL, context, CYJSString(context, arguments[0]));
-        // XXX: check for support of cy$toJSON?
-        return CYCastJSValue(context, CYJSString(context, [internal->GetValue() cy$toJSON:key]));
+
+        if (!CYImplements(value, object_getClass(value), @selector(cy$toJSON:inContext:)))
+            return CYJSUndefined(context);
+        else if (JSValueRef json = [value cy$toJSON:key inContext:context])
+            return json;
+        else
+            return CYCastJSValue(context, CYJSString(context, [value description]));
     } CYPoolCatch(NULL)
 } CYCatch return /*XXX*/ NULL; }
 
@@ -2528,6 +2494,12 @@ static JSStaticFunction Selector_staticFunctions[5] = {
     {NULL, NULL, 0}
 };
 
+#ifdef __APPLE__
+JSValueRef NSCFType$cy$toJSON$inContext$(id self, SEL sel, JSValueRef key, JSContextRef context) { CYObjectiveTry_(context) {
+    return CYCastJSValue(context, [(NSString *) CFCopyDescription((CFTypeRef) self) autorelease]);
+} CYObjectiveCatch }
+#endif
+
 void CYObjectiveC_Initialize() { /*XXX*/ JSContextRef context(NULL); CYPoolTry {
     $objc_setAssociatedObject = reinterpret_cast<void (*)(id, void *, id value, objc_AssociationPolicy)>(dlsym(RTLD_DEFAULT, "objc_setAssociatedObject"));
     $objc_getAssociatedObject = reinterpret_cast<id (*)(id, void *)>(dlsym(RTLD_DEFAULT, "objc_getAssociatedObject"));
@@ -2663,7 +2635,7 @@ void CYObjectiveC_Initialize() { /*XXX*/ JSContextRef context(NULL); CYPoolTry {
     ObjectiveC_Protocols_ = JSClassCreate(&definition);
 
 #ifdef __APPLE__
-    class_addMethod(NSCFType_, @selector(cy$toJSON:), reinterpret_cast<IMP>(&NSCFType$cy$toJSON), "@12@0:4@8");
+    class_addMethod(NSCFType_, @selector(cy$toJSON:inContext:), reinterpret_cast<IMP>(&NSCFType$cy$toJSON$inContext$), "^{OpaqueJSValue=}16@0:4@8^{OpaqueJSContext=}12");
 #endif
 } CYPoolCatch() }
 
index f6b586347ae0609c0800c7cccc21840745032167..28f2580c42d8042595b5a31b2e0707188a45a5d9 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -87,7 +87,8 @@ with is being translated in a manner that doesn't handle variables
 cy# function b() { for each (var t in a) {} }
 function b(){var e,t,n;with({t:a,n:undefined})for(n in t)e=t[n]}
 
-I feel like [[self toJSON] toCYON] might should be one or the other
+[[self description] cy$toCYON:] seems like a poor implementation of toCYON
+implement cy$toJSON:inContext: for NSDictionary and NSArray
 
 the non-local transform used for let is ludicrous... :( :(