expo-modules-core 0.9.2 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -3
- package/README.md +3 -3
- package/android/CMakeLists.txt +163 -0
- package/android/build.gradle +343 -5
- package/android/src/main/cpp/CachedReferencesRegistry.cpp +65 -0
- package/android/src/main/cpp/CachedReferencesRegistry.h +80 -0
- package/android/src/main/cpp/Exceptions.cpp +22 -0
- package/android/src/main/cpp/Exceptions.h +38 -0
- package/android/src/main/cpp/ExpoModulesHostObject.cpp +47 -0
- package/android/src/main/cpp/ExpoModulesHostObject.h +32 -0
- package/android/src/main/cpp/JNIFunctionBody.cpp +44 -0
- package/android/src/main/cpp/JNIFunctionBody.h +50 -0
- package/android/src/main/cpp/JNIInjector.cpp +23 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +122 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.h +96 -0
- package/android/src/main/cpp/JSIObjectWrapper.h +33 -0
- package/android/src/main/cpp/JSITypeConverter.h +84 -0
- package/android/src/main/cpp/JavaScriptModuleObject.cpp +219 -0
- package/android/src/main/cpp/JavaScriptModuleObject.h +144 -0
- package/android/src/main/cpp/JavaScriptObject.cpp +125 -0
- package/android/src/main/cpp/JavaScriptObject.h +131 -0
- package/android/src/main/cpp/JavaScriptRuntime.cpp +127 -0
- package/android/src/main/cpp/JavaScriptRuntime.h +87 -0
- package/android/src/main/cpp/JavaScriptValue.cpp +172 -0
- package/android/src/main/cpp/JavaScriptValue.h +78 -0
- package/android/src/main/cpp/MethodMetadata.cpp +340 -0
- package/android/src/main/cpp/MethodMetadata.h +131 -0
- package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +2 -0
- package/android/src/main/java/expo/modules/core/errors/ContextDestroyedException.kt +7 -0
- package/android/src/main/java/expo/modules/interfaces/permissions/Permissions.java +30 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +98 -3
- package/android/src/main/java/expo/modules/kotlin/ConcatIterator.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +15 -12
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +45 -3
- package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAware.kt +49 -0
- package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAwareHelper.kt +43 -0
- package/android/src/main/java/expo/modules/kotlin/activityaware/OnActivityAvailableListener.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/ActivityResultsManager.kt +99 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +25 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultContract.kt +27 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultFallbackCallback.kt +17 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultLauncher.kt +30 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultRegistry.kt +358 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/DataPersistor.kt +135 -0
- package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +2 -2
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +13 -0
- package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +2 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +53 -15
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +35 -7
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +13 -121
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +63 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +36 -0
- package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +19 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JNIFunctionBody.kt +39 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +89 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +46 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +113 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +35 -0
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +16 -6
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +5 -500
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +30 -5
- package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +271 -0
- package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionData.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponent.kt +54 -0
- package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponentBuilder.kt +32 -0
- package/android/src/main/java/expo/modules/kotlin/providers/AppContextProvider.kt +14 -0
- package/android/src/main/java/expo/modules/kotlin/providers/CurrentActivityProvider.kt +22 -0
- package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +19 -2
- package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/types/AnyTypeConverter.kt +36 -0
- package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +7 -2
- package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +68 -20
- package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +50 -22
- package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +18 -2
- package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +18 -2
- package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +17 -2
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +43 -3
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +12 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -41
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -33
- package/build/NativeModulesProxy.native.d.ts.map +1 -1
- package/build/NativeModulesProxy.native.js +9 -3
- package/build/NativeModulesProxy.native.js.map +1 -1
- package/build/PermissionsInterface.d.ts +29 -0
- package/build/PermissionsInterface.d.ts.map +1 -1
- package/build/PermissionsInterface.js +9 -0
- package/build/PermissionsInterface.js.map +1 -1
- package/ios/AppDelegates/EXAppDelegatesLoader.m +1 -2
- package/ios/ExpoModulesCore.podspec +3 -2
- package/ios/JSI/EXJSIConversions.mm +6 -0
- package/ios/JSI/EXJSIInstaller.h +15 -21
- package/ios/JSI/EXJSIInstaller.mm +39 -3
- package/ios/JSI/EXJSIUtils.h +48 -3
- package/ios/JSI/EXJSIUtils.mm +88 -4
- package/ios/JSI/EXJavaScriptObject.h +11 -18
- package/ios/JSI/EXJavaScriptObject.mm +37 -18
- package/ios/JSI/EXJavaScriptRuntime.h +43 -9
- package/ios/JSI/EXJavaScriptRuntime.mm +70 -27
- package/ios/JSI/EXJavaScriptTypedArray.h +30 -0
- package/ios/JSI/EXJavaScriptTypedArray.mm +29 -0
- package/ios/JSI/EXJavaScriptValue.h +3 -2
- package/ios/JSI/EXJavaScriptValue.mm +17 -20
- package/ios/JSI/EXJavaScriptWeakObject.h +23 -0
- package/ios/JSI/EXJavaScriptWeakObject.mm +53 -0
- package/ios/JSI/EXObjectDeallocator.h +27 -0
- package/ios/JSI/ExpoModulesHostObject.h +3 -3
- package/ios/JSI/ExpoModulesHostObject.mm +4 -4
- package/ios/JSI/JavaScriptRuntime.swift +38 -1
- package/ios/JSI/JavaScriptValue.swift +7 -0
- package/ios/JSI/TypedArray.cpp +67 -0
- package/ios/JSI/TypedArray.h +46 -0
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -11
- package/ios/NativeModulesProxy/EXNativeModulesProxy.h +17 -10
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +86 -77
- package/ios/NativeModulesProxy/NativeModulesProxyModule.swift +17 -0
- package/ios/Services/EXReactNativeEventEmitter.h +2 -2
- package/ios/Services/EXReactNativeEventEmitter.m +11 -6
- package/ios/Swift/AppContext.swift +206 -28
- package/ios/Swift/Arguments/AnyArgument.swift +18 -0
- package/ios/Swift/Arguments/{Types/EnumArgumentType.swift → EnumArgument.swift} +2 -17
- package/ios/Swift/Classes/ClassComponent.swift +95 -0
- package/ios/Swift/Classes/ClassComponentElement.swift +33 -0
- package/ios/Swift/Classes/ClassComponentElementsBuilder.swift +34 -0
- package/ios/Swift/Classes/ClassComponentFactories.swift +96 -0
- package/ios/Swift/DynamicTypes/AnyDynamicType.swift +44 -0
- package/ios/Swift/DynamicTypes/DynamicArrayType.swift +56 -0
- package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicEnumType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +63 -0
- package/ios/Swift/DynamicTypes/DynamicRawType.swift +33 -0
- package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +37 -0
- package/ios/Swift/DynamicTypes/DynamicType.swift +39 -0
- package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +46 -0
- package/ios/Swift/Exceptions/ChainableException.swift +3 -3
- package/ios/Swift/Exceptions/CodedError.swift +1 -1
- package/ios/Swift/Exceptions/Exception.swift +8 -6
- package/ios/Swift/Exceptions/UnexpectedException.swift +2 -1
- package/ios/Swift/ExpoBridgeModule.m +5 -0
- package/ios/Swift/ExpoBridgeModule.swift +79 -0
- package/ios/Swift/Functions/AnyFunction.swift +33 -31
- package/ios/Swift/Functions/AsyncFunctionComponent.swift +196 -59
- package/ios/Swift/Functions/SyncFunctionComponent.swift +142 -58
- package/ios/Swift/JavaScriptUtils.swift +32 -57
- package/ios/Swift/Logging/LogHandlers.swift +39 -0
- package/ios/Swift/Logging/LogType.swift +62 -0
- package/ios/Swift/Logging/Logger.swift +201 -0
- package/ios/Swift/ModuleHolder.swift +19 -54
- package/ios/Swift/ModuleRegistry.swift +7 -1
- package/ios/Swift/Modules/AnyModule.swift +3 -3
- package/ios/Swift/ModulesProvider.swift +2 -0
- package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +37 -0
- package/ios/Swift/Objects/ObjectDefinition.swift +74 -1
- package/ios/Swift/Objects/ObjectDefinitionComponents.swift +77 -68
- package/ios/Swift/Objects/PropertyComponent.swift +147 -0
- package/ios/Swift/Promise.swift +17 -4
- package/ios/Swift/Records/Field.swift +2 -2
- package/ios/Swift/SharedObjects/SharedObject.swift +20 -0
- package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +129 -0
- package/ios/Swift/TypedArrays/AnyTypedArray.swift +11 -0
- package/ios/Swift/TypedArrays/ConcreteTypedArrays.swift +56 -0
- package/ios/Swift/TypedArrays/GenericTypedArray.swift +49 -0
- package/ios/Swift/TypedArrays/TypedArray.swift +80 -0
- package/ios/Swift/Utilities.swift +28 -0
- package/ios/Swift/Views/ConcreteViewProp.swift +3 -3
- package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +2 -2
- package/ios/Tests/ClassComponentSpec.swift +210 -0
- package/ios/Tests/DynamicTypeSpec.swift +336 -0
- package/ios/Tests/EnumArgumentSpec.swift +48 -0
- package/ios/Tests/ExpoModulesSpec.swift +17 -3
- package/ios/Tests/FunctionSpec.swift +167 -118
- package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
- package/ios/Tests/PropertyComponentSpec.swift +95 -0
- package/ios/Tests/SharedObjectRegistrySpec.swift +109 -0
- package/ios/Tests/TypedArraysSpec.swift +136 -0
- package/package.json +2 -2
- package/src/NativeModulesProxy.native.ts +13 -3
- package/src/PermissionsInterface.ts +29 -0
- package/src/ts-declarations/ExpoModules.d.ts +7 -0
- package/tsconfig.json +1 -1
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +0 -15
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +0 -36
- package/ios/Swift/Arguments/AnyArgumentType.swift +0 -13
- package/ios/Swift/Arguments/ArgumentType.swift +0 -28
- package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +0 -42
- package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +0 -16
- package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +0 -49
- package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +0 -15
- package/ios/Swift/Arguments/Types/RawArgumentType.swift +0 -25
- package/ios/Swift/Functions/ConcreteFunction.swift +0 -103
- package/ios/Swift/SwiftInteropBridge.swift +0 -155
- package/ios/Tests/ArgumentTypeSpec.swift +0 -143
|
@@ -1,16 +1,41 @@
|
|
|
1
1
|
package expo.modules.kotlin.modules
|
|
2
2
|
|
|
3
|
+
import expo.modules.kotlin.ConcatIterator
|
|
4
|
+
import expo.modules.kotlin.ModuleHolder
|
|
3
5
|
import expo.modules.kotlin.events.EventListener
|
|
4
6
|
import expo.modules.kotlin.events.EventName
|
|
5
|
-
import expo.modules.kotlin.
|
|
6
|
-
import expo.modules.kotlin.functions.AnyFunction
|
|
7
|
+
import expo.modules.kotlin.objects.ObjectDefinitionData
|
|
7
8
|
import expo.modules.kotlin.views.ViewManagerDefinition
|
|
8
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Intermediate data used to create a proper [ProcessedModuleDefinition].
|
|
12
|
+
* It contains all, unprocessed data from [ModuleDefinitionBuilder].
|
|
13
|
+
*/
|
|
9
14
|
class ModuleDefinitionData(
|
|
10
15
|
val name: String,
|
|
11
|
-
val
|
|
12
|
-
val methods: Map<String, AnyFunction>,
|
|
16
|
+
val objectDefinition: ObjectDefinitionData,
|
|
13
17
|
val viewManagerDefinition: ViewManagerDefinition? = null,
|
|
14
18
|
val eventListeners: Map<EventName, EventListener> = emptyMap(),
|
|
15
|
-
val eventsDefinition: EventsDefinition? = null
|
|
16
19
|
)
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A final version of the ModuleDefinition.
|
|
23
|
+
* Most values are just copied from [ModuleDefinitionData].
|
|
24
|
+
* However some fields like `asyncFunctions` need to be processed or bound with the [ModuleHolder].
|
|
25
|
+
*/
|
|
26
|
+
class ProcessedModuleDefinition(
|
|
27
|
+
data: ModuleDefinitionData,
|
|
28
|
+
moduleHolder: ModuleHolder
|
|
29
|
+
) {
|
|
30
|
+
val name = data.name
|
|
31
|
+
val constantsProvider = data.objectDefinition.constantsProvider
|
|
32
|
+
val syncFunctions = data.objectDefinition.syncFunctions
|
|
33
|
+
val asyncFunctions = data.objectDefinition.asyncFunctions + data.objectDefinition.buildSuspendFunctions(moduleHolder)
|
|
34
|
+
val viewManagerDefinition = data.viewManagerDefinition
|
|
35
|
+
val eventListeners = data.eventListeners
|
|
36
|
+
val eventsDefinition = data.objectDefinition.eventsDefinition
|
|
37
|
+
val properties = data.objectDefinition.properties
|
|
38
|
+
|
|
39
|
+
val functions
|
|
40
|
+
get() = ConcatIterator(syncFunctions.values.iterator(), asyncFunctions.values.iterator())
|
|
41
|
+
}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* We used a function from the experimental STD API - typeOf (see kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/type-of.html).
|
|
3
|
+
* We shouldn't have any problem with that function, cause it's widely used in other libraries created by JetBrains like kotlinx-serializer.
|
|
4
|
+
* This function is super handy if we want to receive a collection type.
|
|
5
|
+
* For example, it's very hard to obtain the generic parameter type from the list class.
|
|
6
|
+
* In plain Java, it's almost impossible. There is a trick to getting such information using something called TypeToken.
|
|
7
|
+
* For instance, the Gson library uses this workaround. But there still will be a problem with nullability.
|
|
8
|
+
* We didn't find a good solution to distinguish between List<Any?> and List<Any>.
|
|
9
|
+
* Mainly because from the JVM perspective it's the same type.
|
|
10
|
+
* That's why we used typeOf. It solves all problems described above.
|
|
11
|
+
*/
|
|
12
|
+
@file:OptIn(ExperimentalStdlibApi::class)
|
|
13
|
+
@file:Suppress("FunctionName")
|
|
14
|
+
|
|
15
|
+
package expo.modules.kotlin.objects
|
|
16
|
+
|
|
17
|
+
import expo.modules.kotlin.Promise
|
|
18
|
+
import expo.modules.kotlin.events.EventsDefinition
|
|
19
|
+
import expo.modules.kotlin.functions.AsyncFunction
|
|
20
|
+
import expo.modules.kotlin.functions.AsyncFunctionBuilder
|
|
21
|
+
import expo.modules.kotlin.functions.AsyncFunctionComponent
|
|
22
|
+
import expo.modules.kotlin.functions.AsyncFunctionWithPromiseComponent
|
|
23
|
+
import expo.modules.kotlin.functions.SyncFunctionComponent
|
|
24
|
+
import expo.modules.kotlin.types.toAnyType
|
|
25
|
+
import kotlin.reflect.typeOf
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Base class for other definitions representing an object, such as `ModuleDefinition`.
|
|
29
|
+
*/
|
|
30
|
+
open class ObjectDefinitionBuilder {
|
|
31
|
+
private var constantsProvider = { emptyMap<String, Any?>() }
|
|
32
|
+
private var eventsDefinition: EventsDefinition? = null
|
|
33
|
+
|
|
34
|
+
@PublishedApi
|
|
35
|
+
internal var syncFunctions = mutableMapOf<String, SyncFunctionComponent>()
|
|
36
|
+
|
|
37
|
+
@PublishedApi
|
|
38
|
+
internal var asyncFunctions = mutableMapOf<String, AsyncFunction>()
|
|
39
|
+
|
|
40
|
+
private var functionBuilders = mutableMapOf<String, AsyncFunctionBuilder>()
|
|
41
|
+
|
|
42
|
+
@PublishedApi
|
|
43
|
+
internal var properties = mutableMapOf<String, PropertyComponentBuilder>()
|
|
44
|
+
|
|
45
|
+
fun buildObject(): ObjectDefinitionData {
|
|
46
|
+
return ObjectDefinitionData(
|
|
47
|
+
constantsProvider,
|
|
48
|
+
syncFunctions,
|
|
49
|
+
asyncFunctions,
|
|
50
|
+
functionBuilders.mapValues { (_, value) -> value.build() },
|
|
51
|
+
eventsDefinition,
|
|
52
|
+
properties.mapValues { (_, value) -> value.build() }
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Definition function setting the module's constants to export.
|
|
58
|
+
*/
|
|
59
|
+
fun Constants(constantsProvider: () -> Map<String, Any?>) {
|
|
60
|
+
this.constantsProvider = constantsProvider
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Definition of the module's constants to export.
|
|
65
|
+
*/
|
|
66
|
+
fun Constants(vararg constants: Pair<String, Any?>) {
|
|
67
|
+
constantsProvider = { constants.toMap() }
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@JvmName("FunctionWithoutArgs")
|
|
71
|
+
inline fun Function(
|
|
72
|
+
name: String,
|
|
73
|
+
crossinline body: () -> Any?
|
|
74
|
+
) {
|
|
75
|
+
SyncFunctionComponent(name, arrayOf()) { body() }.also {
|
|
76
|
+
syncFunctions[name] = it
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
inline fun <reified R> Function(
|
|
81
|
+
name: String,
|
|
82
|
+
crossinline body: () -> R
|
|
83
|
+
) {
|
|
84
|
+
SyncFunctionComponent(name, arrayOf()) { body() }.also {
|
|
85
|
+
syncFunctions[name] = it
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
inline fun <reified R, reified P0> Function(
|
|
90
|
+
name: String,
|
|
91
|
+
crossinline body: (p0: P0) -> R
|
|
92
|
+
) {
|
|
93
|
+
SyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType())) { body(it[0] as P0) }.also {
|
|
94
|
+
syncFunctions[name] = it
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
inline fun <reified R, reified P0, reified P1> Function(
|
|
99
|
+
name: String,
|
|
100
|
+
crossinline body: (p0: P0, p1: P1) -> R
|
|
101
|
+
) {
|
|
102
|
+
SyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType())) { body(it[0] as P0, it[1] as P1) }.also {
|
|
103
|
+
syncFunctions[name] = it
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
inline fun <reified R, reified P0, reified P1, reified P2> Function(
|
|
108
|
+
name: String,
|
|
109
|
+
crossinline body: (p0: P0, p1: P1, p2: P2) -> R
|
|
110
|
+
) {
|
|
111
|
+
SyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2) }.also {
|
|
112
|
+
syncFunctions[name] = it
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5> Function(
|
|
117
|
+
name: String,
|
|
118
|
+
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5) -> R
|
|
119
|
+
) {
|
|
120
|
+
SyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType(), typeOf<P5>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3, it[4] as P4, it[5] as P5) }.also {
|
|
121
|
+
syncFunctions[name] = it
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@JvmName("AsyncFunctionWithoutArgs")
|
|
126
|
+
inline fun AsyncFunction(
|
|
127
|
+
name: String,
|
|
128
|
+
crossinline body: () -> Any?
|
|
129
|
+
) {
|
|
130
|
+
asyncFunctions[name] = AsyncFunctionComponent(name, arrayOf()) { body() }
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
inline fun <reified R> AsyncFunction(
|
|
134
|
+
name: String,
|
|
135
|
+
crossinline body: () -> R
|
|
136
|
+
) {
|
|
137
|
+
asyncFunctions[name] = AsyncFunctionComponent(name, arrayOf()) { body() }
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
inline fun <reified R, reified P0> AsyncFunction(
|
|
141
|
+
name: String,
|
|
142
|
+
crossinline body: (p0: P0) -> R
|
|
143
|
+
) {
|
|
144
|
+
asyncFunctions[name] = if (P0::class == Promise::class) {
|
|
145
|
+
AsyncFunctionWithPromiseComponent(name, arrayOf()) { _, promise -> body(promise as P0) }
|
|
146
|
+
} else {
|
|
147
|
+
AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType())) { body(it[0] as P0) }
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
inline fun <reified R, reified P0, reified P1> AsyncFunction(
|
|
152
|
+
name: String,
|
|
153
|
+
crossinline body: (p0: P0, p1: P1) -> R
|
|
154
|
+
) {
|
|
155
|
+
asyncFunctions[name] = if (P1::class == Promise::class) {
|
|
156
|
+
AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType())) { args, promise -> body(args[0] as P0, promise as P1) }
|
|
157
|
+
} else {
|
|
158
|
+
AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType())) { body(it[0] as P0, it[1] as P1) }
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
inline fun <reified R, reified P0, reified P1, reified P2> AsyncFunction(
|
|
163
|
+
name: String,
|
|
164
|
+
crossinline body: (p0: P0, p1: P1, p2: P2) -> R
|
|
165
|
+
) {
|
|
166
|
+
asyncFunctions[name] = if (P2::class == Promise::class) {
|
|
167
|
+
AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType())) { args, promise -> body(args[0] as P0, args[1] as P1, promise as P2) }
|
|
168
|
+
} else {
|
|
169
|
+
AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2) }
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
inline fun <reified R, reified P0, reified P1, reified P2, reified P3> AsyncFunction(
|
|
174
|
+
name: String,
|
|
175
|
+
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3) -> R
|
|
176
|
+
) {
|
|
177
|
+
asyncFunctions[name] = if (P3::class == Promise::class) {
|
|
178
|
+
AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType())) { args, promise -> body(args[0] as P0, args[1] as P1, args[2] as P2, promise as P3) }
|
|
179
|
+
} else {
|
|
180
|
+
AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3) }
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4> AsyncFunction(
|
|
185
|
+
name: String,
|
|
186
|
+
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4) -> R
|
|
187
|
+
) {
|
|
188
|
+
asyncFunctions[name] = if (P4::class == Promise::class) {
|
|
189
|
+
AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType())) { args, promise -> body(args[0] as P0, args[1] as P1, args[2] as P2, args[3] as P3, promise as P4) }
|
|
190
|
+
} else {
|
|
191
|
+
AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3, it[4] as P4) }
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5> AsyncFunction(
|
|
196
|
+
name: String,
|
|
197
|
+
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5) -> R
|
|
198
|
+
) {
|
|
199
|
+
asyncFunctions[name] = if (P5::class == Promise::class) {
|
|
200
|
+
AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType())) { args, promise -> body(args[0] as P0, args[1] as P1, args[2] as P2, args[3] as P3, args[4] as P4, promise as P5) }
|
|
201
|
+
} else {
|
|
202
|
+
AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType(), typeOf<P5>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3, it[4] as P4, it[5] as P5) }
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6> AsyncFunction(
|
|
207
|
+
name: String,
|
|
208
|
+
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6) -> R
|
|
209
|
+
) {
|
|
210
|
+
asyncFunctions[name] = if (P6::class == Promise::class) {
|
|
211
|
+
AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType(), typeOf<P5>().toAnyType())) { args, promise -> body(args[0] as P0, args[1] as P1, args[2] as P2, args[3] as P3, args[4] as P4, args[5] as P5, promise as P6) }
|
|
212
|
+
} else {
|
|
213
|
+
AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType(), typeOf<P5>().toAnyType(), typeOf<P6>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3, it[4] as P4, it[5] as P5, it[6] as P6) }
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6, reified P7> AsyncFunction(
|
|
218
|
+
name: String,
|
|
219
|
+
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7) -> R
|
|
220
|
+
) {
|
|
221
|
+
asyncFunctions[name] = if (P7::class == Promise::class) {
|
|
222
|
+
AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType(), typeOf<P5>().toAnyType(), typeOf<P6>().toAnyType())) { args, promise -> body(args[0] as P0, args[1] as P1, args[2] as P2, args[3] as P3, args[4] as P4, args[5] as P5, args[6] as P6, promise as P7) }
|
|
223
|
+
} else {
|
|
224
|
+
AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType(), typeOf<P5>().toAnyType(), typeOf<P6>().toAnyType(), typeOf<P7>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3, it[4] as P4, it[5] as P5, it[6] as P6, it[7] as P7) }
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
fun AsyncFunction(
|
|
229
|
+
name: String
|
|
230
|
+
) = AsyncFunctionBuilder(name).also { functionBuilders[name] = it }
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Defines event names that this module can send to JavaScript.
|
|
234
|
+
*/
|
|
235
|
+
fun Events(vararg events: String) {
|
|
236
|
+
eventsDefinition = EventsDefinition(events)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Creates module's lifecycle listener that is called right after the first event listener is added.
|
|
241
|
+
*/
|
|
242
|
+
inline fun OnStartObserving(crossinline body: () -> Unit) {
|
|
243
|
+
AsyncFunction("startObserving", body)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Creates module's lifecycle listener that is called right after all event listeners are removed.
|
|
248
|
+
*/
|
|
249
|
+
inline fun OnStopObserving(crossinline body: () -> Unit) {
|
|
250
|
+
AsyncFunction("stopObserving", body)
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Creates the property with given name. The component is basically no-op if you don't call `.get()` or `.set()` on it.
|
|
255
|
+
*/
|
|
256
|
+
fun Property(name: String): PropertyComponentBuilder {
|
|
257
|
+
return PropertyComponentBuilder(name).also {
|
|
258
|
+
properties[name] = it
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Creates the read-only property whose getter doesn't take the caller as an argument.
|
|
264
|
+
*/
|
|
265
|
+
inline fun <T> Property(name: String, crossinline body: () -> T): PropertyComponentBuilder {
|
|
266
|
+
return PropertyComponentBuilder(name).also {
|
|
267
|
+
it.get(body)
|
|
268
|
+
properties[name] = it
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package expo.modules.kotlin.objects
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.ModuleHolder
|
|
4
|
+
import expo.modules.kotlin.events.EventsDefinition
|
|
5
|
+
import expo.modules.kotlin.functions.AsyncFunction
|
|
6
|
+
import expo.modules.kotlin.functions.SuspendFunctionComponent
|
|
7
|
+
import expo.modules.kotlin.functions.SuspendFunctionComponentBuilder
|
|
8
|
+
import expo.modules.kotlin.functions.SyncFunctionComponent
|
|
9
|
+
|
|
10
|
+
class ObjectDefinitionData(
|
|
11
|
+
val constantsProvider: () -> Map<String, Any?>,
|
|
12
|
+
val syncFunctions: Map<String, SyncFunctionComponent>,
|
|
13
|
+
val asyncFunctions: Map<String, AsyncFunction>,
|
|
14
|
+
val suspendFunctionBuilders: Map<String, SuspendFunctionComponentBuilder>,
|
|
15
|
+
val eventsDefinition: EventsDefinition?,
|
|
16
|
+
val properties: Map<String, PropertyComponent>
|
|
17
|
+
) {
|
|
18
|
+
fun buildSuspendFunctions(moduleHolder: ModuleHolder): Map<String, SuspendFunctionComponent> {
|
|
19
|
+
return suspendFunctionBuilders.mapValues { (_, value) -> value.build(moduleHolder) }
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
package expo.modules.kotlin.objects
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import expo.modules.kotlin.functions.SyncFunctionComponent
|
|
5
|
+
import expo.modules.kotlin.jni.CppType
|
|
6
|
+
import expo.modules.kotlin.jni.JNIFunctionBody
|
|
7
|
+
import expo.modules.kotlin.jni.JavaScriptModuleObject
|
|
8
|
+
|
|
9
|
+
class PropertyComponent(
|
|
10
|
+
/**
|
|
11
|
+
* Name of the property.
|
|
12
|
+
*/
|
|
13
|
+
val name: String,
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Synchronous function that is called when the property is being accessed.
|
|
17
|
+
*/
|
|
18
|
+
val getter: SyncFunctionComponent? = null,
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Synchronous function that is called when the property is being set.
|
|
22
|
+
*/
|
|
23
|
+
val setter: SyncFunctionComponent? = null
|
|
24
|
+
) {
|
|
25
|
+
/**
|
|
26
|
+
* Attaches property to the provided js object.
|
|
27
|
+
*/
|
|
28
|
+
fun attachToJSObject(jsObject: JavaScriptModuleObject) {
|
|
29
|
+
val jniGetter = if (getter != null) {
|
|
30
|
+
JNIFunctionBody {
|
|
31
|
+
val result = getter.call(emptyArray())
|
|
32
|
+
return@JNIFunctionBody Arguments.fromJavaArgs(arrayOf(result))
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
null
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
val jniSetter = if (setter != null) {
|
|
39
|
+
JNIFunctionBody { args ->
|
|
40
|
+
setter.call(args)
|
|
41
|
+
return@JNIFunctionBody null
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
jsObject.registerProperty(
|
|
48
|
+
name,
|
|
49
|
+
setter?.getCppRequiredTypes()?.first() ?: CppType.NONE.value,
|
|
50
|
+
jniGetter,
|
|
51
|
+
jniSetter
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
@file:OptIn(ExperimentalStdlibApi::class)
|
|
2
|
+
|
|
3
|
+
package expo.modules.kotlin.objects
|
|
4
|
+
|
|
5
|
+
import expo.modules.kotlin.functions.SyncFunctionComponent
|
|
6
|
+
import expo.modules.kotlin.types.toAnyType
|
|
7
|
+
import kotlin.reflect.typeOf
|
|
8
|
+
|
|
9
|
+
class PropertyComponentBuilder(
|
|
10
|
+
val name: String
|
|
11
|
+
) {
|
|
12
|
+
var getter: SyncFunctionComponent? = null
|
|
13
|
+
var setter: SyncFunctionComponent? = null
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Modifier that sets property getter that has no arguments (the caller is not used).
|
|
17
|
+
*/
|
|
18
|
+
inline fun <T> get(crossinline body: () -> T) = apply {
|
|
19
|
+
getter = SyncFunctionComponent("get", arrayOf()) { body() }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Modifier that sets property setter that receives only the new value as an argument.
|
|
24
|
+
*/
|
|
25
|
+
inline fun <reified T> set(crossinline body: (newValue: T) -> Unit) = apply {
|
|
26
|
+
setter = SyncFunctionComponent("set", arrayOf(typeOf<T>().toAnyType())) { body(it[0] as T) }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
fun build(): PropertyComponent {
|
|
30
|
+
return PropertyComponent(name, getter, setter)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
package expo.modules.kotlin.providers
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.AppContext
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Provider that allows accessing [AppContext] and all it's public parts (e.g. [AppContext.reactContext]).
|
|
7
|
+
*/
|
|
8
|
+
interface AppContextProvider {
|
|
9
|
+
/**
|
|
10
|
+
* [AppContext] reference. If it's not possible to access the [AppContext], because it's null
|
|
11
|
+
* then it's an invalid situation and should result in throwing descriptive error.
|
|
12
|
+
*/
|
|
13
|
+
val appContext: AppContext
|
|
14
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package expo.modules.kotlin.providers
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactActivity
|
|
4
|
+
import androidx.appcompat.app.AppCompatActivity
|
|
5
|
+
import androidx.fragment.app.FragmentActivity
|
|
6
|
+
import androidx.core.app.ComponentActivity
|
|
7
|
+
import android.app.Activity
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A class that provides the accessor to the [ReactActivity]. It enables accessing
|
|
11
|
+
* AndroidX/Android Jetpack features in Expo libraries coming from all subclassing chain:
|
|
12
|
+
* [AppCompatActivity], [FragmentActivity], [ComponentActivity], [Activity]
|
|
13
|
+
*/
|
|
14
|
+
interface CurrentActivityProvider {
|
|
15
|
+
/**
|
|
16
|
+
* Returns the current [Activity] that should be an instance of [AppCompatActivity].
|
|
17
|
+
* This activity is most likely an instance of [ReactActivity], but it's been decided not to expose
|
|
18
|
+
* `react-native` symbols via `expo-module-core` public API.
|
|
19
|
+
* @returns null if the [Activity] is not yet available (eg. Application has not yet fully started)
|
|
20
|
+
*/
|
|
21
|
+
val currentActivity: AppCompatActivity?
|
|
22
|
+
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
package expo.modules.kotlin.records
|
|
2
2
|
|
|
3
3
|
import com.facebook.react.bridge.Dynamic
|
|
4
|
+
import com.facebook.react.bridge.ReadableMap
|
|
4
5
|
import expo.modules.kotlin.allocators.ObjectConstructor
|
|
5
6
|
import expo.modules.kotlin.allocators.ObjectConstructorFactory
|
|
6
7
|
import expo.modules.kotlin.exception.FieldCastException
|
|
7
8
|
import expo.modules.kotlin.exception.FieldRequiredException
|
|
8
9
|
import expo.modules.kotlin.exception.RecordCastException
|
|
9
10
|
import expo.modules.kotlin.exception.exceptionDecorator
|
|
11
|
+
import expo.modules.kotlin.jni.CppType
|
|
10
12
|
import expo.modules.kotlin.recycle
|
|
13
|
+
import expo.modules.kotlin.types.DynamicAwareTypeConverters
|
|
11
14
|
import expo.modules.kotlin.types.TypeConverter
|
|
12
15
|
import expo.modules.kotlin.types.TypeConverterProvider
|
|
13
16
|
import kotlin.reflect.KClass
|
|
@@ -21,7 +24,7 @@ import kotlin.reflect.jvm.javaField
|
|
|
21
24
|
class RecordTypeConverter<T : Record>(
|
|
22
25
|
private val converterProvider: TypeConverterProvider,
|
|
23
26
|
val type: KType,
|
|
24
|
-
) :
|
|
27
|
+
) : DynamicAwareTypeConverters<T>(type.isMarkedNullable) {
|
|
25
28
|
private val objectConstructorFactory = ObjectConstructorFactory()
|
|
26
29
|
private val propertyDescriptors: Map<KProperty1<out Any, *>, PropertyDescriptor> =
|
|
27
30
|
(type.classifier as KClass<*>)
|
|
@@ -40,9 +43,23 @@ class RecordTypeConverter<T : Record>(
|
|
|
40
43
|
.filterNotNull()
|
|
41
44
|
.toMap()
|
|
42
45
|
|
|
43
|
-
override fun
|
|
46
|
+
override fun convertFromDynamic(value: Dynamic): T = exceptionDecorator({ cause -> RecordCastException(type, cause) }) {
|
|
44
47
|
val jsMap = value.asMap()
|
|
48
|
+
return convertFromReadableMap(jsMap)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
override fun convertFromAny(value: Any): T {
|
|
52
|
+
if (value is ReadableMap) {
|
|
53
|
+
return convertFromReadableMap(value)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@Suppress("UNCHECKED_CAST")
|
|
57
|
+
return value as T
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.READABLE_MAP)
|
|
45
61
|
|
|
62
|
+
private fun convertFromReadableMap(jsMap: ReadableMap): T {
|
|
46
63
|
val kClass = type.classifier as KClass<*>
|
|
47
64
|
val instance = getObjectConstructor(kClass.java).construct()
|
|
48
65
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
package expo.modules.kotlin.types
|
|
2
2
|
|
|
3
|
-
import com.facebook.react.bridge.Dynamic
|
|
4
3
|
import kotlin.reflect.KType
|
|
5
4
|
|
|
6
5
|
fun KType.toAnyType(): AnyType = AnyType(this)
|
|
@@ -10,5 +9,7 @@ class AnyType(val kType: KType) {
|
|
|
10
9
|
TypeConverterProviderImpl.obtainTypeConverter(kType)
|
|
11
10
|
}
|
|
12
11
|
|
|
13
|
-
fun convert(value:
|
|
12
|
+
fun convert(value: Any?): Any? = converter.convert(value)
|
|
13
|
+
|
|
14
|
+
fun getCppRequiredTypes(): Int = converter.getCppRequiredTypes().fold(0) { acc, current -> acc or current.value }
|
|
14
15
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
package expo.modules.kotlin.types
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Dynamic
|
|
4
|
+
import com.facebook.react.bridge.ReadableType
|
|
5
|
+
import expo.modules.kotlin.jni.CppType
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Type converter that handles conversion from [Any] or [Dynamic] to [Any].
|
|
9
|
+
* In the first case, it will just pass provided value.
|
|
10
|
+
* In case when it receives [Dynamic], it will unpack the provided value.
|
|
11
|
+
* In that way, we produce the same output for JSI and bridge implementation.
|
|
12
|
+
*/
|
|
13
|
+
class AnyTypeConverter(isOptional: Boolean) : DynamicAwareTypeConverters<Any>(isOptional) {
|
|
14
|
+
override fun convertFromDynamic(value: Dynamic): Any {
|
|
15
|
+
return when (value.type) {
|
|
16
|
+
ReadableType.Boolean -> value.asBoolean()
|
|
17
|
+
ReadableType.Number -> value.asDouble()
|
|
18
|
+
ReadableType.String -> value.asString()
|
|
19
|
+
ReadableType.Map -> value.asMap()
|
|
20
|
+
ReadableType.Array -> value.asArray()
|
|
21
|
+
else -> error("Unknown dynamic type: ${value.type}")
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
override fun convertFromAny(value: Any): Any {
|
|
26
|
+
return value
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(
|
|
30
|
+
CppType.READABLE_MAP,
|
|
31
|
+
CppType.READABLE_ARRAY,
|
|
32
|
+
CppType.STRING,
|
|
33
|
+
CppType.BOOLEAN,
|
|
34
|
+
CppType.DOUBLE
|
|
35
|
+
)
|
|
36
|
+
}
|
|
@@ -3,6 +3,7 @@ package expo.modules.kotlin.types
|
|
|
3
3
|
import com.facebook.react.bridge.Dynamic
|
|
4
4
|
import expo.modules.kotlin.exception.CollectionElementCastException
|
|
5
5
|
import expo.modules.kotlin.exception.exceptionDecorator
|
|
6
|
+
import expo.modules.kotlin.jni.CppType
|
|
6
7
|
import expo.modules.kotlin.recycle
|
|
7
8
|
import kotlin.reflect.KClass
|
|
8
9
|
import kotlin.reflect.KType
|
|
@@ -10,14 +11,14 @@ import kotlin.reflect.KType
|
|
|
10
11
|
class ArrayTypeConverter(
|
|
11
12
|
converterProvider: TypeConverterProvider,
|
|
12
13
|
private val arrayType: KType,
|
|
13
|
-
) :
|
|
14
|
+
) : DynamicAwareTypeConverters<Array<*>>(arrayType.isMarkedNullable) {
|
|
14
15
|
private val arrayElementConverter = converterProvider.obtainTypeConverter(
|
|
15
16
|
requireNotNull(arrayType.arguments.first().type) {
|
|
16
17
|
"The array type should contain the type of the elements."
|
|
17
18
|
}
|
|
18
19
|
)
|
|
19
20
|
|
|
20
|
-
override fun
|
|
21
|
+
override fun convertFromDynamic(value: Dynamic): Array<*> {
|
|
21
22
|
val jsArray = value.asArray()
|
|
22
23
|
val array = createTypedArray(jsArray.size())
|
|
23
24
|
for (i in 0 until jsArray.size()) {
|
|
@@ -34,6 +35,8 @@ class ArrayTypeConverter(
|
|
|
34
35
|
return array
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
override fun convertFromAny(value: Any): Array<*> = value as Array<*>
|
|
39
|
+
|
|
37
40
|
/**
|
|
38
41
|
* We can't use a Array<Any?> here. We have to create a typed array.
|
|
39
42
|
* Otherwise, cast which is done before calling lambda provided by the user will always fail.
|
|
@@ -47,4 +50,6 @@ class ArrayTypeConverter(
|
|
|
47
50
|
size
|
|
48
51
|
) as Array<Any?>
|
|
49
52
|
}
|
|
53
|
+
|
|
54
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.READABLE_ARRAY)
|
|
50
55
|
}
|