expo-modules-macros 0.17.0-0 → 0.17.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/apple/ExpoModulesMacros +0 -0
- package/apple/Sources/ExpoModulesMacros/DecorateModuleBuilder.swift +7 -7
- package/apple/Sources/ExpoModulesMacros/FreeFormTypes.swift +10 -7
- package/apple/Sources/ExpoModulesMacros/JSConstructor.swift +1 -1
- package/apple/Sources/ExpoModulesMacros/JSMacro.swift +4 -5
- package/apple/Sources/ExpoModulesMacros/RecordMacro.swift +1 -1
- package/package.json +3 -3
package/apple/ExpoModulesMacros
CHANGED
|
Binary file
|
|
@@ -154,7 +154,7 @@ internal struct JSFunction {
|
|
|
154
154
|
lines.append(contentsOf: encodeResultLines().map { " " + $0 })
|
|
155
155
|
} else {
|
|
156
156
|
lines.append(" \(callExpression(receiver: receiver, arity: arity))")
|
|
157
|
-
lines.append(" return .undefined")
|
|
157
|
+
lines.append(" return .undefined()")
|
|
158
158
|
}
|
|
159
159
|
lines.append("}")
|
|
160
160
|
return lines
|
|
@@ -204,7 +204,7 @@ internal struct JSFunction {
|
|
|
204
204
|
|
|
205
205
|
/// The flat (single-arity) call-and-encode lines used when no trailing parameter is omittable:
|
|
206
206
|
/// `let result = <callee>.f(...)` then the return encode (or the no-return `<callee>.f(...)` +
|
|
207
|
-
/// `.undefined`).
|
|
207
|
+
/// `.undefined()`).
|
|
208
208
|
private func callAndEncodeLines(receiver: Receiver, arity: Int, decodingFrom: Int) -> [String] {
|
|
209
209
|
var lines: [String] = []
|
|
210
210
|
for index in decodingFrom..<arity {
|
|
@@ -215,7 +215,7 @@ internal struct JSFunction {
|
|
|
215
215
|
lines.append(contentsOf: encodeResultLines())
|
|
216
216
|
} else {
|
|
217
217
|
lines.append(callExpression(receiver: receiver, arity: arity))
|
|
218
|
-
lines.append("return .undefined")
|
|
218
|
+
lines.append("return .undefined()")
|
|
219
219
|
}
|
|
220
220
|
return lines
|
|
221
221
|
}
|
|
@@ -225,7 +225,7 @@ internal struct JSFunction {
|
|
|
225
225
|
/// value as the primitive's `toJavaScriptValue(in:)` except for `Int`/`UInt`, where it range-checks
|
|
226
226
|
/// and throws instead of silently encoding an out-of-safe-range value as a lossy number — the
|
|
227
227
|
/// catchable error is the right behavior, and matches how non-primitive integers already encode. A
|
|
228
|
-
/// no-return function returns `.undefined` instead.
|
|
228
|
+
/// no-return function returns `.undefined()` instead.
|
|
229
229
|
///
|
|
230
230
|
/// For an `async` function the encode must run on the JS thread. An `async` body may suspend and
|
|
231
231
|
/// resume on an arbitrary cooperative-pool thread, and encoding a heap-allocated JS value (a string,
|
|
@@ -235,7 +235,7 @@ internal struct JSFunction {
|
|
|
235
235
|
/// which always run on the JS thread — keep encoding directly without the wrapper.
|
|
236
236
|
private func encodeResultLines() -> [String] {
|
|
237
237
|
guard let returnType else {
|
|
238
|
-
return ["return .undefined"]
|
|
238
|
+
return ["return .undefined()"]
|
|
239
239
|
}
|
|
240
240
|
let encode = "try \(expressionType(returnType)).encode(result, in: runtime)"
|
|
241
241
|
if isAsync {
|
|
@@ -340,7 +340,7 @@ internal struct JSProperty {
|
|
|
340
340
|
let setDecode = "\(callee).\(swiftName) = try \(decodeCall(valueType, from: "arguments.unownedValue(at: 0)"))"
|
|
341
341
|
lines.append(
|
|
342
342
|
accessorClosure(
|
|
343
|
-
descriptorName, "set", receiver: receiver, body: "\(unwrap)\(setDecode)\nreturn .undefined"))
|
|
343
|
+
descriptorName, "set", receiver: receiver, body: "\(unwrap)\(setDecode)\nreturn .undefined()"))
|
|
344
344
|
}
|
|
345
345
|
|
|
346
346
|
lines.append("\(object).defineProperty(\"\(jsName)\", descriptor: \(descriptorName))")
|
|
@@ -437,7 +437,7 @@ internal func buildDecorateSharedObjectPhase(
|
|
|
437
437
|
}
|
|
438
438
|
|
|
439
439
|
/// True when a return clause is absent or written as `Void` / `()` — i.e. the function returns
|
|
440
|
-
/// nothing JS-visible, so the binding returns `.undefined`.
|
|
440
|
+
/// nothing JS-visible, so the binding returns `.undefined()`.
|
|
441
441
|
private func isVoidType(_ type: TypeSyntax?) -> Bool {
|
|
442
442
|
guard let type else {
|
|
443
443
|
return true
|
|
@@ -30,13 +30,16 @@ private let freeFormDecodeMethods: [String: String] = [
|
|
|
30
30
|
"[String:Any]": "decodeAnyDictionary",
|
|
31
31
|
]
|
|
32
32
|
|
|
33
|
-
/// The type-safe alternative a free-form type's diagnostic steers to: the
|
|
34
|
-
///
|
|
35
|
-
///
|
|
33
|
+
/// The type-safe alternative a free-form type's diagnostic steers to: the JS wrapper of the same shape
|
|
34
|
+
/// (`JavaScriptArray` for an array, `JavaScriptObject` for a dictionary, `JavaScriptValue` for an
|
|
35
|
+
/// untyped value). The wrappers conform to the codable protocols and keep the value unconverted; a
|
|
36
|
+
/// non-copyable `JavaScriptValue` cannot be an element of a Swift array or dictionary, so the container
|
|
37
|
+
/// shapes map to a wrapper rather than to a container of values. Keyed by the free-form type's
|
|
38
|
+
/// normalized spelling.
|
|
36
39
|
private let typedFreeFormReplacements: [String: String] = [
|
|
37
40
|
"Any": "JavaScriptValue",
|
|
38
|
-
"[Any]": "
|
|
39
|
-
"[String:Any]": "
|
|
41
|
+
"[Any]": "JavaScriptArray",
|
|
42
|
+
"[String:Any]": "JavaScriptObject",
|
|
40
43
|
]
|
|
41
44
|
|
|
42
45
|
/// True when a boundary type (as written) is one of the free-form spellings, ignoring internal
|
|
@@ -54,8 +57,8 @@ internal func freeFormDecodeMethod(for type: String) -> String? {
|
|
|
54
57
|
return freeFormDecodeMethods[normalizedTypeSpelling(type)]
|
|
55
58
|
}
|
|
56
59
|
|
|
57
|
-
/// The type-safe alternative to suggest in place of a free-form type (
|
|
58
|
-
///
|
|
60
|
+
/// The type-safe alternative to suggest in place of a free-form type (the JS wrapper of the same shape),
|
|
61
|
+
/// or `nil` when the type isn't free-form.
|
|
59
62
|
internal func typedFreeFormReplacement(for type: String) -> String? {
|
|
60
63
|
return typedFreeFormReplacements[normalizedTypeSpelling(type)]
|
|
61
64
|
}
|
|
@@ -51,7 +51,7 @@ internal struct JSConstructor {
|
|
|
51
51
|
func buildConstructor(typeName: String) -> DeclSyntax {
|
|
52
52
|
return """
|
|
53
53
|
@JavaScriptActor
|
|
54
|
-
public override class func _constructSharedObject(this: JavaScriptValue, arguments: borrowing JavaScriptValuesBuffer, in runtime: JavaScriptRuntime) throws -> SharedObject? {
|
|
54
|
+
public override class func _constructSharedObject(this: borrowing JavaScriptValue, arguments: borrowing JavaScriptValuesBuffer, in runtime: JavaScriptRuntime) throws -> SharedObject? {
|
|
55
55
|
\(raw: bodyStatements(typeName: typeName, indent: " "))
|
|
56
56
|
}
|
|
57
57
|
"""
|
|
@@ -120,7 +120,7 @@ private func insertAsyncFixIt(for funcDecl: FunctionDeclSyntax) -> FixIt {
|
|
|
120
120
|
/// `JavaScriptValue.decodeAny…`; there is no free-form encode, so any position that encodes is a hard
|
|
121
121
|
/// error. That means:
|
|
122
122
|
/// - a function/constructor **parameter** typed free-form gets a warning steering to
|
|
123
|
-
/// `
|
|
123
|
+
/// `JavaScriptValue` (the type-safe alternative), but compiles;
|
|
124
124
|
/// - a function **return** typed free-form is an error (it would need to encode);
|
|
125
125
|
/// - a **property** typed free-form is an error regardless of settability, because its getter always
|
|
126
126
|
/// encodes.
|
|
@@ -156,9 +156,8 @@ private func diagnoseFreeFormTypes(
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
/// The tail of a free-form encode error: the
|
|
160
|
-
///
|
|
161
|
-
/// for a bare `Any`. Both conform to the codable protocols, so either is a valid fix.
|
|
159
|
+
/// The tail of a free-form encode error: the typed wrapper of the same shape (`JavaScriptArray`,
|
|
160
|
+
/// `JavaScriptObject`) when there is one, otherwise the plain `JavaScriptValue` passthrough suggestion.
|
|
162
161
|
private func suggestedAlternative(for freeFormType: String) -> String {
|
|
163
162
|
if let reshaped = typedFreeFormReplacement(for: freeFormType), reshaped != "JavaScriptValue" {
|
|
164
163
|
return "Use '\(reshaped)', or 'JavaScriptValue' to pass a JS value through unchanged."
|
|
@@ -189,7 +188,7 @@ private func freeFormArgumentWarning(
|
|
|
189
188
|
suggesting suggestedType: String
|
|
190
189
|
) -> JSDiagnosticMessage {
|
|
191
190
|
return JSDiagnosticMessage(
|
|
192
|
-
"Prefer '\(suggestedType)' over the free-form '\(freeFormType)' for a @JS argument. Free-form decoding boxes every value as 'Any' (slower, no static typing);
|
|
191
|
+
"Prefer '\(suggestedType)' over the free-form '\(freeFormType)' for a @JS argument. Free-form decoding boxes every value as 'Any' (slower, no static typing); '\(suggestedType)' keeps the JS value inspectable without converting it.",
|
|
193
192
|
id: "js-free-form-argument",
|
|
194
193
|
severity: .warning
|
|
195
194
|
)
|
|
@@ -529,7 +529,7 @@ private func toObjectMethod(properties: [RecordProperty], inheritsRecord: Bool)
|
|
|
529
529
|
switch property.freeForm {
|
|
530
530
|
case .shape(_, let encodeMethod, let isOptional, _):
|
|
531
531
|
encode = isOptional
|
|
532
|
-
? "self.\(property.name) == nil ? .null : try JavaScriptValue.\(encodeMethod)(self.\(property.name)!, in: runtime)"
|
|
532
|
+
? "self.\(property.name) == nil ? .null() : try JavaScriptValue.\(encodeMethod)(self.\(property.name)!, in: runtime)"
|
|
533
533
|
: "try JavaScriptValue.\(encodeMethod)(self.\(property.name), in: runtime)"
|
|
534
534
|
case .generic:
|
|
535
535
|
// The explicit `as Any` keeps an optional property from warning about its implicit coercion.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-modules-macros",
|
|
3
|
-
"version": "0.17.0
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Swift macro plugin for Expo modules",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"typescript": "^5.4.0"
|
|
24
24
|
},
|
|
25
25
|
"optionalDependencies": {
|
|
26
|
-
"@expo/modules-macros-win32-arm64": "0.17.0
|
|
27
|
-
"@expo/modules-macros-win32-x64": "0.17.0
|
|
26
|
+
"@expo/modules-macros-win32-arm64": "0.17.0",
|
|
27
|
+
"@expo/modules-macros-win32-x64": "0.17.0"
|
|
28
28
|
}
|
|
29
29
|
}
|