@scriptc/compiler 0.4.8 → 0.4.9

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 (536) hide show
  1. package/ambient/node-fallback/buffer.d.ts +2 -0
  2. package/ambient/node-fallback/child_process.d.ts +9 -3
  3. package/ambient/node-fallback/dns-promises.d.ts +25 -0
  4. package/ambient/node-fallback/dns.d.ts +29 -0
  5. package/ambient/node-fallback/test.d.ts +7 -0
  6. package/ambient/scriptc-node-fallback.d.ts +145 -2
  7. package/ambient/scriptc-overrides.d.ts +22 -13
  8. package/dist/backend/build-cache.d.ts +1 -1
  9. package/dist/backend/build-cache.js +1 -1
  10. package/dist/backend/build-cache.js.map +1 -1
  11. package/dist/backend/cache-root.d.ts +7 -0
  12. package/dist/backend/cache-root.js +27 -0
  13. package/dist/backend/cache-root.js.map +1 -1
  14. package/dist/backend/executable-features.js +5 -1
  15. package/dist/backend/executable-features.js.map +1 -1
  16. package/dist/backend/link-plan.js +7 -1
  17. package/dist/backend/link-plan.js.map +1 -1
  18. package/dist/backend/llvm/bytes-loop-versions.d.ts +12 -1
  19. package/dist/backend/llvm/bytes-loop-versions.js +107 -30
  20. package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
  21. package/dist/backend/llvm/bytes-loop-versions.test.js +96 -0
  22. package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
  23. package/dist/backend/llvm/checked-value-lifetimes.js +1 -0
  24. package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
  25. package/dist/backend/llvm/classes.d.ts +16 -5
  26. package/dist/backend/llvm/classes.js +34 -6
  27. package/dist/backend/llvm/classes.js.map +1 -1
  28. package/dist/backend/llvm/classes.test.js +21 -2
  29. package/dist/backend/llvm/classes.test.js.map +1 -1
  30. package/dist/backend/llvm/common.d.ts +9 -0
  31. package/dist/backend/llvm/common.js +9 -0
  32. package/dist/backend/llvm/common.js.map +1 -1
  33. package/dist/backend/llvm/cpu-dispatch.d.ts +36 -2
  34. package/dist/backend/llvm/cpu-dispatch.js +96 -2
  35. package/dist/backend/llvm/cpu-dispatch.js.map +1 -1
  36. package/dist/backend/llvm/dense-array-access.d.ts +5 -2
  37. package/dist/backend/llvm/dense-array-access.js +16 -12
  38. package/dist/backend/llvm/dense-array-access.js.map +1 -1
  39. package/dist/backend/llvm/dense-array-access.test.js +3 -1
  40. package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
  41. package/dist/backend/llvm/dyn.d.ts +24 -0
  42. package/dist/backend/llvm/dyn.js +117 -3
  43. package/dist/backend/llvm/dyn.js.map +1 -1
  44. package/dist/backend/llvm/emit-function.js +6 -0
  45. package/dist/backend/llvm/emit-function.js.map +1 -1
  46. package/dist/backend/llvm/emit-journal.d.ts +1 -0
  47. package/dist/backend/llvm/emit-journal.js.map +1 -1
  48. package/dist/backend/llvm/emit-module.js +48 -5
  49. package/dist/backend/llvm/emit-module.js.map +1 -1
  50. package/dist/backend/llvm/emit-module.test.js +41 -0
  51. package/dist/backend/llvm/emit-module.test.js.map +1 -1
  52. package/dist/backend/llvm/emit-statements.js +11 -0
  53. package/dist/backend/llvm/emit-statements.js.map +1 -1
  54. package/dist/backend/llvm/emitter.d.ts +87 -7
  55. package/dist/backend/llvm/emitter.js +136 -15
  56. package/dist/backend/llvm/emitter.js.map +1 -1
  57. package/dist/backend/llvm/expr-async.js +28 -6
  58. package/dist/backend/llvm/expr-async.js.map +1 -1
  59. package/dist/backend/llvm/expr-containers.js +19 -5
  60. package/dist/backend/llvm/expr-containers.js.map +1 -1
  61. package/dist/backend/llvm/expr-dynamic.js +29 -1
  62. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  63. package/dist/backend/llvm/expr-primitives.js +104 -6
  64. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  65. package/dist/backend/llvm/expr-records.js +15 -1
  66. package/dist/backend/llvm/expr-records.js.map +1 -1
  67. package/dist/backend/llvm/expr-stream-bridges.js +53 -5
  68. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  69. package/dist/backend/llvm/inline-arrays.js +1 -1
  70. package/dist/backend/llvm/inline-arrays.js.map +1 -1
  71. package/dist/backend/llvm/js-ic.js +126 -2
  72. package/dist/backend/llvm/js-ic.js.map +1 -1
  73. package/dist/backend/llvm/lanes.d.ts +38 -0
  74. package/dist/backend/llvm/lanes.js +778 -0
  75. package/dist/backend/llvm/lanes.js.map +1 -0
  76. package/dist/backend/llvm/lanes.test.d.ts +1 -0
  77. package/dist/backend/llvm/lanes.test.js +402 -0
  78. package/dist/backend/llvm/lanes.test.js.map +1 -0
  79. package/dist/backend/llvm/lib-dispatch.js +9 -4
  80. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  81. package/dist/backend/llvm/lib-network.js +20 -0
  82. package/dist/backend/llvm/lib-network.js.map +1 -1
  83. package/dist/backend/llvm/lib-shared.js +27 -0
  84. package/dist/backend/llvm/lib-shared.js.map +1 -1
  85. package/dist/backend/llvm/lib-test.js +11 -0
  86. package/dist/backend/llvm/lib-test.js.map +1 -1
  87. package/dist/backend/llvm/local-array-reads.js +2 -2
  88. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  89. package/dist/backend/llvm/map-number-lookup.js +8 -2
  90. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  91. package/dist/backend/llvm/nullable-unions.js +5 -2
  92. package/dist/backend/llvm/nullable-unions.js.map +1 -1
  93. package/dist/backend/llvm/publish.d.ts +3 -0
  94. package/dist/backend/llvm/publish.js +2 -2
  95. package/dist/backend/llvm/publish.js.map +1 -1
  96. package/dist/backend/llvm/reference-writes.js +1 -0
  97. package/dist/backend/llvm/reference-writes.js.map +1 -1
  98. package/dist/backend/llvm/region-groups.js +43 -4
  99. package/dist/backend/llvm/region-groups.js.map +1 -1
  100. package/dist/backend/llvm/region-groups.test.js +79 -0
  101. package/dist/backend/llvm/region-groups.test.js.map +1 -1
  102. package/dist/backend/llvm/runtime-registries.test.js +32 -1
  103. package/dist/backend/llvm/runtime-registries.test.js.map +1 -1
  104. package/dist/backend/llvm/shapes.js +10 -1
  105. package/dist/backend/llvm/shapes.js.map +1 -1
  106. package/dist/backend/llvm/string-reads.d.ts +1 -1
  107. package/dist/backend/llvm/string-reads.js +1 -1
  108. package/dist/backend/llvm/string-reads.js.map +1 -1
  109. package/dist/backend/llvm/unwind-abi.js +24 -2
  110. package/dist/backend/llvm/unwind-abi.js.map +1 -1
  111. package/dist/backend/llvm/unwind-abi.test.js +38 -0
  112. package/dist/backend/llvm/unwind-abi.test.js.map +1 -1
  113. package/dist/backend/llvm/walkers.d.ts +3 -0
  114. package/dist/backend/llvm/walkers.js +20 -2
  115. package/dist/backend/llvm/walkers.js.map +1 -1
  116. package/dist/backend/native/contracts.d.ts +15 -3
  117. package/dist/backend/native/executable.js +19 -5
  118. package/dist/backend/native/executable.js.map +1 -1
  119. package/dist/backend/native-codegen-core.d.ts +20 -0
  120. package/dist/backend/native-codegen-core.js +15 -0
  121. package/dist/backend/native-codegen-core.js.map +1 -1
  122. package/dist/backend/native-codegen.d.ts +5 -0
  123. package/dist/backend/native-codegen.js +62 -8
  124. package/dist/backend/native-codegen.js.map +1 -1
  125. package/dist/backend/native-codegen.test.js +48 -8
  126. package/dist/backend/native-codegen.test.js.map +1 -1
  127. package/dist/backend/native-link-info-core.d.ts +27 -3
  128. package/dist/backend/native-link-info-core.js.map +1 -1
  129. package/dist/backend/native-link-info.test.js +17 -1
  130. package/dist/backend/native-link-info.test.js.map +1 -1
  131. package/dist/backend/native-toolchain.d.ts +1 -1
  132. package/dist/backend/native-toolchain.js +1 -1
  133. package/dist/backend/native-toolchain.js.map +1 -1
  134. package/dist/backend/native-toolchain.test.js +14 -1
  135. package/dist/backend/native-toolchain.test.js.map +1 -1
  136. package/dist/backend/runtime-pack-core.d.ts +9 -3
  137. package/dist/backend/runtime-pack-core.js +6 -1
  138. package/dist/backend/runtime-pack-core.js.map +1 -1
  139. package/dist/backend/runtime-pack.test.js +32 -1
  140. package/dist/backend/runtime-pack.test.js.map +1 -1
  141. package/dist/backend/targets.d.ts +9 -1
  142. package/dist/backend/targets.js +11 -2
  143. package/dist/backend/targets.js.map +1 -1
  144. package/dist/backend/targets.test.js +6 -0
  145. package/dist/backend/targets.test.js.map +1 -1
  146. package/dist/cli/command.js +15 -1
  147. package/dist/cli/command.js.map +1 -1
  148. package/dist/cli/host.d.ts +6 -0
  149. package/dist/cli/mcp.d.ts +72 -0
  150. package/dist/cli/mcp.js +601 -0
  151. package/dist/cli/mcp.js.map +1 -0
  152. package/dist/cli/mcp.test.d.ts +1 -0
  153. package/dist/cli/mcp.test.js +380 -0
  154. package/dist/cli/mcp.test.js.map +1 -0
  155. package/dist/cli/output-options.d.ts +1 -0
  156. package/dist/cli/output-options.js +3 -0
  157. package/dist/cli/output-options.js.map +1 -1
  158. package/dist/cli/usage.d.ts +51 -1
  159. package/dist/cli/usage.js +709 -186
  160. package/dist/cli/usage.js.map +1 -1
  161. package/dist/compat/fetch-profile.js +9 -4
  162. package/dist/compat/fetch-profile.js.map +1 -1
  163. package/dist/compile-types.d.ts +17 -0
  164. package/dist/coverage/report.d.ts +5 -9
  165. package/dist/coverage/report.js.map +1 -1
  166. package/dist/executable/executable-cache.d.ts +17 -3
  167. package/dist/executable/executable-cache.js +17 -3
  168. package/dist/executable/executable-cache.js.map +1 -1
  169. package/dist/executable/prepare.js +87 -10
  170. package/dist/executable/prepare.js.map +1 -1
  171. package/dist/frontend/analysis.js +3 -2
  172. package/dist/frontend/analysis.js.map +1 -1
  173. package/dist/frontend/canon-map.js +13 -8
  174. package/dist/frontend/canon-map.js.map +1 -1
  175. package/dist/frontend/decl-projection.d.ts +18 -0
  176. package/dist/frontend/decl-projection.js +90 -22
  177. package/dist/frontend/decl-projection.js.map +1 -1
  178. package/dist/frontend/decl-projection.test.js +47 -1
  179. package/dist/frontend/decl-projection.test.js.map +1 -1
  180. package/dist/frontend/default-library.d.ts +10 -0
  181. package/dist/frontend/default-library.js +43 -0
  182. package/dist/frontend/default-library.js.map +1 -0
  183. package/dist/frontend/fork-target.js +54 -9
  184. package/dist/frontend/fork-target.js.map +1 -1
  185. package/dist/frontend/fork-target.test.js +82 -0
  186. package/dist/frontend/fork-target.test.js.map +1 -1
  187. package/dist/frontend/inferred-js-diagnostics.test.js +73 -0
  188. package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -1
  189. package/dist/frontend/lowering/abstract-equality.d.ts +2 -1
  190. package/dist/frontend/lowering/abstract-equality.js +7 -1
  191. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  192. package/dist/frontend/lowering/array-values.js +2 -2
  193. package/dist/frontend/lowering/array-values.js.map +1 -1
  194. package/dist/frontend/lowering/assertion-members.js +52 -2
  195. package/dist/frontend/lowering/assertion-members.js.map +1 -1
  196. package/dist/frontend/lowering/builtin-namespaces.d.ts +5 -0
  197. package/dist/frontend/lowering/builtin-namespaces.js +19 -12
  198. package/dist/frontend/lowering/builtin-namespaces.js.map +1 -1
  199. package/dist/frontend/lowering/builtins/callable-aliases.js +42 -6
  200. package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
  201. package/dist/frontend/lowering/builtins/child-process.d.ts +12 -11
  202. package/dist/frontend/lowering/builtins/child-process.js +235 -38
  203. package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
  204. package/dist/frontend/lowering/builtins/compression.d.ts +6 -1
  205. package/dist/frontend/lowering/builtins/compression.js +3 -3
  206. package/dist/frontend/lowering/builtins/compression.js.map +1 -1
  207. package/dist/frontend/lowering/builtins/constants.js +2 -2
  208. package/dist/frontend/lowering/builtins/constants.js.map +1 -1
  209. package/dist/frontend/lowering/builtins/crypto.d.ts +3 -1
  210. package/dist/frontend/lowering/builtins/crypto.js +9 -1
  211. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  212. package/dist/frontend/lowering/builtins/dates.js +26 -6
  213. package/dist/frontend/lowering/builtins/dates.js.map +1 -1
  214. package/dist/frontend/lowering/builtins/environment.d.ts +13 -1
  215. package/dist/frontend/lowering/builtins/environment.js +15 -4
  216. package/dist/frontend/lowering/builtins/environment.js.map +1 -1
  217. package/dist/frontend/lowering/builtins/module-bindings.d.ts +33 -0
  218. package/dist/frontend/lowering/builtins/module-bindings.js +213 -11
  219. package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
  220. package/dist/frontend/lowering/builtins/module-resolution.d.ts +9 -2
  221. package/dist/frontend/lowering/builtins/module-resolution.js +187 -19
  222. package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
  223. package/dist/frontend/lowering/builtins/performance.js +1 -1
  224. package/dist/frontend/lowering/builtins/performance.js.map +1 -1
  225. package/dist/frontend/lowering/builtins/process.js +40 -2
  226. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  227. package/dist/frontend/lowering/builtins/promises.js +33 -0
  228. package/dist/frontend/lowering/builtins/promises.js.map +1 -1
  229. package/dist/frontend/lowering/builtins/readline.d.ts +9 -5
  230. package/dist/frontend/lowering/builtins/readline.js +184 -75
  231. package/dist/frontend/lowering/builtins/readline.js.map +1 -1
  232. package/dist/frontend/lowering/builtins/url.d.ts +4 -0
  233. package/dist/frontend/lowering/builtins/url.js +6 -0
  234. package/dist/frontend/lowering/builtins/url.js.map +1 -1
  235. package/dist/frontend/lowering/call-arguments.js +15 -0
  236. package/dist/frontend/lowering/call-arguments.js.map +1 -1
  237. package/dist/frontend/lowering/callable-properties.d.ts +34 -0
  238. package/dist/frontend/lowering/callable-properties.js +210 -0
  239. package/dist/frontend/lowering/callable-properties.js.map +1 -0
  240. package/dist/frontend/lowering/cjs-inline-require.d.ts +16 -0
  241. package/dist/frontend/lowering/cjs-inline-require.js +105 -0
  242. package/dist/frontend/lowering/cjs-inline-require.js.map +1 -1
  243. package/dist/frontend/lowering/cjs-inline-require.test.d.ts +1 -0
  244. package/dist/frontend/lowering/cjs-inline-require.test.js +61 -0
  245. package/dist/frontend/lowering/cjs-inline-require.test.js.map +1 -0
  246. package/dist/frontend/lowering/class-dynamic-dispatch.js +82 -2
  247. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  248. package/dist/frontend/lowering/class-protocols.d.ts +57 -4
  249. package/dist/frontend/lowering/class-protocols.js +597 -30
  250. package/dist/frontend/lowering/class-protocols.js.map +1 -1
  251. package/dist/frontend/lowering/class-unions.js +2 -2
  252. package/dist/frontend/lowering/class-unions.js.map +1 -1
  253. package/dist/frontend/lowering/coercions/function-adapters.d.ts +12 -0
  254. package/dist/frontend/lowering/coercions/function-adapters.js +62 -0
  255. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
  256. package/dist/frontend/lowering/coercions/structural-plans.js +56 -1
  257. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
  258. package/dist/frontend/lowering/coercions/structural.js +9 -4
  259. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  260. package/dist/frontend/lowering/collection-ingestion.d.ts +9 -0
  261. package/dist/frontend/lowering/collection-ingestion.js +115 -41
  262. package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
  263. package/dist/frontend/lowering/containers/array-callbacks.js +16 -0
  264. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  265. package/dist/frontend/lowering/containers/bytes.js +66 -10
  266. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  267. package/dist/frontend/lowering/containers/collection-methods.js +61 -5
  268. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  269. package/dist/frontend/lowering/containers/filter-predicates.js +11 -0
  270. package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -1
  271. package/dist/frontend/lowering/containers/indexed-objects.d.ts +15 -0
  272. package/dist/frontend/lowering/containers/indexed-objects.js +213 -30
  273. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  274. package/dist/frontend/lowering/error-name-order.d.ts +16 -0
  275. package/dist/frontend/lowering/error-name-order.js +61 -0
  276. package/dist/frontend/lowering/error-name-order.js.map +1 -1
  277. package/dist/frontend/lowering/expressions/asserted-receiver.d.ts +17 -0
  278. package/dist/frontend/lowering/expressions/asserted-receiver.js +123 -1
  279. package/dist/frontend/lowering/expressions/asserted-receiver.js.map +1 -1
  280. package/dist/frontend/lowering/expressions/binary.js +147 -20
  281. package/dist/frontend/lowering/expressions/binary.js.map +1 -1
  282. package/dist/frontend/lowering/expressions/element-access.js +63 -14
  283. package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
  284. package/dist/frontend/lowering/expressions/erased-delete.d.ts +59 -0
  285. package/dist/frontend/lowering/expressions/erased-delete.js +247 -0
  286. package/dist/frontend/lowering/expressions/erased-delete.js.map +1 -0
  287. package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +10 -0
  288. package/dist/frontend/lowering/expressions/hosted-narrowing.js +48 -1
  289. package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -1
  290. package/dist/frontend/lowering/expressions/identifiers.js +20 -0
  291. package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
  292. package/dist/frontend/lowering/expressions/narrowing.d.ts +7 -2
  293. package/dist/frontend/lowering/expressions/narrowing.js +77 -45
  294. package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
  295. package/dist/frontend/lowering/expressions/object-literals.js +62 -19
  296. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  297. package/dist/frontend/lowering/expressions/optional-chains.js +19 -0
  298. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  299. package/dist/frontend/lowering/expressions/property-access.d.ts +7 -7
  300. package/dist/frontend/lowering/expressions/property-access.js +247 -48
  301. package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
  302. package/dist/frontend/lowering/expressions/relational.d.ts +1 -0
  303. package/dist/frontend/lowering/expressions/relational.js +18 -8
  304. package/dist/frontend/lowering/expressions/relational.js.map +1 -1
  305. package/dist/frontend/lowering/expressions/union-fields.js +11 -5
  306. package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
  307. package/dist/frontend/lowering/expressions/updates.js +121 -11
  308. package/dist/frontend/lowering/expressions/updates.js.map +1 -1
  309. package/dist/frontend/lowering/function-context.d.ts +10 -0
  310. package/dist/frontend/lowering/function-context.js +36 -0
  311. package/dist/frontend/lowering/function-context.js.map +1 -1
  312. package/dist/frontend/lowering/function-returns.js +8 -8
  313. package/dist/frontend/lowering/function-returns.js.map +1 -1
  314. package/dist/frontend/lowering/handle-properties.d.ts +62 -3
  315. package/dist/frontend/lowering/handle-properties.js +674 -26
  316. package/dist/frontend/lowering/handle-properties.js.map +1 -1
  317. package/dist/frontend/lowering/handle-properties.test.js +95 -2
  318. package/dist/frontend/lowering/handle-properties.test.js.map +1 -1
  319. package/dist/frontend/lowering/lower-builtin-values.d.ts +12 -0
  320. package/dist/frontend/lowering/lower-builtin-values.js +44 -0
  321. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  322. package/dist/frontend/lowering/lower-calls.js +328 -136
  323. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  324. package/dist/frontend/lowering/lower-classes.js +82 -17
  325. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  326. package/dist/frontend/lowering/lower-event-emitter.js +113 -9
  327. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  328. package/dist/frontend/lowering/lower-expando.d.ts +13 -21
  329. package/dist/frontend/lowering/lower-expando.js +90 -126
  330. package/dist/frontend/lowering/lower-expando.js.map +1 -1
  331. package/dist/frontend/lowering/lower-exprs.js +2 -2
  332. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  333. package/dist/frontend/lowering/lower-functions.js +65 -0
  334. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  335. package/dist/frontend/lowering/lower-inspect.js +471 -0
  336. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  337. package/dist/frontend/lowering/lower-modules.js +36 -10
  338. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  339. package/dist/frontend/lowering/lower-node-island.js +28 -0
  340. package/dist/frontend/lowering/lower-node-island.js.map +1 -1
  341. package/dist/frontend/lowering/lower-server.d.ts +53 -7
  342. package/dist/frontend/lowering/lower-server.js +213 -42
  343. package/dist/frontend/lowering/lower-server.js.map +1 -1
  344. package/dist/frontend/lowering/lower-stdlib.js +50 -7
  345. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  346. package/dist/frontend/lowering/lower-stmts.d.ts +24 -0
  347. package/dist/frontend/lowering/lower-stmts.js +463 -220
  348. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  349. package/dist/frontend/lowering/lower-stream.js +2 -2
  350. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  351. package/dist/frontend/lowering/lower-test.js +71 -2
  352. package/dist/frontend/lowering/lower-test.js.map +1 -1
  353. package/dist/frontend/lowering/lowerer.d.ts +81 -10
  354. package/dist/frontend/lowering/lowerer.js +319 -72
  355. package/dist/frontend/lowering/lowerer.js.map +1 -1
  356. package/dist/frontend/lowering/new-target.js +10 -2
  357. package/dist/frontend/lowering/new-target.js.map +1 -1
  358. package/dist/frontend/lowering/nullish-empty-pattern.js +3 -3
  359. package/dist/frontend/lowering/nullish-empty-pattern.js.map +1 -1
  360. package/dist/frontend/lowering/partial-assertions.js +30 -5
  361. package/dist/frontend/lowering/partial-assertions.js.map +1 -1
  362. package/dist/frontend/lowering/primitive-throws.js +91 -1
  363. package/dist/frontend/lowering/primitive-throws.js.map +1 -1
  364. package/dist/frontend/lowering/primitive-wrappers.d.ts +9 -0
  365. package/dist/frontend/lowering/primitive-wrappers.js +2 -2
  366. package/dist/frontend/lowering/primitive-wrappers.js.map +1 -1
  367. package/dist/frontend/lowering/promise-executor-adapter.js +5 -2
  368. package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -1
  369. package/dist/frontend/lowering/record-links.js +7 -2
  370. package/dist/frontend/lowering/record-links.js.map +1 -1
  371. package/dist/frontend/lowering/surfaces.d.ts +4 -0
  372. package/dist/frontend/lowering/surfaces.js +118 -2
  373. package/dist/frontend/lowering/surfaces.js.map +1 -1
  374. package/dist/frontend/lowering/surfaces.test.d.ts +1 -0
  375. package/dist/frontend/lowering/surfaces.test.js +31 -0
  376. package/dist/frontend/lowering/surfaces.test.js.map +1 -0
  377. package/dist/frontend/mock-shapes.js +3 -3
  378. package/dist/frontend/mock-shapes.js.map +1 -1
  379. package/dist/frontend/npm-static-ladder.d.ts +21 -0
  380. package/dist/frontend/npm-static-ladder.js +2 -0
  381. package/dist/frontend/npm-static-ladder.js.map +1 -0
  382. package/dist/frontend/npm-static-ladder.test.d.ts +1 -0
  383. package/dist/frontend/npm-static-ladder.test.js +138 -0
  384. package/dist/frontend/npm-static-ladder.test.js.map +1 -0
  385. package/dist/frontend/npm-static-status.d.ts +15 -0
  386. package/dist/frontend/npm-static-status.js +2 -0
  387. package/dist/frontend/npm-static-status.js.map +1 -0
  388. package/dist/frontend/package-shims.js +1 -1
  389. package/dist/frontend/package-shims.js.map +1 -1
  390. package/dist/frontend/pipeline.d.ts +1 -1
  391. package/dist/frontend/pipeline.js +222 -25
  392. package/dist/frontend/pipeline.js.map +1 -1
  393. package/dist/frontend/program-analysis.d.ts +4 -0
  394. package/dist/frontend/program-analysis.js +6 -0
  395. package/dist/frontend/program-analysis.js.map +1 -1
  396. package/dist/frontend/program.js +258 -32
  397. package/dist/frontend/program.js.map +1 -1
  398. package/dist/frontend/program.test.js +30 -0
  399. package/dist/frontend/program.test.js.map +1 -1
  400. package/dist/frontend/resolve.js +29 -5
  401. package/dist/frontend/resolve.js.map +1 -1
  402. package/dist/frontend/resolve.test.js +40 -0
  403. package/dist/frontend/resolve.test.js.map +1 -1
  404. package/dist/frontend/services.d.ts +8 -0
  405. package/dist/frontend/services.js +7 -0
  406. package/dist/frontend/services.js.map +1 -1
  407. package/dist/frontend/ts7/checker.d.ts +7 -0
  408. package/dist/frontend/ts7/checker.js +12 -0
  409. package/dist/frontend/ts7/checker.js.map +1 -1
  410. package/dist/frontend/ts7/checker.test.js +1 -0
  411. package/dist/frontend/ts7/checker.test.js.map +1 -1
  412. package/dist/frontend/ts7/program-host.d.ts +39 -2
  413. package/dist/frontend/ts7/program-host.js +62 -8
  414. package/dist/frontend/ts7/program-host.js.map +1 -1
  415. package/dist/frontend/ts7/program-host.test.js +33 -0
  416. package/dist/frontend/ts7/program-host.test.js.map +1 -1
  417. package/dist/frontend/ts7/session-cache.d.ts +5 -1
  418. package/dist/frontend/ts7/session-cache.js +7 -1
  419. package/dist/frontend/ts7/session-cache.js.map +1 -1
  420. package/dist/frontend/ts7/session-cache.test.js +37 -0
  421. package/dist/frontend/ts7/session-cache.test.js.map +1 -1
  422. package/dist/frontend/ts7/session.js +19 -1
  423. package/dist/frontend/ts7/session.js.map +1 -1
  424. package/dist/frontend/ts7/source-parser.d.ts +17 -2
  425. package/dist/frontend/ts7/source-parser.js +61 -2
  426. package/dist/frontend/ts7/source-parser.js.map +1 -1
  427. package/dist/frontend/ts7/source-parser.test.js +55 -2
  428. package/dist/frontend/ts7/source-parser.test.js.map +1 -1
  429. package/dist/frontend/tsc-codes.d.ts +3 -2
  430. package/dist/frontend/tsc-codes.js +129 -22
  431. package/dist/frontend/tsc-codes.js.map +1 -1
  432. package/dist/frontend/type-mapper.d.ts +5 -11
  433. package/dist/frontend/type-mapper.js +380 -70
  434. package/dist/frontend/type-mapper.js.map +1 -1
  435. package/dist/index.d.ts +1 -1
  436. package/dist/index.js +67 -7
  437. package/dist/index.js.map +1 -1
  438. package/dist/ir/builtin-effects.js +29 -0
  439. package/dist/ir/builtin-effects.js.map +1 -1
  440. package/dist/ir/builtin-signatures.d.ts +1 -1
  441. package/dist/ir/builtin-signatures.js +72 -6
  442. package/dist/ir/builtin-signatures.js.map +1 -1
  443. package/dist/ir/codec.generated.d.ts +1 -1
  444. package/dist/ir/codec.generated.js +321 -263
  445. package/dist/ir/codec.generated.js.map +1 -1
  446. package/dist/ir/constant-length-clones.d.ts +26 -0
  447. package/dist/ir/constant-length-clones.js +589 -0
  448. package/dist/ir/constant-length-clones.js.map +1 -0
  449. package/dist/ir/constant-length-clones.test.d.ts +1 -0
  450. package/dist/ir/constant-length-clones.test.js +292 -0
  451. package/dist/ir/constant-length-clones.test.js.map +1 -0
  452. package/dist/ir/constant-tables.d.ts +10 -5
  453. package/dist/ir/constant-tables.js +83 -17
  454. package/dist/ir/constant-tables.js.map +1 -1
  455. package/dist/ir/constant-tables.test.js +58 -1
  456. package/dist/ir/constant-tables.test.js.map +1 -1
  457. package/dist/ir/fields.generated.js +5 -2
  458. package/dist/ir/fields.generated.js.map +1 -1
  459. package/dist/ir/function-references.js +2 -0
  460. package/dist/ir/function-references.js.map +1 -1
  461. package/dist/ir/function-references.test.js +13 -0
  462. package/dist/ir/function-references.test.js.map +1 -1
  463. package/dist/ir/integer-loops.js +1 -0
  464. package/dist/ir/integer-loops.js.map +1 -1
  465. package/dist/ir/integer-loops.test.js +16 -0
  466. package/dist/ir/integer-loops.test.js.map +1 -1
  467. package/dist/ir/ir.d.ts +50 -6
  468. package/dist/ir/ir.js +44 -2
  469. package/dist/ir/ir.js.map +1 -1
  470. package/dist/ir/ir.test.js +83 -1
  471. package/dist/ir/ir.test.js.map +1 -1
  472. package/dist/ir/js-groups.js +5 -1
  473. package/dist/ir/js-groups.js.map +1 -1
  474. package/dist/ir/js-ic.d.ts +20 -0
  475. package/dist/ir/js-ic.js +81 -4
  476. package/dist/ir/js-ic.js.map +1 -1
  477. package/dist/ir/js-ic.test.js +8 -1
  478. package/dist/ir/js-ic.test.js.map +1 -1
  479. package/dist/ir/lane-plans.d.ts +86 -0
  480. package/dist/ir/lane-plans.js +589 -0
  481. package/dist/ir/lane-plans.js.map +1 -0
  482. package/dist/ir/lane-plans.test.d.ts +1 -0
  483. package/dist/ir/lane-plans.test.js +549 -0
  484. package/dist/ir/lane-plans.test.js.map +1 -0
  485. package/dist/ir/runtime-features.d.ts +68 -10
  486. package/dist/ir/runtime-features.js +285 -17
  487. package/dist/ir/runtime-features.js.map +1 -1
  488. package/dist/ir/runtime-features.test.js +190 -1
  489. package/dist/ir/runtime-features.test.js.map +1 -1
  490. package/dist/ir/validate.js +61 -24
  491. package/dist/ir/validate.js.map +1 -1
  492. package/dist/native/cache.d.ts +5 -0
  493. package/dist/native/cache.js +23 -1
  494. package/dist/native/cache.js.map +1 -1
  495. package/dist/native/cache.test.js +29 -1
  496. package/dist/native/cache.test.js.map +1 -1
  497. package/dist/native/cli.js +4 -2
  498. package/dist/native/cli.js.map +1 -1
  499. package/dist/native/compiler.d.ts +11 -3
  500. package/dist/native/compiler.js +102 -16
  501. package/dist/native/compiler.js.map +1 -1
  502. package/dist/native/compiler.test.js +244 -2
  503. package/dist/native/compiler.test.js.map +1 -1
  504. package/dist/native/prepare.d.ts +14 -1
  505. package/dist/native/prepare.js +79 -29
  506. package/dist/native/prepare.js.map +1 -1
  507. package/dist/native/sanitizer.test.js +3 -0
  508. package/dist/native/sanitizer.test.js.map +1 -1
  509. package/dist/native/unchanged.d.ts +80 -0
  510. package/dist/native/unchanged.js +301 -0
  511. package/dist/native/unchanged.js.map +1 -0
  512. package/dist/native/unchanged.test.d.ts +1 -0
  513. package/dist/native/unchanged.test.js +249 -0
  514. package/dist/native/unchanged.test.js.map +1 -0
  515. package/dist/node-islands/boundary.d.ts +16 -0
  516. package/dist/node-islands/boundary.js +70 -7
  517. package/dist/node-islands/boundary.js.map +1 -1
  518. package/dist/node-islands/boundary.test.js +59 -14
  519. package/dist/node-islands/boundary.test.js.map +1 -1
  520. package/dist/node-islands/detect.js +203 -47
  521. package/dist/node-islands/detect.js.map +1 -1
  522. package/dist/node-islands/detect.test.js +45 -0
  523. package/dist/node-islands/detect.test.js.map +1 -1
  524. package/dist/node-islands/growth.js +4 -16
  525. package/dist/node-islands/growth.js.map +1 -1
  526. package/dist/node-islands/modules.d.ts +3 -0
  527. package/dist/node-islands/modules.js +143 -12
  528. package/dist/node-islands/modules.js.map +1 -1
  529. package/dist/node-islands/modules.test.js +125 -0
  530. package/dist/node-islands/modules.test.js.map +1 -1
  531. package/dist/node-islands/report.d.ts +1 -1
  532. package/dist/node-islands/report.js +2 -1
  533. package/dist/node-islands/report.js.map +1 -1
  534. package/package.json +20 -20
  535. package/shims/undici/core/request.ts +7 -1
  536. package/surface-manifest.json +380 -2
