@expo/expo-modules-macros-plugin 0.6.0 → 0.6.2
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/apple/ExpoModulesMacros-tool +0 -0
- package/apple/Sources/ExpoModulesMacros/DecorateModuleBuilder.swift +14 -15
- package/apple/Sources/ExpoModulesMacros/JSConstructor.swift +3 -5
- package/apple/Sources/ExpoModulesMacros/MacroHelpers.swift +7 -13
- package/apple/Sources/ExpoModulesMacros/Receiver.swift +9 -4
- package/package.json +1 -1
|
Binary file
|
|
@@ -60,7 +60,7 @@ internal struct JSFunction {
|
|
|
60
60
|
let maximum = parameters.count
|
|
61
61
|
var lines: [String] = []
|
|
62
62
|
|
|
63
|
-
if let unwrap = receiver.unwrapStatement {
|
|
63
|
+
if let unwrap = receiver.unwrapStatement(isAsync: isAsync) {
|
|
64
64
|
lines.append(unwrap)
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -90,23 +90,21 @@ internal struct JSFunction {
|
|
|
90
90
|
// No omittable trailing run: a single flat call with every argument decoded.
|
|
91
91
|
lines.append(contentsOf: callAndEncodeLines(receiver: receiver, arity: maximum, decodingFrom: required))
|
|
92
92
|
} else {
|
|
93
|
-
// One call shape per accepted arity.
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if returnType != nil {
|
|
99
|
-
lines.append("let result = switch arguments.count {")
|
|
100
|
-
} else {
|
|
101
|
-
lines.append("switch arguments.count {")
|
|
93
|
+
// One call shape per accepted arity, branching on `arguments.count`. A branch decodes a
|
|
94
|
+
// trailing slot before the call, so this is a `switch` statement (not an expression): a
|
|
95
|
+
// value-returning function declares `result` up front and each branch assigns it.
|
|
96
|
+
if let returnType {
|
|
97
|
+
lines.append("let result: \(expressionType(returnType))")
|
|
102
98
|
}
|
|
99
|
+
lines.append("switch arguments.count {")
|
|
103
100
|
for arity in required...maximum {
|
|
104
101
|
let label = arity == maximum ? "default:" : "case \(arity):"
|
|
105
102
|
lines.append(label)
|
|
106
103
|
for index in required..<arity {
|
|
107
104
|
lines.append(" " + decodeStatement(at: index))
|
|
108
105
|
}
|
|
109
|
-
|
|
106
|
+
let assignment = returnType != nil ? "result = " : ""
|
|
107
|
+
lines.append(" \(assignment)\(callExpression(receiver: receiver, arity: arity))")
|
|
110
108
|
}
|
|
111
109
|
lines.append("}")
|
|
112
110
|
lines.append(contentsOf: encodeResultLines())
|
|
@@ -255,8 +253,9 @@ internal struct JSProperty {
|
|
|
255
253
|
let callee = receiver.callee
|
|
256
254
|
let object = receiver.decoratedObject
|
|
257
255
|
// A shared object's accessors unwrap the JS `this` into `_self` before reading/writing; a module
|
|
258
|
-
// reads `self` directly. The unwrap leads each accessor body.
|
|
259
|
-
|
|
256
|
+
// reads `self` directly. The unwrap leads each accessor body. Property accessors are synchronous, so
|
|
257
|
+
// they take the borrowed unowned `this`.
|
|
258
|
+
let unwrap = receiver.unwrapStatement(isAsync: false).map { "\($0)\n" } ?? ""
|
|
260
259
|
var lines: [String] = []
|
|
261
260
|
|
|
262
261
|
lines.append("let \(descriptorName) = runtime.createObject()")
|
|
@@ -340,7 +339,7 @@ internal func buildDecorateJavaScriptObject(functions: [JSFunction], properties:
|
|
|
340
339
|
let body = decorateBody(functions: functions, properties: properties, receiver: .module)
|
|
341
340
|
return """
|
|
342
341
|
@JavaScriptActor
|
|
343
|
-
public func _decorateModule(object: borrowing JavaScriptObject, in runtime: JavaScriptRuntime
|
|
342
|
+
public func _decorateModule(object: borrowing JavaScriptObject, in runtime: JavaScriptRuntime) throws {
|
|
344
343
|
\(raw: body)
|
|
345
344
|
}
|
|
346
345
|
"""
|
|
@@ -361,7 +360,7 @@ internal func buildDecorateSharedObject(
|
|
|
361
360
|
let body = decorateBody(functions: functions, properties: properties, receiver: .sharedObject(typeName: typeName))
|
|
362
361
|
return """
|
|
363
362
|
@JavaScriptActor
|
|
364
|
-
public override class func _decorateSharedObject(prototype: borrowing JavaScriptObject, in runtime: JavaScriptRuntime
|
|
363
|
+
public override class func _decorateSharedObject(prototype: borrowing JavaScriptObject, in runtime: JavaScriptRuntime) throws {
|
|
365
364
|
\(raw: body)
|
|
366
365
|
}
|
|
367
366
|
"""
|
|
@@ -42,14 +42,12 @@ internal struct JSConstructor {
|
|
|
42
42
|
.joined(separator: "\n")
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
///
|
|
46
|
-
///
|
|
47
|
-
/// concrete type's metatype; the body returns the concrete instance, which promotes to the base
|
|
48
|
-
/// `SharedObject?` return type. `this`/`appContext` may go unreferenced, which is harmless.
|
|
45
|
+
/// Builds an instance from the JS arguments. Overrides the base `SharedObject` class method; returns
|
|
46
|
+
/// the concrete instance, which promotes to the base `SharedObject?` return type.
|
|
49
47
|
func buildConstructor(typeName: String) -> DeclSyntax {
|
|
50
48
|
return """
|
|
51
49
|
@JavaScriptActor
|
|
52
|
-
public override class func _constructSharedObject(this: JavaScriptValue, arguments: borrowing JavaScriptValuesBuffer, in runtime: JavaScriptRuntime
|
|
50
|
+
public override class func _constructSharedObject(this: JavaScriptValue, arguments: borrowing JavaScriptValuesBuffer, in runtime: JavaScriptRuntime) throws -> SharedObject? {
|
|
53
51
|
\(raw: bodyStatements(typeName: typeName, indent: " "))
|
|
54
52
|
}
|
|
55
53
|
"""
|
|
@@ -145,14 +145,13 @@ internal func memberHasJSAttribute(_ decl: DeclSyntaxProtocol) -> Bool {
|
|
|
145
145
|
return false
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
*/
|
|
148
|
+
/// Decides whether the macro should stamp `@JavaScriptActor` on a `@JS`-marked member.
|
|
149
|
+
/// The macro defers to the user when they've already chosen an isolation:
|
|
150
|
+
/// - the `nonisolated` modifier is present on the member
|
|
151
|
+
/// - any attribute whose name matches a known global actor (`@MainActor`, `@JavaScriptActor`)
|
|
152
|
+
/// or follows the `*Actor` naming convention is present on the member or its enclosing type
|
|
153
|
+
/// `async` members are stamped too: an `async` function starts its execution on the JS thread and
|
|
154
|
+
/// stays there until the first suspension point, where it may hop to another executor.
|
|
156
155
|
internal func shouldStampJavaScriptActor(
|
|
157
156
|
on member: DeclSyntaxProtocol,
|
|
158
157
|
enclosedBy enclosing: some DeclGroupSyntax
|
|
@@ -162,11 +161,6 @@ internal func shouldStampJavaScriptActor(
|
|
|
162
161
|
return false
|
|
163
162
|
}
|
|
164
163
|
|
|
165
|
-
if let funcDecl = member.as(FunctionDeclSyntax.self),
|
|
166
|
-
funcDecl.signature.effectSpecifiers?.asyncSpecifier != nil {
|
|
167
|
-
return false
|
|
168
|
-
}
|
|
169
|
-
|
|
170
164
|
let memberAttributes = memberAttributes(of: member)
|
|
171
165
|
if memberAttributes.contains(where: hasGlobalActorShape) {
|
|
172
166
|
return false
|
|
@@ -33,14 +33,19 @@ internal enum Receiver {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/// The leading body line binding the receiver, or `nil` for a module (it reads `self` directly). For a
|
|
36
|
-
/// shared object, `native(from:as:)` recovers the typed instance from
|
|
37
|
-
///
|
|
38
|
-
|
|
36
|
+
/// shared object, `native(from:as:)` recovers the typed instance from `this`, throwing on a foreign
|
|
37
|
+
/// object or a type mismatch.
|
|
38
|
+
///
|
|
39
|
+
/// The `this` object comes from the borrowed `JavaScriptUnownedValue` in a sync binding (`asObject(in:)`)
|
|
40
|
+
/// and from the owning `JavaScriptValue` in an async one (`asObject()`). An async binding must take an
|
|
41
|
+
/// owning `this` because a borrowed unowned value can't survive the closure's suspension points.
|
|
42
|
+
func unwrapStatement(isAsync: Bool) -> String? {
|
|
39
43
|
switch self {
|
|
40
44
|
case .module:
|
|
41
45
|
return nil
|
|
42
46
|
case .sharedObject(let typeName):
|
|
43
|
-
|
|
47
|
+
let thisObject = isAsync ? "this.asObject()" : "this.asObject(in: runtime)"
|
|
48
|
+
return "let _self = try SharedObject.native(from: \(thisObject), as: \(typeName).self)"
|
|
44
49
|
}
|
|
45
50
|
}
|
|
46
51
|
|