expo-modules-core 1.2.6 → 1.3.0
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 -4
- package/ExpoModulesCore.podspec +1 -0
- package/README.md +1 -1
- package/android/ExpoModulesCorePlugin.gradle +16 -0
- package/android/build.gradle +3 -2
- package/android/src/main/cpp/Exceptions.cpp +8 -0
- package/android/src/main/cpp/Exceptions.h +11 -0
- package/android/src/main/cpp/ExpoModulesHostObject.cpp +22 -5
- package/android/src/main/cpp/ExpoModulesHostObject.h +5 -0
- package/android/src/main/cpp/JNIInjector.cpp +2 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +25 -1
- package/android/src/main/cpp/JSIInteropModuleRegistry.h +14 -0
- package/android/src/main/cpp/JSIObjectWrapper.h +15 -4
- package/android/src/main/cpp/JSITypeConverter.h +3 -2
- package/android/src/main/cpp/JavaReferencesCache.cpp +2 -0
- package/android/src/main/cpp/JavaScriptFunction.cpp +56 -0
- package/android/src/main/cpp/JavaScriptFunction.h +54 -0
- package/android/src/main/cpp/JavaScriptModuleObject.cpp +225 -105
- package/android/src/main/cpp/JavaScriptModuleObject.h +67 -34
- package/android/src/main/cpp/JavaScriptObject.cpp +55 -1
- package/android/src/main/cpp/JavaScriptObject.h +17 -13
- package/android/src/main/cpp/JavaScriptRuntime.cpp +12 -3
- package/android/src/main/cpp/JavaScriptRuntime.h +9 -1
- package/android/src/main/cpp/JavaScriptValue.cpp +9 -0
- package/android/src/main/cpp/JavaScriptValue.h +4 -0
- package/android/src/main/cpp/MethodMetadata.cpp +66 -87
- package/android/src/main/cpp/MethodMetadata.h +18 -16
- package/android/src/main/cpp/ObjectDeallocator.h +25 -0
- package/android/src/main/cpp/WeakRuntimeHolder.cpp +7 -0
- package/android/src/main/cpp/WeakRuntimeHolder.h +4 -0
- package/android/src/main/cpp/types/CppType.h +4 -1
- package/android/src/main/cpp/types/FrontendConverter.cpp +58 -0
- package/android/src/main/cpp/types/FrontendConverter.h +45 -0
- package/android/src/main/cpp/types/FrontendConverterProvider.cpp +3 -0
- package/android/src/main/cpp/types/JNIToJSIConverter.cpp +88 -0
- package/android/src/main/cpp/types/JNIToJSIConverter.h +22 -0
- package/android/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMapHelper.kt +10 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +18 -25
- package/android/src/main/java/expo/modules/kotlin/FilteredIterator.kt +37 -0
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +1 -1
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +34 -21
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +13 -3
- package/android/src/main/java/expo/modules/kotlin/Utils.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +21 -1
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +112 -0
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassDefinitionData.kt +10 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CommonExceptions.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +17 -4
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +38 -8
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +1 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +18 -11
- package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +4 -1
- package/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt +73 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +28 -2
- package/android/src/main/java/expo/modules/kotlin/jni/JavaCallback.kt +8 -1
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptFunction.kt +48 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +40 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +23 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +26 -1
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +0 -11
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +26 -16
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +3 -1
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObject.kt +12 -0
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +62 -0
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectTypeConverter.kt +27 -0
- package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +2 -1
- package/android/src/main/java/expo/modules/kotlin/types/EitherTypeConverter.kt +7 -6
- package/android/src/main/java/expo/modules/kotlin/types/JavaScriptFunctionTypeConverter.kt +22 -0
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +30 -24
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +45 -1
- package/android/src/main/java/expo/modules/kotlin/types/TypedArrayTypeConverter.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +3 -1
- package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +3 -3
- package/android/src/main/java/expo/modules/kotlin/views/FilteredReadableMap.kt +53 -0
- package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +25 -5
- package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +25 -5
- package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +161 -10
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -67
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +7 -8
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +40 -3
- package/android/src/main/java/expo/modules/kotlin/views/ViewTypeConverter.kt +44 -0
- package/android-annotation/build.gradle +45 -0
- package/android-annotation/src/main/java/expo/modules/annotation/Config.kt +7 -0
- package/android-annotation/src/main/java/expo/modules/annotation/ConverterBinder.kt +7 -0
- package/android-annotation-processor/build.gradle +51 -0
- package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessor.kt +175 -0
- package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessorProvider.kt +10 -0
- package/android-annotation-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +1 -0
- package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
- package/build/NativeViewManagerAdapter.native.js +36 -23
- package/build/NativeViewManagerAdapter.native.js.map +1 -1
- package/build/requireNativeModule.js +2 -2
- package/build/requireNativeModule.js.map +1 -1
- package/common/cpp/fabric/ExpoViewProps.cpp +18 -3
- package/common/cpp/fabric/ExpoViewProps.h +4 -1
- package/ios/Fabric/ExpoFabricView.swift +10 -10
- package/ios/Fabric/ExpoFabricViewObjC.h +2 -0
- package/ios/Fabric/ExpoFabricViewObjC.mm +17 -2
- package/ios/JSI/EXJSIInstaller.mm +1 -1
- package/ios/JSI/EXJSIUtils.h +5 -0
- package/ios/JSI/EXJSIUtils.mm +17 -0
- package/ios/JSI/EXJavaScriptRuntime.h +5 -0
- package/ios/JSI/EXJavaScriptRuntime.mm +6 -0
- package/ios/JSI/EXJavaScriptValue.h +2 -0
- package/ios/JSI/EXJavaScriptValue.mm +8 -0
- package/ios/JSI/EXJavaScriptWeakObject.mm +29 -8
- package/ios/JSI/EXRawJavaScriptFunction.h +24 -0
- package/ios/JSI/EXRawJavaScriptFunction.mm +52 -0
- package/ios/JSI/ExpoModulesHostObject.mm +1 -1
- package/ios/JSI/JavaScriptValue.swift +28 -1
- package/ios/ModuleRegistry/EXModuleRegistry.h +0 -4
- package/ios/ModuleRegistry/EXModuleRegistry.m +0 -23
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -16
- package/ios/ModuleRegistryProvider/EXModuleRegistryProvider.m +0 -6
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +1 -31
- package/ios/Swift/AppContext.swift +46 -6
- package/ios/Swift/Arguments/Convertible.swift +3 -3
- package/ios/Swift/Arguments/Convertibles.swift +5 -5
- package/ios/Swift/Classes/ClassComponent.swift +18 -12
- package/ios/Swift/Classes/ClassRegistry.swift +31 -0
- package/ios/Swift/Conversions.swift +19 -3
- package/ios/Swift/Convertibles/Convertibles+Color.swift +3 -3
- package/ios/Swift/Convertibles/Either.swift +6 -4
- package/ios/Swift/DynamicTypes/AnyDynamicType.swift +18 -2
- package/ios/Swift/DynamicTypes/DynamicArrayType.swift +3 -3
- package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +2 -2
- package/ios/Swift/DynamicTypes/DynamicEnumType.swift +1 -1
- package/ios/Swift/DynamicTypes/DynamicJavaScriptType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +9 -2
- package/ios/Swift/DynamicTypes/DynamicRawType.swift +1 -1
- package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +16 -2
- package/ios/Swift/DynamicTypes/DynamicType.swift +6 -0
- package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +15 -4
- package/ios/Swift/DynamicTypes/DynamicViewType.swift +68 -0
- package/ios/Swift/ExpoBridgeModule.swift +1 -1
- package/ios/Swift/Functions/AnyFunction.swift +5 -4
- package/ios/Swift/Functions/AsyncFunctionComponent.swift +22 -19
- package/ios/Swift/Functions/ConcurrentFunctionDefinition.swift +29 -13
- package/ios/Swift/Functions/SyncFunctionComponent.swift +26 -15
- package/ios/Swift/JavaScriptFunction.swift +68 -0
- package/ios/Swift/JavaScriptUtils.swift +57 -18
- package/ios/Swift/ModuleHolder.swift +22 -10
- package/ios/Swift/Modules/ModuleDefinition.swift +8 -2
- package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +8 -8
- package/ios/Swift/Objects/ObjectDefinition.swift +17 -15
- package/ios/Swift/Objects/PropertyComponent.swift +23 -17
- package/ios/Swift/Records/AnyField.swift +1 -1
- package/ios/Swift/Records/Field.swift +2 -2
- package/ios/Swift/Records/Record.swift +5 -5
- package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +4 -0
- package/ios/Swift/Views/AnyViewProp.swift +1 -1
- package/ios/Swift/Views/ComponentData.swift +37 -2
- package/ios/Swift/Views/ConcreteViewProp.swift +2 -2
- package/ios/Swift/Views/ViewDefinition.swift +39 -0
- package/ios/Swift/Views/ViewModuleWrapper.swift +0 -29
- package/ios/Tests/ClassComponentSpec.swift +39 -27
- package/ios/Tests/ConvertiblesSpec.swift +75 -49
- package/ios/Tests/DynamicTypeSpec.swift +29 -27
- package/ios/Tests/EitherSpec.swift +9 -7
- package/ios/Tests/ExpoModulesSpec.swift +13 -13
- package/ios/Tests/FunctionSpec.swift +38 -22
- package/ios/Tests/JavaScriptRuntimeSpec.swift +4 -0
- package/ios/Tests/PropertyComponentSpec.swift +33 -30
- package/ios/Tests/RecordSpec.swift +7 -5
- package/ios/Tests/SharedObjectRegistrySpec.swift +12 -12
- package/ios/Tests/TypedArraysSpec.swift +1 -1
- package/ios/Tests/ViewDefinitionSpec.swift +4 -2
- package/package.json +2 -2
- package/src/NativeViewManagerAdapter.native.tsx +33 -29
- package/src/requireNativeModule.ts +2 -2
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -132
- package/ios/EXViewManager.h +0 -21
- package/ios/EXViewManager.m +0 -128
- package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.h +0 -17
- package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.m +0 -67
- package/ios/ViewManagerAdapter/EXViewManagerAdapter.h +0 -17
- package/ios/ViewManagerAdapter/EXViewManagerAdapter.m +0 -45
|
@@ -7,6 +7,9 @@ import com.facebook.react.common.MapBuilder
|
|
|
7
7
|
import expo.modules.core.utilities.ifNull
|
|
8
8
|
import expo.modules.kotlin.ModuleHolder
|
|
9
9
|
import expo.modules.kotlin.events.normalizeEventName
|
|
10
|
+
import expo.modules.kotlin.exception.CodedException
|
|
11
|
+
import expo.modules.kotlin.exception.OnViewDidUpdatePropsException
|
|
12
|
+
import expo.modules.kotlin.exception.exceptionDecorator
|
|
10
13
|
import expo.modules.kotlin.logger
|
|
11
14
|
import expo.modules.kotlin.viewevent.ViewEventDelegate
|
|
12
15
|
import kotlin.reflect.full.declaredMemberProperties
|
|
@@ -22,6 +25,9 @@ class ViewManagerWrapperDelegate(internal var moduleHolder: ModuleHolder) {
|
|
|
22
25
|
val name: String
|
|
23
26
|
get() = moduleHolder.name
|
|
24
27
|
|
|
28
|
+
val props: Map<String, AnyViewProp>
|
|
29
|
+
get() = definition.props
|
|
30
|
+
|
|
25
31
|
fun createView(context: Context): View {
|
|
26
32
|
return definition
|
|
27
33
|
.createView(context, moduleHolder.module.appContext)
|
|
@@ -30,9 +36,40 @@ class ViewManagerWrapperDelegate(internal var moduleHolder: ModuleHolder) {
|
|
|
30
36
|
}
|
|
31
37
|
}
|
|
32
38
|
|
|
33
|
-
fun
|
|
34
|
-
definition.
|
|
35
|
-
|
|
39
|
+
fun onViewDidUpdateProps(view: View) {
|
|
40
|
+
definition.onViewDidUpdateProps?.let {
|
|
41
|
+
try {
|
|
42
|
+
exceptionDecorator({ OnViewDidUpdatePropsException(view.javaClass.kotlin, it) }) {
|
|
43
|
+
it.invoke(view)
|
|
44
|
+
}
|
|
45
|
+
} catch (exception: CodedException) {
|
|
46
|
+
logger.error("❌ Error occurred when invoking 'onViewDidUpdateProps' on '${view.javaClass.simpleName}'", exception)
|
|
47
|
+
definition.handleException(view, exception)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Updates the expo related properties of a given View based on a ReadableMap of property values.
|
|
54
|
+
*
|
|
55
|
+
* @param view The View whose properties should be updated.
|
|
56
|
+
* @param propsMap A ReadableMap of property values.
|
|
57
|
+
*
|
|
58
|
+
* @return A List of property names that were successfully updated.
|
|
59
|
+
*/
|
|
60
|
+
fun updateProperties(view: View, propsMap: ReadableMap): List<String> {
|
|
61
|
+
val expoProps = props
|
|
62
|
+
val handledProps = mutableListOf<String>()
|
|
63
|
+
val iterator = propsMap.keySetIterator()
|
|
64
|
+
|
|
65
|
+
while (iterator.hasNextKey()) {
|
|
66
|
+
val key = iterator.nextKey()
|
|
67
|
+
expoProps[key]?.let { expoProp ->
|
|
68
|
+
expoProp.set(propsMap.getDynamic(key), view)
|
|
69
|
+
handledProps.add(key)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return handledProps
|
|
36
73
|
}
|
|
37
74
|
|
|
38
75
|
fun onDestroy(view: View) =
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
package expo.modules.kotlin.views
|
|
2
|
+
|
|
3
|
+
import android.view.View
|
|
4
|
+
import expo.modules.kotlin.AppContext
|
|
5
|
+
import expo.modules.kotlin.Utils
|
|
6
|
+
import expo.modules.kotlin.exception.Exceptions
|
|
7
|
+
import expo.modules.kotlin.exception.NullArgumentException
|
|
8
|
+
import expo.modules.kotlin.jni.CppType
|
|
9
|
+
import expo.modules.kotlin.jni.ExpectedType
|
|
10
|
+
import expo.modules.kotlin.toStrongReference
|
|
11
|
+
import expo.modules.kotlin.types.TypeConverter
|
|
12
|
+
import kotlin.reflect.KClass
|
|
13
|
+
import kotlin.reflect.KType
|
|
14
|
+
|
|
15
|
+
class ViewTypeConverter<T : View>(
|
|
16
|
+
val type: KType
|
|
17
|
+
) : TypeConverter<T>() {
|
|
18
|
+
|
|
19
|
+
override fun convert(value: Any?, context: AppContext?): T? {
|
|
20
|
+
Utils.assertMainThread()
|
|
21
|
+
if (value == null) {
|
|
22
|
+
if (type.isMarkedNullable) {
|
|
23
|
+
return null
|
|
24
|
+
}
|
|
25
|
+
throw NullArgumentException()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
val appContext = context.toStrongReference()
|
|
29
|
+
val viewTag = value as Int
|
|
30
|
+
val view = appContext.findView<T>(viewTag)
|
|
31
|
+
if (!type.isMarkedNullable && view == null) {
|
|
32
|
+
throw Exceptions.ViewNotFound(type.classifier as KClass<*>, viewTag)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return view
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
override fun getCppRequiredTypes(): ExpectedType = ExpectedType(
|
|
39
|
+
CppType.INT,
|
|
40
|
+
CppType.VIEW_TAG
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
override fun isTrivial(): Boolean = false
|
|
44
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
apply plugin: 'java-library'
|
|
2
|
+
apply plugin: 'org.jetbrains.kotlin.jvm'
|
|
3
|
+
apply plugin: 'kotlin'
|
|
4
|
+
|
|
5
|
+
group = 'host.exp.exponent'
|
|
6
|
+
version = '1.1.1'
|
|
7
|
+
|
|
8
|
+
buildscript {
|
|
9
|
+
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
10
|
+
if (expoModulesCorePlugin.exists()) {
|
|
11
|
+
apply from: expoModulesCorePlugin
|
|
12
|
+
applyKotlinExpoModulesCorePlugin()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Simple helper that allows the root project to override versions declared by this library.
|
|
16
|
+
ext.safeExtGet = { prop, fallback ->
|
|
17
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Ensures backward compatibility
|
|
21
|
+
ext.getKotlinVersion = {
|
|
22
|
+
if (ext.has("kotlinVersion")) {
|
|
23
|
+
ext.kotlinVersion()
|
|
24
|
+
} else {
|
|
25
|
+
ext.safeExtGet("kotlinVersion", "1.6.10")
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
repositories {
|
|
30
|
+
mavenCentral()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
dependencies {
|
|
34
|
+
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
java {
|
|
39
|
+
sourceCompatibility = JavaVersion.VERSION_1_8
|
|
40
|
+
targetCompatibility = JavaVersion.VERSION_1_8
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
dependencies {
|
|
44
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
|
|
45
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
apply plugin: 'java-library'
|
|
2
|
+
apply plugin: 'org.jetbrains.kotlin.jvm'
|
|
3
|
+
apply plugin: 'kotlin'
|
|
4
|
+
|
|
5
|
+
group = 'host.exp.exponent'
|
|
6
|
+
version = '1.1.1'
|
|
7
|
+
|
|
8
|
+
buildscript {
|
|
9
|
+
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
10
|
+
if (expoModulesCorePlugin.exists()) {
|
|
11
|
+
apply from: expoModulesCorePlugin
|
|
12
|
+
applyKotlinExpoModulesCorePlugin()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Simple helper that allows the root project to override versions declared by this library.
|
|
16
|
+
ext.safeExtGet = { prop, fallback ->
|
|
17
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Ensures backward compatibility
|
|
21
|
+
ext.getKotlinVersion = {
|
|
22
|
+
if (ext.has("kotlinVersion")) {
|
|
23
|
+
ext.kotlinVersion()
|
|
24
|
+
} else {
|
|
25
|
+
ext.safeExtGet("kotlinVersion", "1.6.10")
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
repositories {
|
|
30
|
+
mavenCentral()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
dependencies {
|
|
34
|
+
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
java {
|
|
39
|
+
sourceCompatibility = JavaVersion.VERSION_1_8
|
|
40
|
+
targetCompatibility = JavaVersion.VERSION_1_8
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
dependencies {
|
|
44
|
+
implementation project(':expo-modules-core$android-annotation')
|
|
45
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
|
|
46
|
+
|
|
47
|
+
implementation "com.google.devtools.ksp:symbol-processing-api:${kspVersion()}"
|
|
48
|
+
|
|
49
|
+
implementation 'com.squareup:kotlinpoet:1.12.0'
|
|
50
|
+
implementation 'com.squareup:kotlinpoet-ksp:1.12.0'
|
|
51
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
package expo.modules.annotationprocessor
|
|
2
|
+
|
|
3
|
+
import com.google.devtools.ksp.getVisibility
|
|
4
|
+
import com.google.devtools.ksp.processing.CodeGenerator
|
|
5
|
+
import com.google.devtools.ksp.processing.Dependencies
|
|
6
|
+
import com.google.devtools.ksp.processing.KSPLogger
|
|
7
|
+
import com.google.devtools.ksp.processing.Resolver
|
|
8
|
+
import com.google.devtools.ksp.processing.SymbolProcessor
|
|
9
|
+
import com.google.devtools.ksp.symbol.FunctionKind
|
|
10
|
+
import com.google.devtools.ksp.symbol.KSAnnotated
|
|
11
|
+
import com.google.devtools.ksp.symbol.KSFunctionDeclaration
|
|
12
|
+
import com.google.devtools.ksp.symbol.KSType
|
|
13
|
+
import com.google.devtools.ksp.symbol.KSVisitorVoid
|
|
14
|
+
import com.google.devtools.ksp.symbol.Visibility
|
|
15
|
+
import com.squareup.kotlinpoet.ClassName
|
|
16
|
+
import com.squareup.kotlinpoet.FileSpec
|
|
17
|
+
import com.squareup.kotlinpoet.FunSpec
|
|
18
|
+
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
|
|
19
|
+
import com.squareup.kotlinpoet.TypeSpec
|
|
20
|
+
import com.squareup.kotlinpoet.ksp.toClassName
|
|
21
|
+
import expo.modules.annotation.Config
|
|
22
|
+
import expo.modules.annotation.ConverterBinder
|
|
23
|
+
import java.io.OutputStreamWriter
|
|
24
|
+
import java.nio.charset.StandardCharsets
|
|
25
|
+
|
|
26
|
+
class ExpoSymbolProcessor(
|
|
27
|
+
private val codeGenerator: CodeGenerator,
|
|
28
|
+
private val logger: KSPLogger,
|
|
29
|
+
) : SymbolProcessor {
|
|
30
|
+
override fun process(resolver: Resolver): List<KSAnnotated> {
|
|
31
|
+
val symbols = resolver
|
|
32
|
+
.getSymbolsWithAnnotation(ConverterBinder::class.java.name)
|
|
33
|
+
.filterIsInstance<KSFunctionDeclaration>()
|
|
34
|
+
|
|
35
|
+
if (symbols.iterator().hasNext().not()) {
|
|
36
|
+
return emptyList()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
symbols.forEach { symbol ->
|
|
40
|
+
val clazz = symbol.annotations.find {
|
|
41
|
+
it.shortName.asString() == ConverterBinder::class.java.simpleName
|
|
42
|
+
}!!.arguments[0].value as KSType
|
|
43
|
+
|
|
44
|
+
val parsedClazz = if (clazz.toString() == "Void") {
|
|
45
|
+
null
|
|
46
|
+
} else {
|
|
47
|
+
clazz.toClassName()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
symbol.accept(ConverterBinderVisitor(parsedClazz, codeGenerator, logger), Unit)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return emptyList()
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
class ConverterBinderVisitor(
|
|
58
|
+
private val clazz: ClassName?,
|
|
59
|
+
private val codeGenerator: CodeGenerator,
|
|
60
|
+
private val logger: KSPLogger,
|
|
61
|
+
) : KSVisitorVoid() {
|
|
62
|
+
|
|
63
|
+
override fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: Unit) {
|
|
64
|
+
if (function.functionKind != FunctionKind.TOP_LEVEL ||
|
|
65
|
+
function.getVisibility() != Visibility.PUBLIC
|
|
66
|
+
) {
|
|
67
|
+
logger.error("ConverterBinder has to be a public top-level function", function)
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
val resolvedType = resolveConverterType(function) ?: return
|
|
72
|
+
val shouldReceiveType = shouldReceiveType(function) ?: return
|
|
73
|
+
|
|
74
|
+
val packageName = "${Config.packageNamePrefix}${resolvedType.packageName}"
|
|
75
|
+
val className = "${resolvedType.simpleName}${Config.classNameSuffix}"
|
|
76
|
+
|
|
77
|
+
val content = generateConverterProvider(
|
|
78
|
+
packageName,
|
|
79
|
+
className,
|
|
80
|
+
function,
|
|
81
|
+
resolvedType,
|
|
82
|
+
shouldReceiveType
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
logger.info("Generating: $packageName.$className")
|
|
86
|
+
|
|
87
|
+
val file = codeGenerator.createNewFile(
|
|
88
|
+
createFileDependencies(function),
|
|
89
|
+
packageName,
|
|
90
|
+
className
|
|
91
|
+
)
|
|
92
|
+
OutputStreamWriter(file, StandardCharsets.UTF_8).use {
|
|
93
|
+
content.writeTo(it)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private fun shouldReceiveType(function: KSFunctionDeclaration): Boolean? {
|
|
98
|
+
val argsNumber = function.parameters.size
|
|
99
|
+
if (argsNumber != 0 && argsNumber != 1) {
|
|
100
|
+
logger.error("ConverterBinder cannot receive more then one argument", function)
|
|
101
|
+
return null
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return function.parameters.firstOrNull()?.type?.toString() == "KType"
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private fun createFileDependencies(function: KSFunctionDeclaration): Dependencies {
|
|
108
|
+
val containingFile = function.containingFile
|
|
109
|
+
return if (containingFile == null) {
|
|
110
|
+
Dependencies(false)
|
|
111
|
+
} else {
|
|
112
|
+
Dependencies(false, containingFile)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private fun resolveConverterType(function: KSFunctionDeclaration): ClassName? {
|
|
117
|
+
if (clazz != null) {
|
|
118
|
+
return clazz
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
val returnType = function.returnType?.resolve()
|
|
122
|
+
if (returnType == null) {
|
|
123
|
+
logger.error("Cannot resolve return type", function)
|
|
124
|
+
return null
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (returnType.arguments.size != 1) {
|
|
128
|
+
logger.error("Incorrect return type", function)
|
|
129
|
+
return null
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
val type = returnType.arguments.first().type?.resolve()
|
|
133
|
+
if (type == null) {
|
|
134
|
+
logger.error("Cannot resolve converter inner type", function)
|
|
135
|
+
return null
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return type.toClassName()
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private fun generateConverterProvider(
|
|
142
|
+
packageName: String,
|
|
143
|
+
className: String,
|
|
144
|
+
function: KSFunctionDeclaration,
|
|
145
|
+
forType: ClassName,
|
|
146
|
+
receivesType: Boolean
|
|
147
|
+
): FileSpec {
|
|
148
|
+
val typeConverter = ClassName("expo.modules.kotlin.types", "TypeConverter")
|
|
149
|
+
.parameterizedBy(forType)
|
|
150
|
+
val kType = ClassName("kotlin.reflect", "KType")
|
|
151
|
+
|
|
152
|
+
return FileSpec
|
|
153
|
+
.builder(packageName, className)
|
|
154
|
+
.addType(
|
|
155
|
+
TypeSpec
|
|
156
|
+
.classBuilder(className)
|
|
157
|
+
.addFunction(
|
|
158
|
+
FunSpec
|
|
159
|
+
.builder(Config.converterProviderFunctionName)
|
|
160
|
+
.addParameter("type", kType)
|
|
161
|
+
.returns(typeConverter)
|
|
162
|
+
.apply {
|
|
163
|
+
if (receivesType) {
|
|
164
|
+
addStatement("return ${function.packageName.asString()}.${function.simpleName.asString()}(type)")
|
|
165
|
+
} else {
|
|
166
|
+
addStatement("return ${function.packageName.asString()}.${function.simpleName.asString()}()")
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
.build()
|
|
170
|
+
)
|
|
171
|
+
.build()
|
|
172
|
+
)
|
|
173
|
+
.build()
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
package expo.modules.annotationprocessor
|
|
2
|
+
|
|
3
|
+
import com.google.devtools.ksp.processing.SymbolProcessor
|
|
4
|
+
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
|
|
5
|
+
import com.google.devtools.ksp.processing.SymbolProcessorProvider
|
|
6
|
+
|
|
7
|
+
class ExpoSymbolProcessorProvider : SymbolProcessorProvider {
|
|
8
|
+
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor =
|
|
9
|
+
ExpoSymbolProcessor(environment.codeGenerator, environment.logger)
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
expo.modules.annotationprocessor.ExpoSymbolProcessorProvider
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeViewManagerAdapter.native.d.ts","sourceRoot":"","sources":["../src/NativeViewManagerAdapter.native.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"NativeViewManagerAdapter.native.d.ts","sourceRoot":"","sources":["../src/NativeViewManagerAdapter.native.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAmC1B;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAiDpF"}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { NativeModules, requireNativeComponent } from 'react-native';
|
|
2
|
+
import { findNodeHandle, NativeModules, requireNativeComponent } from 'react-native';
|
|
3
|
+
import { requireNativeModule } from './requireNativeModule';
|
|
4
|
+
// To make the transition from React Native's `requireNativeComponent` to Expo's
|
|
5
|
+
// `requireNativeViewManager` as easy as possible, `requireNativeViewManager` is a drop-in
|
|
6
|
+
// replacement for `requireNativeComponent`.
|
|
7
|
+
//
|
|
8
|
+
// For each view manager, we create a wrapper component that accepts all of the props available to
|
|
9
|
+
// the author of the universal module. This wrapper component splits the props into two sets: props
|
|
10
|
+
// passed to React Native's View (ex: style, testID) and custom view props, which are passed to the
|
|
11
|
+
// adapter view component in a prop called `proxiedProperties`.
|
|
3
12
|
/**
|
|
4
13
|
* A map that caches registered native components.
|
|
5
14
|
*/
|
|
@@ -32,29 +41,33 @@ export function requireNativeViewManager(viewName) {
|
|
|
32
41
|
// manager
|
|
33
42
|
const reactNativeViewName = `ViewManagerAdapter_${viewName}`;
|
|
34
43
|
const ReactNativeComponent = requireCachedNativeComponent(reactNativeViewName);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const copied = { ...props };
|
|
47
|
-
for (const propName of propNames) {
|
|
48
|
-
delete copied[propName];
|
|
44
|
+
class NativeComponent extends React.PureComponent {
|
|
45
|
+
static displayName = viewName;
|
|
46
|
+
// This will be accessed from native when the prototype functions are called,
|
|
47
|
+
// in order to find the associated native view.
|
|
48
|
+
nativeTag = null;
|
|
49
|
+
componentDidMount() {
|
|
50
|
+
this.nativeTag = findNodeHandle(this);
|
|
51
|
+
}
|
|
52
|
+
render() {
|
|
53
|
+
return React.createElement(ReactNativeComponent, { ...this.props });
|
|
54
|
+
}
|
|
49
55
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
try {
|
|
57
|
+
const nativeModule = requireNativeModule(viewName);
|
|
58
|
+
const nativeViewPrototype = nativeModule.ViewPrototype;
|
|
59
|
+
if (nativeViewPrototype) {
|
|
60
|
+
// Assign native view functions to the component prototype so they can be accessed from the ref.
|
|
61
|
+
Object.assign(NativeComponent.prototype, nativeViewPrototype);
|
|
56
62
|
}
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// `requireNativeModule` may throw an error when the native module cannot be found.
|
|
66
|
+
// In some tests we don't mock the entire modules, but we do want to mock native views. For now,
|
|
67
|
+
// until we still have to support the legacy modules proxy and don't have better ways to mock,
|
|
68
|
+
// let's just gracefully skip assigning the prototype functions.
|
|
69
|
+
// See: https://github.com/expo/expo/blob/main/packages/expo-modules-core/src/__tests__/NativeViewManagerAdapter-test.native.tsx
|
|
70
|
+
}
|
|
71
|
+
return NativeComponent;
|
|
59
72
|
}
|
|
60
73
|
//# sourceMappingURL=NativeViewManagerAdapter.native.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeViewManagerAdapter.native.js","sourceRoot":"","sources":["../src/NativeViewManagerAdapter.native.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAiB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"NativeViewManagerAdapter.native.js","sourceRoot":"","sources":["../src/NativeViewManagerAdapter.native.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,sBAAsB,EAAiB,MAAM,cAAc,CAAC;AAEpG,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,gFAAgF;AAChF,0FAA0F;AAC1F,4CAA4C;AAC5C,EAAE;AACF,kGAAkG;AAClG,mGAAmG;AACnG,mGAAmG;AACnG,+DAA+D;AAE/D;;GAEG;AACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAA8B,CAAC;AAEpE;;;;GAIG;AACH,SAAS,4BAA4B,CAAQ,QAAgB;IAC3D,MAAM,qBAAqB,GAAG,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAElE,IAAI,CAAC,qBAAqB,EAAE;QAC1B,MAAM,eAAe,GAAG,sBAAsB,CAAQ,QAAQ,CAAC,CAAC;QAChE,qBAAqB,CAAC,GAAG,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;QACrD,OAAO,eAAe,CAAC;KACxB;IACD,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAI,QAAgB;IAC1D,MAAM,EAAE,oBAAoB,EAAE,GAAG,aAAa,CAAC,oBAAoB,CAAC;IACpE,MAAM,iBAAiB,GAAG,oBAAoB,EAAE,CAAC,QAAQ,CAAC,CAAC;IAE3D,IAAI,OAAO,IAAI,CAAC,iBAAiB,EAAE;QACjC,MAAM,wBAAwB,GAAG,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9E,OAAO,CAAC,IAAI,CACV,6CAA6C,QAAQ,8IAA8I,wBAAwB,IAAI,CAChO,CAAC;KACH;IAED,+FAA+F;IAC/F,UAAU;IACV,MAAM,mBAAmB,GAAG,sBAAsB,QAAQ,EAAE,CAAC;IAC7D,MAAM,oBAAoB,GAAG,4BAA4B,CAAC,mBAAmB,CAAC,CAAC;IAE/E,MAAM,eAAgB,SAAQ,KAAK,CAAC,aAAgB;QAClD,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC;QAE9B,6EAA6E;QAC7E,+CAA+C;QAC/C,SAAS,GAAkB,IAAI,CAAC;QAEhC,iBAAiB;YACf,IAAI,CAAC,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;QAED,MAAM;YACJ,OAAO,oBAAC,oBAAoB,OAAK,IAAI,CAAC,KAAK,GAAI,CAAC;QAClD,CAAC;;IAGH,IAAI;QACF,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QACnD,MAAM,mBAAmB,GAAG,YAAY,CAAC,aAAa,CAAC;QAEvD,IAAI,mBAAmB,EAAE;YACvB,gGAAgG;YAChG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;SAC/D;KACF;IAAC,MAAM;QACN,mFAAmF;QACnF,gGAAgG;QAChG,8FAA8F;QAC9F,gEAAgE;QAChE,gIAAgI;KACjI;IAED,OAAO,eAAe,CAAC;AACzB,CAAC","sourcesContent":["import React from 'react';\nimport { findNodeHandle, NativeModules, requireNativeComponent, HostComponent } from 'react-native';\n\nimport { requireNativeModule } from './requireNativeModule';\n\n// To make the transition from React Native's `requireNativeComponent` to Expo's\n// `requireNativeViewManager` as easy as possible, `requireNativeViewManager` is a drop-in\n// replacement for `requireNativeComponent`.\n//\n// For each view manager, we create a wrapper component that accepts all of the props available to\n// the author of the universal module. This wrapper component splits the props into two sets: props\n// passed to React Native's View (ex: style, testID) and custom view props, which are passed to the\n// adapter view component in a prop called `proxiedProperties`.\n\n/**\n * A map that caches registered native components.\n */\nconst nativeComponentsCache = new Map<string, HostComponent<any>>();\n\n/**\n * Requires a React Native component from cache if possible. This prevents\n * \"Tried to register two views with the same name\" errors on fast refresh, but\n * also when there are multiple versions of the same package with native component.\n */\nfunction requireCachedNativeComponent<Props>(viewName: string): HostComponent<Props> {\n const cachedNativeComponent = nativeComponentsCache.get(viewName);\n\n if (!cachedNativeComponent) {\n const nativeComponent = requireNativeComponent<Props>(viewName);\n nativeComponentsCache.set(viewName, nativeComponent);\n return nativeComponent;\n }\n return cachedNativeComponent;\n}\n\n/**\n * A drop-in replacement for `requireNativeComponent`.\n */\nexport function requireNativeViewManager<P>(viewName: string): React.ComponentType<P> {\n const { viewManagersMetadata } = NativeModules.NativeUnimoduleProxy;\n const viewManagerConfig = viewManagersMetadata?.[viewName];\n\n if (__DEV__ && !viewManagerConfig) {\n const exportedViewManagerNames = Object.keys(viewManagersMetadata).join(', ');\n console.warn(\n `The native view manager required by name (${viewName}) from NativeViewManagerAdapter isn't exported by expo-modules-core. Views of this type may not render correctly. Exported view managers: [${exportedViewManagerNames}].`\n );\n }\n\n // Set up the React Native native component, which is an adapter to the universal module's view\n // manager\n const reactNativeViewName = `ViewManagerAdapter_${viewName}`;\n const ReactNativeComponent = requireCachedNativeComponent(reactNativeViewName);\n\n class NativeComponent extends React.PureComponent<P> {\n static displayName = viewName;\n\n // This will be accessed from native when the prototype functions are called,\n // in order to find the associated native view.\n nativeTag: number | null = null;\n\n componentDidMount(): void {\n this.nativeTag = findNodeHandle(this);\n }\n\n render(): React.ReactNode {\n return <ReactNativeComponent {...this.props} />;\n }\n }\n\n try {\n const nativeModule = requireNativeModule(viewName);\n const nativeViewPrototype = nativeModule.ViewPrototype;\n\n if (nativeViewPrototype) {\n // Assign native view functions to the component prototype so they can be accessed from the ref.\n Object.assign(NativeComponent.prototype, nativeViewPrototype);\n }\n } catch {\n // `requireNativeModule` may throw an error when the native module cannot be found.\n // In some tests we don't mock the entire modules, but we do want to mock native views. For now,\n // until we still have to support the legacy modules proxy and don't have better ways to mock,\n // let's just gracefully skip assigning the prototype functions.\n // See: https://github.com/expo/expo/blob/main/packages/expo-modules-core/src/__tests__/NativeViewManagerAdapter-test.native.tsx\n }\n\n return NativeComponent;\n}\n"]}
|
|
@@ -9,8 +9,8 @@ import NativeModulesProxy from './NativeModulesProxy';
|
|
|
9
9
|
* @throws Error when there is no native module with given name.
|
|
10
10
|
*/
|
|
11
11
|
export function requireNativeModule(moduleName) {
|
|
12
|
-
const nativeModule =
|
|
13
|
-
|
|
12
|
+
const nativeModule = globalThis.expo?.modules?.[moduleName] ??
|
|
13
|
+
globalThis.ExpoModules?.[moduleName] ??
|
|
14
14
|
NativeModulesProxy[moduleName];
|
|
15
15
|
if (!nativeModule) {
|
|
16
16
|
throw new Error(`Cannot find native module '${moduleName}'`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requireNativeModule.js","sourceRoot":"","sources":["../src/requireNativeModule.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AAyBtD;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAmB,UAAkB;IACtE,MAAM,YAAY,GAChB,
|
|
1
|
+
{"version":3,"file":"requireNativeModule.js","sourceRoot":"","sources":["../src/requireNativeModule.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AAyBtD;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAmB,UAAkB;IACtE,MAAM,YAAY,GAChB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,UAAU,CAAC;QACtC,UAAU,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC;QACpC,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAEjC,IAAI,CAAC,YAAY,EAAE;QACjB,MAAM,IAAI,KAAK,CAAC,8BAA8B,UAAU,GAAG,CAAC,CAAC;KAC9D;IACD,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["import NativeModulesProxy from './NativeModulesProxy';\n\ntype ExpoObject = {\n modules:\n | undefined\n | {\n [key: string]: any;\n };\n};\n\ndeclare global {\n // eslint-disable-next-line no-var\n var expo: ExpoObject | undefined;\n\n /**\n * @deprecated `global.ExpoModules` is deprecated, use `global.expo.modules` instead.\n */\n // eslint-disable-next-line no-var\n var ExpoModules:\n | undefined\n | {\n [key: string]: any;\n };\n}\n\n/**\n * Imports the native module registered with given name. In the first place it tries to load\n * the module installed through the JSI host object and then falls back to the bridge proxy module.\n * Notice that the modules loaded from the proxy may not support some features like synchronous functions.\n *\n * @param moduleName Name of the requested native module.\n * @returns Object representing the native module.\n * @throws Error when there is no native module with given name.\n */\nexport function requireNativeModule<ModuleType = any>(moduleName: string): ModuleType {\n const nativeModule: ModuleType =\n globalThis.expo?.modules?.[moduleName] ??\n globalThis.ExpoModules?.[moduleName] ??\n NativeModulesProxy[moduleName];\n\n if (!nativeModule) {\n throw new Error(`Cannot find native module '${moduleName}'`);\n }\n return nativeModule;\n}\n"]}
|
|
@@ -7,12 +7,27 @@ namespace react = facebook::react;
|
|
|
7
7
|
|
|
8
8
|
namespace expo {
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
Borrows the props map from the source props and applies the update given in the raw props.
|
|
12
|
+
*/
|
|
13
|
+
std::unordered_map<std::string, folly::dynamic> propsMapFromProps(const ExpoViewProps &sourceProps, const react::RawProps &rawProps) {
|
|
14
|
+
// Move the contents of the source props map – the source props instance will not be used anymore.
|
|
15
|
+
std::unordered_map<std::string, folly::dynamic> propsMap = std::move(sourceProps.propsMap);
|
|
16
|
+
|
|
17
|
+
// Iterate over values in the raw props object.
|
|
18
|
+
// Note that it contains only updated props.
|
|
19
|
+
rawProps.iterateOverValues([&propsMap](react::RawPropsPropNameHash hash, const char *name, const react::RawValue &value) {
|
|
20
|
+
std::string propName(name);
|
|
21
|
+
propsMap[propName] = (folly::dynamic)value;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return propsMap;
|
|
25
|
+
}
|
|
26
|
+
|
|
10
27
|
ExpoViewProps::ExpoViewProps(const react::PropsParserContext &context,
|
|
11
28
|
const ExpoViewProps &sourceProps,
|
|
12
29
|
const react::RawProps &rawProps)
|
|
13
30
|
: ViewProps(context, sourceProps, rawProps),
|
|
14
|
-
|
|
15
|
-
facebook::react::convertRawProp(context, rawProps, "proxiedProperties", sourceProps.proxiedProperties, {})) {
|
|
16
|
-
}
|
|
31
|
+
propsMap(propsMapFromProps(sourceProps, rawProps)) {}
|
|
17
32
|
|
|
18
33
|
} // namespace expo
|
|
@@ -21,13 +21,6 @@ public class ExpoFabricView: ExpoFabricViewObjC {
|
|
|
21
21
|
return appContext?.moduleRegistry.get(moduleHolderForName: moduleName)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
/**
|
|
25
|
-
The view manager of the associated legacy module.
|
|
26
|
-
Not available if the module is registered in the new module registry.
|
|
27
|
-
*/
|
|
28
|
-
lazy var legacyViewManager = appContext?.legacyModuleRegistry?.getAllViewManagers()
|
|
29
|
-
.filter { $0.viewName() == moduleName }
|
|
30
|
-
.first
|
|
31
24
|
|
|
32
25
|
/**
|
|
33
26
|
A dictionary of prop objects that contain prop setters.
|
|
@@ -52,7 +45,7 @@ public class ExpoFabricView: ExpoFabricViewObjC {
|
|
|
52
45
|
// MARK: - ExpoFabricViewInterface
|
|
53
46
|
|
|
54
47
|
public override func updateProps(_ props: [String: Any]) {
|
|
55
|
-
guard let view = contentView, let propsDict = viewManagerPropDict else {
|
|
48
|
+
guard let view = contentView, let context = appContext, let propsDict = viewManagerPropDict else {
|
|
56
49
|
return
|
|
57
50
|
}
|
|
58
51
|
for (key, prop) in propsDict {
|
|
@@ -61,7 +54,7 @@ public class ExpoFabricView: ExpoFabricViewObjC {
|
|
|
61
54
|
// TODO: @tsapeta: Figure out better way to rethrow errors from here.
|
|
62
55
|
// Adding `throws` keyword to the function results in different
|
|
63
56
|
// method signature in Objective-C. Maybe just call `RCTLogError`?
|
|
64
|
-
try? prop.set(value: Conversions.fromNSObject(newValue), onView: view)
|
|
57
|
+
try? prop.set(value: Conversions.fromNSObject(newValue), onView: view, appContext: context)
|
|
65
58
|
}
|
|
66
59
|
}
|
|
67
60
|
|
|
@@ -75,6 +68,13 @@ public class ExpoFabricView: ExpoFabricViewObjC {
|
|
|
75
68
|
viewManager.callLifecycleMethods(withType: .didUpdateProps, forView: view)
|
|
76
69
|
}
|
|
77
70
|
|
|
71
|
+
/**
|
|
72
|
+
Returns a bool value whether the view supports prop with the given name.
|
|
73
|
+
*/
|
|
74
|
+
public override func supportsProp(withName name: String) -> Bool {
|
|
75
|
+
return viewManagerPropDict?.index(forKey: name) != nil
|
|
76
|
+
}
|
|
77
|
+
|
|
78
78
|
/**
|
|
79
79
|
The function that is called by Fabric when the view is unmounted and is being enqueued for recycling.
|
|
80
80
|
It can also be called on app reload, so be careful to wipe out any dependencies specific to the currently running AppContext.
|
|
@@ -110,7 +110,7 @@ public class ExpoFabricView: ExpoFabricViewObjC {
|
|
|
110
110
|
guard let appContext = appContext else {
|
|
111
111
|
fatalError(Exceptions.AppContextLost().reason)
|
|
112
112
|
}
|
|
113
|
-
guard let view = moduleHolder?.definition.viewManager?.createView(appContext: appContext)
|
|
113
|
+
guard let view = moduleHolder?.definition.viewManager?.createView(appContext: appContext) else {
|
|
114
114
|
fatalError("Cannot create a view from module '\(moduleName)'")
|
|
115
115
|
}
|
|
116
116
|
// Setting the content view automatically adds the view as a subview.
|