peachsim 0.1.1625 → 0.1.1640

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.
Files changed (169) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +15 -2
  3. package/cli/app-config.ts +18 -6
  4. package/cli/app-fonts.ts +37 -17
  5. package/cli/app-stubs.ts +284 -20
  6. package/cli/bridge-flow-runner.ts +66 -45
  7. package/cli/cloud-client.ts +60 -40
  8. package/cli/command-registry.ts +1 -0
  9. package/cli/commands/control.ts +283 -49
  10. package/cli/commands/doctor.ts +30 -189
  11. package/cli/commands/flow.ts +79 -11
  12. package/cli/commands/inspect/core.ts +10 -5
  13. package/cli/commands/inspect/settling.ts +14 -2
  14. package/cli/commands/inspect/shared.ts +9 -4
  15. package/cli/commands/inspect/wait-ready.ts +12 -0
  16. package/cli/commands/inspect.ts +91 -50
  17. package/cli/commands/install-desktop.ts +1 -0
  18. package/cli/commands/maestro-compare.ts +97 -38
  19. package/cli/commands/maestro.ts +9 -1
  20. package/cli/commands/preview.ts +1 -1
  21. package/cli/commands/record.ts +118 -48
  22. package/cli/commands/screenshot.ts +23 -1
  23. package/cli/commands/serve.ts +7 -2
  24. package/cli/commands/setup.ts +19 -42
  25. package/cli/commands/swift.ts +14 -3
  26. package/cli/commands/upload.ts +93 -48
  27. package/cli/desktop-companion.ts +102 -17
  28. package/cli/drivers/desktop.ts +14 -1
  29. package/cli/drivers/playwright-sim-host.ts +103 -45
  30. package/cli/drivers/playwright.ts +9 -8
  31. package/cli/drivers/types.ts +5 -0
  32. package/cli/maestro-accessibility.ts +1 -1
  33. package/cli/maestro-compare.ts +84 -12
  34. package/cli/main.ts +3 -2
  35. package/cli/outbound-endpoints.ts +20 -6
  36. package/cli/pause-aware-timeout.ts +106 -0
  37. package/cli/scene-video.ts +89 -0
  38. package/cli/ws-bridge.ts +37 -19
  39. package/detox/attempt-events.cjs +66 -5
  40. package/detox/attempt-events.d.cts +7 -0
  41. package/detox/expectations.ts +7 -3
  42. package/detox/index.ts +269 -170
  43. package/detox/motion-change.cjs +206 -21
  44. package/detox/motion-change.d.cts +39 -2
  45. package/detox/navigation-lifecycle.ts +35 -3
  46. package/dist-lib/agent-daemon-client.cjs +1 -1
  47. package/dist-lib/agent-events.cjs +1 -1
  48. package/dist-lib/attached-projects.cjs +1 -1
  49. package/dist-lib/auth/shared-session.cjs +1 -1
  50. package/dist-lib/backend-origin.cjs +8 -7
  51. package/dist-lib/beta.cjs +1 -1
  52. package/dist-lib/beta.mjs +1 -1
  53. package/dist-lib/bridge-constants.cjs +13 -1
  54. package/dist-lib/bridge-contract-input.cjs +1 -1
  55. package/dist-lib/bridge-contract-input.mjs +1 -1
  56. package/dist-lib/bridge-contract.cjs +14 -8
  57. package/dist-lib/bridge-contract.mjs +13 -7
  58. package/dist-lib/bundle-channel.cjs +11887 -7900
  59. package/dist-lib/capture-contract.cjs +1 -1
  60. package/dist-lib/capture-contract.mjs +1 -1
  61. package/dist-lib/cloud-contract.cjs +1 -1
  62. package/dist-lib/cloud-contract.mjs +1 -1
  63. package/dist-lib/cloud-test-args.cjs +1 -1
  64. package/dist-lib/cloud-test-args.mjs +1 -1
  65. package/dist-lib/cloud.cjs +1 -1
  66. package/dist-lib/cloud.mjs +1 -1
  67. package/dist-lib/config.cjs +6 -3
  68. package/dist-lib/config.mjs +6 -3
  69. package/dist-lib/detox/index.cjs +1379 -725
  70. package/dist-lib/dev-bundle-resolution.cjs +14 -2
  71. package/dist-lib/expo-swift-bundle.cjs +9341 -5462
  72. package/dist-lib/expo-swift-metadata.cjs +11 -7
  73. package/dist-lib/expo-swift-metadata.mjs +11 -7
  74. package/dist-lib/home-paths.cjs +32 -3
  75. package/dist-lib/host/bridge-host.cjs +50204 -7258
  76. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  77. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  78. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  79. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  80. package/dist-lib/host/websocket-proxy.cjs +1 -1
  81. package/dist-lib/index.cjs +3541 -448
  82. package/dist-lib/jump-to-source-babel.cjs +1 -1
  83. package/dist-lib/jump-to-source-native.cjs +1 -1
  84. package/dist-lib/kotlin-host.cjs +1 -1
  85. package/dist-lib/menu.cjs +1 -1
  86. package/dist-lib/menu.mjs +1 -1
  87. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  88. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  89. package/dist-lib/metro-production-bundle.cjs +1 -1
  90. package/dist-lib/metro-production-bundle.mjs +1 -1
  91. package/dist-lib/metro.cjs +2931 -104
  92. package/dist-lib/native-app-identity-project.cjs +289 -49
  93. package/dist-lib/native-app-identity-project.mjs +289 -49
  94. package/dist-lib/native-app-identity.cjs +77 -26
  95. package/dist-lib/native-app-identity.mjs +76 -26
  96. package/dist-lib/native-firebase-metadata.cjs +1 -1
  97. package/dist-lib/native-firebase-metadata.mjs +1 -1
  98. package/dist-lib/plist.cjs +1 -1
  99. package/dist-lib/plist.mjs +1 -1
  100. package/dist-lib/profiles.cjs +1 -1
  101. package/dist-lib/public-brand.cjs +1 -1
  102. package/dist-lib/react-native-host-modules.cjs +6 -2
  103. package/dist-lib/react-native-host-modules.mjs +6 -2
  104. package/dist-lib/scripts/dev-server-scanner.cjs +22 -8
  105. package/dist-lib/sdk.cjs +27 -11
  106. package/dist-lib/sdk.mjs +27 -10
  107. package/dist-lib/skills.cjs +72201 -26208
  108. package/dist-lib/swift-compile.cjs +1007 -140
  109. package/dist-lib/swift-compile.mjs +1049 -174
  110. package/dist-lib/swift-package.cjs +12 -3
  111. package/dist-lib/swift-package.mjs +12 -3
  112. package/dist-lib/swift-submit.cjs +13 -5
  113. package/dist-lib/swift-submit.mjs +11 -5
  114. package/dist-lib/swift-toolchain.cjs +423 -33
  115. package/dist-lib/swift.cjs +1 -1
  116. package/dist-lib/vite-swift.cjs +8628 -5268
  117. package/dist-lib/vite.cjs +2859 -12
  118. package/dist-lib/worklet-executable.cjs +14 -2
  119. package/dist-lib/worklet-executable.mjs +14 -2
  120. package/kotlin/AppSources/dev/peach/app/PeachDrawable.kt +21 -14
  121. package/kotlin/Sources/androidx/annotation/DrawableRes.kt +14 -0
  122. package/package.json +1 -1
  123. package/scripts/dev-server-scanner.ts +2 -1
  124. package/skills/peach-perf/SKILL.md +11 -5
  125. package/skills/peach-setup/SKILL.md +16 -19
  126. package/src/backend-origin.ts +13 -6
  127. package/src/bridge-constants.ts +11 -0
  128. package/src/bridge-contract.ts +22 -34
  129. package/src/config.ts +15 -0
  130. package/src/desktop-host-delivery.ts +5 -1
  131. package/src/dev-bundle-resolution.ts +2 -1
  132. package/src/expo-manifest-body.ts +13 -0
  133. package/src/expo-swift-host.ts +196 -49
  134. package/src/expo-swift-ready.ts +78 -0
  135. package/src/expoKotlinContract.ts +4 -7
  136. package/src/expoSwiftContract.ts +17 -6
  137. package/src/home-paths.ts +48 -2
  138. package/src/host/bridge-host.ts +5 -2
  139. package/src/host/staged-host-files.ts +9 -0
  140. package/src/native-app-identity-project.ts +27 -6
  141. package/src/native-app-identity.ts +91 -4
  142. package/src/native-firebase-config.ts +209 -13
  143. package/src/nativeAppIconContract.ts +1 -4
  144. package/src/output-lock-stdio.ts +36 -0
  145. package/src/process-group.ts +25 -2
  146. package/src/react-native-bridge-modules.ts +431 -0
  147. package/src/react-native-host-modules.ts +8 -1
  148. package/src/settings-bundle.ts +1 -4
  149. package/src/swift-binary-modules.ts +2 -2
  150. package/src/swift-compile.ts +918 -109
  151. package/src/swift-compiler-digest.ts +14 -0
  152. package/src/swift-distribution.lock.json +24 -12
  153. package/src/swift-distribution.ts +103 -4
  154. package/src/swift-host.ts +180 -55
  155. package/src/swift-icu.ts +27 -13
  156. package/src/swift-objc-compile.ts +355 -0
  157. package/src/swift-objc-sdk.ts +821 -27
  158. package/src/swift-objc-standin.ts +148 -14
  159. package/src/swift-package-manifest.ts +60 -7
  160. package/src/swift-package.ts +15 -1
  161. package/src/swift-packages.ts +154 -81
  162. package/src/swift-standin-emit.ts +96 -15
  163. package/src/swift-standins.ts +530 -116
  164. package/src/swift-submit.ts +13 -5
  165. package/src/swift-toolchain.ts +500 -42
  166. package/src/vite-plugin.ts +12 -1
  167. package/src/worker-system-chunks.ts +11 -12
  168. package/src/worklet-executable.ts +19 -1
  169. package/src/xcode-project.ts +270 -30
