expo-modules-core 2.3.13 → 2.4.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 +25 -0
- package/android/build.gradle +3 -2
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +22 -11
- package/android/src/main/java/expo/modules/kotlin/events/EventsDefinition.kt +9 -1
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +6 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +28 -24
- package/android/src/main/java/expo/modules/kotlin/jni/ExpectedType.kt +122 -5
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +6 -1
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleConvertersBuilder.kt +50 -0
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +31 -7
- package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +28 -30
- package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionData.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/traits/SavableTrait.kt +57 -0
- package/android/src/main/java/expo/modules/kotlin/traits/Trait.kt +8 -0
- package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +9 -0
- package/android/src/main/java/expo/modules/kotlin/types/EitherTypeConverter.kt +3 -3
- package/android/src/main/java/expo/modules/kotlin/types/ExpoDynamic.kt +57 -0
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterCollection.kt +81 -0
- package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +18 -3
- package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +40 -25
- package/ios/Api/Factories/ViewFactories.swift +16 -0
- package/ios/Core/Conversions.swift +51 -7
- package/ios/Core/Convertibles/Convertibles+Color.swift +1 -1
- package/ios/Core/DynamicTypes/DynamicSharedObjectType.swift +25 -14
- package/ios/Core/Functions/AsyncFunctionDefinition.swift +1 -1
- package/ios/Core/Promise.swift +0 -11
- package/ios/Core/Views/ConcreteViewProp.swift +16 -0
- package/ios/Core/Views/SwiftUI/Convertibles+SwiftUI.swift +62 -0
- package/ios/Core/Views/SwiftUI/SwiftUIHostingView.swift +7 -0
- package/ios/DevTools/ExpoRequestInterceptorProtocol.swift +14 -4
- package/ios/DevTools/ModuleDefinitionEncoder.swift +182 -0
- package/ios/ReactDelegates/ExpoReactDelegate.swift +2 -2
- package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +1 -1
- package/ios/Tests/FunctionSpec.swift +27 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,31 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 2.4.1 — 2025-07-01
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- Added Android 16KB page size support. ([#37446](https://github.com/expo/expo/pull/37446) by [@kudo](https://github.com/kudo))
|
|
18
|
+
|
|
19
|
+
## 2.4.0 — 2025-06-04
|
|
20
|
+
|
|
21
|
+
### 🎉 New features
|
|
22
|
+
|
|
23
|
+
- [iOS] Add module registry encoder for JSON. ([#36677](https://github.com/expo/expo/pull/36677) by [@aleqsio](https://github.com/aleqsio))
|
|
24
|
+
- [Android] New custom Type Converter API ([#36823](https://github.com/expo/expo/pull/36823) by [@jakex7](https://github.com/jakex7))
|
|
25
|
+
- [iOS] Natively support `rgb` color conversions. ([#36914](https://github.com/expo/expo/pull/36914) by [@alanjhughes](https://github.com/alanjhughes))
|
|
26
|
+
- Add default values to prop definition. ([#37011](https://github.com/expo/expo/pull/37011), [#37013](https://github.com/expo/expo/pull/37013) by [@jakex7](https://github.com/jakex7))
|
|
27
|
+
|
|
28
|
+
### 🐛 Bug fixes
|
|
29
|
+
|
|
30
|
+
- [iOS] Call `createRootViewController` from the `ExpoReactNativeFactoryDelegate`. ([#36787](https://github.com/expo/expo/pull/36787) by [@alanjhughes](https://github.com/alanjhughes))
|
|
31
|
+
- [iOS] Prevent crash on failed networked requests ([#36896](https://github.com/expo/expo/pull/36896) by [@adrum](https://github.com/adrum))
|
|
32
|
+
|
|
33
|
+
### 💡 Others
|
|
34
|
+
|
|
35
|
+
- Improved `@expo/ui/swift-ui-primitives` integrations. ([#36937](https://github.com/expo/expo/pull/36937) by [@kudo](https://github.com/kudo))
|
|
36
|
+
- [iOS] Use dynamic type for AsyncFunction result conversion ([#36986](https://github.com/expo/expo/pull/36986) by [@jakex7](https://github.com/jakex7))
|
|
37
|
+
|
|
13
38
|
## 2.3.13 — 2025-05-08
|
|
14
39
|
|
|
15
40
|
### 🐛 Bug fixes
|
package/android/build.gradle
CHANGED
|
@@ -25,7 +25,7 @@ if (shouldIncludeCompose) {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
group = 'host.exp.exponent'
|
|
28
|
-
version = '2.
|
|
28
|
+
version = '2.4.1'
|
|
29
29
|
|
|
30
30
|
def isExpoModulesCoreTests = {
|
|
31
31
|
Gradle gradle = getGradle()
|
|
@@ -75,7 +75,7 @@ android {
|
|
|
75
75
|
defaultConfig {
|
|
76
76
|
consumerProguardFiles 'proguard-rules.pro'
|
|
77
77
|
versionCode 1
|
|
78
|
-
versionName "2.
|
|
78
|
+
versionName "2.4.1"
|
|
79
79
|
buildConfigField "String", "EXPO_MODULES_CORE_VERSION", "\"${versionName}\""
|
|
80
80
|
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled.toString()
|
|
81
81
|
|
|
@@ -85,6 +85,7 @@ android {
|
|
|
85
85
|
cmake {
|
|
86
86
|
abiFilters(*reactNativeArchitectures())
|
|
87
87
|
arguments "-DANDROID_STL=c++_shared",
|
|
88
|
+
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON",
|
|
88
89
|
"-DREACT_NATIVE_DIR=${expoModuleExtension.reactNativeDir}",
|
|
89
90
|
"-DREACT_NATIVE_TARGET_VERSION=${expoModuleExtension.reactNativeVersion.minor}",
|
|
90
91
|
"-DUSE_HERMES=${USE_HERMES}",
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
package expo.modules.kotlin.classcomponent
|
|
4
4
|
|
|
5
|
+
import expo.modules.kotlin.AppContext
|
|
5
6
|
import expo.modules.kotlin.component6
|
|
6
7
|
import expo.modules.kotlin.component7
|
|
7
8
|
import expo.modules.kotlin.component8
|
|
@@ -10,7 +11,9 @@ import expo.modules.kotlin.objects.ObjectDefinitionBuilder
|
|
|
10
11
|
import expo.modules.kotlin.objects.PropertyComponentBuilderWithThis
|
|
11
12
|
import expo.modules.kotlin.sharedobjects.SharedObject
|
|
12
13
|
import expo.modules.kotlin.sharedobjects.SharedRef
|
|
14
|
+
import expo.modules.kotlin.traits.Trait
|
|
13
15
|
import expo.modules.kotlin.types.AnyType
|
|
16
|
+
import expo.modules.kotlin.types.TypeConverterProvider
|
|
14
17
|
import expo.modules.kotlin.types.enforceType
|
|
15
18
|
import expo.modules.kotlin.types.toAnyType
|
|
16
19
|
import expo.modules.kotlin.types.toArgsArray
|
|
@@ -19,11 +22,14 @@ import kotlin.reflect.KClass
|
|
|
19
22
|
import kotlin.reflect.full.isSubclassOf
|
|
20
23
|
|
|
21
24
|
class ClassComponentBuilder<SharedObjectType : Any>(
|
|
25
|
+
private val appContext: AppContext,
|
|
22
26
|
val name: String,
|
|
23
27
|
private val ownerClass: KClass<SharedObjectType>,
|
|
24
|
-
val ownerType: AnyType
|
|
25
|
-
|
|
28
|
+
val ownerType: AnyType,
|
|
29
|
+
converters: TypeConverterProvider? = null
|
|
30
|
+
) : ObjectDefinitionBuilder(converters) {
|
|
26
31
|
var constructor: SyncFunctionComponent? = null
|
|
32
|
+
val traits = mutableListOf<Trait<in SharedObjectType>>()
|
|
27
33
|
|
|
28
34
|
fun buildClass(): ClassDefinitionData {
|
|
29
35
|
val hasOwnerType = ownerClass != Unit::class
|
|
@@ -43,7 +49,8 @@ class ClassComponentBuilder<SharedObjectType : Any>(
|
|
|
43
49
|
}
|
|
44
50
|
}
|
|
45
51
|
|
|
46
|
-
val objectData = buildObject()
|
|
52
|
+
val objectData = buildObject() + traits.map { t -> t.export(appContext) }.reduceOrNull { t1, t2 -> t1 + t2 }
|
|
53
|
+
|
|
47
54
|
objectData.functions.forEach {
|
|
48
55
|
it.ownerType = ownerType.kType
|
|
49
56
|
it.canTakeOwner = true
|
|
@@ -70,6 +77,10 @@ class ClassComponentBuilder<SharedObjectType : Any>(
|
|
|
70
77
|
)
|
|
71
78
|
}
|
|
72
79
|
|
|
80
|
+
fun UseTrait(trait: Trait<in SharedObjectType>) {
|
|
81
|
+
traits.add(trait)
|
|
82
|
+
}
|
|
83
|
+
|
|
73
84
|
inline fun Constructor(
|
|
74
85
|
crossinline body: () -> SharedObjectType
|
|
75
86
|
): SyncFunctionComponent {
|
|
@@ -82,7 +93,7 @@ class ClassComponentBuilder<SharedObjectType : Any>(
|
|
|
82
93
|
inline fun <reified P0> Constructor(
|
|
83
94
|
crossinline body: (p0: P0) -> SharedObjectType
|
|
84
95
|
): SyncFunctionComponent {
|
|
85
|
-
return SyncFunctionComponent("constructor", toArgsArray<P0>(), toReturnType<Any>()) { (p0) ->
|
|
96
|
+
return SyncFunctionComponent("constructor", toArgsArray<P0>(converterProvider = converters), toReturnType<Any>()) { (p0) ->
|
|
86
97
|
enforceType<P0>(p0)
|
|
87
98
|
body(p0)
|
|
88
99
|
}.also {
|
|
@@ -93,7 +104,7 @@ class ClassComponentBuilder<SharedObjectType : Any>(
|
|
|
93
104
|
inline fun <reified P0, reified P1> Constructor(
|
|
94
105
|
crossinline body: (p0: P0, p1: P1) -> SharedObjectType
|
|
95
106
|
): SyncFunctionComponent {
|
|
96
|
-
return SyncFunctionComponent("constructor", toArgsArray<P0, P1>(), toReturnType<Any>()) { (p0, p1) ->
|
|
107
|
+
return SyncFunctionComponent("constructor", toArgsArray<P0, P1>(converterProvider = converters), toReturnType<Any>()) { (p0, p1) ->
|
|
97
108
|
enforceType<P0, P1>(p0, p1)
|
|
98
109
|
body(p0, p1)
|
|
99
110
|
}.also {
|
|
@@ -104,7 +115,7 @@ class ClassComponentBuilder<SharedObjectType : Any>(
|
|
|
104
115
|
inline fun <reified P0, reified P1, reified P2> Constructor(
|
|
105
116
|
crossinline body: (p0: P0, p1: P1, p2: P2) -> SharedObjectType
|
|
106
117
|
): SyncFunctionComponent {
|
|
107
|
-
return SyncFunctionComponent("constructor", toArgsArray<P0, P1, P2>(), toReturnType<Any>()) { (p0, p1, p2) ->
|
|
118
|
+
return SyncFunctionComponent("constructor", toArgsArray<P0, P1, P2>(converterProvider = converters), toReturnType<Any>()) { (p0, p1, p2) ->
|
|
108
119
|
enforceType<P0, P1, P2>(p0, p1, p2)
|
|
109
120
|
body(p0, p1, p2)
|
|
110
121
|
}.also {
|
|
@@ -115,7 +126,7 @@ class ClassComponentBuilder<SharedObjectType : Any>(
|
|
|
115
126
|
inline fun <reified P0, reified P1, reified P2, reified P3> Constructor(
|
|
116
127
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3) -> SharedObjectType
|
|
117
128
|
): SyncFunctionComponent {
|
|
118
|
-
return SyncFunctionComponent("constructor", toArgsArray<P0, P1, P2, P3>(), toReturnType<Any>()) { (p0, p1, p2, p3) ->
|
|
129
|
+
return SyncFunctionComponent("constructor", toArgsArray<P0, P1, P2, P3>(converterProvider = converters), toReturnType<Any>()) { (p0, p1, p2, p3) ->
|
|
119
130
|
enforceType<P0, P1, P2, P3>(p0, p1, p2, p3)
|
|
120
131
|
body(p0, p1, p2, p3)
|
|
121
132
|
}.also {
|
|
@@ -126,7 +137,7 @@ class ClassComponentBuilder<SharedObjectType : Any>(
|
|
|
126
137
|
inline fun <reified P0, reified P1, reified P2, reified P3, reified P4> Constructor(
|
|
127
138
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4) -> SharedObjectType
|
|
128
139
|
): SyncFunctionComponent {
|
|
129
|
-
return SyncFunctionComponent("constructor", toArgsArray<P0, P1, P2, P3, P4>(), toReturnType<Any>()) { (p0, p1, p2, p3, p4) ->
|
|
140
|
+
return SyncFunctionComponent("constructor", toArgsArray<P0, P1, P2, P3, P4>(converterProvider = converters), toReturnType<Any>()) { (p0, p1, p2, p3, p4) ->
|
|
130
141
|
enforceType<P0, P1, P2, P3, P4>(p0, p1, p2, p3, p4)
|
|
131
142
|
body(p0, p1, p2, p3, p4)
|
|
132
143
|
}.also {
|
|
@@ -137,7 +148,7 @@ class ClassComponentBuilder<SharedObjectType : Any>(
|
|
|
137
148
|
inline fun <reified P0, reified P1, reified P2, reified P3, reified P4, reified P5> Constructor(
|
|
138
149
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5) -> SharedObjectType
|
|
139
150
|
): SyncFunctionComponent {
|
|
140
|
-
return SyncFunctionComponent("constructor", toArgsArray<P0, P1, P2, P3, P4, P5>(), toReturnType<Any>()) { (p0, p1, p2, p3, p4, p5) ->
|
|
151
|
+
return SyncFunctionComponent("constructor", toArgsArray<P0, P1, P2, P3, P4, P5>(converterProvider = converters), toReturnType<Any>()) { (p0, p1, p2, p3, p4, p5) ->
|
|
141
152
|
enforceType<P0, P1, P2, P3, P4, P5>(p0, p1, p2, p3, p4, p5)
|
|
142
153
|
body(p0, p1, p2, p3, p4, p5)
|
|
143
154
|
}.also {
|
|
@@ -148,7 +159,7 @@ class ClassComponentBuilder<SharedObjectType : Any>(
|
|
|
148
159
|
inline fun <reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6> Constructor(
|
|
149
160
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6) -> SharedObjectType
|
|
150
161
|
): SyncFunctionComponent {
|
|
151
|
-
return SyncFunctionComponent("constructor", toArgsArray<P0, P1, P2, P3, P4, P5, P6>(), toReturnType<Any>()) { (p0, p1, p2, p3, p4, p5, p6) ->
|
|
162
|
+
return SyncFunctionComponent("constructor", toArgsArray<P0, P1, P2, P3, P4, P5, P6>(converterProvider = converters), toReturnType<Any>()) { (p0, p1, p2, p3, p4, p5, p6) ->
|
|
152
163
|
enforceType<P0, P1, P2, P3, P4, P5, P6>(p0, p1, p2, p3, p4, p5, p6)
|
|
153
164
|
body(p0, p1, p2, p3, p4, p5, p6)
|
|
154
165
|
}.also {
|
|
@@ -159,7 +170,7 @@ class ClassComponentBuilder<SharedObjectType : Any>(
|
|
|
159
170
|
inline fun <reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6, reified P7> Constructor(
|
|
160
171
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7) -> SharedObjectType
|
|
161
172
|
): SyncFunctionComponent {
|
|
162
|
-
return SyncFunctionComponent("constructor", toArgsArray<P0, P1, P2, P3, P4, P5, P6, P7>(), toReturnType<Any>()) { (p0, p1, p2, p3, p4, p5, p6, p7) ->
|
|
173
|
+
return SyncFunctionComponent("constructor", toArgsArray<P0, P1, P2, P3, P4, P5, P6, P7>(converterProvider = converters), toReturnType<Any>()) { (p0, p1, p2, p3, p4, p5, p6, p7) ->
|
|
163
174
|
enforceType<P0, P1, P2, P3, P4, P5, P6, P7>(p0, p1, p2, p3, p4, p5, p6, p7)
|
|
164
175
|
body(p0, p1, p2, p3, p4, p5, p6, p7)
|
|
165
176
|
}.also {
|
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
package expo.modules.kotlin.events
|
|
2
2
|
|
|
3
|
-
class EventsDefinition(val names: Array<
|
|
3
|
+
class EventsDefinition(val names: Array<String>) {
|
|
4
|
+
operator fun plus(other: EventsDefinition?): EventsDefinition {
|
|
5
|
+
if (other == null) {
|
|
6
|
+
return this
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
return EventsDefinition(names + other.names)
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -93,6 +93,12 @@ internal class MissingTypeConverter(
|
|
|
93
93
|
message = "Cannot find type converter for '$forType'. Make sure the class implements `expo.modules.kotlin.records.Record` (i.e. `class MyObj : Record`)."
|
|
94
94
|
)
|
|
95
95
|
|
|
96
|
+
internal class InvalidExpectedType(
|
|
97
|
+
forType: KType
|
|
98
|
+
) : CodedException(
|
|
99
|
+
message = "Cannot obtain ExpectedType form '$forType'."
|
|
100
|
+
)
|
|
101
|
+
|
|
96
102
|
@DoNotStrip
|
|
97
103
|
internal class InvalidArgsNumberException(received: Int, expected: Int, required: Int = expected) :
|
|
98
104
|
CodedException(
|
|
@@ -6,10 +6,14 @@ import expo.modules.kotlin.component6
|
|
|
6
6
|
import expo.modules.kotlin.component7
|
|
7
7
|
import expo.modules.kotlin.component8
|
|
8
8
|
import expo.modules.kotlin.Promise
|
|
9
|
+
import expo.modules.kotlin.types.TypeConverterProvider
|
|
9
10
|
import expo.modules.kotlin.types.enforceType
|
|
10
11
|
import expo.modules.kotlin.types.toArgsArray
|
|
11
12
|
|
|
12
|
-
class AsyncFunctionBuilder(
|
|
13
|
+
class AsyncFunctionBuilder(
|
|
14
|
+
@PublishedApi internal val name: String,
|
|
15
|
+
@PublishedApi internal val converters: TypeConverterProvider? = null
|
|
16
|
+
) {
|
|
13
17
|
@PublishedApi
|
|
14
18
|
internal var asyncFunctionComponent: BaseAsyncFunctionComponent? = null
|
|
15
19
|
|
|
@@ -20,7 +24,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
inline fun <reified R, reified P0> SuspendBody(crossinline block: suspend (p0: P0) -> R): SuspendFunctionComponent {
|
|
23
|
-
return SuspendFunctionComponent(name, toArgsArray<P0>()) { (p0) ->
|
|
27
|
+
return SuspendFunctionComponent(name, toArgsArray<P0>(converterProvider = converters)) { (p0) ->
|
|
24
28
|
enforceType<P0>(p0)
|
|
25
29
|
block(p0)
|
|
26
30
|
}.also {
|
|
@@ -29,7 +33,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
inline fun <reified R, reified P0, reified P1> SuspendBody(crossinline block: suspend (p0: P0, p1: P1) -> R): SuspendFunctionComponent {
|
|
32
|
-
return SuspendFunctionComponent(name, toArgsArray<P0, P1>()) { (p0, p1) ->
|
|
36
|
+
return SuspendFunctionComponent(name, toArgsArray<P0, P1>(converterProvider = converters)) { (p0, p1) ->
|
|
33
37
|
enforceType<P0, P1>(p0, p1)
|
|
34
38
|
block(p0, p1)
|
|
35
39
|
}.also {
|
|
@@ -38,7 +42,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
inline fun <reified R, reified P0, reified P1, reified P2> SuspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2) -> R): SuspendFunctionComponent {
|
|
41
|
-
return SuspendFunctionComponent(name, toArgsArray<P0, P1, P2>()) { (p0, p1, p2) ->
|
|
45
|
+
return SuspendFunctionComponent(name, toArgsArray<P0, P1, P2>(converterProvider = converters)) { (p0, p1, p2) ->
|
|
42
46
|
enforceType<P0, P1, P2>(p0, p1, p2)
|
|
43
47
|
block(p0, p1, p2)
|
|
44
48
|
}.also {
|
|
@@ -47,7 +51,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
47
51
|
}
|
|
48
52
|
|
|
49
53
|
inline fun <reified R, reified P0, reified P1, reified P2, reified P3> SuspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3) -> R): SuspendFunctionComponent {
|
|
50
|
-
return SuspendFunctionComponent(name, toArgsArray<P0, P1, P2, P3>()) { (p0, p1, p2, p3) ->
|
|
54
|
+
return SuspendFunctionComponent(name, toArgsArray<P0, P1, P2, P3>(converterProvider = converters)) { (p0, p1, p2, p3) ->
|
|
51
55
|
enforceType<P0, P1, P2, P3>(p0, p1, p2, p3)
|
|
52
56
|
block(p0, p1, p2, p3)
|
|
53
57
|
}.also {
|
|
@@ -56,7 +60,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4> SuspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4) -> R): SuspendFunctionComponent {
|
|
59
|
-
return SuspendFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4>()) { (p0, p1, p2, p3, p4) ->
|
|
63
|
+
return SuspendFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4>(converterProvider = converters)) { (p0, p1, p2, p3, p4) ->
|
|
60
64
|
enforceType<P0, P1, P2, P3, P4>(p0, p1, p2, p3, p4)
|
|
61
65
|
block(p0, p1, p2, p3, p4)
|
|
62
66
|
}.also {
|
|
@@ -65,7 +69,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5> SuspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5) -> R): SuspendFunctionComponent {
|
|
68
|
-
return SuspendFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5>()) { (p0, p1, p2, p3, p4, p5) ->
|
|
72
|
+
return SuspendFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5>(converterProvider = converters)) { (p0, p1, p2, p3, p4, p5) ->
|
|
69
73
|
enforceType<P0, P1, P2, P3, P4, P5>(p0, p1, p2, p3, p4, p5)
|
|
70
74
|
block(p0, p1, p2, p3, p4, p5)
|
|
71
75
|
}.also {
|
|
@@ -74,7 +78,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6> SuspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6) -> R): SuspendFunctionComponent {
|
|
77
|
-
return SuspendFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6>()) { (p0, p1, p2, p3, p4, p5, p6) ->
|
|
81
|
+
return SuspendFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6>(converterProvider = converters)) { (p0, p1, p2, p3, p4, p5, p6) ->
|
|
78
82
|
enforceType<P0, P1, P2, P3, P4, P5, P6>(p0, p1, p2, p3, p4, p5, p6)
|
|
79
83
|
block(p0, p1, p2, p3, p4, p5, p6)
|
|
80
84
|
}.also {
|
|
@@ -83,7 +87,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6, reified P7> SuspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7) -> R): SuspendFunctionComponent {
|
|
86
|
-
return SuspendFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6, P7>()) { (p0, p1, p2, p3, p4, p5, p6, p7) ->
|
|
90
|
+
return SuspendFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6, P7>(converterProvider = converters)) { (p0, p1, p2, p3, p4, p5, p6, p7) ->
|
|
87
91
|
enforceType<P0, P1, P2, P3, P4, P5, P6, P7>(p0, p1, p2, p3, p4, p5, p6, p7)
|
|
88
92
|
block(p0, p1, p2, p3, p4, p5, p6, p7)
|
|
89
93
|
}.also {
|
|
@@ -108,7 +112,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
108
112
|
return if (P0::class == Promise::class) {
|
|
109
113
|
AsyncFunctionWithPromiseComponent(name, emptyArray()) { _, promise -> body(promise as P0) }
|
|
110
114
|
} else {
|
|
111
|
-
createAsyncFunctionComponent(name, toArgsArray<P0>()) { (p0) ->
|
|
115
|
+
createAsyncFunctionComponent(name, toArgsArray<P0>(converterProvider = converters)) { (p0) ->
|
|
112
116
|
enforceType<P0>(p0)
|
|
113
117
|
body(p0)
|
|
114
118
|
}
|
|
@@ -118,7 +122,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
118
122
|
}
|
|
119
123
|
|
|
120
124
|
inline fun <reified R, reified P0, reified P1> AsyncBody(crossinline body: (p0: P0, p1: P1) -> R): AsyncFunctionComponent {
|
|
121
|
-
return createAsyncFunctionComponent(name, toArgsArray<P0, P1>()) { (p0, p1) ->
|
|
125
|
+
return createAsyncFunctionComponent(name, toArgsArray<P0, P1>(converterProvider = converters)) { (p0, p1) ->
|
|
122
126
|
enforceType<P0, P1>(p0, p1)
|
|
123
127
|
body(p0, p1)
|
|
124
128
|
}.also {
|
|
@@ -128,7 +132,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
128
132
|
|
|
129
133
|
@JvmName("AsyncFunctionWithPromise")
|
|
130
134
|
inline fun <reified R, reified P0> AsyncBody(crossinline body: (p0: P0, p1: Promise) -> R): AsyncFunctionComponent {
|
|
131
|
-
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0>()) { (p0), promise ->
|
|
135
|
+
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0>(converterProvider = converters)) { (p0), promise ->
|
|
132
136
|
enforceType<P0>(p0)
|
|
133
137
|
body(p0, promise)
|
|
134
138
|
}.also {
|
|
@@ -137,7 +141,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
137
141
|
}
|
|
138
142
|
|
|
139
143
|
inline fun <reified R, reified P0, reified P1, reified P2> AsyncBody(crossinline body: (p0: P0, p1: P1, p2: P2) -> R): AsyncFunctionComponent {
|
|
140
|
-
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2>()) { (p0, p1, p2) ->
|
|
144
|
+
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2>(converterProvider = converters)) { (p0, p1, p2) ->
|
|
141
145
|
enforceType<P0, P1, P2>(p0, p1, p2)
|
|
142
146
|
body(p0, p1, p2)
|
|
143
147
|
}.also {
|
|
@@ -147,7 +151,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
147
151
|
|
|
148
152
|
@JvmName("AsyncFunctionWithPromise")
|
|
149
153
|
inline fun <reified R, reified P0, reified P1> AsyncBody(crossinline body: (p0: P0, p1: P1, p2: Promise) -> R): AsyncFunctionComponent {
|
|
150
|
-
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1>()) { (p0, p1), promise ->
|
|
154
|
+
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1>(converterProvider = converters)) { (p0, p1), promise ->
|
|
151
155
|
enforceType<P0, P1>(p0, p1)
|
|
152
156
|
body(p0, p1, promise)
|
|
153
157
|
}.also {
|
|
@@ -156,7 +160,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
156
160
|
}
|
|
157
161
|
|
|
158
162
|
inline fun <reified R, reified P0, reified P1, reified P2, reified P3> AsyncBody(crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3) -> R): AsyncFunctionComponent {
|
|
159
|
-
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3>()) { (p0, p1, p2, p3) ->
|
|
163
|
+
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3>(converterProvider = converters)) { (p0, p1, p2, p3) ->
|
|
160
164
|
enforceType<P0, P1, P2, P3>(p0, p1, p2, p3)
|
|
161
165
|
body(p0, p1, p2, p3)
|
|
162
166
|
}.also {
|
|
@@ -166,7 +170,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
166
170
|
|
|
167
171
|
@JvmName("AsyncFunctionWithPromise")
|
|
168
172
|
inline fun <reified R, reified P0, reified P1, reified P2> AsyncBody(crossinline body: (p0: P0, p1: P1, p2: P2, p3: Promise) -> R): AsyncFunctionComponent {
|
|
169
|
-
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2>()) { (p0, p1, p2), promise ->
|
|
173
|
+
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2>(converterProvider = converters)) { (p0, p1, p2), promise ->
|
|
170
174
|
enforceType<P0, P1, P2>(p0, p1, p2)
|
|
171
175
|
body(p0, p1, p2, promise)
|
|
172
176
|
}.also {
|
|
@@ -175,7 +179,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
175
179
|
}
|
|
176
180
|
|
|
177
181
|
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4> AsyncBody(crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4) -> R): AsyncFunctionComponent {
|
|
178
|
-
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4>()) { (p0, p1, p2, p3, p4) ->
|
|
182
|
+
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4>(converterProvider = converters)) { (p0, p1, p2, p3, p4) ->
|
|
179
183
|
enforceType<P0, P1, P2, P3, P4>(p0, p1, p2, p3, p4)
|
|
180
184
|
body(p0, p1, p2, p3, p4)
|
|
181
185
|
}.also {
|
|
@@ -185,7 +189,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
185
189
|
|
|
186
190
|
@JvmName("AsyncFunctionWithPromise")
|
|
187
191
|
inline fun <reified R, reified P0, reified P1, reified P2, reified P3> AsyncBody(crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: Promise) -> R): AsyncFunctionComponent {
|
|
188
|
-
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3>()) { (p0, p1, p2, p3), promise ->
|
|
192
|
+
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3>(converterProvider = converters)) { (p0, p1, p2, p3), promise ->
|
|
189
193
|
enforceType<P0, P1, P2, P3>(p0, p1, p2, p3)
|
|
190
194
|
body(p0, p1, p2, p3, promise)
|
|
191
195
|
}.also {
|
|
@@ -194,7 +198,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
194
198
|
}
|
|
195
199
|
|
|
196
200
|
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5> AsyncBody(crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5) -> R): AsyncFunctionComponent {
|
|
197
|
-
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5>()) { (p0, p1, p2, p3, p4, p5) ->
|
|
201
|
+
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5>(converterProvider = converters)) { (p0, p1, p2, p3, p4, p5) ->
|
|
198
202
|
enforceType<P0, P1, P2, P3, P4, P5>(p0, p1, p2, p3, p4, p5)
|
|
199
203
|
body(p0, p1, p2, p3, p4, p5)
|
|
200
204
|
}.also {
|
|
@@ -204,7 +208,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
204
208
|
|
|
205
209
|
@JvmName("AsyncFunctionWithPromise")
|
|
206
210
|
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4> AsyncBody(crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: Promise) -> R): AsyncFunctionComponent {
|
|
207
|
-
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3, P4>()) { (p0, p1, p2, p3, p4), promise ->
|
|
211
|
+
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3, P4>(converterProvider = converters)) { (p0, p1, p2, p3, p4), promise ->
|
|
208
212
|
enforceType<P0, P1, P2, P3, P4>(p0, p1, p2, p3, p4)
|
|
209
213
|
body(p0, p1, p2, p3, p4, promise)
|
|
210
214
|
}.also {
|
|
@@ -213,7 +217,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
213
217
|
}
|
|
214
218
|
|
|
215
219
|
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6> AsyncBody(crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6) -> R): AsyncFunctionComponent {
|
|
216
|
-
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6>()) { (p0, p1, p2, p3, p4, p5, p6) ->
|
|
220
|
+
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6>(converterProvider = converters)) { (p0, p1, p2, p3, p4, p5, p6) ->
|
|
217
221
|
enforceType<P0, P1, P2, P3, P4, P5, P6>(p0, p1, p2, p3, p4, p5, p6)
|
|
218
222
|
body(p0, p1, p2, p3, p4, p5, p6)
|
|
219
223
|
}.also {
|
|
@@ -223,7 +227,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
223
227
|
|
|
224
228
|
@JvmName("AsyncFunctionWithPromise")
|
|
225
229
|
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5> AsyncBody(crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: Promise) -> R): AsyncFunctionComponent {
|
|
226
|
-
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5>()) { (p0, p1, p2, p3, p4, p5), promise ->
|
|
230
|
+
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5>(converterProvider = converters)) { (p0, p1, p2, p3, p4, p5), promise ->
|
|
227
231
|
enforceType<P0, P1, P2, P3, P4, P5>(p0, p1, p2, p3, p4, p5)
|
|
228
232
|
body(p0, p1, p2, p3, p4, p5, promise)
|
|
229
233
|
}.also {
|
|
@@ -232,7 +236,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
232
236
|
}
|
|
233
237
|
|
|
234
238
|
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6, reified P7> AsyncBody(crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7) -> R): AsyncFunctionComponent {
|
|
235
|
-
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6, P7>()) { (p0, p1, p2, p3, p4, p5, p6, p7) ->
|
|
239
|
+
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6, P7>(converterProvider = converters)) { (p0, p1, p2, p3, p4, p5, p6, p7) ->
|
|
236
240
|
enforceType<P0, P1, P2, P3, P4, P5, P6, P7>(p0, p1, p2, p3, p4, p5, p6, p7)
|
|
237
241
|
body(p0, p1, p2, p3, p4, p5, p6, p7)
|
|
238
242
|
}.also {
|
|
@@ -242,7 +246,7 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
|
|
|
242
246
|
|
|
243
247
|
@JvmName("AsyncFunctionWithPromise")
|
|
244
248
|
inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6> AsyncBody(crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: Promise) -> R): AsyncFunctionComponent {
|
|
245
|
-
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6>()) { (p0, p1, p2, p3, p4, p5, p6), promise ->
|
|
249
|
+
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6>(converterProvider = converters)) { (p0, p1, p2, p3, p4, p5, p6), promise ->
|
|
246
250
|
enforceType<P0, P1, P2, P3, P4, P5, P6>(p0, p1, p2, p3, p4, p5, p6)
|
|
247
251
|
body(p0, p1, p2, p3, p4, p5, p6, promise)
|
|
248
252
|
}.also {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
package expo.modules.kotlin.jni
|
|
2
2
|
|
|
3
3
|
import expo.modules.core.interfaces.DoNotStrip
|
|
4
|
+
import expo.modules.kotlin.exception.InvalidExpectedType
|
|
5
|
+
import kotlin.reflect.KClass
|
|
6
|
+
import kotlin.reflect.KType
|
|
4
7
|
|
|
5
8
|
/**
|
|
6
9
|
* A basic class that represents metadata about the expected type.
|
|
@@ -30,6 +33,66 @@ class SingleType(
|
|
|
30
33
|
*/
|
|
31
34
|
@DoNotStrip
|
|
32
35
|
fun getSecondParameterType() = parameterTypes?.get(1)
|
|
36
|
+
|
|
37
|
+
override fun equals(other: Any?): Boolean {
|
|
38
|
+
if (this === other) {
|
|
39
|
+
return true
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (javaClass != other?.javaClass) {
|
|
43
|
+
return false
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
other as SingleType
|
|
47
|
+
|
|
48
|
+
if (expectedCppType != other.expectedCppType) {
|
|
49
|
+
return false
|
|
50
|
+
}
|
|
51
|
+
if (!parameterTypes.contentEquals(other.parameterTypes)) {
|
|
52
|
+
return false
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return true
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
override fun hashCode(): Int {
|
|
59
|
+
var result = expectedCppType.hashCode()
|
|
60
|
+
result = 31 * result + (parameterTypes?.contentHashCode() ?: 0)
|
|
61
|
+
return result
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
companion object {
|
|
65
|
+
fun merge(
|
|
66
|
+
first: SingleType,
|
|
67
|
+
second: SingleType
|
|
68
|
+
): SingleType {
|
|
69
|
+
if (first.expectedCppType != second.expectedCppType) {
|
|
70
|
+
throw IllegalArgumentException(
|
|
71
|
+
"Cannot merge types with different CppType: ${first.expectedCppType} and ${second.expectedCppType}"
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
val firstTypeParameters = first.parameterTypes
|
|
76
|
+
val secondTypeParameters = second.parameterTypes
|
|
77
|
+
if (firstTypeParameters == null || secondTypeParameters == null) {
|
|
78
|
+
return first
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
require(firstTypeParameters.size == secondTypeParameters.size) {
|
|
82
|
+
"Cannot merge types with different number of parameters: ${first.parameterTypes.size} and ${second.parameterTypes.size}"
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
val size = firstTypeParameters.size
|
|
86
|
+
val parameters = (0..<size).map { index ->
|
|
87
|
+
ExpectedType.merge(firstTypeParameters[index], secondTypeParameters[index])
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return SingleType(
|
|
91
|
+
first.expectedCppType,
|
|
92
|
+
parameters.toTypedArray()
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
33
96
|
}
|
|
34
97
|
|
|
35
98
|
/**
|
|
@@ -60,11 +123,25 @@ class ExpectedType(
|
|
|
60
123
|
@DoNotStrip
|
|
61
124
|
fun getFirstType() = innerPossibleTypes.first()
|
|
62
125
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
126
|
+
override fun hashCode(): Int {
|
|
127
|
+
var result = innerCombinedTypes
|
|
128
|
+
result = 31 * result + innerPossibleTypes.contentHashCode()
|
|
129
|
+
return result
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
override operator fun equals(other: Any?): Boolean {
|
|
133
|
+
if (other !is ExpectedType) return false
|
|
134
|
+
|
|
135
|
+
if (this.innerPossibleTypes.size != other.innerPossibleTypes.size) return false
|
|
136
|
+
for (i in this.innerPossibleTypes.indices) {
|
|
137
|
+
if (this.innerPossibleTypes[i].expectedCppType != other.innerPossibleTypes[i].expectedCppType) {
|
|
138
|
+
return false
|
|
139
|
+
}
|
|
140
|
+
if (this.innerPossibleTypes[i].getFirstParameterType() != other.innerPossibleTypes[i].getFirstParameterType()) {
|
|
141
|
+
return false
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return true
|
|
68
145
|
}
|
|
69
146
|
|
|
70
147
|
companion object {
|
|
@@ -96,5 +173,45 @@ class ExpectedType(
|
|
|
96
173
|
fun forMap(valueType: ExpectedType) = ExpectedType(
|
|
97
174
|
SingleType(CppType.MAP, arrayOf(valueType))
|
|
98
175
|
)
|
|
176
|
+
|
|
177
|
+
fun fromKType(type: KType): ExpectedType {
|
|
178
|
+
val kClass = type.classifier as? KClass<*>
|
|
179
|
+
?: throw IllegalArgumentException("Cannot obtain KClass from '$type'")
|
|
180
|
+
when (kClass) {
|
|
181
|
+
Int::class -> return ExpectedType(SingleType(CppType.INT))
|
|
182
|
+
Long::class -> return ExpectedType(SingleType(CppType.LONG))
|
|
183
|
+
Double::class -> return ExpectedType(SingleType(CppType.DOUBLE))
|
|
184
|
+
Float::class -> return ExpectedType(SingleType(CppType.FLOAT))
|
|
185
|
+
Boolean::class -> return ExpectedType(SingleType(CppType.BOOLEAN))
|
|
186
|
+
String::class -> return ExpectedType(SingleType(CppType.STRING))
|
|
187
|
+
}
|
|
188
|
+
if (kClass.java.isAssignableFrom(List::class.java)) {
|
|
189
|
+
val argType = type.arguments.firstOrNull()?.type
|
|
190
|
+
if (argType != null) {
|
|
191
|
+
return forList(fromKType(argType))
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (kClass.java.isAssignableFrom(Map::class.java)) {
|
|
195
|
+
val argType = type.arguments.getOrNull(1)?.type
|
|
196
|
+
if (argType != null) {
|
|
197
|
+
return forMap(fromKType(argType))
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
throw InvalidExpectedType(type)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
fun merge(
|
|
204
|
+
vararg types: ExpectedType
|
|
205
|
+
): ExpectedType {
|
|
206
|
+
val typesGroup = types
|
|
207
|
+
.flatMap { it.innerPossibleTypes.asIterable() }
|
|
208
|
+
.groupBy { it.expectedCppType }
|
|
209
|
+
|
|
210
|
+
val mergedTypes = typesGroup.map { (_, types) ->
|
|
211
|
+
types.reduce { a, b -> SingleType.merge(a, b) }
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return ExpectedType(*mergedTypes.toTypedArray())
|
|
215
|
+
}
|
|
99
216
|
}
|
|
100
217
|
}
|
|
@@ -51,7 +51,7 @@ abstract class Module : AppContextProvider {
|
|
|
51
51
|
moduleEventEmitter?.emit(convertEnumToString(enum), body)
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
open fun
|
|
54
|
+
open fun converters(): TypeConverterProvider? = null
|
|
55
55
|
|
|
56
56
|
abstract fun definition(): ModuleDefinitionData
|
|
57
57
|
}
|
|
@@ -60,3 +60,8 @@ abstract class Module : AppContextProvider {
|
|
|
60
60
|
inline fun Module.ModuleDefinition(crossinline block: ModuleDefinitionBuilder.() -> Unit): ModuleDefinitionData {
|
|
61
61
|
return trace("${this.javaClass}.ModuleDefinition") { ModuleDefinitionBuilder(this).also(block).buildModule() }
|
|
62
62
|
}
|
|
63
|
+
|
|
64
|
+
@Suppress("FunctionName")
|
|
65
|
+
inline fun Module.ModuleConverters(crossinline block: ModuleConvertersBuilder.() -> Unit): TypeConverterProvider {
|
|
66
|
+
return trace("${this.javaClass}.TypeConverters") { ModuleConvertersBuilder().also(block).buildTypeConverterProvider() }
|
|
67
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
@file:Suppress("FunctionName")
|
|
2
|
+
|
|
3
|
+
package expo.modules.kotlin.modules
|
|
4
|
+
|
|
5
|
+
import expo.modules.kotlin.exception.MissingTypeConverter
|
|
6
|
+
import expo.modules.kotlin.types.TypeConverter
|
|
7
|
+
import expo.modules.kotlin.types.TypeConverterComponent
|
|
8
|
+
import expo.modules.kotlin.types.TypeConverterProvider
|
|
9
|
+
import expo.modules.kotlin.types.lazyTypeOf
|
|
10
|
+
import kotlin.reflect.KClass
|
|
11
|
+
import kotlin.reflect.KType
|
|
12
|
+
|
|
13
|
+
class ModuleConvertersBuilder {
|
|
14
|
+
@PublishedApi
|
|
15
|
+
internal var convertersComponent = mutableListOf<TypeConverterComponent<*>>()
|
|
16
|
+
|
|
17
|
+
inline fun <reified T : Any> TypeConverter(classifier: KClass<T>): TypeConverterComponent<T> {
|
|
18
|
+
val converterComponent = TypeConverterComponent<T>(lazyTypeOf<T>(), lazyTypeOf<(T?)?>())
|
|
19
|
+
convertersComponent.add(converterComponent)
|
|
20
|
+
return converterComponent
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
inline fun <reified T : Any, reified P0 : Any> TypeConverter(
|
|
24
|
+
classifier: KClass<T>,
|
|
25
|
+
crossinline body: (p0: P0) -> T
|
|
26
|
+
): TypeConverterComponent<T> {
|
|
27
|
+
return TypeConverter<T>(classifier).apply {
|
|
28
|
+
from<P0> { value ->
|
|
29
|
+
body(value)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fun buildTypeConverterProvider(): TypeConverterProvider {
|
|
35
|
+
val converterMap = convertersComponent
|
|
36
|
+
.map { it.build() }
|
|
37
|
+
.flatten()
|
|
38
|
+
.toMap()
|
|
39
|
+
return object : TypeConverterProvider {
|
|
40
|
+
override fun obtainTypeConverter(type: KType): TypeConverter<*> {
|
|
41
|
+
val typeConverter = converterMap[type]
|
|
42
|
+
if (typeConverter != null) {
|
|
43
|
+
return typeConverter
|
|
44
|
+
} else {
|
|
45
|
+
throw MissingTypeConverter(type)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|