From e23a907053d46f6db4b3123316ef8d671fb3714a Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Thu, 13 Sep 2012 02:02:06 -0700 Subject: [PATCH] Fix the implementation of cy$toJSON for primitives. --- ObjectiveC/Library.mm | 80 ++++++++++++++----------------------------- todo.txt | 3 +- 2 files changed, 28 insertions(+), 55 deletions(-) diff --git a/ObjectiveC/Library.mm b/ObjectiveC/Library.mm index a113779..e3b8917 100644 --- a/ObjectiveC/Library.mm +++ b/ObjectiveC/Library.mm @@ -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(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(dlsym(RTLD_DEFAULT, "objc_setAssociatedObject")); $objc_getAssociatedObject = reinterpret_cast(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(&NSCFType$cy$toJSON), "@12@0:4@8"); + class_addMethod(NSCFType_, @selector(cy$toJSON:inContext:), reinterpret_cast(&NSCFType$cy$toJSON$inContext$), "^{OpaqueJSValue=}16@0:4@8^{OpaqueJSContext=}12"); #endif } CYPoolCatch() } diff --git a/todo.txt b/todo.txt index f6b5863..28f2580 100644 --- 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... :( :( -- 2.45.2