@@ -16,8 +16,9 @@ import {
16
16
  import os from 'node:os'
17
17
  import path from 'node:path'
18
18
  import { admittedMacBuilderSlot } from './admitted-mac-build'
19
- import { rnxHomeDir } from './home-paths'
19
+ import { rnxHomeDir, swiftPackageCacheOptions } from './home-paths'
20
20
  import { terminateProcessGroup } from './process-group'
21
+ import { swiftCompilerSourceDigest } from './swift-compiler-digest'
21
22
  import { designTimeDiagnostic, designTimeSource } from './swift-design-time'
22
23
  import {
23
24
  parseSwiftDistributionManifest,
@@ -32,26 +33,30 @@ import {
32
33
  swiftTargetModuleName,
33
34
  type SwiftPackageTarget,
34
35
  } from './swift-package'
36
+ import { swiftEnvironment, swiftSdkOptions, type SwiftWasmSdk } from './swift-toolchain'
35
37
  import { isSwiftResourceBundles } from './swiftContract'
36
38
  import type { SwiftImageUpload } from './swift-submit'
37
- import type { SwiftWasmSdk } from './swift-toolchain'
38
39
  import type { SwiftResourceBundle } from './swiftContract'
39
40
 
40
41
  export { swiftIcuAsset, type SwiftIcuAsset }
41
42
 
42
43
  // compiler drivers own descendants such as admission and swiftpm workers.
43
44
  // cancellation waits for their pipes to close before releasing the build root.
45
+ // `stream` echoes the output as it arrives: all of it, or only matching lines.
46
+ // a successful run then echoes the rest minus lines matching `quiet`, its
47
+ // warnings; a failed run's output goes to the caller's one diagnostic.
44
48
  async function runCompiler(
45
49
  command: string,
46
50
  args: string[],
47
51
  options: ExecFileOptions & { signal?: AbortSignal },
48
- stream = false,
52
+ stream: boolean | RegExp = false,
53
+ quiet?: RegExp,
49
54
  ): Promise<void> {
50
55
  const { signal } = options
51
56
  signal?.throwIfAborted()
52
57
  const child = spawn(command, args, {
53
58
  cwd: options.cwd,
54
- env: options.env,
59
+ env: swiftEnvironment(options.env),
55
60
  detached: true,
56
61
  stdio: ['ignore', 'pipe', 'pipe'],
57
62
  })
@@ -62,6 +67,7 @@ async function runCompiler(
62
67
  let timeout: ReturnType<typeof setTimeout> | undefined
63
68
  const chunks: Record<'stdout' | 'stderr', Buffer[]> = { stdout: [], stderr: [] }
64
69
  const sizes = { stdout: 0, stderr: 0 }
70
+ const partial = { stdout: '', stderr: '' }
65
71
  const stop = () => {
66
72
  stopping ??= terminateProcessGroup(child)
67
73
  // close and cancellation share the same awaited cleanup below.
@@ -69,7 +75,13 @@ async function runCompiler(
69
75
  }
70
76
  for (const name of ['stdout', 'stderr'] as const) {
71
77
  child[name].on('data', (bytes: Buffer) => {
72
- if (stream) process[name].write(bytes)
78
+ if (stream === true) process[name].write(bytes)
79
+ else if (stream) {
80
+ const lines = (partial[name] + bytes.toString()).split('\n')
81
+ partial[name] = lines.pop()!
82
+ for (const line of lines)
83
+ if (stream.test(line)) process[name].write(`${line}\n`)
84
+ }
73
85
  sizes[name] += bytes.length
74
86
  if (sizes[name] <= (options.maxBuffer ?? 1024 * 1024)) chunks[name].push(bytes)
75
87
  else {
@@ -101,7 +113,13 @@ async function runCompiler(
101
113
  },
102
114
  ),
103
115
  )
104
- else resolve()
116
+ else {
117
+ if (quiet)
118
+ for (const name of ['stdout', 'stderr'] as const)
119
+ for (const line of Buffer.concat(chunks[name]).toString().split('\n'))
120
+ if (line && !quiet.test(line)) process[name].write(`${line}\n`)
121
+ resolve()
122
+ }
105
123
  })
106
124
  if (options.timeout)
107
125
  timeout = setTimeout(() => {
@@ -117,6 +135,14 @@ async function runCompiler(
117
135
 
118
136
  const WASM_TRIPLE = 'wasm32-unknown-wasip1'
119
137
 
138
+ // swiftpm's step counter, echoed while a build runs; its diagnostics print
139
+ // once, with the failure.
140
+ const SWIFTPM_PROGRESS = /^\[\d+\/\d+\] /
141
+ // lines that are not diagnostics: progress, already echoed, and the notice
142
+ // that the native build system peach selects is deprecated.
143
+ const SWIFTPM_NOISE =
144
+ /^(?:\[\d+\/\d+\] |Building for production\.\.\.$|warning: '--build-system native' has been deprecated)/
145
+
120
146
  // compiler jobs match the fixture builder's cap to fit a 16GiB Linux slot.
121
147
  const BUILD_JOBS = String(
122
148
  Math.min(4, Math.max(1, Math.floor(os.availableParallelism() / 2))),
@@ -211,6 +237,10 @@ export function swiftModuleInputFiles(root: string): string[] {
211
237
  'scripts/contrast-app-Package.swift',
212
238
  'scripts/build-distribution.ts',
213
239
  'scripts/distribution-clang.ts',
240
+ 'scripts/distribution-libxml2.ts',
241
+ 'scripts/distribution-libxml2.json',
242
+ 'Sources/libxml2/include/module.modulemap',
243
+ 'Sources/libxml2/COPYING',
214
244
  'scripts/build-distribution-plugins.sh',
215
245
  'scripts/build-distribution-plugins-docker.sh',
216
246
  'scripts/build-preview-plugin.sh',
@@ -233,12 +263,8 @@ export function swiftModuleInputFiles(root: string): string[] {
233
263
  return files.sort()
234
264
  }
235
265
 
236
- // the host halves of the module's macros: the rnx plugin (#Preview, @Entry,
237
- // @Model) and #Predicate's FoundationMacros stand-in, which one script builds
238
- // side by side. manifest swiftSettings cannot load a plugin library (RAN: the
239
- // flag reaches the driver but the plugin never loads), so every build loads
240
- // both with -Xswiftc, as scripts/build.sh does for the fixtures. their
241
- // sources are under Sources/, which the artifact hash already covers.
266
+ // the host macro plugins build side by side and load explicitly for every
267
+ // app compile. their source inputs also participate in artifact identity.
242
268
  /** the host macro plugin libraries a module root compiles with, and whether a
243
269
  * checkout's must be rebuilt (scripts/build-preview-plugin.sh) first. */
244
270
  export function swiftMacroPlugins(moduleRoot: string): {
@@ -261,11 +287,21 @@ export function swiftMacroPlugins(moduleRoot: string): {
261
287
  const plugins = [
262
288
  {
263
289
  library: path.join(dir, `libRnxPreviewMacros.${ext}`),
264
- source: path.join(moduleRoot, 'Sources/RnxPreviewMacros/PreviewMacro.swift'),
290
+ sources: [path.join(moduleRoot, 'Sources/RnxPreviewMacros/PreviewMacro.swift')],
265
291
  },
266
292
  {
267
293
  library: path.join(dir, `libFoundationMacros.${ext}`),
268
- source: path.join(moduleRoot, 'Sources/FoundationMacros/PredicateMacro.swift'),
294
+ sources: [
295
+ path.join(moduleRoot, 'Sources/FoundationMacros/PredicateMacro.swift'),
296
+ path.join(moduleRoot, 'Sources/SwiftMacroSupport/PredicateExpression.swift'),
297
+ ],
298
+ },
299
+ {
300
+ library: path.join(dir, `libTipKitMacros.${ext}`),
301
+ sources: [
302
+ path.join(moduleRoot, 'Sources/TipKitMacros/TipKitMacros.swift'),
303
+ path.join(moduleRoot, 'Sources/SwiftMacroSupport/PredicateExpression.swift'),
304
+ ],
269
305
  },
270
306
  ]
271
307
  return {
@@ -274,8 +310,9 @@ export function swiftMacroPlugins(moduleRoot: string): {
274
310
  !existsSync(compilerStamp) ||
275
311
  readFileSync(compilerStamp, 'utf8').trim() !== release ||
276
312
  plugins.some(
277
- ({ library, source }) =>
278
- !existsSync(library) || statSync(source).mtimeMs > statSync(library).mtimeMs,
313
+ ({ library, sources }) =>
314
+ !existsSync(library) ||
315
+ sources.some((source) => statSync(source).mtimeMs > statSync(library).mtimeMs),
279
316
  ),
280
317
  }
281
318
  }
@@ -341,6 +378,16 @@ export function swiftModuleDigest(root: string): Buffer {
341
378
  return digest
342
379
  }
343
380
 
381
+ // optimized consumers can reference private symbols from an imported framework.
382
+ // source revisions need separate object trees, while app edits keep one warm tree.
383
+ export function swiftProjectBuildKey(moduleRoot: string, release: string): string {
384
+ return createHash('sha256')
385
+ .update(`${release}\0${swiftModuleSdk(moduleRoot).wasmSdkId}`)
386
+ .update(swiftModuleDigest(moduleRoot))
387
+ .digest('hex')
388
+ .slice(0, 32)
389
+ }
390
+
344
391
  export function compileTargets(input: SwiftCompileInput): SwiftPackageTarget[] {
345
392
  const manifest = input.files['Package.swift']
346
393
  return manifest === undefined
@@ -378,21 +425,24 @@ export function withNativeSourceGlue(
378
425
  const OPTIONAL_FRAMEWORK_DEPENDENCIES: Record<string, string[]> = {
379
426
  GameplayKit: [],
380
427
  simd: [],
381
- GLKit: [],
428
+ ModelIO: ['simd'],
429
+ GLKit: ['ModelIO'],
382
430
  Accelerate: [],
383
431
  CryptoKit: [],
384
432
  CommonCrypto: [],
433
+ ImagePlayground: [],
434
+ QuickLookThumbnailing: [],
435
+ libxml2: [],
385
436
  CoreText: [],
386
437
  Compression: ['PeachCodec'],
387
438
  zlib: ['PeachCodec'],
388
439
  PeachCodec: [],
389
- Security: ['CryptoKit'],
390
440
  TikTokBusinessSDK: [],
391
441
  nSure: [],
392
442
  Statsig: [],
393
443
  TOCropViewController: [],
394
444
  RiveRuntime: ['MetalKit'],
395
- MetalKit: [],
445
+ MetalKit: ['ModelIO'],
396
446
  DatadogCore: [],
397
447
  DatadogLogs: ['DatadogCore'],
398
448
  DatadogRUM: ['DatadogCore'],
@@ -554,13 +604,20 @@ export function swiftSdkPaths(
554
604
  toolchainBin: string,
555
605
  ): { sysroot: string; resources: string } {
556
606
  const sdk = swiftModuleSdk(moduleRoot).wasmSdkId
557
- const key = `${toolchainBin}\0${sdk}`
607
+ const key = JSON.stringify([toolchainBin, sdk, swiftSdkOptions()])
558
608
  const cached = sdkPaths.get(key)
559
609
  if (cached) return cached
560
610
  const configuration = execFileSync(
561
611
  path.join(toolchainBin, 'swift'),
562
- ['sdk', 'configure', '--show-configuration', sdk, 'wasm32-unknown-wasip1'],
563
- { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] },
612
+ [
613
+ 'sdk',
614
+ 'configure',
615
+ ...swiftSdkOptions(),
616
+ '--show-configuration',
617
+ sdk,
618
+ 'wasm32-unknown-wasip1',
619
+ ],
620
+ { encoding: 'utf8', env: swiftEnvironment(), stdio: ['ignore', 'pipe', 'pipe'] },
564
621
  )
565
622
  const field = (name: string) => {
566
623
  const value = new RegExp(`^${name}:\\s*(.+)$`, 'm').exec(configuration)?.[1]?.trim()
@@ -586,7 +643,7 @@ export function swiftAvailableModules(
586
643
  toolchainBin: string,
587
644
  ): Set<string> {
588
645
  const sdk = swiftModuleSdk(moduleRoot).wasmSdkId
589
- const key = `${moduleRoot}\0${sdk}`
646
+ const key = JSON.stringify([moduleRoot, sdk, swiftSdkOptions()])
590
647
  const cached = availableModules.get(key)
591
648
  if (cached) return cached
592
649
  const modules = new Set(swiftPeachModules(moduleRoot))
@@ -712,7 +769,14 @@ const EXECUTABLE_LINK_FLAGS = ` "-Xclang-linker", "-O0",
712
769
  const REACTOR_FLAG = '"-Xclang-linker", "-mexec-model=reactor",\n'
713
770
 
714
771
  /** bump with any change to the emitted multi-target manifest text. */
715
- export const MULTI_MANIFEST_VERSION = 38
772
+ export const MULTI_MANIFEST_VERSION = 39
773
+
774
+ // build-cli replaces this in every bundle; source runs read the files directly.
775
+ declare const __SWIFT_COMPILER_DIGEST__: string | undefined
776
+ const compilerSourceDigest =
777
+ typeof __SWIFT_COMPILER_DIGEST__ === 'string'
778
+ ? __SWIFT_COMPILER_DIGEST__
779
+ : swiftCompilerSourceDigest(import.meta.dirname)
716
780
 
717
781
  export function swiftArtifactHash(
718
782
  input: SwiftCompileInput,
@@ -720,56 +784,8 @@ export function swiftArtifactHash(
720
784
  moduleRoot: string,
721
785
  ): string {
722
786
  const hash = createHash('sha256')
723
- // v49: NSObject metatype initialization reaches its explicit runtime boundary
724
- // v48: top-level classes rooted in an Apple framework class stay out of C++
725
- // v47: target ownership honors exclusions before lowering manifest-named files
726
- // v46: view builder literals compile as design-time lookups
727
- // v45: the link runs no wasm-opt pass, whatever the compiling machine has
728
- // v44: fixed-signature optional type methods retain metatype dispatch
729
- // v43: optional type-property witnesses preserve class getter dispatch
730
- // v42: the source-checkout template route takes the same executable stack layout
731
- // v41: executable stack size and layout match the native main-thread budget
732
- // v40: generic classes expose fixed-signature optional SDK witnesses
733
- // v39: target source files named Package.swift lower with their owning module
734
- // v38: dependency manifests stay intact and backend threads match build jobs
735
- // v37: optional requirement calls lower trailing closures without parentheses
736
- // v36: javascript dialog witnesses preserve typed main actor completions
737
- // v35: input-suggestion witnesses keep UIKit payload and optional results
738
- // v34: typed async SDK witnesses keep imported names and completion results
739
- // v33: Foundation-qualified authentication types use their networking owner
740
- // v32: extension override slots resolve across each target's files
741
- // v31: the text, table, scroll, collection and flow layout delegates'
742
- // witnesses gain selector records, and their optional calls lower to
743
- // selector sends
744
- // v30: async methods answer their completion handler selector, async
745
- // optional requirements get members, and non-escaping closures reach sends
746
- // v29: the SDK's delegate protocols' witnesses gain selector records, and
747
- // optional calls reach a requirement by its labels and witnesses by types
748
- // v28: AnyClass method calls and IMP casts lower to selector sends
749
- // v27: @objc protocols' optional requirements lower to selector sends
750
- // v26: an @objc protocol is class-bound, #keyPath lowers to its string,
751
- // and an override lifted from an extension keeps the extension's access
752
- // v25: every Clang submodule import names its framework module
753
- // v24: distribution objects use an ordered linker response file
754
- // v22: Foundation sources see Darwin, which carries the libc and Mach
755
- // v21: Foundation sources see the ObservableObject and Published aliases
756
- // v20: supplied table editing and swipe methods preserve objective-c selectors
757
- // v18: NSValue(time:) constructs NSStructBox through NSValue.boxedTime
758
- // v17: AVAsset(url:) constructs AVURLAsset for the class cluster
759
- // v16: overrides of @objc extension members rename to __peach_ovr_
760
- // v15: Foundation-only sources see the platform libc (WASILibc, including
761
- // math round) and its pthread mutexes (wasi_pthread)
762
- // v14: AnyObject doubleValue lowers to the typed _objcNumber getter
763
- // v13: implicit target resources synthesize Bundle.module
764
- // v12: overrides in an extension of a same-file class lift into the class
765
- // v10: Foundation-only sources see Dispatch queues
766
- // v9: table cell and header footer view initializers compile required
767
- // v8: optional framework products and distribution objects link on import
768
- // v7: runtime class lookup uses the same objc class registry as messages
769
- // v6: app and scene delegate classes compile final
770
- // (v5: a target declaring resources gets SwiftPM's Bundle.module accessor;
771
- // v4: sources compile through swiftSourceAsIOS)
772
- hash.update(`swift-compile/v49\n${release}\n`)
787
+ hash.update(`swift-compile\n${release}\n`)
788
+ hash.update(compilerSourceDigest)
773
789
  if (input.oneModule) hash.update('one-module\n')
774
790
  hash.update(swiftModuleDigest(moduleRoot))
775
791
  for (const file of Object.keys(input.files).sort()) {
@@ -858,19 +874,18 @@ export function emitSwiftPackageManifest(args: {
858
874
  libraries?: Map<string, string>
859
875
  }): string {
860
876
  const { targets, siblings, moduleRoot, oneModule, spriteKit, distribution } = args
861
- const reachedFrameworks = new Set(
862
- [...siblings.values()]
863
- .flat()
864
- .filter(
865
- (name) =>
866
- OPTIONAL_FRAMEWORKS.has(name) &&
867
- !targets.some((target) => target.name === name),
868
- )
869
- .flatMap((name) => [name, ...(OPTIONAL_FRAMEWORK_DEPENDENCIES[name] ?? [])]),
870
- )
877
+ const reachedFrameworks = new Set<string>()
878
+ const reach = (name: string) => {
879
+ if (reachedFrameworks.has(name)) return
880
+ reachedFrameworks.add(name)
881
+ for (const dependency of OPTIONAL_FRAMEWORK_DEPENDENCIES[name] ?? [])
882
+ reach(dependency)
883
+ }
884
+ for (const name of [...siblings.values()].flat())
885
+ if (OPTIONAL_FRAMEWORKS.has(name) && !targets.some((target) => target.name === name))
886
+ reach(name)
871
887
  if (spriteKit) {
872
- reachedFrameworks.add('SpriteKit')
873
- reachedFrameworks.add('PeachBox2D')
888
+ for (const name of ['SpriteKit', 'PeachBox2D', 'simd', 'GLKit']) reach(name)
874
889
  }
875
890
  // the distribution builder names each object lib/<target>-<file>.o.
876
891
  // preserve link order while leaving unreached optional module objects out.
@@ -917,6 +932,10 @@ export function emitSwiftPackageManifest(args: {
917
932
  // each target compiles in the language mode and default isolation its
918
933
  // author declared, the way xcode builds the same package.
919
934
  const stanza = (target: SwiftPackageTarget): string => {
935
+ // system modules keep their upstream module map and resolve headers and
936
+ // libraries from the wasm SDK, never the build host's pkg-config paths.
937
+ if (target.systemLibrary)
938
+ return ` .systemLibrary(name: ${JSON.stringify(target.name)}, path: ${JSON.stringify(target.path)}),`
920
939
  const isolation = target.mainActorIsolation
921
940
  ? ' .defaultIsolation(MainActor.self),'
922
941
  : ''
@@ -980,17 +999,27 @@ export function emitSwiftPackageManifest(args: {
980
999
  .join('')
981
1000
  : ''
982
1001
  const kind = target.executable ? '.executableTarget' : '.target'
1002
+ const linkedLibraries = (target.linkedLibraries ?? []).map(
1003
+ (name) => `.linkedLibrary(${JSON.stringify(name)})`,
1004
+ )
1005
+ const librarySettings = [
1006
+ ...linkedLibraries,
1007
+ ...(args.libraries?.has(target.name)
1008
+ ? [`.unsafeFlags([${JSON.stringify(args.libraries.get(target.name))}])`]
1009
+ : []),
1010
+ ]
983
1011
  const link = target.executable
984
1012
  ? `,
985
1013
  linkerSettings: [
1014
+ ${linkedLibraries.map((setting) => `${setting},`).join('\n ')}
986
1015
  .unsafeFlags([
987
1016
  ${REACTOR_FLAG}${EXECUTABLE_LINK_FLAGS} "-Xlinker", "--export-if-defined=__main_argc_argv"${library},
988
1017
  ]),
989
1018
  .unsafeFlags(["-Xlinker", "--strip-all"], .when(configuration: .release)),
990
1019
  ]`
991
- : args.libraries?.has(target.name)
1020
+ : librarySettings.length > 0
992
1021
  ? `,
993
- linkerSettings: [.unsafeFlags([${JSON.stringify(args.libraries.get(target.name))}])]`
1022
+ linkerSettings: [${librarySettings.join(', ')}]`
994
1023
  : ''
995
1024
  return [
996
1025
  ` ${kind}(`,
@@ -1065,7 +1094,8 @@ export function syncSwiftTree(base: string, files: Map<string, string | Buffer>)
1065
1094
  }
1066
1095
 
1067
1096
  // the app runs as iOS, but it compiles for wasm, where `os(iOS)` is false and
1068
- // every iOS branch of the app would compile out. a condition line names iOS
1097
+ // every iOS branch of the app would compile out. peach is the iOS simulator,
1098
+ // so `targetEnvironment(simulator)` holds too. a condition line names iOS
1069
1099
  // as `true` padded to the same length, so diagnostics keep their columns;
1070
1100
  // os(WASI) still holds for code written for wasm. only `#if` and `#elseif`
1071
1101
  // lines that begin in code change: a line inside a string literal or a block
@@ -1079,7 +1109,7 @@ export function syncSwiftTree(base: string, files: Map<string, string | Buffer>)
1079
1109
  // explicit `@objc(name:)` on a member, whose name becomes a string argument,
1080
1110
  // and a delegate class that becomes final (below).
1081
1111
  const DIRECTIVE = /^[ \t]*#(?:if|elseif)\b/
1082
- const OS_IOS = /\bos\(\s*iOS\s*\)/g
1112
+ const OS_IOS = /\b(?:os\(\s*iOS\s*\)|targetEnvironment\(\s*simulator\s*\))/g
1083
1113
  const OBJC_ATTRIBUTE = /^@(?:objcMembers\b|objc\b(?:(\s*)\(([^()]*)\))?|IBAction\b)/
1084
1114
  const SELECTOR = /^#selector\b/
1085
1115
  const PROTOCOL_NAME = /^\s+[A-Za-z_]\w*(\s*:)?/
@@ -1654,25 +1684,32 @@ function objcRootedClasses(sources: string[]): Set<string> {
1654
1684
  // the header swift emits on iOS keeps an Objective-C class out of its C++
1655
1685
  // section. here its root is a swift class from a module with no C++ header,
1656
1686
  // so C++ that includes the header fails on the undeclared base. a top-level
1657
- // class in `rooted` gains @_expose(!Cxx) in front of its declaration,
1658
- // shifting that one line's columns. swift rejects the attribute in a local
1687
+ // class in `rooted` gains @_expose(!Cxx), keeping @main first so SwiftPM
1688
+ // recognizes the entry without changing source lines. swift rejects it in a local
1659
1689
  // scope, so a nested class keeps its exposure.
1660
1690
  function hideObjCClassesFromCxx(source: string, rooted: Set<string>): string {
1661
1691
  if (rooted.size === 0) return source
1662
1692
  const code = swiftCodeMask(source)
1663
- const starts: number[] = []
1693
+ const insertions: { at: number; text: string }[] = []
1664
1694
  let depth = 0
1665
1695
  for (const match of code.matchAll(
1666
1696
  /[{}]|\bclass\s+(?!(?:func|var|let|subscript)\b)([A-Za-z_]\w*)/g,
1667
1697
  )) {
1668
1698
  if (match[0] === '{') depth++
1669
1699
  else if (match[0] === '}') depth--
1670
- else if (depth === 0 && rooted.has(match[1]!))
1671
- starts.push(declarationStart(code, match.index, 0))
1700
+ else if (depth === 0 && rooted.has(match[1]!)) {
1701
+ const start = declarationStart(code, match.index, 0)
1702
+ const main = /@main\b/.exec(code.slice(start, match.index))
1703
+ insertions.push(
1704
+ main
1705
+ ? { at: start + main.index + main[0].length, text: ' @_expose(!Cxx)' }
1706
+ : { at: start, text: '@_expose(!Cxx) ' },
1707
+ )
1708
+ }
1672
1709
  }
1673
1710
  let out = source
1674
- for (const at of starts.reverse())
1675
- out = `${out.slice(0, at)}@_expose(!Cxx) ${out.slice(at)}`
1711
+ for (const { at, text } of insertions.reverse())
1712
+ out = `${out.slice(0, at)}${text}${out.slice(at)}`
1676
1713
  return out
1677
1714
  }
1678
1715
 
@@ -4359,7 +4396,7 @@ function lowerObjCRuntimeCalls(source: string, index: ObjCIndex): string {
4359
4396
  // char outside code (comments, strings, regex literals) reads as a space,
4360
4397
  // so an identifier that survives is code. newlines stay, keeping every
4361
4398
  // offset valid in both views.
4362
- function swiftCodeMask(source: string): string {
4399
+ export function swiftCodeMask(source: string): string {
4363
4400
  const chars = source.split('')
4364
4401
  const blank = (from: number, to: number): void => {
4365
4402
  for (let i = Math.max(0, from); i < Math.min(to, chars.length); i++)
@@ -4474,6 +4511,710 @@ function swiftCodeMask(source: string): string {
4474
4511
  return chars.join('')
4475
4512
  }
4476
4513
 
4514
+ // darwin declares these in Foundation; the guest networking module owns them.
4515
+ const FOUNDATION_NETWORKING_TYPES = new Set([
4516
+ 'CachedURLResponse',
4517
+ 'HTTPCookieStorage',
4518
+ 'HTTPURLResponse',
4519
+ 'NSMutableURLRequest',
4520
+ 'NSURLConnection',
4521
+ 'NSURLConnectionDataDelegate',
4522
+ 'NSURLConnectionDelegate',
4523
+ 'NSURLConnectionDownloadDelegate',
4524
+ 'URLAuthenticationChallenge',
4525
+ 'URLAuthenticationChallengeSender',
4526
+ 'URLCache',
4527
+ 'URLCredential',
4528
+ 'URLCredentialStorage',
4529
+ 'URLProtectionSpace',
4530
+ 'URLProtocol',
4531
+ 'URLProtocolClient',
4532
+ 'URLRequest',
4533
+ 'URLResponse',
4534
+ 'URLSession',
4535
+ 'URLSessionConfiguration',
4536
+ 'URLSessionDataDelegate',
4537
+ 'URLSessionDataTask',
4538
+ 'URLSessionDelegate',
4539
+ 'URLSessionDownloadDelegate',
4540
+ 'URLSessionDownloadTask',
4541
+ 'URLSessionStreamDelegate',
4542
+ 'URLSessionStreamTask',
4543
+ 'URLSessionTask',
4544
+ 'URLSessionTaskDelegate',
4545
+ 'URLSessionTaskMetrics',
4546
+ 'URLSessionTaskTransactionMetrics',
4547
+ 'URLSessionUploadTask',
4548
+ 'URLSessionWebSocketDelegate',
4549
+ 'URLSessionWebSocketTask',
4550
+ ])
4551
+
4552
+ // Foundation overlay declarations live in the shared guest overlay module.
4553
+ const FOUNDATION_OVERLAY_TYPES = new Set([
4554
+ 'AsyncCharacterSequence',
4555
+ 'AsyncLineSequence',
4556
+ 'AsyncUnicodeScalarSequence',
4557
+ 'BlockOperation',
4558
+ 'DateComponentsFormatter',
4559
+ 'ErrorUserInfoKey',
4560
+ 'FileWrapper',
4561
+ 'HTTPCookie',
4562
+ 'HTTPCookiePropertyKey',
4563
+ 'HTTPCookieStringPolicy',
4564
+ 'InlinePresentationIntent',
4565
+ 'ListFormatter',
4566
+ 'LocalizedStringResource',
4567
+ 'MachError',
4568
+ 'MeasurementFormatUnitUsage',
4569
+ 'MeasurementFormatter',
4570
+ 'MessagePort',
4571
+ 'NSAssertionHandler',
4572
+ 'NSAttributedStringFormattingContextKey',
4573
+ 'NSBundleResourceRequest',
4574
+ 'NSCollectionChangeType',
4575
+ 'NSConditionLock',
4576
+ 'NSDataDetector',
4577
+ 'NSException',
4578
+ 'NSExtensionContext',
4579
+ 'NSExtensionItem',
4580
+ 'NSExtensionRequestHandling',
4581
+ 'NSFastEnumerationIterator',
4582
+ 'NSFastEnumerationState',
4583
+ 'NSFileAccessIntent',
4584
+ 'NSFileCoordinator',
4585
+ 'NSFileManagerResumeSyncBehavior',
4586
+ 'NSFileManagerSupportedSyncControls',
4587
+ 'NSFileManagerUploadLocalVersionConflictPolicy',
4588
+ 'NSFileProviderService',
4589
+ 'NSFileProviderServiceName',
4590
+ 'NSFileSecurity',
4591
+ 'NSFileVersion',
4592
+ 'NSGrammaticalCase',
4593
+ 'NSGrammaticalDefiniteness',
4594
+ 'NSGrammaticalDetermination',
4595
+ 'NSGrammaticalGender',
4596
+ 'NSGrammaticalNumber',
4597
+ 'NSGrammaticalPartOfSpeech',
4598
+ 'NSGrammaticalPerson',
4599
+ 'NSGrammaticalPronounType',
4600
+ 'NSHashEnumerator',
4601
+ 'NSHashTable',
4602
+ 'NSHashTableCallBacks',
4603
+ 'NSItemProvider',
4604
+ 'NSItemProviderFileOptions',
4605
+ 'NSItemProviderRepresentationVisibility',
4606
+ 'NSKeyValueOperator',
4607
+ 'NSKeyValueSetMutationKind',
4608
+ 'NSKeyValueSharedObservers',
4609
+ 'NSLinguisticTag',
4610
+ 'NSLinguisticTagScheme',
4611
+ 'NSLinguisticTagger',
4612
+ 'NSLinguisticTaggerUnit',
4613
+ 'NSMachPort',
4614
+ 'NSMapEnumerator',
4615
+ 'NSMapTable',
4616
+ 'NSMapTableKeyCallBacks',
4617
+ 'NSMapTableValueCallBacks',
4618
+ 'NSMetadataItem',
4619
+ 'NSMetadataQuery',
4620
+ 'NSMetadataQueryAttributeValueTuple',
4621
+ 'NSMetadataQueryDelegate',
4622
+ 'NSMetadataQueryResultGroup',
4623
+ 'NSOrderedCollectionChange',
4624
+ 'NSOrderedCollectionDifference',
4625
+ 'NSOrderedCollectionDifferenceCalculationOptions',
4626
+ 'NSPointerArray',
4627
+ 'NSPointerFunctions',
4628
+ 'NSPredicateValidating',
4629
+ 'NSProxy',
4630
+ 'NSPurgeableData',
4631
+ 'NSSecureUnarchiveFromDataTransformer',
4632
+ 'NSSwappedDouble',
4633
+ 'NSSwappedFloat',
4634
+ 'NSURLRequest',
4635
+ 'NSUbiquitousKeyValueStore',
4636
+ 'NSUserActivity',
4637
+ 'NSUserActivityDelegate',
4638
+ 'NSValueTransformerName',
4639
+ 'NSXPCCoder',
4640
+ 'NSXPCConnection',
4641
+ 'NSXPCInterface',
4642
+ 'NSXPCListener',
4643
+ 'NSXPCListenerDelegate',
4644
+ 'NSXPCListenerEndpoint',
4645
+ 'NetService',
4646
+ 'NetServiceBrowser',
4647
+ 'NetServiceBrowserDelegate',
4648
+ 'NetServiceDelegate',
4649
+ 'NotificationQueue',
4650
+ 'Operation',
4651
+ 'OperationQueue',
4652
+ 'PredicateCodableConfiguration',
4653
+ 'PresentationIntent',
4654
+ 'Progress',
4655
+ 'ProgressKind',
4656
+ 'ProgressUserInfoKey',
4657
+ 'RelativeDateTimeFormatter',
4658
+ 'SocketPort',
4659
+ 'StringEncodingDetectionOptionsKey',
4660
+ 'TermOfAddress',
4661
+ 'URLFileProtection',
4662
+ 'URLResource',
4663
+ 'URLThumbnailDictionaryItem',
4664
+ 'URLUbiquitousItemDownloadingStatus',
4665
+ 'URLUbiquitousSharedItemPermissions',
4666
+ 'URLUbiquitousSharedItemRole',
4667
+ 'UndoManager',
4668
+ 'ValueTransformer',
4669
+ 'XMLParser',
4670
+ 'XMLParserDelegate',
4671
+ ])
4672
+
4673
+ // existing overlay globals retain their declaration and runtime owner.
4674
+ const FOUNDATION_OVERLAY_GLOBALS = new Set([
4675
+ 'CFBridgingRetain',
4676
+ 'NSASCIIStringEncoding',
4677
+ 'NSAllHashTableObjects',
4678
+ 'NSAllMapTableKeys',
4679
+ 'NSAllMapTableValues',
4680
+ 'NSAllocateMemoryPages',
4681
+ 'NSAssertionHandlerKey',
4682
+ 'NSBuddhistCalendar',
4683
+ 'NSBundleErrorMaximum',
4684
+ 'NSBundleErrorMinimum',
4685
+ 'NSBundleExecutableArchitectureARM64',
4686
+ 'NSBundleExecutableArchitectureI386',
4687
+ 'NSBundleExecutableArchitecturePPC',
4688
+ 'NSBundleExecutableArchitecturePPC64',
4689
+ 'NSBundleExecutableArchitectureX86_64',
4690
+ 'NSBundleOnDemandResourceExceededMaximumSizeError',
4691
+ 'NSBundleOnDemandResourceInvalidTagError',
4692
+ 'NSBundleOnDemandResourceOutOfSpaceError',
4693
+ 'NSBundleResourceRequestLoadingPriorityUrgent',
4694
+ 'NSChineseCalendar',
4695
+ 'NSCloudSharingConflictError',
4696
+ 'NSCloudSharingErrorMaximum',
4697
+ 'NSCloudSharingErrorMinimum',
4698
+ 'NSCloudSharingNetworkFailureError',
4699
+ 'NSCloudSharingNoPermissionError',
4700
+ 'NSCloudSharingOtherError',
4701
+ 'NSCloudSharingQuotaExceededError',
4702
+ 'NSCloudSharingTooManyParticipantsError',
4703
+ 'NSCoderErrorMaximum',
4704
+ 'NSCoderErrorMinimum',
4705
+ 'NSCoderInvalidValueError',
4706
+ 'NSCompareHashTables',
4707
+ 'NSCompareMapTables',
4708
+ 'NSCompressionErrorMaximum',
4709
+ 'NSCompressionErrorMinimum',
4710
+ 'NSCompressionFailedError',
4711
+ 'NSConvertHostDoubleToSwapped',
4712
+ 'NSConvertHostFloatToSwapped',
4713
+ 'NSConvertSwappedDoubleToHost',
4714
+ 'NSConvertSwappedFloatToHost',
4715
+ 'NSCopyMemoryPages',
4716
+ 'NSCountHashTable',
4717
+ 'NSCountMapTable',
4718
+ 'NSCreateHashTable',
4719
+ 'NSCreateMapTable',
4720
+ 'NSDeallocateMemoryPages',
4721
+ 'NSDecompressionFailedError',
4722
+ 'NSEndHashTableEnumeration',
4723
+ 'NSEndMapTableEnumeration',
4724
+ 'NSEnumerateHashTable',
4725
+ 'NSEnumerateMapTable',
4726
+ 'NSExecutableErrorMaximum',
4727
+ 'NSExecutableErrorMinimum',
4728
+ 'NSExtensionItemAttachmentsKey',
4729
+ 'NSExtensionItemAttributedContentTextKey',
4730
+ 'NSExtensionItemAttributedTitleKey',
4731
+ 'NSExtensionItemsAndErrorsKey',
4732
+ 'NSExtensionJavaScriptFinalizeArgumentKey',
4733
+ 'NSExtensionJavaScriptPreprocessingResultsKey',
4734
+ 'NSFileErrorMaximum',
4735
+ 'NSFileErrorMinimum',
4736
+ 'NSFormattingErrorMaximum',
4737
+ 'NSFormattingErrorMinimum',
4738
+ 'NSFoundationVersionNumber',
4739
+ 'NSFoundationVersionNumber10_0',
4740
+ 'NSFoundationVersionNumber10_1',
4741
+ 'NSFoundationVersionNumber10_10',
4742
+ 'NSFoundationVersionNumber10_10_1',
4743
+ 'NSFoundationVersionNumber10_10_2',
4744
+ 'NSFoundationVersionNumber10_10_3',
4745
+ 'NSFoundationVersionNumber10_10_4',
4746
+ 'NSFoundationVersionNumber10_10_5',
4747
+ 'NSFoundationVersionNumber10_10_Max',
4748
+ 'NSFoundationVersionNumber10_11',
4749
+ 'NSFoundationVersionNumber10_11_1',
4750
+ 'NSFoundationVersionNumber10_11_2',
4751
+ 'NSFoundationVersionNumber10_11_3',
4752
+ 'NSFoundationVersionNumber10_11_4',
4753
+ 'NSFoundationVersionNumber10_11_Max',
4754
+ 'NSFoundationVersionNumber10_1_1',
4755
+ 'NSFoundationVersionNumber10_1_2',
4756
+ 'NSFoundationVersionNumber10_1_3',
4757
+ 'NSFoundationVersionNumber10_1_4',
4758
+ 'NSFoundationVersionNumber10_2',
4759
+ 'NSFoundationVersionNumber10_2_1',
4760
+ 'NSFoundationVersionNumber10_2_2',
4761
+ 'NSFoundationVersionNumber10_2_3',
4762
+ 'NSFoundationVersionNumber10_2_4',
4763
+ 'NSFoundationVersionNumber10_2_5',
4764
+ 'NSFoundationVersionNumber10_2_6',
4765
+ 'NSFoundationVersionNumber10_2_7',
4766
+ 'NSFoundationVersionNumber10_2_8',
4767
+ 'NSFoundationVersionNumber10_3',
4768
+ 'NSFoundationVersionNumber10_3_1',
4769
+ 'NSFoundationVersionNumber10_3_2',
4770
+ 'NSFoundationVersionNumber10_3_3',
4771
+ 'NSFoundationVersionNumber10_3_4',
4772
+ 'NSFoundationVersionNumber10_3_5',
4773
+ 'NSFoundationVersionNumber10_3_6',
4774
+ 'NSFoundationVersionNumber10_3_7',
4775
+ 'NSFoundationVersionNumber10_3_8',
4776
+ 'NSFoundationVersionNumber10_3_9',
4777
+ 'NSFoundationVersionNumber10_4',
4778
+ 'NSFoundationVersionNumber10_4_1',
4779
+ 'NSFoundationVersionNumber10_4_10',
4780
+ 'NSFoundationVersionNumber10_4_11',
4781
+ 'NSFoundationVersionNumber10_4_2',
4782
+ 'NSFoundationVersionNumber10_4_3',
4783
+ 'NSFoundationVersionNumber10_4_4_Intel',
4784
+ 'NSFoundationVersionNumber10_4_4_PowerPC',
4785
+ 'NSFoundationVersionNumber10_4_5',
4786
+ 'NSFoundationVersionNumber10_4_6',
4787
+ 'NSFoundationVersionNumber10_4_7',
4788
+ 'NSFoundationVersionNumber10_4_8',
4789
+ 'NSFoundationVersionNumber10_4_9',
4790
+ 'NSFoundationVersionNumber10_5',
4791
+ 'NSFoundationVersionNumber10_5_1',
4792
+ 'NSFoundationVersionNumber10_5_2',
4793
+ 'NSFoundationVersionNumber10_5_3',
4794
+ 'NSFoundationVersionNumber10_5_4',
4795
+ 'NSFoundationVersionNumber10_5_5',
4796
+ 'NSFoundationVersionNumber10_5_6',
4797
+ 'NSFoundationVersionNumber10_5_7',
4798
+ 'NSFoundationVersionNumber10_5_8',
4799
+ 'NSFoundationVersionNumber10_6',
4800
+ 'NSFoundationVersionNumber10_6_1',
4801
+ 'NSFoundationVersionNumber10_6_2',
4802
+ 'NSFoundationVersionNumber10_6_3',
4803
+ 'NSFoundationVersionNumber10_6_4',
4804
+ 'NSFoundationVersionNumber10_6_5',
4805
+ 'NSFoundationVersionNumber10_6_6',
4806
+ 'NSFoundationVersionNumber10_6_7',
4807
+ 'NSFoundationVersionNumber10_6_8',
4808
+ 'NSFoundationVersionNumber10_7',
4809
+ 'NSFoundationVersionNumber10_7_1',
4810
+ 'NSFoundationVersionNumber10_7_2',
4811
+ 'NSFoundationVersionNumber10_7_3',
4812
+ 'NSFoundationVersionNumber10_7_4',
4813
+ 'NSFoundationVersionNumber10_8',
4814
+ 'NSFoundationVersionNumber10_8_1',
4815
+ 'NSFoundationVersionNumber10_8_2',
4816
+ 'NSFoundationVersionNumber10_8_3',
4817
+ 'NSFoundationVersionNumber10_8_4',
4818
+ 'NSFoundationVersionNumber10_9',
4819
+ 'NSFoundationVersionNumber10_9_1',
4820
+ 'NSFoundationVersionNumber10_9_2',
4821
+ 'NSFoundationVersionNumber_iOS_4_0',
4822
+ 'NSFoundationVersionNumber_iOS_4_1',
4823
+ 'NSFoundationVersionNumber_iOS_4_2',
4824
+ 'NSFoundationVersionNumber_iOS_4_3',
4825
+ 'NSFoundationVersionNumber_iOS_5_0',
4826
+ 'NSFoundationVersionNumber_iOS_5_1',
4827
+ 'NSFoundationVersionNumber_iOS_6_0',
4828
+ 'NSFoundationVersionNumber_iOS_6_1',
4829
+ 'NSFoundationVersionNumber_iOS_7_0',
4830
+ 'NSFoundationVersionNumber_iOS_7_1',
4831
+ 'NSFoundationVersionNumber_iOS_8_0',
4832
+ 'NSFoundationVersionNumber_iOS_8_1',
4833
+ 'NSFoundationVersionNumber_iOS_8_2',
4834
+ 'NSFoundationVersionNumber_iOS_8_3',
4835
+ 'NSFoundationVersionNumber_iOS_8_4',
4836
+ 'NSFoundationVersionNumber_iOS_8_x_Max',
4837
+ 'NSFoundationVersionNumber_iOS_9_0',
4838
+ 'NSFoundationVersionNumber_iOS_9_1',
4839
+ 'NSFoundationVersionNumber_iOS_9_2',
4840
+ 'NSFoundationVersionNumber_iOS_9_3',
4841
+ 'NSFoundationVersionNumber_iOS_9_4',
4842
+ 'NSFoundationVersionNumber_iOS_9_x_Max',
4843
+ 'NSFoundationVersionNumber_iPhoneOS_2_0',
4844
+ 'NSFoundationVersionNumber_iPhoneOS_2_1',
4845
+ 'NSFoundationVersionNumber_iPhoneOS_2_2',
4846
+ 'NSFoundationVersionNumber_iPhoneOS_3_0',
4847
+ 'NSFoundationVersionNumber_iPhoneOS_3_1',
4848
+ 'NSFoundationVersionNumber_iPhoneOS_3_2',
4849
+ 'NSFoundationVersionWithFileManagerResourceForkSupport',
4850
+ 'NSFreeHashTable',
4851
+ 'NSFreeMapTable',
4852
+ 'NSGetUncaughtExceptionHandler',
4853
+ 'NSGregorianCalendar',
4854
+ 'NSHPUXOperatingSystem',
4855
+ 'NSHashGet',
4856
+ 'NSHashInsert',
4857
+ 'NSHashInsertIfAbsent',
4858
+ 'NSHashInsertKnownAbsent',
4859
+ 'NSHashRemove',
4860
+ 'NSHashTableCopyIn',
4861
+ 'NSHashTableObjectPointerPersonality',
4862
+ 'NSHashTableStrongMemory',
4863
+ 'NSHashTableWeakMemory',
4864
+ 'NSHebrewCalendar',
4865
+ 'NSHostByteOrder',
4866
+ 'NSISO2022JPStringEncoding',
4867
+ 'NSISO8601Calendar',
4868
+ 'NSISOLatin1StringEncoding',
4869
+ 'NSISOLatin2StringEncoding',
4870
+ 'NSIndianCalendar',
4871
+ 'NSIslamicCalendar',
4872
+ 'NSIslamicCivilCalendar',
4873
+ 'NSItemProviderPreferredImageSizeKey',
4874
+ 'NSJapaneseCalendar',
4875
+ 'NSJapaneseEUCStringEncoding',
4876
+ 'NSLoadedClasses',
4877
+ 'NSLocalizedFailureErrorKey',
4878
+ 'NSLogPageSize',
4879
+ 'NSMACHOperatingSystem',
4880
+ 'NSMacOSRomanStringEncoding',
4881
+ 'NSMapGet',
4882
+ 'NSMapInsert',
4883
+ 'NSMapInsertIfAbsent',
4884
+ 'NSMapInsertKnownAbsent',
4885
+ 'NSMapMember',
4886
+ 'NSMapRemove',
4887
+ 'NSMapTableCopyIn',
4888
+ 'NSMapTableObjectPointerPersonality',
4889
+ 'NSMapTableStrongMemory',
4890
+ 'NSMapTableWeakMemory',
4891
+ 'NSMetadataItemContentTypeKey',
4892
+ 'NSMetadataItemContentTypeTreeKey',
4893
+ 'NSMetadataItemDisplayNameKey',
4894
+ 'NSMetadataItemFSContentChangeDateKey',
4895
+ 'NSMetadataItemFSCreationDateKey',
4896
+ 'NSMetadataItemFSNameKey',
4897
+ 'NSMetadataItemFSSizeKey',
4898
+ 'NSMetadataItemIsUbiquitousKey',
4899
+ 'NSMetadataItemPathKey',
4900
+ 'NSMetadataItemURLKey',
4901
+ 'NSMetadataQueryAccessibleUbiquitousExternalDocumentsScope',
4902
+ 'NSMetadataQueryResultContentRelevanceAttribute',
4903
+ 'NSMetadataQueryUbiquitousDataScope',
4904
+ 'NSMetadataQueryUbiquitousDocumentsScope',
4905
+ 'NSMetadataQueryUpdateAddedItemsKey',
4906
+ 'NSMetadataQueryUpdateChangedItemsKey',
4907
+ 'NSMetadataQueryUpdateRemovedItemsKey',
4908
+ 'NSMetadataUbiquitousItemContainerDisplayNameKey',
4909
+ 'NSMetadataUbiquitousItemDownloadRequestedKey',
4910
+ 'NSMetadataUbiquitousItemDownloadingErrorKey',
4911
+ 'NSMetadataUbiquitousItemDownloadingStatusCurrent',
4912
+ 'NSMetadataUbiquitousItemDownloadingStatusDownloaded',
4913
+ 'NSMetadataUbiquitousItemDownloadingStatusKey',
4914
+ 'NSMetadataUbiquitousItemDownloadingStatusNotDownloaded',
4915
+ 'NSMetadataUbiquitousItemHasUnresolvedConflictsKey',
4916
+ 'NSMetadataUbiquitousItemIsDownloadingKey',
4917
+ 'NSMetadataUbiquitousItemIsExternalDocumentKey',
4918
+ 'NSMetadataUbiquitousItemIsSharedKey',
4919
+ 'NSMetadataUbiquitousItemIsUploadedKey',
4920
+ 'NSMetadataUbiquitousItemIsUploadingKey',
4921
+ 'NSMetadataUbiquitousItemPercentDownloadedKey',
4922
+ 'NSMetadataUbiquitousItemPercentUploadedKey',
4923
+ 'NSMetadataUbiquitousItemURLInLocalContainerKey',
4924
+ 'NSMetadataUbiquitousItemUploadingErrorKey',
4925
+ 'NSMetadataUbiquitousSharedItemCurrentUserPermissionsKey',
4926
+ 'NSMetadataUbiquitousSharedItemCurrentUserRoleKey',
4927
+ 'NSMetadataUbiquitousSharedItemMostRecentEditorNameComponentsKey',
4928
+ 'NSMetadataUbiquitousSharedItemOwnerNameComponentsKey',
4929
+ 'NSMetadataUbiquitousSharedItemPermissionsReadOnly',
4930
+ 'NSMetadataUbiquitousSharedItemPermissionsReadWrite',
4931
+ 'NSMetadataUbiquitousSharedItemRoleOwner',
4932
+ 'NSMetadataUbiquitousSharedItemRoleParticipant',
4933
+ 'NSMultipleUnderlyingErrorsKey',
4934
+ 'NSNEXTSTEPStringEncoding',
4935
+ 'NSNextHashEnumeratorItem',
4936
+ 'NSNextMapEnumeratorPair',
4937
+ 'NSNonLossyASCIIStringEncoding',
4938
+ 'NSNonOwnedPointerHashCallBacks',
4939
+ 'NSNonOwnedPointerMapKeyCallBacks',
4940
+ 'NSNonOwnedPointerMapValueCallBacks',
4941
+ 'NSNonOwnedPointerOrNullMapKeyCallBacks',
4942
+ 'NSNonRetainedObjectHashCallBacks',
4943
+ 'NSNonRetainedObjectMapKeyCallBacks',
4944
+ 'NSNonRetainedObjectMapValueCallBacks',
4945
+ 'NSOSF1OperatingSystem',
4946
+ 'NSObjectHashCallBacks',
4947
+ 'NSObjectMapKeyCallBacks',
4948
+ 'NSObjectMapValueCallBacks',
4949
+ 'NSOpenStepRootDirectory',
4950
+ 'NSOpenStepUnicodeReservedBase',
4951
+ 'NSOwnedObjectIdentityHashCallBacks',
4952
+ 'NSOwnedPointerHashCallBacks',
4953
+ 'NSOwnedPointerMapKeyCallBacks',
4954
+ 'NSOwnedPointerMapValueCallBacks',
4955
+ 'NSPersianCalendar',
4956
+ 'NSPointerToStructHashCallBacks',
4957
+ 'NSPropertyListErrorMaximum',
4958
+ 'NSPropertyListErrorMinimum',
4959
+ 'NSProprietaryStringEncoding',
4960
+ 'NSProtocolFromString',
4961
+ 'NSRepublicOfChinaCalendar',
4962
+ 'NSResetHashTable',
4963
+ 'NSResetMapTable',
4964
+ 'NSShiftJISStringEncoding',
4965
+ 'NSSolarisOperatingSystem',
4966
+ 'NSStringFromHashTable',
4967
+ 'NSStringFromMapTable',
4968
+ 'NSStringFromProtocol',
4969
+ 'NSSunOSOperatingSystem',
4970
+ 'NSSwapBigDoubleToHost',
4971
+ 'NSSwapBigFloatToHost',
4972
+ 'NSSwapBigIntToHost',
4973
+ 'NSSwapBigLongLongToHost',
4974
+ 'NSSwapBigLongToHost',
4975
+ 'NSSwapBigShortToHost',
4976
+ 'NSSwapDouble',
4977
+ 'NSSwapFloat',
4978
+ 'NSSwapHostDoubleToBig',
4979
+ 'NSSwapHostDoubleToLittle',
4980
+ 'NSSwapHostFloatToBig',
4981
+ 'NSSwapHostFloatToLittle',
4982
+ 'NSSwapHostIntToBig',
4983
+ 'NSSwapHostIntToLittle',
4984
+ 'NSSwapHostLongLongToBig',
4985
+ 'NSSwapHostLongLongToLittle',
4986
+ 'NSSwapHostLongToBig',
4987
+ 'NSSwapHostLongToLittle',
4988
+ 'NSSwapHostShortToBig',
4989
+ 'NSSwapHostShortToLittle',
4990
+ 'NSSwapInt',
4991
+ 'NSSwapLittleDoubleToHost',
4992
+ 'NSSwapLittleFloatToHost',
4993
+ 'NSSwapLittleIntToHost',
4994
+ 'NSSwapLittleLongLongToHost',
4995
+ 'NSSwapLittleLongToHost',
4996
+ 'NSSwapLittleShortToHost',
4997
+ 'NSSwapLong',
4998
+ 'NSSwapLongLong',
4999
+ 'NSSwapShort',
5000
+ 'NSSymbolStringEncoding',
5001
+ 'NSTextCheckingAllCustomTypes',
5002
+ 'NSTextCheckingAllSystemTypes',
5003
+ 'NSTextCheckingAllTypes',
5004
+ 'NSURLAuthenticationMethodHTMLForm',
5005
+ 'NSURLAuthenticationMethodNTLM',
5006
+ 'NSURLAuthenticationMethodNegotiate',
5007
+ 'NSURLCredentialStorageRemoveSynchronizableCredentials',
5008
+ 'NSURLErrorFileOutsideSafeArea',
5009
+ 'NSURLFileScheme',
5010
+ 'NSURLProtectionSpaceFTP',
5011
+ 'NSURLProtectionSpaceFTPProxy',
5012
+ 'NSURLProtectionSpaceHTTP',
5013
+ 'NSURLProtectionSpaceHTTPProxy',
5014
+ 'NSURLProtectionSpaceHTTPS',
5015
+ 'NSURLProtectionSpaceHTTPSProxy',
5016
+ 'NSURLProtectionSpaceSOCKSProxy',
5017
+ 'NSURLSessionDownloadTaskResumeData',
5018
+ 'NSURLSessionTransferSizeUnknown',
5019
+ 'NSURLSessionUploadTaskResumeData',
5020
+ 'NSUTF16BigEndianStringEncoding',
5021
+ 'NSUTF16LittleEndianStringEncoding',
5022
+ 'NSUTF16StringEncoding',
5023
+ 'NSUTF32BigEndianStringEncoding',
5024
+ 'NSUTF32LittleEndianStringEncoding',
5025
+ 'NSUTF32StringEncoding',
5026
+ 'NSUTF8StringEncoding',
5027
+ 'NSUbiquitousFileErrorMaximum',
5028
+ 'NSUbiquitousFileErrorMinimum',
5029
+ 'NSUbiquitousKeyValueStoreAccountChange',
5030
+ 'NSUbiquitousKeyValueStoreChangeReasonKey',
5031
+ 'NSUbiquitousKeyValueStoreChangedKeysKey',
5032
+ 'NSUbiquitousKeyValueStoreInitialSyncChange',
5033
+ 'NSUbiquitousKeyValueStoreQuotaViolationChange',
5034
+ 'NSUbiquitousKeyValueStoreServerChange',
5035
+ 'NSUndefinedDateComponent',
5036
+ 'NSUndoCloseGroupingRunLoopOrdering',
5037
+ 'NSUndoManagerGroupIsDiscardableKey',
5038
+ 'NSUnicodeStringEncoding',
5039
+ 'NSUserActivityErrorMaximum',
5040
+ 'NSUserActivityErrorMinimum',
5041
+ 'NSUserActivityTypeBrowsingWeb',
5042
+ 'NSValidationErrorMaximum',
5043
+ 'NSValidationErrorMinimum',
5044
+ 'NSWindows95OperatingSystem',
5045
+ 'NSWindowsCP1250StringEncoding',
5046
+ 'NSWindowsCP1251StringEncoding',
5047
+ 'NSWindowsCP1252StringEncoding',
5048
+ 'NSWindowsCP1253StringEncoding',
5049
+ 'NSWindowsCP1254StringEncoding',
5050
+ 'NSWindowsNTOperatingSystem',
5051
+ 'NSWrapCalendarComponents',
5052
+ 'NSXPCConnectionCodeSigningRequirementFailure',
5053
+ 'NSXPCConnectionErrorMaximum',
5054
+ 'NSXPCConnectionErrorMinimum',
5055
+ 'NS_BigEndian',
5056
+ 'NS_LittleEndian',
5057
+ 'NS_UnknownByteOrder',
5058
+ 'kCFStringEncodingASCII',
5059
+ ])
5060
+
5061
+ const CORE_FOUNDATION_OVERLAY_GLOBALS = new Set([
5062
+ 'kCFCoreFoundationVersionNumber10_0',
5063
+ 'kCFCoreFoundationVersionNumber10_0_3',
5064
+ 'kCFCoreFoundationVersionNumber10_1',
5065
+ 'kCFCoreFoundationVersionNumber10_10',
5066
+ 'kCFCoreFoundationVersionNumber10_10_1',
5067
+ 'kCFCoreFoundationVersionNumber10_10_2',
5068
+ 'kCFCoreFoundationVersionNumber10_10_3',
5069
+ 'kCFCoreFoundationVersionNumber10_10_4',
5070
+ 'kCFCoreFoundationVersionNumber10_10_5',
5071
+ 'kCFCoreFoundationVersionNumber10_10_Max',
5072
+ 'kCFCoreFoundationVersionNumber10_11',
5073
+ 'kCFCoreFoundationVersionNumber10_11_1',
5074
+ 'kCFCoreFoundationVersionNumber10_11_2',
5075
+ 'kCFCoreFoundationVersionNumber10_11_3',
5076
+ 'kCFCoreFoundationVersionNumber10_11_4',
5077
+ 'kCFCoreFoundationVersionNumber10_11_Max',
5078
+ 'kCFCoreFoundationVersionNumber10_1_1',
5079
+ 'kCFCoreFoundationVersionNumber10_1_2',
5080
+ 'kCFCoreFoundationVersionNumber10_1_3',
5081
+ 'kCFCoreFoundationVersionNumber10_1_4',
5082
+ 'kCFCoreFoundationVersionNumber10_2',
5083
+ 'kCFCoreFoundationVersionNumber10_2_1',
5084
+ 'kCFCoreFoundationVersionNumber10_2_2',
5085
+ 'kCFCoreFoundationVersionNumber10_2_3',
5086
+ 'kCFCoreFoundationVersionNumber10_2_4',
5087
+ 'kCFCoreFoundationVersionNumber10_2_5',
5088
+ 'kCFCoreFoundationVersionNumber10_2_6',
5089
+ 'kCFCoreFoundationVersionNumber10_2_7',
5090
+ 'kCFCoreFoundationVersionNumber10_2_8',
5091
+ 'kCFCoreFoundationVersionNumber10_3',
5092
+ 'kCFCoreFoundationVersionNumber10_3_1',
5093
+ 'kCFCoreFoundationVersionNumber10_3_2',
5094
+ 'kCFCoreFoundationVersionNumber10_3_3',
5095
+ 'kCFCoreFoundationVersionNumber10_3_4',
5096
+ 'kCFCoreFoundationVersionNumber10_3_5',
5097
+ 'kCFCoreFoundationVersionNumber10_3_6',
5098
+ 'kCFCoreFoundationVersionNumber10_3_7',
5099
+ 'kCFCoreFoundationVersionNumber10_3_8',
5100
+ 'kCFCoreFoundationVersionNumber10_3_9',
5101
+ 'kCFCoreFoundationVersionNumber10_4',
5102
+ 'kCFCoreFoundationVersionNumber10_4_1',
5103
+ 'kCFCoreFoundationVersionNumber10_4_10',
5104
+ 'kCFCoreFoundationVersionNumber10_4_11',
5105
+ 'kCFCoreFoundationVersionNumber10_4_2',
5106
+ 'kCFCoreFoundationVersionNumber10_4_3',
5107
+ 'kCFCoreFoundationVersionNumber10_4_4_Intel',
5108
+ 'kCFCoreFoundationVersionNumber10_4_4_PowerPC',
5109
+ 'kCFCoreFoundationVersionNumber10_4_5_Intel',
5110
+ 'kCFCoreFoundationVersionNumber10_4_5_PowerPC',
5111
+ 'kCFCoreFoundationVersionNumber10_4_6_Intel',
5112
+ 'kCFCoreFoundationVersionNumber10_4_6_PowerPC',
5113
+ 'kCFCoreFoundationVersionNumber10_4_7',
5114
+ 'kCFCoreFoundationVersionNumber10_4_8',
5115
+ 'kCFCoreFoundationVersionNumber10_4_9',
5116
+ 'kCFCoreFoundationVersionNumber10_5',
5117
+ 'kCFCoreFoundationVersionNumber10_5_1',
5118
+ 'kCFCoreFoundationVersionNumber10_5_2',
5119
+ 'kCFCoreFoundationVersionNumber10_5_3',
5120
+ 'kCFCoreFoundationVersionNumber10_5_4',
5121
+ 'kCFCoreFoundationVersionNumber10_5_5',
5122
+ 'kCFCoreFoundationVersionNumber10_5_6',
5123
+ 'kCFCoreFoundationVersionNumber10_5_7',
5124
+ 'kCFCoreFoundationVersionNumber10_5_8',
5125
+ 'kCFCoreFoundationVersionNumber10_6',
5126
+ 'kCFCoreFoundationVersionNumber10_6_1',
5127
+ 'kCFCoreFoundationVersionNumber10_6_2',
5128
+ 'kCFCoreFoundationVersionNumber10_6_3',
5129
+ 'kCFCoreFoundationVersionNumber10_6_4',
5130
+ 'kCFCoreFoundationVersionNumber10_6_5',
5131
+ 'kCFCoreFoundationVersionNumber10_6_6',
5132
+ 'kCFCoreFoundationVersionNumber10_6_7',
5133
+ 'kCFCoreFoundationVersionNumber10_6_8',
5134
+ 'kCFCoreFoundationVersionNumber10_7',
5135
+ 'kCFCoreFoundationVersionNumber10_7_1',
5136
+ 'kCFCoreFoundationVersionNumber10_7_2',
5137
+ 'kCFCoreFoundationVersionNumber10_7_3',
5138
+ 'kCFCoreFoundationVersionNumber10_7_4',
5139
+ 'kCFCoreFoundationVersionNumber10_7_5',
5140
+ 'kCFCoreFoundationVersionNumber10_8',
5141
+ 'kCFCoreFoundationVersionNumber10_8_1',
5142
+ 'kCFCoreFoundationVersionNumber10_8_2',
5143
+ 'kCFCoreFoundationVersionNumber10_8_3',
5144
+ 'kCFCoreFoundationVersionNumber10_8_4',
5145
+ 'kCFCoreFoundationVersionNumber10_9',
5146
+ 'kCFCoreFoundationVersionNumber10_9_1',
5147
+ 'kCFCoreFoundationVersionNumber10_9_2',
5148
+ 'kCFCoreFoundationVersionNumber_iOS_4_0',
5149
+ 'kCFCoreFoundationVersionNumber_iOS_4_1',
5150
+ 'kCFCoreFoundationVersionNumber_iOS_4_2',
5151
+ 'kCFCoreFoundationVersionNumber_iOS_4_3',
5152
+ 'kCFCoreFoundationVersionNumber_iOS_5_0',
5153
+ 'kCFCoreFoundationVersionNumber_iOS_5_1',
5154
+ 'kCFCoreFoundationVersionNumber_iOS_6_0',
5155
+ 'kCFCoreFoundationVersionNumber_iOS_6_1',
5156
+ 'kCFCoreFoundationVersionNumber_iOS_7_0',
5157
+ 'kCFCoreFoundationVersionNumber_iOS_7_1',
5158
+ 'kCFCoreFoundationVersionNumber_iOS_8_0',
5159
+ 'kCFCoreFoundationVersionNumber_iOS_8_1',
5160
+ 'kCFCoreFoundationVersionNumber_iOS_8_2',
5161
+ 'kCFCoreFoundationVersionNumber_iOS_8_3',
5162
+ 'kCFCoreFoundationVersionNumber_iOS_8_4',
5163
+ 'kCFCoreFoundationVersionNumber_iOS_8_x_Max',
5164
+ 'kCFCoreFoundationVersionNumber_iOS_9_0',
5165
+ 'kCFCoreFoundationVersionNumber_iOS_9_1',
5166
+ 'kCFCoreFoundationVersionNumber_iOS_9_2',
5167
+ 'kCFCoreFoundationVersionNumber_iOS_9_3',
5168
+ 'kCFCoreFoundationVersionNumber_iOS_9_4',
5169
+ 'kCFCoreFoundationVersionNumber_iOS_9_x_Max',
5170
+ 'kCFCoreFoundationVersionNumber_iPhoneOS_2_0',
5171
+ 'kCFCoreFoundationVersionNumber_iPhoneOS_2_1',
5172
+ 'kCFCoreFoundationVersionNumber_iPhoneOS_2_2',
5173
+ 'kCFCoreFoundationVersionNumber_iPhoneOS_3_0',
5174
+ 'kCFCoreFoundationVersionNumber_iPhoneOS_3_1',
5175
+ 'kCFCoreFoundationVersionNumber_iPhoneOS_3_2',
5176
+ ])
5177
+
5178
+ // the Darwin CoreFoundation overlay exposes Foundation's geometry identities.
5179
+ const CORE_FOUNDATION_GEOMETRY_TYPES = new Set([
5180
+ 'CGFloat',
5181
+ 'CGPoint',
5182
+ 'CGSize',
5183
+ 'CGRect',
5184
+ 'CGRectEdge',
5185
+ ])
5186
+
5187
+ const CORE_FOUNDATION_GRAPHICS_TYPES = new Set([
5188
+ 'CGAffineTransform',
5189
+ 'CGAffineTransformComponents',
5190
+ 'CGVector',
5191
+ ])
5192
+
5193
+ // scoped imports select native CF handles over overlay bridge aliases without
5194
+ // rewriting references or changing the overlay's measured storage contracts.
5195
+ const CORE_FOUNDATION_HANDLE_IMPORTS = [
5196
+ 'CFAllocator',
5197
+ 'CFArray',
5198
+ 'CFAttributedString',
5199
+ 'CFBoolean',
5200
+ 'CFData',
5201
+ 'CFDate',
5202
+ 'CFDictionary',
5203
+ 'CFError',
5204
+ 'CFMutableData',
5205
+ 'CFNumber',
5206
+ 'CFSet',
5207
+ 'CFString',
5208
+ 'CFURL',
5209
+ ]
5210
+ .map((name) => `import class CoreFoundation.${name}`)
5211
+ .concat([
5212
+ 'import typealias CoreFoundation.CFPropertyList',
5213
+ 'import typealias CoreFoundation.CFTypeRef',
5214
+ 'import CoreGraphics',
5215
+ ])
5216
+ .join('; ')
5217
+
4477
5218
  export function swiftSourceAsIOS(
4478
5219
  original: string,
4479
5220
  extraObjCExtensions?: Map<string, Set<string>>,
@@ -4539,25 +5280,80 @@ export function swiftSourceAsIOS(
4539
5280
  if (imported) {
4540
5281
  out +=
4541
5282
  conditioned.slice(copied, at) + `import ${imported[1]}`.padEnd(imported[0].length)
5283
+ if (imported[1] === 'CoreFoundation') out += `; ${CORE_FOUNDATION_HANDLE_IMPORTS}`
4542
5284
  copied = at + imported[0].length
4543
5285
  continue
4544
5286
  }
5287
+ const coreFoundationImport = /^import\s+CoreFoundation\b/.exec(rest)
5288
+ if (coreFoundationImport) {
5289
+ out +=
5290
+ conditioned.slice(copied, at) +
5291
+ coreFoundationImport[0] +
5292
+ `; ${CORE_FOUNDATION_HANDLE_IMPORTS}`
5293
+ copied = at + coreFoundationImport[0].length
5294
+ continue
5295
+ }
4545
5296
  if (/^NSClassFromString\b/.test(rest)) {
4546
5297
  out += conditioned.slice(copied, at) + '_peachClassFromString'
4547
5298
  copied = at + 'NSClassFromString'.length
4548
5299
  continue
4549
5300
  }
4550
- // darwin exports these types from Foundation; wasm leaves unavailable
4551
- // aliases there and their implementation lives in networking.
4552
- if (
4553
- /^Foundation\s*\.\s*(?:HTTPURLResponse|URLAuthenticationChallenge|URLAuthenticationChallengeSender|URLCredential|URLProtectionSpace|URLRequest|URLResponse|URLSession)\b/.test(
4554
- rest,
5301
+ // darwin exposes these names through Foundation; the guest keeps networking
5302
+ // and overlay declarations in their owning modules.
5303
+ const foundationMember =
5304
+ /^Foundation\s*\.\s*(?:`([A-Za-z_]\w*)`|([A-Za-z_]\w*)\b)/.exec(rest)
5305
+ const foundationName = foundationMember?.[1] ?? foundationMember?.[2]
5306
+ let foundationOwner: string | undefined
5307
+ if (foundationName !== undefined) {
5308
+ if (
5309
+ foundationName === 'NSClassFromString' ||
5310
+ foundationName === 'NSKeyValueChange' ||
5311
+ foundationName === 'NSKeyValueObservedChange' ||
5312
+ foundationName === 'NSKeyValueObservation'
4555
5313
  )
4556
- ) {
4557
- out += conditioned.slice(copied, at) + 'FoundationNetworking'
5314
+ foundationOwner = 'PeachObjC'
5315
+ else if (foundationName === 'DispatchData') foundationOwner = 'Dispatch'
5316
+ else if (FOUNDATION_NETWORKING_TYPES.has(foundationName))
5317
+ foundationOwner = 'FoundationNetworking'
5318
+ else if (
5319
+ FOUNDATION_OVERLAY_TYPES.has(foundationName) ||
5320
+ FOUNDATION_OVERLAY_GLOBALS.has(foundationName) ||
5321
+ CORE_FOUNDATION_OVERLAY_GLOBALS.has(foundationName)
5322
+ )
5323
+ foundationOwner = 'PeachFoundation'
5324
+ }
5325
+ if (foundationOwner !== undefined) {
5326
+ out += conditioned.slice(copied, at) + foundationOwner
4558
5327
  copied = at + 'Foundation'.length
4559
5328
  continue
4560
5329
  }
5330
+ const coreFoundationMember =
5331
+ /^CoreFoundation\s*\.\s*(?:`([A-Za-z_]\w*)`|([A-Za-z_]\w*)\b)/.exec(rest)
5332
+ const coreFoundationName = coreFoundationMember?.[1] ?? coreFoundationMember?.[2]
5333
+ if (
5334
+ coreFoundationName !== undefined &&
5335
+ CORE_FOUNDATION_OVERLAY_GLOBALS.has(coreFoundationName)
5336
+ ) {
5337
+ out += conditioned.slice(copied, at) + 'PeachFoundation'
5338
+ copied = at + 'CoreFoundation'.length
5339
+ continue
5340
+ }
5341
+ if (
5342
+ coreFoundationName !== undefined &&
5343
+ CORE_FOUNDATION_GEOMETRY_TYPES.has(coreFoundationName)
5344
+ ) {
5345
+ out += conditioned.slice(copied, at) + 'Foundation'
5346
+ copied = at + 'CoreFoundation'.length
5347
+ continue
5348
+ }
5349
+ if (
5350
+ coreFoundationName !== undefined &&
5351
+ CORE_FOUNDATION_GRAPHICS_TYPES.has(coreFoundationName)
5352
+ ) {
5353
+ out += conditioned.slice(copied, at) + 'CoreGraphics'
5354
+ copied = at + 'CoreFoundation'.length
5355
+ continue
5356
+ }
4561
5357
  if (rest.startsWith('class')) {
4562
5358
  const declared = CLASS_BASE.exec(rest)
4563
5359
  if (declared && reusableViews.has(declared[2]!.split('.').pop()!)) {
@@ -4823,7 +5619,9 @@ function swiftCodeScan(source: string): {
4823
5619
  ? 'NSClassFromString'
4824
5620
  : source.startsWith('Foundation', i)
4825
5621
  ? 'Foundation'
4826
- : null
5622
+ : source.startsWith('CoreFoundation', i)
5623
+ ? 'CoreFoundation'
5624
+ : null
4827
5625
  if (
4828
5626
  keyword &&
4829
5627
  !/[\w$]/.test(source[i - 1] ?? '') &&
@@ -5209,6 +6007,7 @@ function projectDiagnostic(
5209
6007
  const prefix = `${base}${path.sep}`
5210
6008
  return designTimeDiagnostic(output, files)
5211
6009
  .split('\n')
6010
+ .filter((line) => !SWIFTPM_NOISE.test(line))
5212
6011
  .map((line) => (line.startsWith(prefix) ? line.slice(prefix.length) : line))
5213
6012
  .join('\n')
5214
6013
  .trim()
@@ -5390,7 +6189,9 @@ export function compileSwiftProjectUnit(
5390
6189
  hash,
5391
6190
  release: options.release,
5392
6191
  timeoutMs: options.timeoutMs,
5393
- buildKey: createHash('sha256').update(root).digest('hex').slice(0, 32),
6192
+ // framework sources and compiler inputs own the shared object tree;
6193
+ // unrelated app edits reuse it without retaining stale private ABI.
6194
+ buildKey: swiftProjectBuildKey(moduleRoot, options.release),
5394
6195
  }),
5395
6196
  )
5396
6197
  try {
@@ -5451,12 +6252,14 @@ export function compileSwiftProjectUnit(
5451
6252
  const icu = swiftIcuAsset(options.toolchainBin, sdk)
5452
6253
  const buildArgs = [
5453
6254
  'build',
6255
+ ...swiftPackageCacheOptions(),
5454
6256
  '--build-system',
5455
6257
  'native',
5456
6258
  '-j',
5457
6259
  BUILD_JOBS,
5458
6260
  '--package-path',
5459
6261
  root,
6262
+ ...swiftSdkOptions(),
5460
6263
  '--swift-sdk',
5461
6264
  sdk,
5462
6265
  '-c',
@@ -5496,7 +6299,7 @@ export function compileSwiftProjectUnit(
5496
6299
  }
5497
6300
  report('compiling and linking Swift modules')
5498
6301
  try {
5499
- await runCompiler(swift, buildArgs, buildOptions, true)
6302
+ await runCompiler(swift, buildArgs, buildOptions, SWIFTPM_PROGRESS, SWIFTPM_NOISE)
5500
6303
  } catch (error) {
5501
6304
  const output = outputOf(error)
5502
6305
  const moduleCache = path.join(
@@ -5512,7 +6315,13 @@ export function compileSwiftProjectUnit(
5512
6315
  ) {
5513
6316
  rmSync(moduleCache, { recursive: true, force: true })
5514
6317
  try {
5515
- await runCompiler(swift, buildArgs, buildOptions, true)
6318
+ await runCompiler(
6319
+ swift,
6320
+ buildArgs,
6321
+ buildOptions,
6322
+ SWIFTPM_PROGRESS,
6323
+ SWIFTPM_NOISE,
6324
+ )
5516
6325
  } catch (retryError) {
5517
6326
  throw new Error(
5518
6327
  projectDiagnostic(outputOf(retryError), layout, input.files),