From 26ef7a82c9367b813682af1bea19e8e788efed64 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Sun, 3 Jun 2012 08:39:47 -0700 Subject: [PATCH] Expose Objective-C class names to tab completion. --- Execute.cpp | 37 ++++++++++++++++++++++++++++++------- JavaScript.hpp | 1 - ObjectiveC/Library.mm | 34 +++++++++++++++++++++++++++++++--- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/Execute.cpp b/Execute.cpp index 2cb0387..7eb2f80 100644 --- a/Execute.cpp +++ b/Execute.cpp @@ -954,17 +954,17 @@ static void *CYCastSymbol(const char *name) { static JSValueRef All_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry { JSObjectRef global(CYGetGlobalObject(context)); JSObjectRef cycript(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Cycript")))); - if (JSValueRef value = CYGetProperty(context, cycript, property)) - if (!JSValueIsUndefined(context, value)) - return value; + JSObjectRef alls(CYCastJSObject(context, CYGetProperty(context, cycript, CYJSString("alls")))); + + for (size_t i(0), count(CYArrayLength(context, alls)); i != count; ++i) + if (JSObjectRef space = CYCastJSObject(context, CYArrayGet(context, alls, count - i - 1))) + if (JSValueRef value = CYGetProperty(context, space, property)) + if (!JSValueIsUndefined(context, value)) + return value; CYPool pool; CYUTF8String name(CYPoolUTF8String(pool, context, property)); - if (hooks_ != NULL && hooks_->RuntimeProperty != NULL) - if (JSValueRef value = (*hooks_->RuntimeProperty)(context, name)) - return value; - size_t length(name.size); char keyed[length + 2]; memcpy(keyed + 1, name.data, length + 1); @@ -1003,6 +1003,20 @@ static JSValueRef All_getProperty(JSContextRef context, JSObjectRef object, JSSt return NULL; } CYCatch } +static void All_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef names) { + JSObjectRef global(CYGetGlobalObject(context)); + JSObjectRef cycript(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Cycript")))); + JSObjectRef alls(CYCastJSObject(context, CYGetProperty(context, cycript, CYJSString("alls")))); + + for (size_t i(0), count(CYArrayLength(context, alls)); i != count; ++i) + if (JSObjectRef space = CYCastJSObject(context, CYArrayGet(context, alls, count - i - 1))) { + JSPropertyNameArrayRef subset(JSObjectCopyPropertyNames(context, space)); + for (size_t index(0), count(JSPropertyNameArrayGetCount(subset)); index != count; ++index) + JSPropertyNameAccumulatorAddName(names, JSPropertyNameArrayGetNameAtIndex(subset, index)); + JSPropertyNameArrayRelease(subset); + } +} + static JSObjectRef Pointer_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { if (count != 2) throw CYJSError(context, "incorrect number of arguments to Functor constructor"); @@ -1265,6 +1279,7 @@ void CYInitializeDynamic() { definition = kJSClassDefinitionEmpty; definition.className = "All"; definition.getProperty = &All_getProperty; + definition.getPropertyNames = &All_getPropertyNames; All_ = JSClassCreate(&definition); definition = kJSClassDefinitionEmpty; @@ -1379,6 +1394,8 @@ JSGlobalContextRef CYGetJSContext(JSContextRef context) { } extern "C" void CYSetupContext(JSGlobalContextRef context) { + JSValueRef exception(NULL); + CYInitializeDynamic(); JSObjectRef global(CYGetGlobalObject(context)); @@ -1432,6 +1449,10 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) { JSObjectRef all(JSObjectMake(context, All_, NULL)); CYSetProperty(context, cycript, CYJSString("all"), all); + JSObjectRef alls(JSObjectCallAsConstructor(context, Array, 0, NULL, &exception)); + CYThrow(context, exception); + CYSetProperty(context, cycript, CYJSString("alls"), alls); + if (true) { JSObjectRef last(NULL), curr(global); @@ -1459,6 +1480,8 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) { if (hooks_ != NULL && hooks_->SetupContext != NULL) (*hooks_->SetupContext)(context); + + CYArrayPush(context, alls, cycript); } JSGlobalContextRef CYGetJSContext() { diff --git a/JavaScript.hpp b/JavaScript.hpp index 5e76bb4..ac84c11 100644 --- a/JavaScript.hpp +++ b/JavaScript.hpp @@ -109,7 +109,6 @@ struct CYHooks { void *(*ExecuteStart)(JSContextRef); void (*ExecuteEnd)(JSContextRef, void *); - JSValueRef (*RuntimeProperty)(JSContextRef, CYUTF8String); void (*CallFunction)(JSContextRef, ffi_cif *, void (*)(), uint8_t *, void **); void (*Initialize)(); diff --git a/ObjectiveC/Library.mm b/ObjectiveC/Library.mm index 5ccb90e..447a6fe 100644 --- a/ObjectiveC/Library.mm +++ b/ObjectiveC/Library.mm @@ -242,6 +242,7 @@ static JSClassRef StringInstance_; static JSClassRef Super_; static JSClassRef ObjectiveC_Classes_; +static JSClassRef ObjectiveC_Constants_; static JSClassRef ObjectiveC_Protocols_; #ifdef __APPLE__ @@ -2011,6 +2012,18 @@ static void ObjectiveC_Protocols_getPropertyNames(JSContextRef context, JSObject #endif } +static JSValueRef ObjectiveC_Constants_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry { + CYPool pool; + CYUTF8String name(CYPoolUTF8String(pool, context, property)); + if (name == "nil") + return Instance::Make(context, nil); + return NULL; +} CYCatch } + +static void ObjectiveC_Constants_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef names) { + JSPropertyNameAccumulatorAddName(names, CYJSString("nil")); +} + #ifdef __APPLE__ static bool stret(ffi_type *ffi_type) { return ffi_type->type == FFI_TYPE_STRUCT && ( @@ -2464,6 +2477,12 @@ void CYObjectiveC_Initialize() { /*XXX*/ JSContextRef context(NULL); CYPoolTry { definition.getPropertyNames = &ObjectiveC_Classes_getPropertyNames; ObjectiveC_Classes_ = JSClassCreate(&definition); + definition = kJSClassDefinitionEmpty; + definition.className = "ObjectiveC::Constants"; + definition.getProperty = &ObjectiveC_Constants_getProperty; + definition.getPropertyNames = &ObjectiveC_Constants_getPropertyNames; + ObjectiveC_Constants_ = JSClassCreate(&definition); + #if OBJC_API_VERSION >= 2 definition = kJSClassDefinitionEmpty; definition.className = "ObjectiveC::Images"; @@ -2498,12 +2517,22 @@ void CYObjectiveC_SetupContext(JSContextRef context) { CYPoolTry { JSObjectRef cy(CYCastJSObject(context, CYGetProperty(context, global, cy_s))); JSObjectRef cycript(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Cycript")))); JSObjectRef all(CYCastJSObject(context, CYGetProperty(context, cycript, CYJSString("all")))); + JSObjectRef alls(CYCastJSObject(context, CYGetProperty(context, cycript, CYJSString("alls")))); JSObjectRef ObjectiveC(JSObjectMake(context, NULL, NULL)); CYSetProperty(context, cycript, CYJSString("ObjectiveC"), ObjectiveC); - CYSetProperty(context, ObjectiveC, CYJSString("classes"), JSObjectMake(context, ObjectiveC_Classes_, NULL)); - CYSetProperty(context, ObjectiveC, CYJSString("protocols"), JSObjectMake(context, ObjectiveC_Protocols_, NULL)); + JSObjectRef protocols(JSObjectMake(context, ObjectiveC_Protocols_, NULL)); + CYSetProperty(context, ObjectiveC, CYJSString("protocols"), protocols); + CYArrayPush(context, alls, protocols); + + JSObjectRef classes(JSObjectMake(context, ObjectiveC_Classes_, NULL)); + CYSetProperty(context, ObjectiveC, CYJSString("classes"), classes); + CYArrayPush(context, alls, classes); + + JSObjectRef constants(JSObjectMake(context, ObjectiveC_Constants_, NULL)); + CYSetProperty(context, ObjectiveC, CYJSString("constants"), constants); + CYArrayPush(context, alls, constants); #if OBJC_API_VERSION >= 2 CYSetProperty(context, ObjectiveC, CYJSString("images"), JSObjectMake(context, ObjectiveC_Images_, NULL)); @@ -2542,7 +2571,6 @@ void CYObjectiveC_SetupContext(JSContextRef context) { CYPoolTry { static CYHooks CYObjectiveCHooks = { &CYObjectiveC_ExecuteStart, &CYObjectiveC_ExecuteEnd, - &CYObjectiveC_RuntimeProperty, &CYObjectiveC_CallFunction, &CYObjectiveC_Initialize, &CYObjectiveC_SetupContext, -- 2.49.0