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.
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 same shape with the `Any`
34
- /// element replaced by `JavaScriptValue`, which conforms to the codable protocols. Keyed by the
35
- /// free-form type's normalized spelling; spelled with conventional spacing for the message.
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]": "[JavaScriptValue]",
39
- "[String:Any]": "[String: JavaScriptValue]",
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 (its `Any` element replaced by
58
- /// `JavaScriptValue`), or `nil` when the type isn't free-form.
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
- /// `[String: JavaScriptValue]` (the type-safe alternative), but compiles;
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 reshaped `JavaScriptValue` alternative when the type is a
160
- /// container (`[String: Any]` -> `[String: JavaScriptValue]`), otherwise the passthrough suggestion
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); the 'JavaScriptValue' element keeps each value inspectable without erasing it.",
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-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-0",
27
- "@expo/modules-macros-win32-x64": "0.17.0-0"
26
+ "@expo/modules-macros-win32-arm64": "0.17.0",
27
+ "@expo/modules-macros-win32-x64": "0.17.0"
28
28
  }
29
29
  }