expo-modules-core 0.6.4 → 0.8.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 +53 -0
- package/README.md +1 -1
- package/android/ExpoModulesCorePlugin.gradle +15 -0
- package/android/build.gradle +46 -32
- package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +5 -5
- package/android/src/main/java/expo/modules/adapters/react/services/UIManagerModuleWrapper.java +13 -0
- package/android/src/main/java/expo/modules/core/ViewManager.java +9 -0
- package/android/src/main/java/expo/modules/core/interfaces/JavaScriptContextProvider.java +4 -0
- package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +37 -1
- package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +19 -0
- package/android/src/main/java/expo/modules/core/interfaces/services/UIManager.java +2 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +23 -5
- package/android/src/main/java/expo/modules/kotlin/DynamicExtenstions.kt +5 -3
- package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +3 -8
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +24 -9
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +12 -7
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +23 -1
- package/android/src/main/java/expo/modules/kotlin/Promise.kt +1 -1
- package/android/src/main/java/expo/modules/kotlin/callbacks/Callback.kt +5 -0
- package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallback.kt +39 -0
- package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallbackDelegate.kt +27 -0
- package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +25 -0
- package/android/src/main/java/expo/modules/kotlin/events/EventEmitter.kt +13 -0
- package/android/src/main/java/expo/modules/kotlin/events/KModuleEventEmitterWrapper.kt +102 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +93 -9
- package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +11 -0
- package/android/src/main/java/expo/modules/kotlin/{methods/AnyMethod.kt → functions/AnyFunction.kt} +18 -18
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +61 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +36 -0
- package/android/src/main/java/expo/modules/kotlin/modules/DefinitionMarker.kt +4 -0
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +17 -2
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +219 -30
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +2 -2
- package/android/src/main/java/expo/modules/kotlin/records/FieldValidator.kt +139 -0
- package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +71 -15
- package/android/src/main/java/expo/modules/kotlin/records/Required.kt +5 -0
- package/android/src/main/java/expo/modules/kotlin/records/ValidationBinder.kt +110 -0
- package/android/src/main/java/expo/modules/kotlin/records/Validators.kt +61 -0
- package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +11 -5
- package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverter.kt +35 -0
- package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverterHelper.kt +148 -0
- package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +10 -4
- package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +12 -6
- package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +29 -13
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +2 -1
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +9 -1
- package/android/src/main/java/expo/modules/kotlin/views/CallbacksDefinition.kt +3 -0
- package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +71 -0
- package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +22 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinition.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +64 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +30 -2
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +42 -1
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +62 -2
- package/build/EventEmitter.d.ts +1 -0
- package/build/EventEmitter.d.ts.map +1 -0
- package/build/NativeModulesProxy.d.ts +1 -0
- package/build/NativeModulesProxy.d.ts.map +1 -0
- package/build/NativeModulesProxy.native.d.ts +1 -4
- package/build/NativeModulesProxy.native.d.ts.map +1 -0
- package/build/NativeModulesProxy.native.js +1 -14
- package/build/NativeModulesProxy.native.js.map +1 -1
- package/build/NativeModulesProxy.types.d.ts +1 -3
- package/build/NativeModulesProxy.types.d.ts.map +1 -0
- package/build/NativeModulesProxy.types.js.map +1 -1
- package/build/NativeViewManagerAdapter.d.ts +1 -0
- package/build/NativeViewManagerAdapter.d.ts.map +1 -0
- package/build/NativeViewManagerAdapter.native.d.ts +1 -0
- package/build/NativeViewManagerAdapter.native.d.ts.map +1 -0
- package/build/NativeViewManagerAdapter.native.js +9 -33
- package/build/NativeViewManagerAdapter.native.js.map +1 -1
- package/build/PermissionsHook.d.ts +1 -0
- package/build/PermissionsHook.d.ts.map +1 -0
- package/build/PermissionsInterface.d.ts +1 -0
- package/build/PermissionsInterface.d.ts.map +1 -0
- package/build/Platform.d.ts +1 -0
- package/build/Platform.d.ts.map +1 -0
- package/build/SyntheticPlatformEmitter.d.ts +1 -0
- package/build/SyntheticPlatformEmitter.d.ts.map +1 -0
- package/build/SyntheticPlatformEmitter.web.d.ts +1 -0
- package/build/SyntheticPlatformEmitter.web.d.ts.map +1 -0
- package/build/deprecate.d.ts +1 -0
- package/build/deprecate.d.ts.map +1 -0
- package/build/environment/browser.d.ts +1 -0
- package/build/environment/browser.d.ts.map +1 -0
- package/build/environment/browser.web.d.ts +1 -0
- package/build/environment/browser.web.d.ts.map +1 -0
- package/build/errors/CodedError.d.ts +1 -0
- package/build/errors/CodedError.d.ts.map +1 -0
- package/build/errors/UnavailabilityError.d.ts +1 -0
- package/build/errors/UnavailabilityError.d.ts.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +2 -0
- package/build/index.js.map +1 -1
- package/build/requireNativeModule.d.ts +16 -0
- package/build/requireNativeModule.d.ts.map +1 -0
- package/build/requireNativeModule.js +18 -0
- package/build/requireNativeModule.js.map +1 -0
- package/build/sweet/NativeErrorManager.d.ts +3 -0
- package/build/sweet/NativeErrorManager.d.ts.map +1 -0
- package/build/sweet/NativeErrorManager.js +3 -0
- package/build/sweet/NativeErrorManager.js.map +1 -0
- package/build/sweet/setUpErrorManager.fx.d.ts +2 -0
- package/build/sweet/setUpErrorManager.fx.d.ts.map +1 -0
- package/build/sweet/setUpErrorManager.fx.js +11 -0
- package/build/sweet/setUpErrorManager.fx.js.map +1 -0
- package/ios/AppDelegates/EXAppDelegatesLoader.m +4 -8
- package/ios/AppDelegates/ExpoAppDelegate.swift +22 -20
- package/ios/EXAppDefines.h +1 -0
- package/ios/EXAppDefines.m +6 -0
- package/ios/EXUtilities.h +2 -0
- package/ios/EXUtilities.m +12 -0
- package/ios/ExpoModulesCore.h +4 -0
- package/ios/ExpoModulesCore.podspec +4 -2
- package/ios/Interfaces/FileSystem/EXFileSystemInterface.h +1 -1
- package/ios/Interfaces/TaskManager/EXTaskServiceInterface.h +1 -0
- package/ios/JSI/{JSIConversions.h → EXJSIConversions.h} +5 -0
- package/ios/JSI/{JSIConversions.mm → EXJSIConversions.mm} +21 -1
- package/ios/JSI/{JSIInstaller.h → EXJSIInstaller.h} +10 -0
- package/ios/JSI/EXJSIInstaller.mm +17 -0
- package/ios/JSI/EXJSIUtils.h +19 -0
- package/ios/JSI/EXJSIUtils.mm +89 -0
- package/ios/JSI/EXJavaScriptObject.h +97 -0
- package/ios/JSI/EXJavaScriptObject.mm +121 -0
- package/ios/JSI/EXJavaScriptRuntime.h +73 -0
- package/ios/JSI/EXJavaScriptRuntime.mm +153 -0
- package/ios/JSI/EXJavaScriptValue.h +57 -0
- package/ios/JSI/EXJavaScriptValue.mm +166 -0
- package/ios/JSI/ExpoModulesHostObject.h +33 -0
- package/ios/JSI/ExpoModulesHostObject.mm +41 -0
- package/ios/JSI/JavaScriptRuntime.swift +32 -0
- package/ios/JSI/JavaScriptValue.swift +94 -0
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +3 -23
- package/ios/NativeModulesProxy/EXNativeModulesProxy.h +2 -2
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +101 -75
- package/ios/RCTComponentData+Privates.h +12 -0
- package/ios/ReactDelegates/EXReactCompatibleHelpers.h +18 -0
- package/ios/ReactDelegates/EXReactCompatibleHelpers.m +19 -0
- package/ios/ReactDelegates/ExpoReactDelegate.swift +3 -3
- package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +4 -4
- package/ios/ReactDelegates/ModulePriorities.swift +1 -1
- package/ios/Swift/AppContext.swift +64 -4
- package/ios/Swift/Arguments/ArgumentType.swift +4 -0
- package/ios/Swift/Arguments/Convertibles.swift +13 -13
- package/ios/Swift/Arguments/Types/EnumArgumentType.swift +11 -17
- package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +1 -1
- package/ios/Swift/Arguments/Types/RawArgumentType.swift +2 -2
- package/ios/Swift/Conversions.swift +51 -56
- package/ios/Swift/EventListener.swift +8 -10
- package/ios/Swift/Events/Callback.swift +66 -0
- package/ios/Swift/Events/Event.swift +43 -0
- package/ios/Swift/Exceptions/ChainableException.swift +51 -0
- package/ios/Swift/{CodedError.swift → Exceptions/CodedError.swift} +1 -12
- package/ios/Swift/Exceptions/Exception.swift +62 -0
- package/ios/Swift/Exceptions/ExceptionOrigin.swift +28 -0
- package/ios/Swift/Exceptions/GenericException.swift +20 -0
- package/ios/Swift/Exceptions/UnexpectedException.swift +16 -0
- package/ios/Swift/Functions/AnyFunction.swift +11 -1
- package/ios/Swift/Functions/AsyncFunction.swift +17 -0
- package/ios/Swift/Functions/ConcreteFunction.swift +43 -17
- package/ios/Swift/JavaScriptUtils.swift +54 -0
- package/ios/Swift/ModuleHolder.swift +66 -16
- package/ios/Swift/ModuleRegistry.swift +4 -1
- package/ios/Swift/Modules/AnyModule.swift +0 -1
- package/ios/Swift/Modules/ModuleDefinition.swift +4 -13
- package/ios/Swift/Modules/ModuleDefinitionBuilder.swift +0 -1
- package/ios/Swift/Modules/ModuleDefinitionComponents.swift +0 -188
- package/ios/Swift/ModulesProvider.swift +3 -11
- package/ios/Swift/Objects/ObjectDefinition.swift +30 -0
- package/ios/Swift/Objects/ObjectDefinitionComponents.swift +384 -0
- package/ios/Swift/Promise.swift +8 -3
- package/ios/Swift/Records/AnyField.swift +7 -0
- package/ios/Swift/Records/Field.swift +24 -19
- package/ios/Swift/Records/FieldOption.swift +1 -1
- package/ios/Swift/Records/Record.swift +12 -4
- package/ios/Swift/SwiftInteropBridge.swift +53 -15
- package/ios/Swift/Views/AnyViewProp.swift +1 -1
- package/ios/Swift/Views/ComponentData.swift +96 -0
- package/ios/Swift/Views/ConcreteViewProp.swift +6 -8
- package/ios/Swift/Views/ExpoView.swift +8 -0
- package/ios/Swift/Views/ViewFactory.swift +1 -1
- package/ios/Swift/Views/ViewManagerDefinition.swift +23 -2
- package/ios/Swift/Views/ViewManagerDefinitionBuilder.swift +0 -1
- package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +26 -0
- package/ios/Swift/Views/ViewModuleWrapper.swift +5 -2
- package/ios/Swift.h +5 -0
- package/ios/Tests/ArgumentTypeSpec.swift +5 -7
- package/ios/Tests/ConstantsSpec.swift +6 -7
- package/ios/Tests/ConvertiblesSpec.swift +35 -36
- package/ios/Tests/ExceptionsSpec.swift +111 -0
- package/ios/Tests/ExpoModulesSpec.swift +76 -0
- package/ios/Tests/FunctionSpec.swift +22 -25
- package/ios/Tests/FunctionWithConvertiblesSpec.swift +4 -5
- package/ios/Tests/JavaScriptObjectSpec.swift +97 -0
- package/ios/Tests/JavaScriptRuntimeSpec.swift +94 -0
- package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
- package/ios/Tests/Mocks/ModulesProviderMock.swift +0 -1
- package/ios/Tests/ModuleEventListenersSpec.swift +3 -4
- package/ios/Tests/ModuleRegistrySpec.swift +2 -3
- package/ios/Tests/RecordSpec.swift +9 -20
- package/package.json +3 -3
- package/src/NativeModulesProxy.native.ts +2 -22
- package/src/NativeModulesProxy.types.ts +0 -8
- package/src/NativeViewManagerAdapter.native.tsx +12 -28
- package/src/index.ts +4 -0
- package/src/requireNativeModule.ts +29 -0
- package/src/sweet/NativeErrorManager.ts +2 -0
- package/src/sweet/setUpErrorManager.fx.ts +12 -0
- package/android/src/main/java/expo/modules/kotlin/events/KEventEmitterWrapper.kt +0 -26
- package/android/src/main/java/expo/modules/kotlin/methods/Method.kt +0 -14
- package/android/src/main/java/expo/modules/kotlin/methods/PromiseMethod.kt +0 -15
- package/ios/JSI/ExpoModulesProxySpec.h +0 -24
- package/ios/JSI/ExpoModulesProxySpec.mm +0 -135
- package/ios/JSI/JSIInstaller.mm +0 -22
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Dispatch
|
|
2
2
|
|
|
3
|
-
public
|
|
4
|
-
public typealias ClosureType = (Args) -> ReturnType
|
|
3
|
+
public class ConcreteFunction<Args, ReturnType>: AnyFunction {
|
|
4
|
+
public typealias ClosureType = (Args) throws -> ReturnType
|
|
5
5
|
|
|
6
6
|
public let name: String
|
|
7
7
|
|
|
@@ -15,6 +15,8 @@ public final class ConcreteFunction<Args, ReturnType>: AnyFunction {
|
|
|
15
15
|
|
|
16
16
|
public var queue: DispatchQueue?
|
|
17
17
|
|
|
18
|
+
public var isAsync: Bool = true
|
|
19
|
+
|
|
18
20
|
let closure: ClosureType
|
|
19
21
|
|
|
20
22
|
let argTypes: [AnyArgumentType]
|
|
@@ -27,6 +29,11 @@ public final class ConcreteFunction<Args, ReturnType>: AnyFunction {
|
|
|
27
29
|
self.name = name
|
|
28
30
|
self.argTypes = argTypes
|
|
29
31
|
self.closure = closure
|
|
32
|
+
|
|
33
|
+
// This is temporary solution to keep backwards compatibility for existing functions — they all end with "Async".
|
|
34
|
+
// `function` component that we've used so far was async by default, but we decided to replace it with `asyncFunction`
|
|
35
|
+
// and make `function`s synchronous. Introduced in SDK45, can be removed in SDK46 after migrating all modules.
|
|
36
|
+
self.isAsync = name.hasSuffix("Async")
|
|
30
37
|
}
|
|
31
38
|
|
|
32
39
|
public func call(args: [Any], promise: Promise) {
|
|
@@ -41,12 +48,12 @@ public final class ConcreteFunction<Args, ReturnType>: AnyFunction {
|
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
let tuple = try Conversions.toTuple(finalArgs) as! Args
|
|
44
|
-
returnedValue = closure(tuple)
|
|
51
|
+
returnedValue = try closure(tuple)
|
|
45
52
|
} catch let error as CodedError {
|
|
46
|
-
promise.reject(error)
|
|
53
|
+
promise.reject(FunctionCallException(name).causedBy(error))
|
|
47
54
|
return
|
|
48
|
-
} catch
|
|
49
|
-
promise.reject(
|
|
55
|
+
} catch {
|
|
56
|
+
promise.reject(UnexpectedException(error))
|
|
50
57
|
return
|
|
51
58
|
}
|
|
52
59
|
if !takesPromise {
|
|
@@ -62,7 +69,7 @@ public final class ConcreteFunction<Args, ReturnType>: AnyFunction {
|
|
|
62
69
|
let promise = Promise {
|
|
63
70
|
result = $0
|
|
64
71
|
semaphore.signal()
|
|
65
|
-
} rejecter: {
|
|
72
|
+
} rejecter: { _ in
|
|
66
73
|
semaphore.signal()
|
|
67
74
|
}
|
|
68
75
|
call(args: args, promise: promise)
|
|
@@ -72,7 +79,7 @@ public final class ConcreteFunction<Args, ReturnType>: AnyFunction {
|
|
|
72
79
|
do {
|
|
73
80
|
let finalArgs = try castArguments(args)
|
|
74
81
|
let tuple = try Conversions.toTuple(finalArgs) as! Args
|
|
75
|
-
return closure(tuple)
|
|
82
|
+
return try closure(tuple)
|
|
76
83
|
} catch let error {
|
|
77
84
|
return error
|
|
78
85
|
}
|
|
@@ -84,27 +91,46 @@ public final class ConcreteFunction<Args, ReturnType>: AnyFunction {
|
|
|
84
91
|
return self
|
|
85
92
|
}
|
|
86
93
|
|
|
94
|
+
public func runSynchronously() -> Self {
|
|
95
|
+
self.isAsync = false
|
|
96
|
+
return self
|
|
97
|
+
}
|
|
98
|
+
|
|
87
99
|
private func argumentType(atIndex index: Int) -> AnyArgumentType? {
|
|
88
100
|
return (0..<argTypes.count).contains(index) ? argTypes[index] : nil
|
|
89
101
|
}
|
|
90
102
|
|
|
91
103
|
private func castArguments(_ args: [Any]) throws -> [Any] {
|
|
92
104
|
if args.count != argumentsCount {
|
|
93
|
-
throw
|
|
105
|
+
throw InvalidArgsNumberException((received: args.count, expected: argumentsCount))
|
|
94
106
|
}
|
|
95
|
-
return try args.enumerated().map {
|
|
107
|
+
return try args.enumerated().map { index, arg in
|
|
96
108
|
let expectedType = argumentType(atIndex: index)
|
|
97
109
|
|
|
98
|
-
|
|
99
|
-
|
|
110
|
+
do {
|
|
111
|
+
// It's safe to unwrap since the arguments count matches.
|
|
112
|
+
return try expectedType!.cast(arg)
|
|
113
|
+
} catch {
|
|
114
|
+
throw ArgumentCastException((index: index, type: expectedType!)).causedBy(error)
|
|
115
|
+
}
|
|
100
116
|
}
|
|
101
117
|
}
|
|
102
118
|
}
|
|
103
119
|
|
|
104
|
-
internal
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
120
|
+
internal class InvalidArgsNumberException: GenericException<(received: Int, expected: Int)> {
|
|
121
|
+
override var reason: String {
|
|
122
|
+
"Received \(param.received) arguments, but \(param.expected) was expected"
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
internal class ArgumentCastException: GenericException<(index: Int, type: AnyArgumentType)> {
|
|
127
|
+
override var reason: String {
|
|
128
|
+
"Argument at index '\(param.index)' couldn't be cast to type \(param.type.description)"
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
internal class FunctionCallException: GenericException<String> {
|
|
133
|
+
override var reason: String {
|
|
134
|
+
"Call to function '\(param)' has been rejected"
|
|
109
135
|
}
|
|
110
136
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
// FIXME: Calling module's functions needs solid refactoring to not reference the module holder.
|
|
4
|
+
// Instead, it should be possible to directly call the function instance from here. (added by @tsapeta)
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
Creates a block that is executed when the module's async function is called.
|
|
8
|
+
*/
|
|
9
|
+
internal func createAsyncFunctionBlock(holder: ModuleHolder, name functionName: String) -> JSAsyncFunctionBlock {
|
|
10
|
+
let moduleName = holder.name
|
|
11
|
+
return { [weak holder, moduleName] args, resolve, reject in
|
|
12
|
+
guard let holder = holder else {
|
|
13
|
+
let exception = ModuleUnavailableException(moduleName)
|
|
14
|
+
reject(exception.code, exception.description, exception)
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
holder.call(function: functionName, args: args) { result, error in
|
|
18
|
+
if let error = error {
|
|
19
|
+
reject(error.code, error.description, error)
|
|
20
|
+
} else {
|
|
21
|
+
resolve(result)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
Creates a block that is executed when the module's sync function is called.
|
|
29
|
+
*/
|
|
30
|
+
internal func createSyncFunctionBlock(holder: ModuleHolder, name functionName: String) -> JSSyncFunctionBlock {
|
|
31
|
+
return { [weak holder] args in
|
|
32
|
+
guard let holder = holder else {
|
|
33
|
+
return nil
|
|
34
|
+
}
|
|
35
|
+
return holder.callSync(function: functionName, args: args)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
If given argument is a JavaScriptValue, it's unpacked and converted to corresponding Foundation type.
|
|
41
|
+
Otherwise, the argument is returned as is.
|
|
42
|
+
*/
|
|
43
|
+
internal func unpackIfJavaScriptValue(_ value: Any) -> Any {
|
|
44
|
+
if let value = value as? JavaScriptValue {
|
|
45
|
+
return value.getRaw() as Any
|
|
46
|
+
}
|
|
47
|
+
return value
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private class ModuleUnavailableException: GenericException<String> {
|
|
51
|
+
override var reason: String {
|
|
52
|
+
"Module '\(param)' is no longer available"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -14,6 +14,11 @@ public final class ModuleHolder {
|
|
|
14
14
|
*/
|
|
15
15
|
private(set) weak var appContext: AppContext?
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
JavaScript object that represents the module instance in the runtime.
|
|
19
|
+
*/
|
|
20
|
+
public internal(set) lazy var javaScriptObject: JavaScriptObject? = createJavaScriptModuleObject()
|
|
21
|
+
|
|
17
22
|
/**
|
|
18
23
|
Caches the definition of the module type.
|
|
19
24
|
*/
|
|
@@ -26,6 +31,13 @@ public final class ModuleHolder {
|
|
|
26
31
|
return definition.name.isEmpty ? String(describing: type(of: module)) : definition.name
|
|
27
32
|
}
|
|
28
33
|
|
|
34
|
+
/**
|
|
35
|
+
Shortcut to get the underlying view manager definition.
|
|
36
|
+
*/
|
|
37
|
+
var viewManager: ViewManagerDefinition? {
|
|
38
|
+
return definition.viewManager
|
|
39
|
+
}
|
|
40
|
+
|
|
29
41
|
/**
|
|
30
42
|
Number of JavaScript listeners attached to the module.
|
|
31
43
|
*/
|
|
@@ -54,17 +66,25 @@ public final class ModuleHolder {
|
|
|
54
66
|
func call(function functionName: String, args: [Any], promise: Promise) {
|
|
55
67
|
do {
|
|
56
68
|
guard let function = definition.functions[functionName] else {
|
|
57
|
-
throw
|
|
69
|
+
throw FunctionNotFoundException((functionName: functionName, moduleName: self.name))
|
|
58
70
|
}
|
|
59
71
|
let queue = function.queue ?? DispatchQueue.global(qos: .default)
|
|
60
72
|
|
|
73
|
+
// Given arguments can be:
|
|
74
|
+
// - Swift primitives when invoked through the bridge and in unit tests
|
|
75
|
+
// - `JavaScriptValue`s when the function is called through the JSI
|
|
76
|
+
// The latter need to be unpacked to Swift primitives on the JS thread,
|
|
77
|
+
// so before the function call is scheduled on the queue.
|
|
78
|
+
// TODO: Move arguments conversion mechanism to JS thread and allow JS types as function arguments.
|
|
79
|
+
let unpackedArgs = args.map { arg in unpackIfJavaScriptValue(arg) }
|
|
80
|
+
|
|
61
81
|
queue.async {
|
|
62
|
-
function.call(args:
|
|
82
|
+
function.call(args: unpackedArgs, promise: promise)
|
|
63
83
|
}
|
|
64
84
|
} catch let error as CodedError {
|
|
65
85
|
promise.reject(error)
|
|
66
86
|
} catch {
|
|
67
|
-
promise.reject(
|
|
87
|
+
promise.reject(UnexpectedException(error))
|
|
68
88
|
}
|
|
69
89
|
}
|
|
70
90
|
|
|
@@ -80,11 +100,44 @@ public final class ModuleHolder {
|
|
|
80
100
|
@discardableResult
|
|
81
101
|
func callSync(function functionName: String, args: [Any]) -> Any? {
|
|
82
102
|
if let function = definition.functions[functionName] {
|
|
83
|
-
|
|
103
|
+
// The comment in `call(function:args:promise)` is partially applicable here as well.
|
|
104
|
+
// TODO: Move unpacking JS values to `callSync` in function's instance
|
|
105
|
+
let unpackedArgs = args.map { arg in unpackIfJavaScriptValue(arg) }
|
|
106
|
+
return function.callSync(args: unpackedArgs)
|
|
84
107
|
}
|
|
85
108
|
return nil
|
|
86
109
|
}
|
|
87
110
|
|
|
111
|
+
// MARK: JavaScript Module Object
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
Creates the JavaScript object that will be used to communicate with the native module.
|
|
115
|
+
The object is prefilled with module's constants and functions.
|
|
116
|
+
JavaScript can access it through `global.ExpoModules[moduleName]`.
|
|
117
|
+
- Note: The object will be `nil` when the runtime is unavailable (e.g. remote debugger is enabled).
|
|
118
|
+
*/
|
|
119
|
+
private func createJavaScriptModuleObject() -> JavaScriptObject? {
|
|
120
|
+
// It might be impossible to create any object at the moment (e.g. remote debugging, app context destroyed)
|
|
121
|
+
guard let object = appContext?.runtime?.createObject() else {
|
|
122
|
+
return nil
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Fill in with constants
|
|
126
|
+
for (key, value) in getConstants() {
|
|
127
|
+
object.setProperty(key, value: value)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Fill in with functions
|
|
131
|
+
for (_, fn) in definition.functions {
|
|
132
|
+
if fn.isAsync {
|
|
133
|
+
object.setAsyncFunction(fn.name, argsCount: fn.argumentsCount, block: createAsyncFunctionBlock(holder: self, name: fn.name))
|
|
134
|
+
} else {
|
|
135
|
+
object.setSyncFunction(fn.name, argsCount: fn.argumentsCount, block: createSyncFunctionBlock(holder: self, name: fn.name))
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return object
|
|
139
|
+
}
|
|
140
|
+
|
|
88
141
|
// MARK: Listening to native events
|
|
89
142
|
|
|
90
143
|
func listeners(forEvent event: EventName) -> [EventListener] {
|
|
@@ -112,9 +165,9 @@ public final class ModuleHolder {
|
|
|
112
165
|
*/
|
|
113
166
|
func modifyListenersCount(_ count: Int) {
|
|
114
167
|
if count > 0 && listenersCount == 0 {
|
|
115
|
-
|
|
168
|
+
_ = definition.functions["startObserving"]?.callSync(args: [])
|
|
116
169
|
} else if count < 0 && listenersCount + count <= 0 {
|
|
117
|
-
|
|
170
|
+
_ = definition.functions["stopObserving"]?.callSync(args: [])
|
|
118
171
|
}
|
|
119
172
|
listenersCount = max(0, listenersCount + count)
|
|
120
173
|
}
|
|
@@ -125,20 +178,17 @@ public final class ModuleHolder {
|
|
|
125
178
|
post(event: .moduleDestroy)
|
|
126
179
|
}
|
|
127
180
|
|
|
128
|
-
// MARK:
|
|
181
|
+
// MARK: - Exceptions
|
|
129
182
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
"Cannot find module `\(moduleName)`"
|
|
183
|
+
internal class ModuleNotFoundException: GenericException<String> {
|
|
184
|
+
override var reason: String {
|
|
185
|
+
"Module '\(param)' not found"
|
|
134
186
|
}
|
|
135
187
|
}
|
|
136
188
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
var description: String {
|
|
141
|
-
"Cannot find function `\(functionName)` in module `\(moduleName)`"
|
|
189
|
+
internal class FunctionNotFoundException: GenericException<(functionName: String, moduleName: String)> {
|
|
190
|
+
override var reason: String {
|
|
191
|
+
"Function '\(param.functionName)' not found in module '\(param.moduleName)'"
|
|
142
192
|
}
|
|
143
193
|
}
|
|
144
194
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
public final class ModuleRegistry: Sequence {
|
|
3
2
|
public typealias Element = ModuleHolder
|
|
4
3
|
|
|
@@ -63,6 +62,10 @@ public final class ModuleRegistry: Sequence {
|
|
|
63
62
|
return registry[moduleName]?.module
|
|
64
63
|
}
|
|
65
64
|
|
|
65
|
+
public func getModuleNames() -> [String] {
|
|
66
|
+
return Array(registry.keys)
|
|
67
|
+
}
|
|
68
|
+
|
|
66
69
|
public func makeIterator() -> IndexingIterator<[ModuleHolder]> {
|
|
67
70
|
return registry.map({ $1 }).makeIterator()
|
|
68
71
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
/**
|
|
3
2
|
A protocol that must be implemented to be a part of module's definition and the module definition itself.
|
|
4
3
|
*/
|
|
@@ -9,7 +8,7 @@ public protocol AnyDefinition {}
|
|
|
9
8
|
of the module and what it exports to the JavaScript world.
|
|
10
9
|
See `ModuleDefinitionBuilder` for more details on how to create it.
|
|
11
10
|
*/
|
|
12
|
-
public final class ModuleDefinition:
|
|
11
|
+
public final class ModuleDefinition: ObjectDefinition {
|
|
13
12
|
/**
|
|
14
13
|
The module's type associated with the definition. It's used to create the module instance.
|
|
15
14
|
*/
|
|
@@ -20,8 +19,6 @@ public final class ModuleDefinition: AnyDefinition {
|
|
|
20
19
|
*/
|
|
21
20
|
var name: String
|
|
22
21
|
|
|
23
|
-
let functions: [String : AnyFunction]
|
|
24
|
-
let constants: [ConstantsDefinition]
|
|
25
22
|
let eventListeners: [EventListener]
|
|
26
23
|
let viewManager: ViewManagerDefinition?
|
|
27
24
|
|
|
@@ -33,20 +30,12 @@ public final class ModuleDefinition: AnyDefinition {
|
|
|
33
30
|
/**
|
|
34
31
|
Initializer that is called by the `ModuleDefinitionBuilder` results builder.
|
|
35
32
|
*/
|
|
36
|
-
init(definitions: [AnyDefinition]) {
|
|
33
|
+
override init(definitions: [AnyDefinition]) {
|
|
37
34
|
self.name = definitions
|
|
38
35
|
.compactMap { $0 as? ModuleNameDefinition }
|
|
39
36
|
.last?
|
|
40
37
|
.name ?? ""
|
|
41
38
|
|
|
42
|
-
self.functions = definitions
|
|
43
|
-
.compactMap { $0 as? AnyFunction }
|
|
44
|
-
.reduce(into: [String : AnyFunction]()) { dict, function in
|
|
45
|
-
dict[function.name] = function
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
self.constants = definitions.compactMap { $0 as? ConstantsDefinition }
|
|
49
|
-
|
|
50
39
|
self.eventListeners = definitions.compactMap { $0 as? EventListener }
|
|
51
40
|
|
|
52
41
|
self.viewManager = definitions
|
|
@@ -58,6 +47,8 @@ public final class ModuleDefinition: AnyDefinition {
|
|
|
58
47
|
.compactMap { ($0 as? EventsDefinition)?.names }
|
|
59
48
|
.joined()
|
|
60
49
|
)
|
|
50
|
+
|
|
51
|
+
super.init(definitions: definitions)
|
|
61
52
|
}
|
|
62
53
|
|
|
63
54
|
/**
|
|
@@ -16,150 +16,6 @@ extension AnyModule {
|
|
|
16
16
|
return ModuleNameDefinition(name: name)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
// MARK: - Constants
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
Definition function setting the module's constants to export.
|
|
23
|
-
*/
|
|
24
|
-
public func constants(_ body: @escaping () -> [String: Any?]) -> AnyDefinition {
|
|
25
|
-
return ConstantsDefinition(body: body)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
Definition function setting the module's constants to export.
|
|
30
|
-
*/
|
|
31
|
-
public func constants(_ body: @autoclosure @escaping () -> [String: Any?]) -> AnyDefinition {
|
|
32
|
-
return ConstantsDefinition(body: body)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// MARK: - Functions
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
Function without arguments.
|
|
39
|
-
*/
|
|
40
|
-
public func function<R>(
|
|
41
|
-
_ name: String,
|
|
42
|
-
_ closure: @escaping () -> R
|
|
43
|
-
) -> AnyFunction {
|
|
44
|
-
return ConcreteFunction(
|
|
45
|
-
name,
|
|
46
|
-
argTypes: [],
|
|
47
|
-
closure
|
|
48
|
-
)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
Function with one argument.
|
|
53
|
-
*/
|
|
54
|
-
public func function<R, A0: AnyArgument>(
|
|
55
|
-
_ name: String,
|
|
56
|
-
_ closure: @escaping (A0) -> R
|
|
57
|
-
) -> AnyFunction {
|
|
58
|
-
return ConcreteFunction(
|
|
59
|
-
name,
|
|
60
|
-
argTypes: [ArgumentType(A0.self)],
|
|
61
|
-
closure
|
|
62
|
-
)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
Function with two arguments.
|
|
67
|
-
*/
|
|
68
|
-
public func function<R, A0: AnyArgument, A1: AnyArgument>(
|
|
69
|
-
_ name: String,
|
|
70
|
-
_ closure: @escaping (A0, A1) -> R
|
|
71
|
-
) -> AnyFunction {
|
|
72
|
-
return ConcreteFunction(
|
|
73
|
-
name,
|
|
74
|
-
argTypes: [ArgumentType(A0.self), ArgumentType(A1.self)],
|
|
75
|
-
closure
|
|
76
|
-
)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
Function with three arguments.
|
|
81
|
-
*/
|
|
82
|
-
public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument>(
|
|
83
|
-
_ name: String,
|
|
84
|
-
_ closure: @escaping (A0, A1, A2) -> R
|
|
85
|
-
) -> AnyFunction {
|
|
86
|
-
return ConcreteFunction(
|
|
87
|
-
name,
|
|
88
|
-
argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self)],
|
|
89
|
-
closure
|
|
90
|
-
)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
Function with four arguments.
|
|
95
|
-
*/
|
|
96
|
-
public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument>(
|
|
97
|
-
_ name: String,
|
|
98
|
-
_ closure: @escaping (A0, A1, A2, A3) -> R
|
|
99
|
-
) -> AnyFunction {
|
|
100
|
-
return ConcreteFunction(
|
|
101
|
-
name,
|
|
102
|
-
argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self)],
|
|
103
|
-
closure
|
|
104
|
-
)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
Function with five arguments.
|
|
109
|
-
*/
|
|
110
|
-
public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument>(
|
|
111
|
-
_ name: String,
|
|
112
|
-
_ closure: @escaping (A0, A1, A2, A3, A4) -> R
|
|
113
|
-
) -> AnyFunction {
|
|
114
|
-
return ConcreteFunction(
|
|
115
|
-
name,
|
|
116
|
-
argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self), ArgumentType(A4.self)],
|
|
117
|
-
closure
|
|
118
|
-
)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
Function with six arguments.
|
|
123
|
-
*/
|
|
124
|
-
public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument>(
|
|
125
|
-
_ name: String,
|
|
126
|
-
_ closure: @escaping (A0, A1, A2, A3, A4, A5) -> R
|
|
127
|
-
) -> AnyFunction {
|
|
128
|
-
return ConcreteFunction(
|
|
129
|
-
name,
|
|
130
|
-
argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self), ArgumentType(A4.self), ArgumentType(A5.self)],
|
|
131
|
-
closure
|
|
132
|
-
)
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
Function with seven arguments.
|
|
137
|
-
*/
|
|
138
|
-
public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument>(
|
|
139
|
-
_ name: String,
|
|
140
|
-
_ closure: @escaping (A0, A1, A2, A3, A4, A5, A6) -> R
|
|
141
|
-
) -> AnyFunction {
|
|
142
|
-
return ConcreteFunction(
|
|
143
|
-
name,
|
|
144
|
-
argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self), ArgumentType(A4.self), ArgumentType(A5.self), ArgumentType(A6.self)],
|
|
145
|
-
closure
|
|
146
|
-
)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
Function with eight arguments.
|
|
151
|
-
*/
|
|
152
|
-
public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument, A7: AnyArgument>(
|
|
153
|
-
_ name: String,
|
|
154
|
-
_ closure: @escaping (A0, A1, A2, A3, A4, A5, A6, A7) -> R
|
|
155
|
-
) -> AnyFunction {
|
|
156
|
-
return ConcreteFunction(
|
|
157
|
-
name,
|
|
158
|
-
argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self), ArgumentType(A4.self), ArgumentType(A5.self), ArgumentType(A6.self), ArgumentType(A7.self)],
|
|
159
|
-
closure
|
|
160
|
-
)
|
|
161
|
-
}
|
|
162
|
-
|
|
163
19
|
// MARK: - Module's lifecycle
|
|
164
20
|
|
|
165
21
|
/**
|
|
@@ -212,50 +68,6 @@ extension AnyModule {
|
|
|
212
68
|
public func viewManager(@ViewManagerDefinitionBuilder _ closure: @escaping () -> ViewManagerDefinition) -> AnyDefinition {
|
|
213
69
|
return closure()
|
|
214
70
|
}
|
|
215
|
-
|
|
216
|
-
// MARK: - Events
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
Defines event names that this module can send to JavaScript.
|
|
220
|
-
*/
|
|
221
|
-
public func events(_ names: String...) -> AnyDefinition {
|
|
222
|
-
return EventsDefinition(names: names)
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
Function that is invoked when the first event listener is added.
|
|
227
|
-
*/
|
|
228
|
-
public func onStartObserving(_ body: @escaping () -> ()) -> AnyFunction {
|
|
229
|
-
return ConcreteFunction("startObserving", argTypes: [], body)
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
Function that is invoked when all event listeners are removed.
|
|
234
|
-
*/
|
|
235
|
-
public func onStopObserving(_ body: @escaping () -> ()) -> AnyFunction {
|
|
236
|
-
return ConcreteFunction("stopObserving", argTypes: [], body)
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
Defines the factory creating a native view when the module is used as a view.
|
|
242
|
-
*/
|
|
243
|
-
public func view(_ closure: @escaping () -> UIView) -> AnyDefinition {
|
|
244
|
-
return ViewFactory(closure)
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
Creates a view prop that defines its name and setter.
|
|
249
|
-
*/
|
|
250
|
-
public func prop<ViewType: UIView, PropType: AnyArgument>(
|
|
251
|
-
_ name: String,
|
|
252
|
-
_ setter: @escaping (ViewType, PropType) -> Void
|
|
253
|
-
) -> AnyDefinition {
|
|
254
|
-
return ConcreteViewProp(
|
|
255
|
-
name: name,
|
|
256
|
-
propType: ArgumentType(PropType.self),
|
|
257
|
-
setter: setter
|
|
258
|
-
)
|
|
259
71
|
}
|
|
260
72
|
|
|
261
73
|
// TODO: - Remove deprecated `method` component once SDK44 is out.
|
|
@@ -1,17 +1,9 @@
|
|
|
1
|
-
|
|
2
1
|
import Foundation
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
|
-
|
|
6
|
-
In Objective-C code we do not do anything with it except passing it back to the Swift light side.
|
|
7
|
-
*/
|
|
8
|
-
@objc
|
|
9
|
-
public protocol ModulesProviderObjCProtocol {}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
Swift protocol defining the requirements for modules providers. Extends its Objective-C counterpart `ModulesProviderObjCProtocol`.
|
|
4
|
+
Swift protocol defining the requirements for modules providers.
|
|
13
5
|
*/
|
|
14
|
-
public protocol ModulesProviderProtocol
|
|
6
|
+
public protocol ModulesProviderProtocol {
|
|
15
7
|
func getModuleClasses() -> [AnyModule.Type]
|
|
16
8
|
|
|
17
9
|
/**
|
|
@@ -31,7 +23,7 @@ public protocol ModulesProviderProtocol: ModulesProviderObjCProtocol {
|
|
|
31
23
|
The proper implementation is generated by autolinking as part of `pod install` command.
|
|
32
24
|
*/
|
|
33
25
|
@objc
|
|
34
|
-
open class ModulesProvider: NSObject, ModulesProviderProtocol
|
|
26
|
+
open class ModulesProvider: NSObject, ModulesProviderProtocol {
|
|
35
27
|
open func getModuleClasses() -> [AnyModule.Type] {
|
|
36
28
|
return []
|
|
37
29
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright 2021-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Base class for other definitions representing an object, such as `ModuleDefinition`.
|
|
5
|
+
*/
|
|
6
|
+
public class ObjectDefinition: AnyDefinition {
|
|
7
|
+
/**
|
|
8
|
+
A dictionary of functions defined by the object.
|
|
9
|
+
*/
|
|
10
|
+
let functions: [String: AnyFunction]
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
An array of constants definitions.
|
|
14
|
+
*/
|
|
15
|
+
let constants: [ConstantsDefinition]
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
Default initializer receiving children definitions from the result builder.
|
|
19
|
+
*/
|
|
20
|
+
init(definitions: [AnyDefinition]) {
|
|
21
|
+
self.functions = definitions
|
|
22
|
+
.compactMap { $0 as? AnyFunction }
|
|
23
|
+
.reduce(into: [String: AnyFunction]()) { dict, function in
|
|
24
|
+
dict[function.name] = function
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
self.constants = definitions
|
|
28
|
+
.compactMap { $0 as? ConstantsDefinition }
|
|
29
|
+
}
|
|
30
|
+
}
|