**/
/* }}} */
+#include <typeinfo>
+
#include "cycript.hpp"
#include "Driver.hpp"
message = $ CYFalse();
driver.script_ = $ CYScript($ CYExpress($C4(ParseExpression(pool,
- " function(object, prefix, word, message) {\n"
+ " function(value, prefix, word, message) {\n"
+ " var object = value;\n"
" var names = [];\n"
" var before = prefix.length;\n"
" prefix += word;\n"
" if (name.substring(0, entire) == prefix)\n"
" names.push(name);\n"
" } else do {\n"
- " if (object.hasOwnProperty(\"cy$complete\")) {\n"
- " names = names.concat(object.cy$complete(prefix, message));\n"
- " continue;\n"
- " }\n"
+ " if (object.hasOwnProperty(\"cy$complete\"))\n"
+ " names = names.concat(object.cy$complete.call(value, prefix, message));\n"
" try {\n"
" var local = Object.getOwnPropertyNames(object);\n"
" } catch (e) {\n"
_assert(value != NULL);
element = value->next_;
+ _assert(value->value_ != NULL);
CYString *string(dynamic_cast<CYString *>(value->value_));
- _assert(string != NULL);
+ if (string == NULL)
+ CYThrow("string was actually %s", typeid(*value->value_).name());
CYUTF8String completion;
if (string->size_ != 0)
#include "Code.hpp"
#include "Decode.hpp"
#include "Error.hpp"
+#include "Functor.hpp"
#include "JavaScript.hpp"
#include "String.hpp"
#include "Execute.hpp"
} CYPoolCatch(false)
} CYCatch(false) return /*XXX*/ false; }
-static void Instance_getPropertyNames_message(JSPropertyNameAccumulatorRef names, objc_method *method) {
- const char *name(sel_getName(method_getName(method)));
- if (strchr(name, ':') != NULL)
- return;
+static void CYForEachProperty(CYPool &pool, Class _class, const Functor<void (objc_method *, const char *)> &code) {
+ for (; _class != Nil; _class = class_getSuperclass(_class)) {
+ unsigned int size;
+ objc_method **data(class_copyMethodList(_class, &size));
+ pool.atexit(free, data);
+
+ for (size_t i(0); i != size; ++i) {
+ objc_method *method(data[i]);
- const char *type(method_getTypeEncoding(method));
- if (type == NULL || *type == '\0' || *type == 'v')
- return;
+ const char *name(sel_getName(method_getName(method)));
+ if (strchr(name, ':') != NULL)
+ continue;
- JSPropertyNameAccumulatorAddName(names, CYJSString(name));
+ code(method, name);
+ }
+ }
}
static void Instance_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef names) {
CYPool pool;
Class _class(object_getClass(self));
- {
+ for (Class current(_class); current != Nil; current = class_getSuperclass(current)) {
unsigned int size;
- objc_property_t *data(class_copyPropertyList(_class, &size));
+ objc_property_t *data(class_copyPropertyList(current, &size));
pool.atexit(free, data);
for (size_t i(0); i != size; ++i)
}
if (CYHasImplicitProperties(context, _class))
- for (Class current(_class); current != nil; current = class_getSuperclass(current)) {
- unsigned int size;
- objc_method **data(class_copyMethodList(current, &size));
- pool.atexit(free, data);
-
- for (size_t i(0); i != size; ++i)
- Instance_getPropertyNames_message(names, data[i]);
- }
+ CYForEachProperty(pool, _class, fun([&](objc_method *method, const char *name) {
+ JSPropertyNameAccumulatorAddName(names, CYJSString(name));
+ }));
CYPoolTry {
// XXX: this is an evil hack to deal with NSProxy; fix elsewhere
} CYPoolCatch()
}
+static JSValueRef Instance_complete_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
+ if (!CYJSValueIsNSObject(context, _this))
+ return CYObjectMakeArray(context, 0, NULL);
+
+ Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(_this)));
+ id self(internal->value_);
+
+ _assert(count == 1 || count == 2);
+ CYPool pool;
+ Class _class(object_getClass(self));
+
+ CYUTF8String prefix(CYPoolUTF8String(pool, context, CYJSString(context, arguments[0])));
+
+ JSObjectRef array(NULL); {
+ CYArrayBuilder<1024> values(context, array);
+
+ CYForEachProperty(pool, _class, fun([&](objc_method *method, const char *name) {
+ if (!CYStartsWith(name, prefix))
+ return;
+ const char *type(method_getTypeEncoding(method));
+ if (type == NULL || *type == '\0' || *type == 'v')
+ return;
+ if (class_getProperty(_class, name) != NULL)
+ return;
+ values(CYCastJSValue(context, CYJSString(pool.strcat(name, "()", NULL))));
+ }));
+ } return array;
+} CYCatch(NULL) }
+
static JSObjectRef Constructor_callAsConstructor(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
auto internal(CYPrivate<Constructor>::Get(context, object));
JSObjectRef value(CYMakeInstance(context, [internal->value_ alloc], Instance::Uninitialized));
{NULL, NULL, NULL, 0}
};
-static JSStaticFunction Instance_staticFunctions[6] = {
+static JSStaticFunction Instance_staticFunctions[7] = {
+ {"cy$complete", &Instance_complete_callAsFunction, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"toCYON", &Instance_callAsFunction_toCYON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"toJSON", &Instance_callAsFunction_toJSON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"valueOf", &Instance_callAsFunction_valueOf, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},