1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2 
3 #pragma once
4 
5 #include <fbjni/fbjni.h>
6 #include <jsi/jsi.h>
7 
8 #include <memory>
9 
10 namespace jni = facebook::jni;
11 namespace jsi = facebook::jsi;
12 
13 namespace expo {
14 class JavaScriptValue;
15 
16 class JavaScriptRuntime;
17 
18 /**
19  * Represents any JavaScript object. Its purpose is to exposes `jsi::Object` API back to Kotlin.
20  */
21 class JavaScriptObject : public jni::HybridClass<JavaScriptObject> {
22 public:
23   static auto constexpr
24     kJavaDescriptor = "Lexpo/modules/kotlin/jni/JavaScriptObject;";
25   static auto constexpr TAG = "JavaScriptObject";
26 
27   static void registerNatives();
28 
29   JavaScriptObject(
30     std::weak_ptr<JavaScriptRuntime> runtime,
31     std::shared_ptr<jsi::Object> jsObject
32   );
33 
34   /**
35    * @return a bool whether the object has a property with the given name
36    */
37   bool hasProperty(const std::string &name);
38 
39   /**
40    * @return the property of the object with the given name.
41    * If the name isn't a property on the object, returns the `jsi::Value::undefined` value.
42    */
43   jsi::Value getProperty(const std::string &name);
44 
45   /**
46    * @return a vector consisting of all enumerable property names in the object and its prototype chain.
47    */
48   std::vector<std::string> getPropertyNames();
49 
50 private:
51   friend HybridBase;
52   std::weak_ptr<JavaScriptRuntime> runtimeHolder;
53   std::shared_ptr<jsi::Object> jsObject;
54 
55   bool jniHasProperty(jni::alias_ref<jstring> name);
56 
57   jni::local_ref<jni::HybridClass<JavaScriptValue>::javaobject> jniGetProperty(
58     jni::alias_ref<jstring> name
59   );
60 
61   jni::local_ref<jni::JArrayClass<jstring>> jniGetPropertyNames();
62 };
63 } // namespace expo
64