@@ -9,6 +9,8 @@ export class ClassProtocols {
9
9
  answers = new Map();
10
10
  /** The program classes each Pick or Omit view accepts (classesAcceptedBy). */
11
11
  accepted = new Map();
12
+ /** copiedArgument's answers, per call and argument position. */
13
+ copiedArguments = new Map();
12
14
  /** What markIdentityFlows learned about the program, while it runs. */
13
15
  facts = null;
14
16
  /** The value types of the string-keyed dictionaries that keep checked
@@ -19,6 +21,9 @@ export class ClassProtocols {
19
21
  * without protocol dispatch: their members are invoked on the collection
20
22
  * itself, not read from a property bag. */
21
23
  collectionViews = new Set();
24
+ /** The mapped views a receiver-dependent literal is used as, whose source
25
+ * cannot carry the marking (see index). */
26
+ literalViews = new Set();
22
27
  constructor(checker, sources) {
23
28
  this.checker = checker;
24
29
  this.sources = sources;
@@ -29,6 +34,23 @@ export class ClassProtocols {
29
34
  const protocols = new Set();
30
35
  this.implemented = protocols;
31
36
  const add = (type) => {
37
+ // A homomorphic mapped view's own symbol is the shared mapped
38
+ // `__type` that every mapped type in the program uses: marking it
39
+ // would make every Pick, Omit, Partial and Readonly a view. Mark the
40
+ // type the view maps instead when that is a structural type. A source
41
+ // that cannot carry the marking keeps its own representation: a class
42
+ // instance would make every instance a view, and an intersection has
43
+ // no symbol. The VIEW type itself is recorded for those, so a
44
+ // receiver-dependent literal typed as it still keeps checked identity
45
+ // and protocol answers it through that record.
46
+ const mapped = this.mappedViewSource(type);
47
+ if (mapped !== null) {
48
+ if (!this.isStructuralTarget(mapped)) {
49
+ this.literalViews.add(type);
50
+ return;
51
+ }
52
+ type = mapped;
53
+ }
32
54
  const symbol = type.getSymbol();
33
55
  if (!symbol || protocols.has(symbol))
34
56
  return;
@@ -106,10 +128,11 @@ export class ClassProtocols {
106
128
  * checked-dynamic view, where the accessor stays live, `Object.keys`
107
129
  * lists it, and `JSON.stringify` calls it — Node's own model.
108
130
  *
109
- * Only the TARGET is marked: the literal then takes the checked-dynamic
110
- * literal path (`lowerDynObjectLiteral`), which defines an accessor member
111
- * as a live get/set property and a data member as a plain property, so
112
- * both directions construct live objects. */
131
+ * Only the TARGET is marked (for an intersection or union, its object
132
+ * constituents): the literal then takes the checked-dynamic literal path
133
+ * (`lowerDynObjectLiteral`), which defines an accessor member as a live
134
+ * get/set property and a data member as a plain property, so both
135
+ * directions construct live objects. */
113
136
  markMemberKindViews(literal, accessorNames, add) {
114
137
  const members = [];
115
138
  for (const property of literal.properties.nodes) {
@@ -134,29 +157,127 @@ export class ClassProtocols {
134
157
  const contextual = attempt(() => this.checker.getContextualType(literal));
135
158
  if (contextual === undefined)
136
159
  return;
137
- // Only one object type can be the one the literal converts into: a union
138
- // with several arms picks its arm from the value itself, and an
139
- // intersection merges members, so neither has the single layout the
140
- // literal would have to disagree with. Nullish arms are ignored, so
141
- // `Counter | undefined` still names Counter.
160
+ // The literal converts into an object PART of its contextual type, so
161
+ // both composites are resolved part by part. An intersection needs the
162
+ // views of every constituent that declares a disagreeing member. A
163
+ // union keeps checked identity only as a whole (usesCheckedIdentity
164
+ // answers it when every present arm does), so it becomes a view only
165
+ // when NO present arm can hold the literal natively: every present arm
166
+ // declares a disagreeing member. An arm that agrees is the arm the
167
+ // literal is, and marking the union anyway would make a program whose
168
+ // literals already match their arms dynamic for nothing. Nullish arms
169
+ // are ignored, so `Counter | undefined` still names Counter.
142
170
  const present = contextual.isUnionType()
143
171
  ? ts
144
172
  .constituentTypes(contextual)
145
173
  .filter((part) => (part.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Null)) === 0)
146
174
  : [contextual];
147
- const target = present.length === 1 ? present[0] : undefined;
148
- if (target === undefined || target.isIntersectionType())
149
- return;
150
- if ((target.flags & ts.TypeFlags.TypeParameter) !== 0)
175
+ if (present.length === 0)
151
176
  return;
152
- if (!this.isStructuralTarget(target))
177
+ const union = present.length > 1;
178
+ if (union && !present.every((part) => this.memberKindDisagrees(part, members)))
153
179
  return;
154
- const disagrees = members.some((member) => {
180
+ const targets = [];
181
+ for (const arm of present) {
182
+ const found = this.viewTargets(arm, members, union);
183
+ // An arm that cannot become a view leaves the union native; marking
184
+ // the other arms alone would not give it checked identity.
185
+ if (found === null)
186
+ return;
187
+ targets.push(...found);
188
+ }
189
+ for (const target of targets)
190
+ add(target);
191
+ }
192
+ /** The view targets `target` needs for a literal with these member kinds,
193
+ * or null when `target` cannot become a view. An intersection needs the
194
+ * targets of every constituent. A homomorphic mapped view (Partial, Pick,
195
+ * Omit, Readonly) has no symbol of its own — its symbol is the shared
196
+ * mapped `__type`, which every mapped type in the program uses — so the
197
+ * type it maps is the target instead, and `protocol` answers the view
198
+ * through that marking. `force` targets a union arm that must keep
199
+ * checked identity even when it agrees with the literal by itself. */
200
+ viewTargets(target, members, force) {
201
+ if (target.isIntersectionType()) {
202
+ const targets = [];
203
+ for (const part of ts.constituentTypes(target)) {
204
+ const found = this.viewTargets(part, members, force);
205
+ if (found === null)
206
+ return null;
207
+ targets.push(...found);
208
+ }
209
+ return targets;
210
+ }
211
+ if ((target.flags & ts.TypeFlags.TypeParameter) !== 0)
212
+ return null;
213
+ const source = this.mappedViewSource(target) ?? target;
214
+ if (!this.isStructuralTarget(source))
215
+ return null;
216
+ if (!force && !this.memberKindDisagrees(target, members))
217
+ return [];
218
+ return [source];
219
+ }
220
+ /** Whether any of the literal's member kinds disagrees with the member
221
+ * `target` declares under that name (a missing member never disagrees). */
222
+ memberKindDisagrees(target, members) {
223
+ return members.some((member) => {
155
224
  const kind = attempt(() => this.memberKind(target, member.name));
156
225
  return kind == null ? false : (kind === "accessor") !== member.accessor;
157
226
  });
158
- if (disagrees)
159
- add(target);
227
+ }
228
+ /** The structural type a homomorphic mapped VIEW maps — Partial, Pick,
229
+ * Omit or Readonly over a program type. Mapped types share one `__type`
230
+ * symbol, so a view is identified through the alias it is spelled with;
231
+ * program aliases of views (`type A = B`, `type B = Partial<X>`) are
232
+ * followed through their declarations, and nested views
233
+ * (`Partial<Omit<X, K>>`) resolve to the type carrying the members.
234
+ * Null for everything else. */
235
+ mappedViewSource(type, depth = 0) {
236
+ if (depth > 8)
237
+ return null;
238
+ const alias = type.getAliasSymbol();
239
+ if (alias === undefined)
240
+ return null;
241
+ if (this.isHomomorphicMappedAlias(alias)) {
242
+ const [source] = type.getAliasTypeArguments();
243
+ if (source === undefined)
244
+ return null;
245
+ return this.mappedViewSource(source, depth + 1) ?? source;
246
+ }
247
+ const declaration = this.programTypeAlias(alias);
248
+ return declaration === null ? null : this.mappedViewSourceNode(declaration.type, depth + 1);
249
+ }
250
+ /** mappedViewSource for a view spelled as a type node (a program alias's
251
+ * declaration, whose resolved type is the alias itself). */
252
+ mappedViewSourceNode(node, depth) {
253
+ if (depth > 8)
254
+ return null;
255
+ while (ts.isParenthesizedTypeNode(node))
256
+ node = node.type;
257
+ if (!ts.isTypeReferenceNode(node))
258
+ return null;
259
+ const symbol = attempt(() => this.checker.getSymbolAtLocation(node.typeName));
260
+ if (symbol === undefined)
261
+ return null;
262
+ if (this.isHomomorphicMappedAlias(symbol)) {
263
+ const sourceNode = node.typeArguments?.nodes[0];
264
+ if (sourceNode === undefined)
265
+ return null;
266
+ const source = attempt(() => this.checker.getTypeFromTypeNode(sourceNode));
267
+ if (source === undefined)
268
+ return null;
269
+ return this.mappedViewSource(source, depth + 1) ?? source;
270
+ }
271
+ const declaration = this.programTypeAlias(symbol);
272
+ return declaration === null ? null : this.mappedViewSourceNode(declaration.type, depth + 1);
273
+ }
274
+ /** The lib's homomorphic mapped utility types. */
275
+ isHomomorphicMappedAlias(symbol) {
276
+ const name = ts.symbolName(symbol);
277
+ if (name !== "Pick" && name !== "Omit" && name !== "Partial" && name !== "Readonly")
278
+ return false;
279
+ return (symbol.declarations.length > 0 &&
280
+ symbol.declarations.every((declaration) => declaration.getSourceFile().isDeclarationFile));
160
281
  }
161
282
  /** The member kind `type` declares at `name` — an accessor (get/set pair)
162
283
  * or a data property — or null when it declares no member by that name. */
@@ -207,9 +328,9 @@ export class ClassProtocols {
207
328
  * signature's parameter) flows into the declared parameter type. */
208
329
  const callbackParams = [];
209
330
  const contextual = (expr) => () => this.checker.getContextualType(expr);
210
- const flow = (expr) => {
331
+ const flow = (expr, call) => {
211
332
  if (expr !== undefined)
212
- sites.push({ source: expr, target: contextual(expr), contextual: expr });
333
+ sites.push({ source: expr, target: contextual(expr), contextual: expr, call });
213
334
  };
214
335
  const write = (target) => {
215
336
  while (ts.isParenthesizedExpression(target) || ts.isNonNullExpression(target))
@@ -303,7 +424,7 @@ export class ClassProtocols {
303
424
  const visit = (node) => {
304
425
  observe(node);
305
426
  if (ts.isCallExpression(node) || ts.isNewExpression(node))
306
- node.arguments?.nodes.forEach(flow);
427
+ node.arguments?.nodes.forEach((argument, index) => flow(argument, { node, index }));
307
428
  else if (ts.isVariableDeclaration(node) && node.type !== undefined)
308
429
  flow(node.initializer);
309
430
  else if (ts.isPropertyDeclaration(node) && node.type !== undefined)
@@ -330,7 +451,11 @@ export class ClassProtocols {
330
451
  !ts.isObjectLiteralExpression(node.left) &&
331
452
  !ts.isArrayLiteralExpression(node.left)) {
332
453
  const left = node.left;
333
- sites.push({ source: node.right, target: () => this.checker.getTypeAtLocation(left) });
454
+ sites.push({
455
+ source: node.right,
456
+ target: () => this.checker.getTypeAtLocation(left),
457
+ call: undefined,
458
+ });
334
459
  }
335
460
  else if ((ts.isAsExpression(node) || ts.isTypeAssertion(node)) && !accessedInPlace(node)) {
336
461
  const typeNode = node.type;
@@ -338,6 +463,7 @@ export class ClassProtocols {
338
463
  source: node.expression,
339
464
  target: () => this.checker.getTypeFromTypeNode(typeNode),
340
465
  assertion: true,
466
+ call: undefined,
341
467
  });
342
468
  }
343
469
  if (ts.isArrowFunction(node) || ts.isFunctionExpression(node))
@@ -377,6 +503,8 @@ export class ClassProtocols {
377
503
  origins: new Map(),
378
504
  targets: new Map(),
379
505
  flows: new Map(),
506
+ callSites: new Map(),
507
+ otherSites: new Set(),
380
508
  genericObservers: new Set(),
381
509
  };
382
510
  const typeOf = (node) => attempt(() => this.checker.getTypeAtLocation(node));
@@ -449,7 +577,7 @@ export class ClassProtocols {
449
577
  const target = attempt(site.target);
450
578
  if (target !== undefined)
451
579
  for (const { classType, view } of attempt(() => this.methodViewSources(target)) ?? []) {
452
- pending.push({ sourceType: classType, target: () => view });
580
+ pending.push({ sourceType: classType, target: () => view, call: undefined });
453
581
  const symbol = view.getSymbol();
454
582
  if (symbol !== undefined)
455
583
  methodViews.add(symbol);
@@ -457,8 +585,8 @@ export class ClassProtocols {
457
585
  continue;
458
586
  }
459
587
  pending.push(site.contextual === undefined
460
- ? { sourceType, target: site.target }
461
- : { sourceType, target: site.target, contextual: site.contextual });
588
+ ? { sourceType, target: site.target, call: site.call }
589
+ : { sourceType, target: site.target, contextual: site.contextual, call: site.call });
462
590
  }
463
591
  for (const { fn, index, name } of callbackParams) {
464
592
  attempt(() => {
@@ -478,6 +606,7 @@ export class ClassProtocols {
478
606
  pending.push({
479
607
  sourceType: this.checker.getTypeOfSymbol(parameter),
480
608
  target: () => declared,
609
+ call: undefined,
481
610
  });
482
611
  }
483
612
  });
@@ -504,7 +633,7 @@ export class ClassProtocols {
504
633
  targets.set(i, attempt(entry.target));
505
634
  const target = targets.get(i);
506
635
  if (target !== undefined &&
507
- attempt(() => this.markTarget(entry.sourceType, target, marked)) === true)
636
+ attempt(() => this.markTarget(entry.sourceType, target, marked, entry.call ?? null, true)) === true)
508
637
  changed = true;
509
638
  }
510
639
  }
@@ -709,7 +838,11 @@ export class ClassProtocols {
709
838
  const writesNames = (written) => written === "all" || [...written].some((name) => names.has(name));
710
839
  for (const origin of origins) {
711
840
  const written = facts.written.get(origin);
712
- if (written !== undefined && writesNames(written))
841
+ // A field written after construction would be stale in a copy — unless
842
+ // every value of the view arrives as a call argument the callee reads
843
+ // and nothing else, where the copy answers the same reads the instance
844
+ // would (copiedAtEverySite).
845
+ if (written !== undefined && writesNames(written) && !this.copiedAtEverySite(symbol, facts))
713
846
  return true;
714
847
  // An accessor runs on every read of the instance: a copy would keep
715
848
  // the value of one call.
@@ -740,6 +873,191 @@ export class ClassProtocols {
740
873
  (declaration.parent !== undefined && facts.genericObservers.has(declaration.parent))));
741
874
  }) === true);
742
875
  }
876
+ /** Whether every value of the view arrives as a call argument whose
877
+ * callee only reads it: then the record copy the boundary builds answers
878
+ * the same reads the instance itself would, and later writes to the
879
+ * instance cannot be observed through the view. */
880
+ copiedAtEverySite(symbol, facts) {
881
+ if (facts.otherSites.has(symbol))
882
+ return false;
883
+ const sites = facts.callSites.get(symbol);
884
+ if (sites === undefined || sites.length === 0)
885
+ return false;
886
+ return sites.every((site) => this.isProgramClassInstance(site.source) && this.copiedArgument(site.node, site.index));
887
+ }
888
+ /** Whether argument `index` of `call` can be copied into the parameter's
889
+ * record: the callee is a program function whose body reads the instance
890
+ * only through declared fields of primitive type, keeps no reference to
891
+ * it, and runs no code that could write to it (assignments only to its
892
+ * own locals, no await or yield, and every call a numeric builtin). */
893
+ copiedArgument(call, index) {
894
+ let byIndex = this.copiedArguments.get(call);
895
+ if (byIndex === undefined) {
896
+ byIndex = [];
897
+ this.copiedArguments.set(call, byIndex);
898
+ }
899
+ const cached = byIndex[index];
900
+ if (cached !== undefined)
901
+ return cached;
902
+ const answer = attempt(() => this.copiedArgumentNow(call, index)) === true;
903
+ byIndex[index] = answer;
904
+ return answer;
905
+ }
906
+ copiedArgumentNow(call, index) {
907
+ const args = call.arguments?.nodes ?? [];
908
+ if (index >= args.length || args.some((argument) => ts.isSpreadElement(argument)))
909
+ return false;
910
+ const signature = this.checker.getResolvedSignature(call);
911
+ const declaration = signature?.declaration;
912
+ if (declaration === undefined)
913
+ return false;
914
+ if (!ts.isFunctionDeclaration(declaration) &&
915
+ !ts.isFunctionExpression(declaration) &&
916
+ !ts.isArrowFunction(declaration))
917
+ return false;
918
+ if (declaration.body === undefined)
919
+ return false;
920
+ if (!this.fixedCallee(declaration, call))
921
+ return false;
922
+ if (declaration.asteriskToken !== undefined)
923
+ return false;
924
+ if (declaration.modifiers?.nodes.some((modifier) => modifier.kind === ts.SyntaxKind.AsyncKeyword) === true)
925
+ return false;
926
+ // Defaults run in the callee's frame, after the arguments, and may write
927
+ // the instance; a parameter pattern reads members the same way.
928
+ if (declaration.parameters.nodes.some((parameter) => !ts.isIdentifier(parameter.name) || parameter.initializer !== undefined))
929
+ return false;
930
+ const parameter = declaration.parameters.nodes[index];
931
+ if (parameter === undefined || !ts.isIdentifier(parameter.name))
932
+ return false;
933
+ if (parameter.dotDotDotToken !== undefined || parameter.questionToken !== undefined)
934
+ return false;
935
+ // Arguments evaluated after this one run while the copy stands: code in
936
+ // them may write the instance before the callee reads the copy.
937
+ for (let position = index + 1; position < args.length; position++) {
938
+ const argument = args[position];
939
+ if (argument !== undefined && containsProgramCode(argument, this.checker))
940
+ return false;
941
+ }
942
+ return this.readsParameterOnlyFields(declaration, parameter.name.text);
943
+ }
944
+ /** Whether the function whose body is inspected is the one this call runs:
945
+ * the callee is the function itself, the identifier of the function
946
+ * declaration, or the identifier of the `const` binding that holds it.
947
+ * A `let` binding, a property, or another binding of the same signature
948
+ * could run a body this analysis never saw. */
949
+ fixedCallee(fn, call) {
950
+ const callee = unwrapExpression(call.expression);
951
+ if (callee === fn)
952
+ return true;
953
+ if (!ts.isIdentifier(callee))
954
+ return false;
955
+ const symbol = attempt(() => this.checker.getSymbolAtLocation(callee));
956
+ if (ts.isFunctionDeclaration(fn))
957
+ return symbol?.declarations?.some((declaration) => declaration === fn) === true;
958
+ const parent = fn.parent;
959
+ const list = parent?.parent;
960
+ if (!ts.isVariableDeclaration(parent) ||
961
+ parent.initializer !== fn ||
962
+ list === undefined ||
963
+ (list.flags & ts.NodeFlags.Const) === 0)
964
+ return false;
965
+ return symbol?.declarations?.some((declaration) => declaration === parent) === true;
966
+ }
967
+ /** The body of `declaration` mentions `name` only as the receiver of a
968
+ * property read whose value is a primitive, and never stores, returns,
969
+ * passes on or compares the value itself. */
970
+ readsParameterOnlyFields(declaration, name) {
971
+ const body = declaration.body;
972
+ if (body === undefined)
973
+ return false;
974
+ const locals = new Set();
975
+ for (const parameter of declaration.parameters.nodes)
976
+ if (ts.isIdentifier(parameter.name))
977
+ locals.add(parameter.name.text);
978
+ ts.walkPreorder(body, (node) => {
979
+ if (ts.isFunctionLike(node))
980
+ return "skip";
981
+ if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name))
982
+ locals.add(node.name.text);
983
+ return undefined;
984
+ });
985
+ let ok = true;
986
+ ts.walkPreorder(body, (node) => {
987
+ if (!ok)
988
+ return "stop";
989
+ if (ts.isTypeNode(node))
990
+ return "skip";
991
+ if (ts.isFunctionLike(node)) {
992
+ // A nested function that mentions the parameter captures the value,
993
+ // so the copy would be told apart from the instance.
994
+ if (mentionsBinding(node, name))
995
+ ok = false;
996
+ return "skip";
997
+ }
998
+ if (ts.isBinaryExpression(node) &&
999
+ node.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
1000
+ node.operatorToken.kind <= ts.SyntaxKind.LastAssignment) {
1001
+ // Only the body's own locals may be written: a write through any
1002
+ // other value could reach the instance. A compound assignment also
1003
+ // coerces both sides, and a non-primitive operand runs its value
1004
+ // hook.
1005
+ const left = unwrapExpression(node.left);
1006
+ if (!ts.isIdentifier(left) || !locals.has(left.text)) {
1007
+ ok = false;
1008
+ return "stop";
1009
+ }
1010
+ if (node.operatorToken.kind !== ts.SyntaxKind.EqualsToken &&
1011
+ !primitiveOperands(left, node.right, this.checker)) {
1012
+ ok = false;
1013
+ return "stop";
1014
+ }
1015
+ return undefined;
1016
+ }
1017
+ if ((ts.isPrefixUnaryExpression(node) || ts.isPostfixUnaryExpression(node)) &&
1018
+ (node.operator === ts.SyntaxKind.PlusPlusToken ||
1019
+ node.operator === ts.SyntaxKind.MinusMinusToken)) {
1020
+ const operand = unwrapExpression(node.operand);
1021
+ if (!ts.isIdentifier(operand) ||
1022
+ !locals.has(operand.text) ||
1023
+ !primitiveNode(operand, this.checker)) {
1024
+ ok = false;
1025
+ return "stop";
1026
+ }
1027
+ return undefined;
1028
+ }
1029
+ // Calls, await and yield, element access, accessors, dynamic member
1030
+ // access, iteration and value coercion can all run program code while
1031
+ // the copy is the callee's parameter.
1032
+ if (expressionRunsCode(node, this.checker)) {
1033
+ ok = false;
1034
+ return "stop";
1035
+ }
1036
+ if (ts.isIdentifier(node) && node.text === name) {
1037
+ if (isMemberName(node))
1038
+ return "skip";
1039
+ const receiver = unwrapExpression(node);
1040
+ const access = receiver.parent;
1041
+ if (access === undefined ||
1042
+ !ts.isPropertyAccessExpression(access) ||
1043
+ access.expression !== receiver) {
1044
+ ok = false;
1045
+ return "stop";
1046
+ }
1047
+ if (!primitiveValue(this.checker.getTypeAtLocation(access))) {
1048
+ ok = false;
1049
+ return "stop";
1050
+ }
1051
+ if (isWrittenAccess(access)) {
1052
+ ok = false;
1053
+ return "stop";
1054
+ }
1055
+ return "skip";
1056
+ }
1057
+ return undefined;
1058
+ });
1059
+ return ok;
1060
+ }
743
1061
  /** Whether one of `names` is a member the collection type itself
744
1062
  * declares (`has`, `get`, `size`, `keys`, ...). */
745
1063
  exposesCollectionMember(collection, names) {
@@ -1109,6 +1427,9 @@ export class ClassProtocols {
1109
1427
  // A live Pick or Omit view of a program class holds the instance itself.
1110
1428
  if (this.pickOfProgramClass(type) && this.usesCheckedIdentity(type))
1111
1429
  return true;
1430
+ // A homomorphic mapped view of a marked type is the live view itself.
1431
+ if (this.mappedViewSource(type) !== null && this.protocol(type))
1432
+ return true;
1112
1433
  const symbol = type.getSymbol();
1113
1434
  if (symbol === undefined)
1114
1435
  return false;
@@ -1141,11 +1462,12 @@ export class ClassProtocols {
1141
1462
  }
1142
1463
  /** Marks the structural parts of `target` that the identity-carrying
1143
1464
  * parts of `source` flow into. Answers whether anything new was marked. */
1144
- markTarget(source, target, marked) {
1465
+ markTarget(source, target, marked, site, record) {
1145
1466
  if (source.isUnionType()) {
1146
1467
  let changed = false;
1147
1468
  for (const part of ts.constituentTypes(source))
1148
- if (this.carriesIdentity(part, marked) && this.markTarget(part, target, marked))
1469
+ if (this.carriesIdentity(part, marked) &&
1470
+ this.markTarget(part, target, marked, site, false))
1149
1471
  changed = true;
1150
1472
  return changed;
1151
1473
  }
@@ -1167,14 +1489,14 @@ export class ClassProtocols {
1167
1489
  }
1168
1490
  let changed = false;
1169
1491
  for (const part of accepting)
1170
- if (this.markTarget(source, part, marked))
1492
+ if (this.markTarget(source, part, marked, site, false))
1171
1493
  changed = true;
1172
1494
  return changed;
1173
1495
  }
1174
1496
  if (this.checker.isArrayType(source) && this.checker.isArrayType(target)) {
1175
1497
  const [from] = this.checker.getTypeArguments(source);
1176
1498
  const [to] = this.checker.getTypeArguments(target);
1177
- return from !== undefined && to !== undefined && this.markTarget(from, to, marked);
1499
+ return (from !== undefined && to !== undefined && this.markTarget(from, to, marked, site, false));
1178
1500
  }
1179
1501
  if (!this.isStructuralTarget(target))
1180
1502
  return false;
@@ -1214,6 +1536,19 @@ export class ClassProtocols {
1214
1536
  facts.flows.set(from, flows);
1215
1537
  }
1216
1538
  }
1539
+ if (facts !== null) {
1540
+ // Every top-level site that reaches this view is remembered: a view
1541
+ // whose values only ever arrive as a call argument the callee reads can
1542
+ // keep the record shape its type declares (copiedAtEverySite).
1543
+ if (site === null || !record)
1544
+ facts.otherSites.add(symbol);
1545
+ else {
1546
+ const recorded = facts.callSites.get(symbol) ?? [];
1547
+ if (!recorded.some((entry) => entry.node === site.node && entry.index === site.index))
1548
+ recorded.push({ node: site.node, index: site.index, source });
1549
+ facts.callSites.set(symbol, recorded);
1550
+ }
1551
+ }
1217
1552
  // A view marked earlier that becomes a collection view still changes
1218
1553
  // the fixpoint: the views its values flow into are asked again.
1219
1554
  if (marked.has(symbol))
@@ -1267,6 +1602,17 @@ export class ClassProtocols {
1267
1602
  const properties = this.checker.getPropertiesOfType(type);
1268
1603
  if (symbol && protocols.has(symbol))
1269
1604
  return true;
1605
+ // A mapped view whose source cannot carry the marking was recorded
1606
+ // itself (index): the receiver-dependent literal typed as it needs the
1607
+ // live object, and no other view of that source does.
1608
+ if (this.literalViews.has(type))
1609
+ return true;
1610
+ // A homomorphic mapped view (Partial, Pick, Omit, Readonly) has no
1611
+ // symbol of its own to mark, so it is a view exactly when the type it
1612
+ // maps is one.
1613
+ const mapped = this.mappedViewSource(type);
1614
+ if (mapped !== null && this.protocol(mapped))
1615
+ return true;
1270
1616
  if (!this.pickOfProgramClass(type) &&
1271
1617
  (!symbol ||
1272
1618
  !symbol.declarations.some((declaration) => ts.isInterfaceDeclaration(declaration) &&
@@ -1436,6 +1782,227 @@ function attempt(query) {
1436
1782
  return undefined;
1437
1783
  }
1438
1784
  }
1785
+ /** Ground numeric calls: they cannot run program code, so a callee that
1786
+ * only uses them cannot observe a write to an instance it was handed. */
1787
+ const PURE_CALLS = new Set(["parseInt", "parseFloat", "isNaN", "isFinite"]);
1788
+ /** The identifier names a member (`o.value`), not the binding `o`. */
1789
+ function isMemberName(node) {
1790
+ const parent = node.parent;
1791
+ if (parent === undefined || ts.isShorthandPropertyAssignment(parent))
1792
+ return false;
1793
+ if (parent.name === node)
1794
+ return true;
1795
+ return ts.isBindingElement(parent) && parent.propertyName === node;
1796
+ }
1797
+ /** The node with parentheses, non-null assertions and type assertions
1798
+ * peeled off. */
1799
+ function unwrapExpression(node) {
1800
+ let outer = node;
1801
+ for (;;) {
1802
+ const parent = outer.parent;
1803
+ if (parent === undefined)
1804
+ return outer;
1805
+ if (!ts.isParenthesizedExpression(parent) &&
1806
+ !ts.isNonNullExpression(parent) &&
1807
+ !ts.isAssertionExpression(parent))
1808
+ return outer;
1809
+ outer = parent;
1810
+ }
1811
+ }
1812
+ /** A number, string, boolean, bigint, null or undefined (or a union of
1813
+ * them): a value a record copy carries by value. */
1814
+ function primitiveValue(type) {
1815
+ if (type.isUnionType())
1816
+ return ts.constituentTypes(type).every(primitiveValue);
1817
+ return ((type.flags &
1818
+ (ts.TypeFlags.Number |
1819
+ ts.TypeFlags.NumberLiteral |
1820
+ ts.TypeFlags.String |
1821
+ ts.TypeFlags.StringLiteral |
1822
+ ts.TypeFlags.Boolean |
1823
+ ts.TypeFlags.BooleanLiteral |
1824
+ ts.TypeFlags.BigInt |
1825
+ ts.TypeFlags.BigIntLiteral |
1826
+ ts.TypeFlags.Null |
1827
+ ts.TypeFlags.Undefined)) !==
1828
+ 0);
1829
+ }
1830
+ /** Whether the property read `access` is assigned, updated or deleted. */
1831
+ function isWrittenAccess(access) {
1832
+ let outer = access;
1833
+ for (;;) {
1834
+ const parent = outer.parent;
1835
+ if (parent !== undefined &&
1836
+ (ts.isParenthesizedExpression(parent) || ts.isNonNullExpression(parent))) {
1837
+ outer = parent;
1838
+ continue;
1839
+ }
1840
+ if (parent === undefined)
1841
+ return false;
1842
+ if (ts.isBinaryExpression(parent))
1843
+ return (parent.left === outer &&
1844
+ parent.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
1845
+ parent.operatorToken.kind <= ts.SyntaxKind.LastAssignment);
1846
+ if (ts.isPrefixUnaryExpression(parent) || ts.isPostfixUnaryExpression(parent))
1847
+ return parent.operand === outer;
1848
+ return ts.isDeleteExpression(parent);
1849
+ }
1850
+ }
1851
+ /** Whether `call` is one of the calls a copying callee may make: a numeric
1852
+ * builtin or console printer the program does not shadow, over values of
1853
+ * primitive type only (a coercion runs no hook on them). */
1854
+ function pureCall(call, checker) {
1855
+ const callee = call.expression;
1856
+ const global = (node) => libSymbol(attempt(() => checker.getSymbolAtLocation(node)));
1857
+ if (ts.isIdentifier(callee)) {
1858
+ if (!PURE_CALLS.has(callee.text) || !global(callee))
1859
+ return false;
1860
+ }
1861
+ else if (ts.isPropertyAccessExpression(callee) && ts.isIdentifier(callee.expression)) {
1862
+ const owner = callee.expression.text;
1863
+ if (owner !== "Math" && owner !== "Number" && owner !== "console")
1864
+ return false;
1865
+ if (!global(callee.expression) || !global(callee.name))
1866
+ return false;
1867
+ }
1868
+ else
1869
+ return false;
1870
+ const args = call.arguments?.nodes ?? [];
1871
+ return args.every((argument) => {
1872
+ if (ts.isSpreadElement(argument))
1873
+ return false;
1874
+ const type = attempt(() => checker.getTypeAtLocation(argument));
1875
+ return type !== undefined && primitiveValue(type);
1876
+ });
1877
+ }
1878
+ /** Whether every declaration of `symbol` is in a declaration file: the
1879
+ * binding is the library's own, not one the program shadows it with. */
1880
+ function libSymbol(symbol) {
1881
+ const declarations = symbol?.declarations;
1882
+ return (declarations !== undefined &&
1883
+ declarations.length > 0 &&
1884
+ declarations.every((declaration) => declaration.getSourceFile().isDeclarationFile));
1885
+ }
1886
+ /** Whether evaluating `node` can run program code — a call, a constructor, a
1887
+ * getter or a dynamic member read, an iterator, a coercion hook — and so
1888
+ * write an instance a copy was made of. */
1889
+ function expressionRunsCode(node, checker) {
1890
+ if (ts.isCallExpression(node))
1891
+ return !pureCall(node, checker);
1892
+ if (ts.isNewExpression(node))
1893
+ return true;
1894
+ if (ts.isElementAccessExpression(node))
1895
+ return true;
1896
+ if (ts.isPropertyAccessExpression(node))
1897
+ return accessRunsCode(node, checker);
1898
+ if (ts.isTemplateExpression(node)) {
1899
+ for (const span of node.templateSpans.nodes)
1900
+ if (!primitiveNode(span.expression, checker))
1901
+ return true;
1902
+ return false;
1903
+ }
1904
+ if (ts.isBinaryExpression(node)) {
1905
+ const operator = node.operatorToken.kind;
1906
+ if (operator === ts.SyntaxKind.InstanceOfKeyword)
1907
+ return true;
1908
+ if (operator >= ts.SyntaxKind.FirstAssignment && operator <= ts.SyntaxKind.LastAssignment)
1909
+ return true;
1910
+ return !primitiveOperands(node.left, node.right, checker);
1911
+ }
1912
+ if (ts.isPrefixUnaryExpression(node)) {
1913
+ const operator = node.operator;
1914
+ if (operator === ts.SyntaxKind.PlusPlusToken || operator === ts.SyntaxKind.MinusMinusToken)
1915
+ return true;
1916
+ if (operator !== ts.SyntaxKind.PlusToken &&
1917
+ operator !== ts.SyntaxKind.MinusToken &&
1918
+ operator !== ts.SyntaxKind.TildeToken)
1919
+ return false;
1920
+ return !primitiveNode(node.operand, checker);
1921
+ }
1922
+ if (ts.isPostfixUnaryExpression(node))
1923
+ return true;
1924
+ if (ts.isDeleteExpression(node) || ts.isAwaitExpression(node) || ts.isYieldExpression(node))
1925
+ return true;
1926
+ if (ts.isTaggedTemplateExpression(node))
1927
+ return true;
1928
+ if (ts.isForOfStatement(node))
1929
+ return true;
1930
+ if (ts.isSpreadElement(node) || ts.isSpreadAssignment(node))
1931
+ return true;
1932
+ return false;
1933
+ }
1934
+ /** Whether reading `access` can run program code: a getter, or a member of
1935
+ * a value the analysis knows nothing static about. */
1936
+ function accessRunsCode(access, checker) {
1937
+ const symbol = attempt(() => checker.getSymbolAtLocation(access.name));
1938
+ if (symbol === undefined)
1939
+ return true;
1940
+ if ((symbol.flags & (ts.SymbolFlags.GetAccessor | ts.SymbolFlags.SetAccessor)) !== 0)
1941
+ return true;
1942
+ const receiver = valueType(access.expression, checker);
1943
+ if (receiver === undefined)
1944
+ return true;
1945
+ return ((receiver.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.TypeParameter)) !== 0);
1946
+ }
1947
+ /** Whether both operand types are primitive, so an operator between them
1948
+ * runs no value coercion. */
1949
+ function primitiveOperands(left, right, checker) {
1950
+ return primitiveNode(left, checker) && primitiveNode(right, checker);
1951
+ }
1952
+ /** The type of `node`'s value, ignoring parentheses, non-null assertions and
1953
+ * type assertions: a cast does not change what the value is at run time. */
1954
+ function valueType(node, checker) {
1955
+ let current = node;
1956
+ while (ts.isParenthesizedExpression(current) ||
1957
+ ts.isNonNullExpression(current) ||
1958
+ ts.isAssertionExpression(current))
1959
+ current = current.expression;
1960
+ return attempt(() => checker.getTypeAtLocation(current));
1961
+ }
1962
+ /** Whether the value of `node` has a primitive type, so coercing it runs no
1963
+ * value hook. */
1964
+ function primitiveNode(node, checker) {
1965
+ const type = valueType(node, checker);
1966
+ return type !== undefined && primitiveValue(type);
1967
+ }
1968
+ /** Whether `root` contains an expression that runs program code. */
1969
+ function containsProgramCode(root, checker) {
1970
+ let runs = false;
1971
+ ts.walkPreorder(root, (node) => {
1972
+ if (runs)
1973
+ return "stop";
1974
+ if (ts.isTypeNode(node))
1975
+ return "skip";
1976
+ if (ts.isFunctionLike(node))
1977
+ return "skip";
1978
+ // A class body's computed keys and static fields run when the class is
1979
+ // evaluated.
1980
+ if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) {
1981
+ runs = true;
1982
+ return "stop";
1983
+ }
1984
+ if (expressionRunsCode(node, checker)) {
1985
+ runs = true;
1986
+ return "stop";
1987
+ }
1988
+ return undefined;
1989
+ });
1990
+ return runs;
1991
+ }
1992
+ /** Whether `node` mentions the binding `name`. */
1993
+ function mentionsBinding(node, name) {
1994
+ let found = false;
1995
+ ts.walkPreorder(node, (child) => {
1996
+ if (found)
1997
+ return "stop";
1998
+ if (ts.isIdentifier(child) && child.text === name && !isMemberName(child)) {
1999
+ found = true;
2000
+ return "stop";
2001
+ }
2002
+ return undefined;
2003
+ });
2004
+ return found;
2005
+ }
1439
2006
  /** The static property name a member declares, or null for a computed key
1440
2007
  * (its name is not a compile-time fact). */
1441
2008
  function propertyNameText(name) {