1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2 
3 #include "JavaScriptObject.h"
4 #include "JavaScriptRuntime.h"
5 #include "JavaScriptValue.h"
6 
7 namespace expo {
8 void JavaScriptObject::registerNatives() {
9   registerHybrid({
10                    makeNativeMethod("hasProperty", JavaScriptObject::jniHasProperty),
11                    makeNativeMethod("getProperty", JavaScriptObject::jniGetProperty),
12                    makeNativeMethod("getPropertyNames", JavaScriptObject::jniGetPropertyNames)
13                  });
14 }
15 
16 JavaScriptObject::JavaScriptObject(
17   std::weak_ptr<JavaScriptRuntime> runtime,
18   std::shared_ptr<jsi::Object> jsObject
19 ) : runtimeHolder(std::move(runtime)), jsObject(std::move(jsObject)) {
20   assert(runtimeHolder.lock() != nullptr);
21 }
22 
23 bool JavaScriptObject::hasProperty(const std::string &name) {
24   auto runtime = runtimeHolder.lock();
25   assert(runtime != nullptr);
26   return jsObject->hasProperty(*runtime->get(), name.c_str());
27 }
28 
29 jsi::Value JavaScriptObject::getProperty(const std::string &name) {
30   auto runtime = runtimeHolder.lock();
31   assert(runtime != nullptr);
32   return jsObject->getProperty(*runtime->get(), name.c_str());
33 }
34 
35 bool JavaScriptObject::jniHasProperty(jni::alias_ref<jstring> name) {
36   return hasProperty(name->toStdString());
37 }
38 
39 jni::local_ref<JavaScriptValue::javaobject> JavaScriptObject::jniGetProperty(
40   jni::alias_ref<jstring> name
41 ) {
42   auto result = std::make_shared<jsi::Value>(getProperty(name->toStdString()));
43   return JavaScriptValue::newObjectCxxArgs(runtimeHolder, result);
44 }
45 
46 std::vector<std::string> JavaScriptObject::getPropertyNames() {
47   auto runtime = runtimeHolder.lock();
48   assert(runtime != nullptr);
49 
50   jsi::Array properties = jsObject->getPropertyNames(*runtime->get());
51   auto size = properties.size(*runtime->get());
52 
53   std::vector<std::string> names(size);
54   for (size_t i = 0; i < size; i++) {
55     auto propertyName = properties
56       .getValueAtIndex(*runtime->get(), i)
57       .asString(*runtime->get())
58       .utf8(*runtime->get());
59     names[i] = propertyName;
60   }
61 
62   return names;
63 }
64 
65 jni::local_ref<jni::JArrayClass<jstring>> JavaScriptObject::jniGetPropertyNames() {
66   std::vector<std::string> cResult = getPropertyNames();
67   auto paredResult = jni::JArrayClass<jstring>::newArray(cResult.size());
68   for (size_t i = 0; i < cResult.size(); i++) {
69     paredResult->setElement(i, jni::make_jstring(cResult[i]).get());
70   }
71 
72   return paredResult;
73 }
74 } // namespace expo
75