expo-modules-core 1.2.7 → 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 +28 -5
- 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 +8 -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 +30 -23
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +0 -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 -3
- 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 +6 -7
- 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
|
@@ -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.
|
|
@@ -140,9 +140,18 @@ static std::unordered_map<std::string, ExpoViewComponentDescriptor::Flavor> _com
|
|
|
140
140
|
- (void)updateProps:(const facebook::react::Props::Shared &)props oldProps:(const facebook::react::Props::Shared &)oldProps
|
|
141
141
|
{
|
|
142
142
|
const auto &newViewProps = *std::static_pointer_cast<ExpoViewProps const>(props);
|
|
143
|
-
|
|
143
|
+
NSMutableDictionary<NSString *, id> *propsMap = [[NSMutableDictionary alloc] init];
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
for (const auto &item : newViewProps.propsMap) {
|
|
146
|
+
NSString *propName = [NSString stringWithUTF8String:item.first.c_str()];
|
|
147
|
+
|
|
148
|
+
// Ignore props inherited from the base view and Yoga.
|
|
149
|
+
if ([self supportsPropWithName:propName]) {
|
|
150
|
+
propsMap[propName] = convertFollyDynamicToId(item.second);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
[self updateProps:propsMap];
|
|
146
155
|
[super updateProps:props oldProps:oldProps];
|
|
147
156
|
[self viewDidUpdateProps];
|
|
148
157
|
}
|
|
@@ -174,6 +183,12 @@ static std::unordered_map<std::string, ExpoViewComponentDescriptor::Flavor> _com
|
|
|
174
183
|
// Implemented in `ExpoFabricView.swift`
|
|
175
184
|
}
|
|
176
185
|
|
|
186
|
+
- (BOOL)supportsPropWithName:(nonnull NSString *)name
|
|
187
|
+
{
|
|
188
|
+
// Implemented in `ExpoFabricView.swift`
|
|
189
|
+
return NO;
|
|
190
|
+
}
|
|
191
|
+
|
|
177
192
|
#pragma mark - Methods to override in the subclass
|
|
178
193
|
|
|
179
194
|
- (nullable EXAppContext *)__injectedAppContext
|
|
@@ -35,7 +35,7 @@ static NSString *modulesHostObjectLegacyPropertyName = @"ExpoModules";
|
|
|
35
35
|
|
|
36
36
|
+ (BOOL)installExpoModulesHostObject:(nonnull EXAppContext *)appContext
|
|
37
37
|
{
|
|
38
|
-
EXJavaScriptRuntime *runtime = [appContext
|
|
38
|
+
EXJavaScriptRuntime *runtime = [appContext _runtime];
|
|
39
39
|
|
|
40
40
|
// The runtime may be unavailable, e.g. remote debugger is enabled or it hasn't been set yet.
|
|
41
41
|
if (!runtime) {
|
package/ios/JSI/EXJSIUtils.h
CHANGED
|
@@ -26,6 +26,11 @@ using ClassConstructor = std::function<void(jsi::Runtime &runtime, const jsi::Va
|
|
|
26
26
|
|
|
27
27
|
std::shared_ptr<jsi::Function> createClass(jsi::Runtime &runtime, const char *name, ClassConstructor constructor);
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
Creates a new object, using the provided object as the prototype.
|
|
31
|
+
*/
|
|
32
|
+
std::shared_ptr<jsi::Object> createObjectWithPrototype(jsi::Runtime &runtime, std::shared_ptr<jsi::Object> prototype);
|
|
33
|
+
|
|
29
34
|
#pragma mark - Weak objects
|
|
30
35
|
|
|
31
36
|
/**
|
package/ios/JSI/EXJSIUtils.mm
CHANGED
|
@@ -115,6 +115,23 @@ std::shared_ptr<jsi::Function> createClass(jsi::Runtime &runtime, const char *na
|
|
|
115
115
|
return std::make_shared<jsi::Function>(klass.asFunction(runtime));
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
std::shared_ptr<jsi::Object> createObjectWithPrototype(jsi::Runtime &runtime, std::shared_ptr<jsi::Object> prototype) {
|
|
119
|
+
// Get the "Object" class.
|
|
120
|
+
jsi::Object objectClass = runtime
|
|
121
|
+
.global()
|
|
122
|
+
.getPropertyAsObject(runtime, "Object");
|
|
123
|
+
|
|
124
|
+
// Call "Object.create(prototype)" to create an object with the given prototype without calling the constructor.
|
|
125
|
+
jsi::Object object = objectClass
|
|
126
|
+
.getPropertyAsFunction(runtime, "create")
|
|
127
|
+
.callWithThis(runtime, objectClass, {
|
|
128
|
+
jsi::Value(runtime, *prototype)
|
|
129
|
+
})
|
|
130
|
+
.asObject(runtime);
|
|
131
|
+
|
|
132
|
+
return std::make_shared<jsi::Object>(std::move(object));
|
|
133
|
+
}
|
|
134
|
+
|
|
118
135
|
#pragma mark - Weak objects
|
|
119
136
|
|
|
120
137
|
bool isWeakRefSupported(jsi::Runtime &runtime) {
|
|
@@ -103,6 +103,11 @@ typedef void (^ClassConstructorBlock)(EXJavaScriptObject * _Nonnull thisValue, N
|
|
|
103
103
|
- (nonnull EXJavaScriptObject *)createClass:(nonnull NSString *)name
|
|
104
104
|
constructor:(nonnull ClassConstructorBlock)constructor;
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
Creates a new object, using the provided object as the prototype.
|
|
108
|
+
*/
|
|
109
|
+
- (nullable EXJavaScriptObject *)createObjectWithPrototype:(nonnull EXJavaScriptObject *)prototype;
|
|
110
|
+
|
|
106
111
|
#pragma mark - Script evaluation
|
|
107
112
|
|
|
108
113
|
/**
|
|
@@ -160,6 +160,12 @@ static NSString *mainObjectPropertyName = @"expo";
|
|
|
160
160
|
return [[EXJavaScriptObject alloc] initWith:klass runtime:self];
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
+
- (nullable EXJavaScriptObject *)createObjectWithPrototype:(nonnull EXJavaScriptObject *)prototype
|
|
164
|
+
{
|
|
165
|
+
std::shared_ptr<jsi::Object> object = expo::createObjectWithPrototype(*_runtime, [prototype getShared]);
|
|
166
|
+
return object ? [[EXJavaScriptObject alloc] initWith:object runtime:self] : nil;
|
|
167
|
+
}
|
|
168
|
+
|
|
163
169
|
#pragma mark - Script evaluation
|
|
164
170
|
|
|
165
171
|
- (nonnull EXJavaScriptValue *)evaluateScript:(nonnull NSString *)scriptSource
|
|
@@ -9,6 +9,7 @@ namespace jsi = facebook::jsi;
|
|
|
9
9
|
#endif // __cplusplus
|
|
10
10
|
|
|
11
11
|
@class EXJavaScriptRuntime;
|
|
12
|
+
@class EXRawJavaScriptFunction;
|
|
12
13
|
@class EXJavaScriptTypedArray;
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -49,6 +50,7 @@ NS_SWIFT_NAME(JavaScriptValue)
|
|
|
49
50
|
- (nonnull NSArray<EXJavaScriptValue *> *)getArray;
|
|
50
51
|
- (nonnull NSDictionary<NSString *, id> *)getDictionary;
|
|
51
52
|
- (nonnull EXJavaScriptObject *)getObject;
|
|
53
|
+
- (nonnull EXRawJavaScriptFunction *)getFunction;
|
|
52
54
|
- (nullable EXJavaScriptTypedArray *)getTypedArray;
|
|
53
55
|
|
|
54
56
|
#pragma mark - Helpers
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#import <ExpoModulesCore/EXJSIConversions.h>
|
|
4
4
|
#import <ExpoModulesCore/EXJavaScriptValue.h>
|
|
5
5
|
#import <ExpoModulesCore/EXJavaScriptRuntime.h>
|
|
6
|
+
#import <ExpoModulesCore/EXRawJavaScriptFunction.h>
|
|
6
7
|
#import <ExpoModulesCore/EXJavaScriptTypedArray.h>
|
|
7
8
|
#import <ExpoModulesCore/TypedArray.h>
|
|
8
9
|
|
|
@@ -142,6 +143,13 @@
|
|
|
142
143
|
return [[EXJavaScriptObject alloc] initWith:objectPtr runtime:_runtime];
|
|
143
144
|
}
|
|
144
145
|
|
|
146
|
+
- (nonnull EXRawJavaScriptFunction *)getFunction
|
|
147
|
+
{
|
|
148
|
+
jsi::Runtime *runtime = [_runtime get];
|
|
149
|
+
std::shared_ptr<jsi::Function> functionPtr = std::make_shared<jsi::Function>(_value->asObject(*runtime).asFunction(*runtime));
|
|
150
|
+
return [[EXRawJavaScriptFunction alloc] initWith:functionPtr runtime:_runtime];
|
|
151
|
+
}
|
|
152
|
+
|
|
145
153
|
- (nullable EXJavaScriptTypedArray *)getTypedArray
|
|
146
154
|
{
|
|
147
155
|
if (![self isTypedArray]) {
|