@scriptc/compiler 0.3.3 → 0.3.5

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 (352) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +844 -36
  2. package/dist/backend/cycle-mutability.d.ts +5 -0
  3. package/dist/backend/cycle-mutability.js +62 -3
  4. package/dist/backend/cycle-mutability.js.map +1 -1
  5. package/dist/backend/executable-features.js +1 -0
  6. package/dist/backend/executable-features.js.map +1 -1
  7. package/dist/backend/library-pack.js +1 -0
  8. package/dist/backend/library-pack.js.map +1 -1
  9. package/dist/backend/llvm/array-search.js +1 -1
  10. package/dist/backend/llvm/array-search.js.map +1 -1
  11. package/dist/backend/llvm/call-lifetimes.d.ts +11 -1
  12. package/dist/backend/llvm/call-lifetimes.js +30 -3
  13. package/dist/backend/llvm/call-lifetimes.js.map +1 -1
  14. package/dist/backend/llvm/call-lifetimes.test.js +31 -1
  15. package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
  16. package/dist/backend/llvm/common.d.ts +5 -0
  17. package/dist/backend/llvm/common.js +7 -0
  18. package/dist/backend/llvm/common.js.map +1 -1
  19. package/dist/backend/llvm/constant-callbacks.d.ts +2 -21
  20. package/dist/backend/llvm/constant-callbacks.js +36 -219
  21. package/dist/backend/llvm/constant-callbacks.js.map +1 -1
  22. package/dist/backend/llvm/constant-callbacks.test.js +22 -0
  23. package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
  24. package/dist/backend/llvm/dense-array-access.d.ts +9 -0
  25. package/dist/backend/llvm/dense-array-access.js +29 -3
  26. package/dist/backend/llvm/dense-array-access.js.map +1 -1
  27. package/dist/backend/llvm/dyn.d.ts +46 -1
  28. package/dist/backend/llvm/dyn.js +218 -33
  29. package/dist/backend/llvm/dyn.js.map +1 -1
  30. package/dist/backend/llvm/emitter.d.ts +87 -1
  31. package/dist/backend/llvm/emitter.js +568 -61
  32. package/dist/backend/llvm/emitter.js.map +1 -1
  33. package/dist/backend/llvm/expr-async.js +17 -7
  34. package/dist/backend/llvm/expr-async.js.map +1 -1
  35. package/dist/backend/llvm/expr-bytes.d.ts +9 -0
  36. package/dist/backend/llvm/expr-bytes.js +159 -64
  37. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  38. package/dist/backend/llvm/expr-callbacks.d.ts +11 -0
  39. package/dist/backend/llvm/expr-callbacks.js +53 -0
  40. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  41. package/dist/backend/llvm/expr-calls.d.ts +3 -1
  42. package/dist/backend/llvm/expr-calls.js +137 -3
  43. package/dist/backend/llvm/expr-calls.js.map +1 -1
  44. package/dist/backend/llvm/expr-containers.js +63 -29
  45. package/dist/backend/llvm/expr-containers.js.map +1 -1
  46. package/dist/backend/llvm/expr-primitives.js +9 -1
  47. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  48. package/dist/backend/llvm/expr-stream-bridges.js +4 -0
  49. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  50. package/dist/backend/llvm/integer-clones.d.ts +103 -0
  51. package/dist/backend/llvm/integer-clones.js +1336 -0
  52. package/dist/backend/llvm/integer-clones.js.map +1 -0
  53. package/dist/backend/llvm/integer-clones.test.d.ts +1 -0
  54. package/dist/backend/llvm/integer-clones.test.js +219 -0
  55. package/dist/backend/llvm/integer-clones.test.js.map +1 -0
  56. package/dist/backend/llvm/intern-tables.test.d.ts +1 -0
  57. package/dist/backend/llvm/intern-tables.test.js +77 -0
  58. package/dist/backend/llvm/intern-tables.test.js.map +1 -0
  59. package/dist/backend/llvm/lib-datagram.js +24 -0
  60. package/dist/backend/llvm/lib-datagram.js.map +1 -1
  61. package/dist/backend/llvm/lib-dispatch.js +96 -1
  62. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  63. package/dist/backend/llvm/lib-filesystem.js +51 -0
  64. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  65. package/dist/backend/llvm/lib-network.js +16 -0
  66. package/dist/backend/llvm/lib-network.js.map +1 -1
  67. package/dist/backend/llvm/lib-process.js +24 -0
  68. package/dist/backend/llvm/lib-process.js.map +1 -1
  69. package/dist/backend/llvm/lib-shared.d.ts +5 -0
  70. package/dist/backend/llvm/lib-shared.js +114 -3
  71. package/dist/backend/llvm/lib-shared.js.map +1 -1
  72. package/dist/backend/llvm/lib-stream.js +87 -0
  73. package/dist/backend/llvm/lib-stream.js.map +1 -1
  74. package/dist/backend/llvm/lib-test.js +9 -0
  75. package/dist/backend/llvm/lib-test.js.map +1 -1
  76. package/dist/backend/llvm/lib-tls.js +6 -0
  77. package/dist/backend/llvm/lib-tls.js.map +1 -1
  78. package/dist/backend/llvm/local-array-reads.js +1 -1
  79. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  80. package/dist/backend/llvm/map-entry-fusion.d.ts +28 -0
  81. package/dist/backend/llvm/map-entry-fusion.js +233 -0
  82. package/dist/backend/llvm/map-entry-fusion.js.map +1 -0
  83. package/dist/backend/llvm/map-entry-fusion.test.d.ts +1 -0
  84. package/dist/backend/llvm/map-entry-fusion.test.js +183 -0
  85. package/dist/backend/llvm/map-entry-fusion.test.js.map +1 -0
  86. package/dist/backend/llvm/map-number-lookup.d.ts +6 -0
  87. package/dist/backend/llvm/map-number-lookup.js +23 -1
  88. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  89. package/dist/backend/llvm/map-number-lookup.test.js +60 -5
  90. package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
  91. package/dist/backend/llvm/map-read-lifetimes.d.ts +11 -0
  92. package/dist/backend/llvm/map-read-lifetimes.js +92 -1
  93. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
  94. package/dist/backend/llvm/map-read-lifetimes.test.js +131 -3
  95. package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
  96. package/dist/backend/llvm/publish.d.ts +21 -0
  97. package/dist/backend/llvm/publish.js +101 -11
  98. package/dist/backend/llvm/publish.js.map +1 -1
  99. package/dist/backend/llvm/publish.test.d.ts +1 -0
  100. package/dist/backend/llvm/publish.test.js +94 -0
  101. package/dist/backend/llvm/publish.test.js.map +1 -0
  102. package/dist/backend/llvm/record-results.js +76 -2
  103. package/dist/backend/llvm/record-results.js.map +1 -1
  104. package/dist/backend/llvm/record-sources.d.ts +7 -0
  105. package/dist/backend/llvm/record-sources.js +14 -0
  106. package/dist/backend/llvm/record-sources.js.map +1 -0
  107. package/dist/backend/llvm/reference-writes.js +5 -2
  108. package/dist/backend/llvm/reference-writes.js.map +1 -1
  109. package/dist/backend/llvm/regions.d.ts +4 -1
  110. package/dist/backend/llvm/regions.js +12 -3
  111. package/dist/backend/llvm/regions.js.map +1 -1
  112. package/dist/backend/llvm/shapes.d.ts +9 -3
  113. package/dist/backend/llvm/shapes.js +18 -14
  114. package/dist/backend/llvm/shapes.js.map +1 -1
  115. package/dist/backend/llvm/shapes.test.js +5 -3
  116. package/dist/backend/llvm/shapes.test.js.map +1 -1
  117. package/dist/backend/llvm/string-lifetimes.test.js +75 -1
  118. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
  119. package/dist/backend/llvm/string-reads.js +2 -2
  120. package/dist/backend/llvm/string-reads.js.map +1 -1
  121. package/dist/backend/llvm/string-slices.js +2 -2
  122. package/dist/backend/llvm/string-slices.js.map +1 -1
  123. package/dist/backend/llvm/walkers.d.ts +17 -0
  124. package/dist/backend/llvm/walkers.js +123 -0
  125. package/dist/backend/llvm/walkers.js.map +1 -1
  126. package/dist/backend/may-throw.js +4 -0
  127. package/dist/backend/may-throw.js.map +1 -1
  128. package/dist/backend/native/contracts.d.ts +5 -1
  129. package/dist/backend/native/executable.js +16 -6
  130. package/dist/backend/native/executable.js.map +1 -1
  131. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  132. package/dist/backend/native/runtime-inputs.js +1 -0
  133. package/dist/backend/native/runtime-inputs.js.map +1 -1
  134. package/dist/backend/native-codegen-core.d.ts +4 -4
  135. package/dist/backend/native-codegen-core.js +4 -6
  136. package/dist/backend/native-codegen-core.js.map +1 -1
  137. package/dist/backend/native-codegen.test.js +7 -8
  138. package/dist/backend/native-codegen.test.js.map +1 -1
  139. package/dist/backend/native-link-info-core.d.ts +3 -0
  140. package/dist/backend/native-link-info-core.js.map +1 -1
  141. package/dist/backend/publication.js +3 -1
  142. package/dist/backend/publication.js.map +1 -1
  143. package/dist/backend/runtime-abi.d.ts +2 -2
  144. package/dist/backend/runtime-abi.js +2 -2
  145. package/dist/backend/runtime-pack-targets.test.js +2 -1
  146. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  147. package/dist/backend/runtime-pack.test.js +2 -1
  148. package/dist/backend/runtime-pack.test.js.map +1 -1
  149. package/dist/backend/target-diagnostics.js +7 -0
  150. package/dist/backend/target-diagnostics.js.map +1 -1
  151. package/dist/backend/warm-cache.js +1 -0
  152. package/dist/backend/warm-cache.js.map +1 -1
  153. package/dist/executable/executable-cache.d.ts +1 -0
  154. package/dist/executable/executable-cache.js +1 -0
  155. package/dist/executable/executable-cache.js.map +1 -1
  156. package/dist/executable/executable-cache.test.js +1 -0
  157. package/dist/executable/executable-cache.test.js.map +1 -1
  158. package/dist/frontend/experimental-import.d.ts +5 -1
  159. package/dist/frontend/experimental-import.js +28 -3
  160. package/dist/frontend/experimental-import.js.map +1 -1
  161. package/dist/frontend/lowering/assert-instances.d.ts +38 -0
  162. package/dist/frontend/lowering/assert-instances.js +269 -0
  163. package/dist/frontend/lowering/assert-instances.js.map +1 -0
  164. package/dist/frontend/lowering/builtin-calls.js +3 -0
  165. package/dist/frontend/lowering/builtin-calls.js.map +1 -1
  166. package/dist/frontend/lowering/builtins/callable-aliases.js +54 -8
  167. package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
  168. package/dist/frontend/lowering/builtins/child-process-async.d.ts +8 -6
  169. package/dist/frontend/lowering/builtins/child-process-async.js +45 -29
  170. package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
  171. package/dist/frontend/lowering/builtins/compression.d.ts +18 -0
  172. package/dist/frontend/lowering/builtins/compression.js +175 -2
  173. package/dist/frontend/lowering/builtins/compression.js.map +1 -1
  174. package/dist/frontend/lowering/builtins/constants.js +7 -2
  175. package/dist/frontend/lowering/builtins/constants.js.map +1 -1
  176. package/dist/frontend/lowering/builtins/crypto.d.ts +6 -0
  177. package/dist/frontend/lowering/builtins/crypto.js +111 -1
  178. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  179. package/dist/frontend/lowering/builtins/errors.js +23 -0
  180. package/dist/frontend/lowering/builtins/errors.js.map +1 -1
  181. package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +2 -0
  182. package/dist/frontend/lowering/builtins/filesystem-calls.js +5 -0
  183. package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
  184. package/dist/frontend/lowering/builtins/filesystem.js +60 -0
  185. package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
  186. package/dist/frontend/lowering/builtins/fs-streams.d.ts +26 -0
  187. package/dist/frontend/lowering/builtins/fs-streams.js +131 -0
  188. package/dist/frontend/lowering/builtins/fs-streams.js.map +1 -0
  189. package/dist/frontend/lowering/builtins/module-calls.js +5 -1
  190. package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
  191. package/dist/frontend/lowering/builtins/timers.d.ts +3 -0
  192. package/dist/frontend/lowering/builtins/timers.js +109 -23
  193. package/dist/frontend/lowering/builtins/timers.js.map +1 -1
  194. package/dist/frontend/lowering/call-signatures.js +6 -0
  195. package/dist/frontend/lowering/call-signatures.js.map +1 -1
  196. package/dist/frontend/lowering/class-dynamic-dispatch.js +216 -20
  197. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  198. package/dist/frontend/lowering/containers/bytes.js +33 -12
  199. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  200. package/dist/frontend/lowering/devirtualize.js +20 -7
  201. package/dist/frontend/lowering/devirtualize.js.map +1 -1
  202. package/dist/frontend/lowering/intern-tables.d.ts +13 -0
  203. package/dist/frontend/lowering/intern-tables.js +536 -0
  204. package/dist/frontend/lowering/intern-tables.js.map +1 -0
  205. package/dist/frontend/lowering/lower-assert.js +700 -61
  206. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  207. package/dist/frontend/lowering/lower-async-iteration.js +11 -2
  208. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  209. package/dist/frontend/lowering/lower-calls.js +75 -6
  210. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  211. package/dist/frontend/lowering/lower-classes.d.ts +3 -0
  212. package/dist/frontend/lowering/lower-classes.js +43 -0
  213. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  214. package/dist/frontend/lowering/lower-dgram.js +132 -67
  215. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  216. package/dist/frontend/lowering/lower-event-emitter.d.ts +9 -1
  217. package/dist/frontend/lowering/lower-event-emitter.js +78 -0
  218. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  219. package/dist/frontend/lowering/lower-exprs.d.ts +4 -0
  220. package/dist/frontend/lowering/lower-exprs.js +144 -58
  221. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  222. package/dist/frontend/lowering/lower-inspect.d.ts +6 -0
  223. package/dist/frontend/lowering/lower-inspect.js +138 -39
  224. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  225. package/dist/frontend/lowering/lower-mock.d.ts +11 -0
  226. package/dist/frontend/lowering/lower-mock.js +504 -0
  227. package/dist/frontend/lowering/lower-mock.js.map +1 -0
  228. package/dist/frontend/lowering/lower-modules.js +7 -0
  229. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  230. package/dist/frontend/lowering/lower-server.d.ts +4 -0
  231. package/dist/frontend/lowering/lower-server.js +448 -30
  232. package/dist/frontend/lowering/lower-server.js.map +1 -1
  233. package/dist/frontend/lowering/lower-stmts.js +35 -8
  234. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  235. package/dist/frontend/lowering/lower-stream.d.ts +10 -6
  236. package/dist/frontend/lowering/lower-stream.js +794 -27
  237. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  238. package/dist/frontend/lowering/lower-test.js +86 -8
  239. package/dist/frontend/lowering/lower-test.js.map +1 -1
  240. package/dist/frontend/lowering/lowerer.d.ts +25 -1
  241. package/dist/frontend/lowering/lowerer.js +74 -9
  242. package/dist/frontend/lowering/lowerer.js.map +1 -1
  243. package/dist/frontend/lowering/pairs-snapshot.d.ts +6 -0
  244. package/dist/frontend/lowering/pairs-snapshot.js +49 -0
  245. package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
  246. package/dist/frontend/lowering/record-sources.d.ts +15 -0
  247. package/dist/frontend/lowering/record-sources.js +46 -0
  248. package/dist/frontend/lowering/record-sources.js.map +1 -0
  249. package/dist/frontend/lowering/surfaces.d.ts +4 -0
  250. package/dist/frontend/lowering/surfaces.js +94 -16
  251. package/dist/frontend/lowering/surfaces.js.map +1 -1
  252. package/dist/frontend/lowering/zlib-constants.d.ts +1 -0
  253. package/dist/frontend/lowering/zlib-constants.js +181 -0
  254. package/dist/frontend/lowering/zlib-constants.js.map +1 -0
  255. package/dist/frontend/mock-shapes.d.ts +10 -0
  256. package/dist/frontend/mock-shapes.js +76 -0
  257. package/dist/frontend/mock-shapes.js.map +1 -0
  258. package/dist/frontend/pipeline.js +5 -3
  259. package/dist/frontend/pipeline.js.map +1 -1
  260. package/dist/frontend/program.js +6 -1
  261. package/dist/frontend/program.js.map +1 -1
  262. package/dist/frontend/resolve.d.ts +4 -0
  263. package/dist/frontend/resolve.js +14 -0
  264. package/dist/frontend/resolve.js.map +1 -1
  265. package/dist/frontend/tsc-codes.js +1 -0
  266. package/dist/frontend/tsc-codes.js.map +1 -1
  267. package/dist/frontend/type-mapper.d.ts +8 -0
  268. package/dist/frontend/type-mapper.js +155 -9
  269. package/dist/frontend/type-mapper.js.map +1 -1
  270. package/dist/index.js +2 -1
  271. package/dist/index.js.map +1 -1
  272. package/dist/ir/analysis.d.ts +10 -0
  273. package/dist/ir/analysis.js +35 -0
  274. package/dist/ir/analysis.js.map +1 -1
  275. package/dist/ir/analysis.test.js +69 -1
  276. package/dist/ir/analysis.test.js.map +1 -1
  277. package/dist/ir/builtin-effects.js +72 -0
  278. package/dist/ir/builtin-effects.js.map +1 -1
  279. package/dist/ir/builtin-signatures.d.ts +1 -1
  280. package/dist/ir/builtin-signatures.js +238 -15
  281. package/dist/ir/builtin-signatures.js.map +1 -1
  282. package/dist/ir/capture-values.d.ts +107 -0
  283. package/dist/ir/capture-values.js +850 -0
  284. package/dist/ir/capture-values.js.map +1 -0
  285. package/dist/ir/capture-values.test.d.ts +1 -0
  286. package/dist/ir/capture-values.test.js +268 -0
  287. package/dist/ir/capture-values.test.js.map +1 -0
  288. package/dist/ir/field-values.d.ts +16 -0
  289. package/dist/ir/field-values.js +128 -0
  290. package/dist/ir/field-values.js.map +1 -0
  291. package/dist/ir/field-values.test.d.ts +1 -0
  292. package/dist/ir/field-values.test.js +160 -0
  293. package/dist/ir/field-values.test.js.map +1 -0
  294. package/dist/ir/final-fields.d.ts +4 -1
  295. package/dist/ir/final-fields.js +11 -3
  296. package/dist/ir/final-fields.js.map +1 -1
  297. package/dist/ir/function-references.test.js +1 -1
  298. package/dist/ir/function-references.test.js.map +1 -1
  299. package/dist/ir/init-only-globals.d.ts +16 -0
  300. package/dist/ir/init-only-globals.js +121 -0
  301. package/dist/ir/init-only-globals.js.map +1 -0
  302. package/dist/ir/init-only-globals.test.d.ts +1 -0
  303. package/dist/ir/init-only-globals.test.js +115 -0
  304. package/dist/ir/init-only-globals.test.js.map +1 -0
  305. package/dist/ir/initializer-bindings.d.ts +18 -1
  306. package/dist/ir/initializer-bindings.js +91 -1
  307. package/dist/ir/initializer-bindings.js.map +1 -1
  308. package/dist/ir/initializer-bindings.test.js +57 -2
  309. package/dist/ir/initializer-bindings.test.js.map +1 -1
  310. package/dist/ir/int32-slots.d.ts +22 -0
  311. package/dist/ir/int32-slots.js +376 -13
  312. package/dist/ir/int32-slots.js.map +1 -1
  313. package/dist/ir/int32-slots.test.js +91 -8
  314. package/dist/ir/int32-slots.test.js.map +1 -1
  315. package/dist/ir/integer-loop-facts.d.ts +19 -1
  316. package/dist/ir/integer-loop-facts.js +155 -7
  317. package/dist/ir/integer-loop-facts.js.map +1 -1
  318. package/dist/ir/integer-ranges.d.ts +8 -5
  319. package/dist/ir/integer-ranges.js +147 -55
  320. package/dist/ir/integer-ranges.js.map +1 -1
  321. package/dist/ir/integer-ranges.test.js +225 -7
  322. package/dist/ir/integer-ranges.test.js.map +1 -1
  323. package/dist/ir/ir.d.ts +29 -2
  324. package/dist/ir/ir.js +17 -0
  325. package/dist/ir/ir.js.map +1 -1
  326. package/dist/ir/property-bags.d.ts +14 -0
  327. package/dist/ir/property-bags.js +121 -0
  328. package/dist/ir/property-bags.js.map +1 -0
  329. package/dist/ir/receiver-readers.d.ts +21 -0
  330. package/dist/ir/receiver-readers.js +217 -0
  331. package/dist/ir/receiver-readers.js.map +1 -0
  332. package/dist/ir/runtime-features.d.ts +1 -0
  333. package/dist/ir/runtime-features.js +34 -2
  334. package/dist/ir/runtime-features.js.map +1 -1
  335. package/dist/ir/validate.js +221 -5
  336. package/dist/ir/validate.js.map +1 -1
  337. package/dist/ir/validate.test.js +21 -0
  338. package/dist/ir/validate.test.js.map +1 -1
  339. package/dist/library/int-infer.js +3 -0
  340. package/dist/library/int-infer.js.map +1 -1
  341. package/dist/library/ir-policy.js +1 -0
  342. package/dist/library/ir-policy.js.map +1 -1
  343. package/dist/native/cli.js +1 -0
  344. package/dist/native/cli.js.map +1 -1
  345. package/dist/native/compiler.js +1 -3
  346. package/dist/native/compiler.js.map +1 -1
  347. package/dist/native/prepare.js +1 -0
  348. package/dist/native/prepare.js.map +1 -1
  349. package/dist/native/sanitizer.test.js +1 -0
  350. package/dist/native/sanitizer.test.js.map +1 -1
  351. package/package.json +20 -20
  352. package/surface-manifest.json +896 -49
@@ -3,7 +3,7 @@ import * as ts from "../ts7/adapter.js";
3
3
  import { ladderFenceExpr } from "./lowerer.js";
4
4
  import { isJsSourceFile, locOf } from "../program.js";
5
5
  import { arrayOf, BOOL, BYTES_U8, canBoxFuncIntoDyn, canConvertToDyn, DYN, DYN_HANDLE_KINDS, F64, funcOf, HTTP2SESSION_T, HTTP2STREAM_T, HTTPCLIENTREQ_T, HTTPREQ_T, HTTPRES_T, NETSERVER_T, NETSOCKET_T, NULL_T, SECURECTX_T, STRING, UNDEFINED_T, typeKey, VOID, } from "../../ir/ir.js";
6
- import { AGENT_DOCUMENTED_OPTIONS, builtinFenceHintOf, builtinModuleFnOf, fenceOrDropOptionKey, HTTP_CLIENT_DOCUMENTED_OPTIONS, HTTP_SERVER_DOCUMENTED_OPTIONS, HTTP2_SECURE_SERVER_DOCUMENTED_OPTIONS, HTTPS_CLIENT_DOCUMENTED_OPTIONS, sideEffectFreeOptionValue, TLS_SERVER_DOCUMENTED_OPTIONS, } from "./surfaces.js";
6
+ import { AGENT_DOCUMENTED_OPTIONS, HTTPS_AGENT_DOCUMENTED_OPTIONS, builtinFenceHintOf, builtinModuleFnOf, fenceOrDropOptionKey, HTTP_CLIENT_DOCUMENTED_OPTIONS, HTTP_SERVER_DOCUMENTED_OPTIONS, HTTP2_SECURE_SERVER_DOCUMENTED_OPTIONS, HTTPS_CLIENT_DOCUMENTED_OPTIONS, sideEffectFreeOptionValue, TLS_SERVER_DOCUMENTED_OPTIONS, } from "./surfaces.js";
7
7
  import { conditionalSpreadOf } from "./expressions/object-literals.js";
8
8
  import { resultIsDiscarded } from "./call-position.js";
9
9
  import { lowerCallbackArg as lowerCallbackArgShared } from "./callback-arg.js";
@@ -166,7 +166,7 @@ export function voidizedCallback(lowerer, cb, loc) {
166
166
  body: [
167
167
  {
168
168
  kind: "return",
169
- value: { kind: "closure", fnName: impl, captures: ["f.0"], type: toT, loc },
169
+ value: { kind: "closure", fnName: impl, captures: ["f.0"], type: toT, adapts: true, loc },
170
170
  loc,
171
171
  },
172
172
  ],
@@ -175,6 +175,20 @@ export function voidizedCallback(lowerer, cb, loc) {
175
175
  }
176
176
  return { kind: "call", callee: name, args: [cb], type: toT, loc };
177
177
  }
178
+ /** A socket or server listener with parameters that the runtime calls
179
+ * through the checked-dynamic boundary (close(hadError), write's
180
+ * cb(err), 'drop', getConnections): a dyn function value as is, or a
181
+ * typed function boxed with per-argument checks. */
182
+ function lowerSocketDynListener(lowerer, node, what) {
183
+ const cb = lowerer.lowerExpr(node);
184
+ if (cb.type.kind === "dyn")
185
+ return cb;
186
+ if (cb.type.kind === "func" &&
187
+ canBoxFuncIntoDyn(cb.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
188
+ return { kind: "dynFrom", value: cb, type: DYN, loc: locOf(node) };
189
+ }
190
+ lowerer.noLowering(`${what} that cannot cross the checked-dynamic boundary`, node, "the callback's parameters and return value must have checked-dynamic conversions");
191
+ }
178
192
  /** A registration/side-effect libCall re-shaped to answer its RECEIVER —
179
193
  * Node's `return this` chaining (server.listen(...), res.writeHead(...)):
180
194
  * an interned helper runs the void call and returns its first argument.
@@ -1030,6 +1044,35 @@ export function lowerHttpServerTimeoutAssignment(lowerer, left, right, loc) {
1030
1044
  loc,
1031
1045
  };
1032
1046
  }
1047
+ /** `server.maxConnections = n`: the value crosses as a dyn (undefined
1048
+ * and null unset the cap). `server.dropMaxConnection = v` stores the
1049
+ * value as is (Node reads it only in cluster mode). */
1050
+ export function lowerNetServerMaxConnectionsAssignment(lowerer, left, right, loc) {
1051
+ if (!ts.isPropertyAccessExpression(left) || left.questionDotToken)
1052
+ return null;
1053
+ const name = left.name.text;
1054
+ if (name !== "maxConnections" && name !== "dropMaxConnection")
1055
+ return null;
1056
+ if (lowerer.mapTypeOf(lowerer.typeOf(left.expression))?.kind !== "netServer")
1057
+ return null;
1058
+ if (!lowerer.isStdlibMember(left))
1059
+ return null;
1060
+ const receiver = coerceToHandle(lowerer, left.expression, NETSERVER_T);
1061
+ const value = lowerer.coerceToExpected(lowerer.lowerExpr(right), DYN);
1062
+ return {
1063
+ kind: "exprStmt",
1064
+ expr: {
1065
+ kind: "libCall",
1066
+ fn: name === "maxConnections"
1067
+ ? "net.serverMaxConnectionsSet"
1068
+ : "net.serverDropMaxConnectionSet",
1069
+ args: [receiver, value],
1070
+ type: VOID,
1071
+ loc,
1072
+ },
1073
+ loc,
1074
+ };
1075
+ }
1033
1076
  /** Method calls on net.Server receivers: listen(port[, cb]), close([cb]),
1034
1077
  * on/once("connection" | "error" | "close", cb). address() alone fences
1035
1078
  * toward the composed address().port read. Null for other receivers. */
@@ -1041,6 +1084,24 @@ function lowerNetServerMethodCall(lowerer, call, access) {
1041
1084
  const name = access.name.text;
1042
1085
  const loc = locOf(call);
1043
1086
  const args = call.arguments;
1087
+ if (name === "getConnections") {
1088
+ // cb(null, count) on the next tick; answers the server.
1089
+ if (args.length !== 1) {
1090
+ lowerer.noLowering(`getConnections with ${args.length} arguments`, call, "the form is getConnections(callback)");
1091
+ }
1092
+ const receiver = coerceToHandle(lowerer, access.expression, NETSERVER_T);
1093
+ const cb = lowerSocketDynListener(lowerer, args[0], "getConnections callbacks");
1094
+ if (resultIsDiscarded(call)) {
1095
+ return {
1096
+ kind: "libCall",
1097
+ fn: "net.serverGetConnections",
1098
+ args: [receiver, cb],
1099
+ type: VOID,
1100
+ loc,
1101
+ };
1102
+ }
1103
+ return receiverReturningCall(lowerer, "net.serverGetConnections", [receiver, cb], NETSERVER_T, loc);
1104
+ }
1044
1105
  if (name === "setTimeout") {
1045
1106
  if (args.length < 1 || args.length > 2)
1046
1107
  lowerer.noLowering("server.setTimeout arguments", call, "pass milliseconds and an optional socket callback");
@@ -1356,6 +1417,17 @@ function lowerNetServerMethodCall(lowerer, call, access) {
1356
1417
  loc,
1357
1418
  };
1358
1419
  }
1420
+ if (event === "drop") {
1421
+ // A connection past maxConnections, with its local and remote
1422
+ // addresses.
1423
+ return {
1424
+ kind: "libCall",
1425
+ fn: "net.serverOnDrop",
1426
+ args: [receiver, lowerSocketDynListener(lowerer, args[1], "drop listeners"), once],
1427
+ type: VOID,
1428
+ loc,
1429
+ };
1430
+ }
1359
1431
  if (event === "session") {
1360
1432
  // The h2c server's per-connection session event: (session). The
1361
1433
  // result is voidized; the handle passes by reference.
@@ -1450,7 +1522,7 @@ function lowerNetServerMethodCall(lowerer, call, access) {
1450
1522
  loc,
1451
1523
  };
1452
1524
  }
1453
- lowerer.noLowering(`server.${name}(${event === null ? "non-literal event" : `"${event}"`}, ...)`, args[0], '"connection", "request", "stream", "session", "upgrade", "connect", "error", "close", "listening", and "sessionError" are the supported server events (as literals)');
1525
+ lowerer.noLowering(`server.${name}(${event === null ? "non-literal event" : `"${event}"`}, ...)`, args[0], '"connection", "request", "drop", "stream", "session", "upgrade", "connect", "error", "close", "listening", and "sessionError" are the supported server events (as literals)');
1454
1526
  }
1455
1527
  if (name === "emit") {
1456
1528
  // The demux route: emit("connection", socket) hands an accepted
@@ -1497,11 +1569,51 @@ function lowerNetServerMethodCall(lowerer, call, access) {
1497
1569
  lowerer.noLowering(`address with ${args.length} arguments`, call, "address() takes no arguments");
1498
1570
  }
1499
1571
  const result = lowerer.mapTypeOf(lowerer.typeOf(call));
1500
- if (!result || !isAddressInfoRecord(lowerer, result)) {
1572
+ if (result && isAddressInfoRecord(lowerer, result)) {
1573
+ const receiver = coerceToHandle(lowerer, access.expression, NETSERVER_T);
1574
+ return { kind: "libCall", fn: "net.serverAddress", args: [receiver], type: result, loc };
1575
+ }
1576
+ // @types/node's `string | AddressInfo | null`: the record while the
1577
+ // server listens (a TCP server never answers the pipe-path string),
1578
+ // null otherwise, like Node.
1579
+ const arms = result?.kind === "union" ? (lowerer.unions.get(result.unionId)?.arms ?? []) : [];
1580
+ const record = arms.find((arm) => isAddressInfoRecord(lowerer, arm));
1581
+ const nullTag = result?.kind === "union" ? lowerer.armTag(result.unionId, NULL_T) : -1;
1582
+ if (!result || result.kind !== "union" || record === undefined || nullTag < 0) {
1501
1583
  lowerer.noLowering("address() where the result is not the {address, family, port} record", call, "the AddressInfo shape is the supported result");
1502
1584
  }
1585
+ const unionId = result.unionId;
1503
1586
  const receiver = coerceToHandle(lowerer, access.expression, NETSERVER_T);
1504
- return { kind: "libCall", fn: "net.serverAddress", args: [receiver], type: result, loc };
1587
+ const local = lowerer.declareHiddenLocal("%addressServer", NETSERVER_T);
1588
+ const server = varRef(local.id, NETSERVER_T, loc);
1589
+ return {
1590
+ kind: "seqExpr",
1591
+ stmts: [{ kind: "varDecl", localId: local.id, init: receiver, loc }],
1592
+ result: {
1593
+ kind: "ternary",
1594
+ cond: { kind: "libCall", fn: "net.serverListening", args: [server], type: BOOL, loc },
1595
+ then: {
1596
+ kind: "unionWrap",
1597
+ unionId,
1598
+ tag: lowerer.armTag(unionId, record),
1599
+ value: { kind: "libCall", fn: "net.serverAddress", args: [server], type: record, loc },
1600
+ type: result,
1601
+ loc,
1602
+ },
1603
+ else_: {
1604
+ kind: "unionWrap",
1605
+ unionId,
1606
+ tag: nullTag,
1607
+ value: { kind: "unitLit", unit: "null", type: NULL_T, loc },
1608
+ type: result,
1609
+ loc,
1610
+ },
1611
+ type: result,
1612
+ loc,
1613
+ },
1614
+ type: result,
1615
+ loc,
1616
+ };
1505
1617
  }
1506
1618
  lowerer.noLowering(`Server.${name}`, call, 'listen, close, address().port, emit("connection", socket), and on/once of connection/request/upgrade/error/close/listening/sessionError are the supported Server members', lowerer.checker.getSymbolAtLocation(access.name));
1507
1619
  }
@@ -1556,6 +1668,79 @@ function lowerNetSocketMethodCall(lowerer, call, access) {
1556
1668
  }
1557
1669
  }
1558
1670
  }
1671
+ // A trailing callback: write's runs once the data is flushed (with
1672
+ // null for the error), end's once the socket finishes ('finish').
1673
+ const last = args.length > 0 ? args[args.length - 1] : null;
1674
+ if (last !== null &&
1675
+ args.length <= 2 &&
1676
+ (name === "end" || args.length === 2) &&
1677
+ lowerer.checker.getCallSignatures(lowerer.typeOf(last)).length > 0) {
1678
+ const sockLocal = lowerer.declareHiddenLocal("%sockCb", NETSOCKET_T);
1679
+ const stmts = [
1680
+ {
1681
+ kind: "varDecl",
1682
+ localId: sockLocal.id,
1683
+ init: coerceToHandle(lowerer, access.expression, NETSOCKET_T),
1684
+ loc,
1685
+ },
1686
+ ];
1687
+ const receiver = () => ({
1688
+ kind: "varRef",
1689
+ localId: sockLocal.id,
1690
+ type: NETSOCKET_T,
1691
+ loc,
1692
+ });
1693
+ const dataNode = args.length === 2 ? args[0] : null;
1694
+ let main = {
1695
+ kind: "libCall",
1696
+ fn: "net.sockEnd",
1697
+ args: [receiver()],
1698
+ type: VOID,
1699
+ loc,
1700
+ };
1701
+ if (dataNode !== null) {
1702
+ const data = lowerer.lowerExpr(dataNode);
1703
+ const fn = data.type.kind === "string"
1704
+ ? name === "write"
1705
+ ? "net.sockWrite"
1706
+ : "net.sockEndStr"
1707
+ : data.type.kind === "bytes" && data.type.elem === "u8"
1708
+ ? name === "write"
1709
+ ? "net.sockWriteBytes"
1710
+ : "net.sockEndBytes"
1711
+ : data.type.kind === "dyn"
1712
+ ? name === "write"
1713
+ ? "net.sockWriteDyn"
1714
+ : "net.sockEndDyn"
1715
+ : null;
1716
+ if (fn === null) {
1717
+ lowerer.noLowering(`${name} of '${lowerer.fmt(data.type)}' data`, dataNode, NARROW_DATA_HINT);
1718
+ }
1719
+ main = { kind: "libCall", fn, args: [receiver(), data], type: VOID, loc };
1720
+ }
1721
+ const cb = lowerer.lowerExpr(last);
1722
+ let register;
1723
+ if (cb.type.kind === "func" && cb.type.params.length === 0 && cb.type.ret.kind === "void") {
1724
+ register = {
1725
+ kind: "libCall",
1726
+ fn: name === "write" ? "net.sockOnWriteFlush" : "net.sockOnFinish",
1727
+ args: [receiver(), cb],
1728
+ type: VOID,
1729
+ loc,
1730
+ };
1731
+ }
1732
+ else {
1733
+ register = {
1734
+ kind: "libCall",
1735
+ fn: name === "write" ? "net.sockOnWriteFlushDyn" : "net.sockOnFinishDyn",
1736
+ args: [receiver(), lowerSocketDynListener(lowerer, last, `${name} callbacks`)],
1737
+ type: VOID,
1738
+ loc,
1739
+ };
1740
+ }
1741
+ stmts.push({ kind: "exprStmt", expr: main, loc });
1742
+ return { kind: "seqExpr", stmts, result: register, type: VOID, loc };
1743
+ }
1559
1744
  const maxArgs = name === "write" ? 1 : 1;
1560
1745
  const minArgs = name === "write" ? 1 : 0;
1561
1746
  if (args.length < minArgs || args.length > maxArgs) {
@@ -1604,13 +1789,44 @@ function lowerNetSocketMethodCall(lowerer, call, access) {
1604
1789
  }
1605
1790
  if (name === "setTimeout") {
1606
1791
  requireStatementPosition(lowerer, call, "socket.setTimeout(...)");
1607
- if (args.length !== 1) {
1608
- lowerer.noLowering(`setTimeout with ${args.length} arguments`, call, "the supported form is setTimeout(ms) — register the callback separately: socket.once('timeout', ...)");
1792
+ if (args.length !== 1 && args.length !== 2) {
1793
+ lowerer.noLowering(`setTimeout with ${args.length} arguments`, call, "the supported forms are setTimeout(ms) and setTimeout(ms, callback)");
1609
1794
  }
1610
1795
  const receiver = coerceToHandle(lowerer, access.expression, NETSOCKET_T);
1611
1796
  const ms = lowerer.lowerExprExpecting(args[0], F64);
1797
+ if (args.length === 2) {
1798
+ // Node adds the callback as a once('timeout') listener (removes it
1799
+ // for 0); msecs is checked first either way.
1800
+ const { cb } = lowerCallbackArg(lowerer, args[1], "setTimeout callbacks", 0, () => false, "use ()", []);
1801
+ return {
1802
+ kind: "libCall",
1803
+ fn: "net.sockSetTimeoutCb",
1804
+ args: [receiver, ms, cb],
1805
+ type: VOID,
1806
+ loc,
1807
+ };
1808
+ }
1612
1809
  return { kind: "libCall", fn: "net.sockSetTimeout", args: [receiver, ms], type: VOID, loc };
1613
1810
  }
1811
+ if (name === "setKeepAlive") {
1812
+ // SO_KEEPALIVE plus the initial delay (whole seconds, at least 1);
1813
+ // Node's defaults are false and 0. Answers the socket.
1814
+ if (args.length > 2) {
1815
+ lowerer.noLowering(`setKeepAlive with ${args.length} arguments`, call, "the form is setKeepAlive(enable?, initialDelay?)");
1816
+ }
1817
+ const receiver = coerceToHandle(lowerer, access.expression, NETSOCKET_T);
1818
+ const enable = args.length >= 1 ? lowerer.lowerExprExpecting(args[0], BOOL) : boolLit(false, loc);
1819
+ const delay = args.length === 2
1820
+ ? lowerer.lowerExprExpecting(args[1], F64)
1821
+ : { kind: "numLit", value: 0, type: F64, loc };
1822
+ return {
1823
+ kind: "libCall",
1824
+ fn: "net.sockSetKeepAlive",
1825
+ args: [receiver, enable, delay],
1826
+ type: NETSOCKET_T,
1827
+ loc,
1828
+ };
1829
+ }
1614
1830
  if (name === "pause" || name === "resume") {
1615
1831
  // Flow control (the struct's flag comments in scr_net.c): pause holds
1616
1832
  // reads off — kernel/TCP backpressure is the buffer; resume flows
@@ -1639,6 +1855,50 @@ function lowerNetSocketMethodCall(lowerer, call, access) {
1639
1855
  loc,
1640
1856
  };
1641
1857
  }
1858
+ if ((name === "getProtocol" || name === "getCipher") && args.length === 0) {
1859
+ // TLSSocket.getProtocol(): "TLSv1.2"/"TLSv1.3" or null;
1860
+ // getCipher(): { name, standardName, version }.
1861
+ const receiver = coerceToHandle(lowerer, access.expression, NETSOCKET_T);
1862
+ const value = {
1863
+ kind: "libCall",
1864
+ fn: name === "getProtocol" ? "tls.sockGetProtocol" : "tls.sockGetCipher",
1865
+ args: [receiver],
1866
+ type: DYN,
1867
+ loc,
1868
+ };
1869
+ const declared = lowerer.mapTypeOf(lowerer.typeOf(call));
1870
+ return declared === null || declared.kind === "dyn"
1871
+ ? value
1872
+ : lowerer.coerceInto(call, value, declared);
1873
+ }
1874
+ if (name === "resetAndDestroy") {
1875
+ // An RST close; a connecting socket resets once it connects. Answers
1876
+ // the socket, Node's chaining.
1877
+ if (args.length !== 0) {
1878
+ lowerer.noLowering(`resetAndDestroy with ${args.length} arguments`, call, "the form is resetAndDestroy()");
1879
+ }
1880
+ const receiver = coerceToHandle(lowerer, access.expression, NETSOCKET_T);
1881
+ return {
1882
+ kind: "libCall",
1883
+ fn: "net.sockResetAndDestroy",
1884
+ args: [receiver],
1885
+ type: NETSOCKET_T,
1886
+ loc,
1887
+ };
1888
+ }
1889
+ if (name === "address") {
1890
+ // { address, family, port } or {} (connecting or destroyed): the
1891
+ // declared AddressInfo | {} maps to a dyn value.
1892
+ if (args.length !== 0) {
1893
+ lowerer.noLowering(`address with ${args.length} arguments`, call, "address() takes no arguments");
1894
+ }
1895
+ const result = lowerer.mapTypeOf(lowerer.typeOf(call));
1896
+ if (result?.kind !== "dyn") {
1897
+ lowerer.noLowering("socket.address() where the result is not AddressInfo | {}", call, "use the declared AddressInfo | {} result, and narrow it with a type assertion");
1898
+ }
1899
+ const receiver = coerceToHandle(lowerer, access.expression, NETSOCKET_T);
1900
+ return { kind: "libCall", fn: "net.sockAddress", args: [receiver], type: DYN, loc };
1901
+ }
1642
1902
  if (name === "destroySoon") {
1643
1903
  // end() now, destroy once the FIN actually flushed — Node's
1644
1904
  // 'finish'-then-destroy.
@@ -1699,6 +1959,28 @@ function lowerNetSocketMethodCall(lowerer, call, access) {
1699
1959
  const event = evT.isStringLiteralType() ? evT.value : null;
1700
1960
  const receiver = coerceToHandle(lowerer, access.expression, NETSOCKET_T);
1701
1961
  if (event === "data") {
1962
+ const sigs = lowerer.checker.getCallSignatures(lowerer.typeOf(args[1]));
1963
+ const firstParam = sigs.length === 1 ? sigs[0].getParameters()[0] : undefined;
1964
+ const param = firstParam !== undefined
1965
+ ? lowerer.mapTypeOf(lowerer.checker.getTypeOfSymbol(firstParam))
1966
+ : null;
1967
+ if (param !== null &&
1968
+ param.kind !== "dyn" &&
1969
+ !(param.kind === "bytes" && param.elem === "u8")) {
1970
+ // A chunk typed string (or string | Buffer): the listener takes
1971
+ // the chunk through a checked boundary, so a string arrives after
1972
+ // setEncoding and a Buffer without it fails the check instead of
1973
+ // being decoded.
1974
+ const boxed = lowerSocketDynListener(lowerer, args[1], "data listeners");
1975
+ const cb = { kind: "dynCheck", value: boxed, type: funcOf([DYN], VOID), loc };
1976
+ return {
1977
+ kind: "libCall",
1978
+ fn: "net.sockOnData",
1979
+ args: [receiver, cb, once],
1980
+ type: VOID,
1981
+ loc,
1982
+ };
1983
+ }
1702
1984
  const { cb } = lowerCallbackArg(lowerer, args[1], "data listeners", 1, (p) => p.kind === "bytes" && p.elem === "u8", "use (chunk: Buffer) or ()", [DYN]);
1703
1985
  return { kind: "libCall", fn: "net.sockOnData", args: [receiver, cb, once], type: VOID, loc };
1704
1986
  }
@@ -1712,9 +1994,23 @@ function lowerNetSocketMethodCall(lowerer, call, access) {
1712
1994
  loc,
1713
1995
  };
1714
1996
  }
1997
+ if (event === "close" &&
1998
+ lowerer.checker
1999
+ .getCallSignatures(lowerer.typeOf(args[1]))
2000
+ .some((sig) => sig.getParameters().length > 0)) {
2001
+ // close(hadError): true when the socket closed because of an error.
2002
+ return {
2003
+ kind: "libCall",
2004
+ fn: "net.sockOnCloseDyn",
2005
+ args: [receiver, lowerSocketDynListener(lowerer, args[1], "close listeners"), once],
2006
+ type: VOID,
2007
+ loc,
2008
+ };
2009
+ }
1715
2010
  if (event === "end" ||
1716
2011
  event === "close" ||
1717
2012
  event === "connect" ||
2013
+ event === "ready" ||
1718
2014
  event === "timeout" ||
1719
2015
  event === "readable") {
1720
2016
  const { cb } = lowerCallbackArg(lowerer, args[1], `${event} listeners`, 0, () => false, "use ()", []);
@@ -1726,7 +2022,9 @@ function lowerNetSocketMethodCall(lowerer, call, access) {
1726
2022
  ? "net.sockOnTimeout"
1727
2023
  : event === "readable"
1728
2024
  ? "net.sockOnReadable"
1729
- : "net.sockOnConnect";
2025
+ : event === "ready"
2026
+ ? "net.sockOnReady"
2027
+ : "net.sockOnConnect";
1730
2028
  return { kind: "libCall", fn, args: [receiver, cb, once], type: VOID, loc };
1731
2029
  }
1732
2030
  if (event === "finish") {
@@ -1761,9 +2059,9 @@ function lowerNetSocketMethodCall(lowerer, call, access) {
1761
2059
  loc,
1762
2060
  };
1763
2061
  }
1764
- lowerer.noLowering(`socket.${name}(${event === null ? "non-literal event" : `"${event}"`}, ...)`, args[0], '"data", "end", "close", "error", "connect", "timeout", "readable", "secureConnect", and "session" are the supported socket events (as literals)');
2062
+ lowerer.noLowering(`socket.${name}(${event === null ? "non-literal event" : `"${event}"`}, ...)`, args[0], '"data", "end", "close", "error", "connect", "ready", "timeout", "readable", "secureConnect", and "session" are the supported socket events (as literals)');
1765
2063
  }
1766
- lowerer.noLowering(`Socket.${name}`, call, "write, end, destroy, pipe, setTimeout, remoteAddress, read, unshift, and on/once of data/end/close/error/connect/timeout/readable are the supported Socket members", lowerer.checker.getSymbolAtLocation(access.name));
2064
+ lowerer.noLowering(`Socket.${name}`, call, "write, end, destroy, pipe, setTimeout, setKeepAlive, setNoDelay, the address fields, read, unshift, and on/once of data/end/close/error/connect/ready/timeout/readable are the supported Socket members", lowerer.checker.getSymbolAtLocation(access.name));
1767
2065
  }
1768
2066
  /** The method-call dispatch for both server-surface receiver kinds — one
1769
2067
  * entry in lower-calls.ts's intrinsic chain (the lowerChildMethodCall
@@ -1792,6 +2090,7 @@ function headersSnapshotHelper(lowerer, shapeId, loc) {
1792
2090
  libCall: "http.reqHeaderPairs",
1793
2091
  params: [{ localId: "r.0", name: "r", type: HTTPREQ_T }],
1794
2092
  callArgs: [varRef("r.0", HTTPREQ_T, loc)],
2093
+ listKey: { name: "set-cookie", libCall: "http.reqHeaderList" },
1795
2094
  });
1796
2095
  }
1797
2096
  function trailersSnapshotHelper(lowerer, shapeId, loc) {
@@ -2227,6 +2526,25 @@ export function lowerServerProperty(lowerer, expr) {
2227
2526
  const receiver = coerceToHandle(lowerer, expr.expression, NETSERVER_T);
2228
2527
  return { kind: "libCall", fn: "net.serverListening", args: [receiver], type: BOOL, loc };
2229
2528
  }
2529
+ if (expr.name.text === "maxConnections" || expr.name.text === "dropMaxConnection") {
2530
+ const receiver = coerceToHandle(lowerer, expr.expression, NETSERVER_T);
2531
+ const value = {
2532
+ kind: "libCall",
2533
+ fn: expr.name.text === "maxConnections"
2534
+ ? "net.serverMaxConnectionsGet"
2535
+ : "net.serverDropMaxConnectionGet",
2536
+ args: [receiver],
2537
+ type: DYN,
2538
+ loc,
2539
+ };
2540
+ // The property's declared type: an earlier `= undefined` narrows
2541
+ // the read's own type to undefined.
2542
+ const sym = lowerer.checker.getSymbolAtLocation(expr.name);
2543
+ const declared = lowerer.mapTypeOf(sym ? lowerer.checker.getTypeOfSymbol(sym) : lowerer.typeOf(expr));
2544
+ return declared === null || declared.kind === "dyn"
2545
+ ? value
2546
+ : lowerer.coerceInto(expr, value, declared);
2547
+ }
2230
2548
  const field = httpServerTimeoutField(expr.name.text);
2231
2549
  if (field !== null) {
2232
2550
  const receiver = coerceToHandle(lowerer, expr.expression, NETSERVER_T);
@@ -2379,6 +2697,24 @@ export function lowerServerProperty(lowerer, expr) {
2379
2697
  const receiver = coerceToHandle(lowerer, expr.expression, NETSOCKET_T);
2380
2698
  return { kind: "libCall", fn: "tls.sockAuthorized", args: [receiver], type: BOOL, loc };
2381
2699
  }
2700
+ if (recvKind === "netSocket" &&
2701
+ lowerer.isStdlibMember(expr) &&
2702
+ expr.name.text === "alpnProtocol") {
2703
+ // TLSSocket.alpnProtocol: null before the handshake, then the
2704
+ // negotiated protocol or false.
2705
+ const receiver = coerceToHandle(lowerer, expr.expression, NETSOCKET_T);
2706
+ const value = {
2707
+ kind: "libCall",
2708
+ fn: "tls.sockAlpnProtocol",
2709
+ args: [receiver],
2710
+ type: DYN,
2711
+ loc,
2712
+ };
2713
+ const declared = lowerer.mapTypeOf(lowerer.typeOf(expr));
2714
+ return declared === null || declared.kind === "dyn"
2715
+ ? value
2716
+ : lowerer.coerceInto(expr, value, declared);
2717
+ }
2382
2718
  if (recvKind === "netSocket" && expr.name.text === "authorizationError") {
2383
2719
  // TLSSocket.authorizationError — the verify-failure CODE STRING
2384
2720
  // (DEPTH_ZERO_SELF_SIGNED_CERT, ...) or null when authorized/never
@@ -2428,6 +2764,45 @@ export function lowerServerProperty(lowerer, expr) {
2428
2764
  loc,
2429
2765
  };
2430
2766
  }
2767
+ if (recvKind === "netSocket" && lowerer.isStdlibMember(expr)) {
2768
+ const name = expr.name.text;
2769
+ // The other address fields: the peer's cached like remoteAddress, the
2770
+ // local ones read live (undefined while connecting and after close).
2771
+ const field = [
2772
+ "remotePort",
2773
+ "remoteFamily",
2774
+ "localAddress",
2775
+ "localPort",
2776
+ "localFamily",
2777
+ ].indexOf(name);
2778
+ if (field >= 0) {
2779
+ const receiver = coerceToHandle(lowerer, expr.expression, NETSOCKET_T);
2780
+ const value = {
2781
+ kind: "libCall",
2782
+ fn: "net.sockAddrField",
2783
+ args: [receiver, { kind: "numLit", value: field, type: F64, loc }],
2784
+ type: DYN,
2785
+ loc,
2786
+ };
2787
+ const declared = lowerer.mapTypeOf(lowerer.typeOf(expr));
2788
+ return declared === null || declared.kind === "dyn"
2789
+ ? value
2790
+ : lowerer.coerceInto(expr, value, declared);
2791
+ }
2792
+ const scalar = name === "bytesRead"
2793
+ ? { fn: "net.sockBytesRead", type: F64 }
2794
+ : name === "connecting"
2795
+ ? { fn: "net.sockConnecting", type: BOOL }
2796
+ : name === "pending"
2797
+ ? { fn: "net.sockPending", type: BOOL }
2798
+ : name === "readyState"
2799
+ ? { fn: "net.sockReadyState", type: STRING }
2800
+ : null;
2801
+ if (scalar !== null) {
2802
+ const receiver = coerceToHandle(lowerer, expr.expression, NETSOCKET_T);
2803
+ return { kind: "libCall", fn: scalar.fn, args: [receiver], type: scalar.type, loc };
2804
+ }
2805
+ }
2431
2806
  if (recvKind === "httpClientReq" &&
2432
2807
  lowerer.isStdlibMember(expr) &&
2433
2808
  expr.name.text === "destroyed") {
@@ -2481,14 +2856,15 @@ export function lowerServerProperty(lowerer, expr) {
2481
2856
  const collection = httpReqFieldCollection(lowerer, expr.expression);
2482
2857
  const receiver = coerceToHandle(lowerer, expr.expression.expression, HTTPREQ_T);
2483
2858
  const key = { kind: "strLit", value: expr.name.text, type: STRING, loc };
2484
- const fn = collection === "headers"
2859
+ const list = isSetCookieRead(lowerer, expr, collection, key);
2860
+ const fn = collection === "headers" && !list
2485
2861
  ? "http.reqHeader"
2486
2862
  : collection === "trailers"
2487
2863
  ? "http.reqTrailer"
2488
- : collection === "headersDistinct"
2864
+ : collection === "headersDistinct" || list
2489
2865
  ? "http.reqHeaderValues"
2490
2866
  : "http.reqTrailerValues";
2491
- const type = collection.endsWith("Distinct")
2867
+ const type = collection.endsWith("Distinct") || list
2492
2868
  ? lowerer.withUndefinedArm(arrayOf(STRING))
2493
2869
  : lowerer.envValueType();
2494
2870
  return { kind: "libCall", fn, args: [receiver, key], type, loc };
@@ -2962,7 +3338,9 @@ export function lowerHttpAgentNew(lowerer, expr) {
2962
3338
  lowerer.lowerExpr(initializer); // evaluate, like Node
2963
3339
  break;
2964
3340
  default:
2965
- fenceOrDropOptionKey(lowerer, prop, key, api, AGENT_DOCUMENTED_OPTIONS, "keepAlive, keepAliveMsecs, maxSockets, maxFreeSockets, timeout, port, and scheduling are the supported options");
3341
+ fenceOrDropOptionKey(lowerer, prop, key, api, bi.module === "https" ? HTTPS_AGENT_DOCUMENTED_OPTIONS : AGENT_DOCUMENTED_OPTIONS, bi.module === "https"
3342
+ ? "keepAlive, keepAliveMsecs, maxSockets, maxFreeSockets, timeout, port, and scheduling are the supported options; pass TLS options such as ca and rejectUnauthorized on each https.request"
3343
+ : "keepAlive, keepAliveMsecs, maxSockets, maxFreeSockets, timeout, port, and scheduling are the supported options");
2966
3344
  }
2967
3345
  }
2968
3346
  }
@@ -4804,22 +5182,36 @@ export function lowerHttpHeadersElement(lowerer, expr) {
4804
5182
  lowerer.unsupported("SC1090", expr.argumentExpression, `indexing req.${collection} with non-string keys`);
4805
5183
  }
4806
5184
  const receiver = lowerer.lowerExpr(recv);
5185
+ const list = isSetCookieRead(lowerer, expr, collection, key);
4807
5186
  return {
4808
5187
  kind: "libCall",
4809
- fn: collection === "headers"
5188
+ fn: collection === "headers" && !list
4810
5189
  ? "http.reqHeader"
4811
5190
  : collection === "trailers"
4812
5191
  ? "http.reqTrailer"
4813
- : collection === "headersDistinct"
5192
+ : collection === "headersDistinct" || list
4814
5193
  ? "http.reqHeaderValues"
4815
5194
  : "http.reqTrailerValues",
4816
5195
  args: [receiver, key],
4817
- type: collection.endsWith("Distinct")
5196
+ type: collection.endsWith("Distinct") || list
4818
5197
  ? lowerer.withUndefinedArm(arrayOf(STRING))
4819
5198
  : lowerer.envValueType(),
4820
5199
  loc: locOf(expr),
4821
5200
  };
4822
5201
  }
5202
+ /** `headers["set-cookie"]` reads Node's array of every Set-Cookie line,
5203
+ * the `string[] | undefined` that @types/node's IncomingHttpHeaders
5204
+ * declares. A read typed as a string (the bundled declarations type every
5205
+ * header as one) is refused, because Node's value is an array. */
5206
+ function isSetCookieRead(lowerer, expr, collection, key) {
5207
+ if (collection !== "headers" || key.kind !== "strLit" || key.value !== "set-cookie")
5208
+ return false;
5209
+ const type = lowerer.mapTypeOf(lowerer.typeOf(expr));
5210
+ const array = lowerer.withUndefinedArm(arrayOf(STRING));
5211
+ if (type?.kind === "union" && array.kind === "union" && type.unionId === array.unionId)
5212
+ return true;
5213
+ lowerer.noLowering("reading set-cookie through string-typed headers", expr, "Node stores set-cookie as an array: read headersDistinct['set-cookie'], or install @types/node, which types headers['set-cookie'] as string[]");
5214
+ }
4823
5215
  /** Method calls on IncomingMessage receivers: on/once("data" | "end").
4824
5216
  * Null for other receivers. */
4825
5217
  function lowerHttpReqMethodCall(lowerer, call, access) {
@@ -5078,12 +5470,17 @@ function lowerHttpResMethodCall(lowerer, call, access) {
5078
5470
  // retains the setHeader refusal below.
5079
5471
  value = lowerer.coerceInto(args[1], value, STRING);
5080
5472
  }
5081
- if (value.type.kind === "f64") {
5082
- // Node formats number values via String(n) — the same ToString.
5083
- value = { kind: "toString", operand: value, type: STRING, loc };
5084
- }
5085
5473
  if (value.type.kind !== "string") {
5086
- lowerer.noLowering(`setHeader with a '${lowerer.fmt(value.type)}' value`, args[1], "header values are strings or numbers here");
5474
+ // Numbers and arrays keep their type for getHeader/getHeaders, like
5475
+ // Node's stored value; numbers serialize as String(n) and arrays as
5476
+ // one line per element.
5477
+ return {
5478
+ kind: "libCall",
5479
+ fn: "http.resSetHeaderDyn",
5480
+ args: [receiver, header, lowerer.coerceToExpected(value, DYN)],
5481
+ type: VOID,
5482
+ loc,
5483
+ };
5087
5484
  }
5088
5485
  return {
5089
5486
  kind: "libCall",
@@ -5093,6 +5490,22 @@ function lowerHttpResMethodCall(lowerer, call, access) {
5093
5490
  loc,
5094
5491
  };
5095
5492
  }
5493
+ if (name === "appendHeader") {
5494
+ requireStatementPosition(lowerer, call, "res.appendHeader(...)");
5495
+ if (args.length !== 2) {
5496
+ lowerer.noLowering(`appendHeader with ${args.length} arguments`, call, "the supported form is appendHeader(name, value)");
5497
+ }
5498
+ const receiver = coerceToHandle(lowerer, access.expression, HTTPRES_T);
5499
+ const header = lowerer.lowerExprExpecting(args[0], STRING);
5500
+ const value = lowerer.lowerExpr(args[1]);
5501
+ return {
5502
+ kind: "libCall",
5503
+ fn: "http.resAppendHeader",
5504
+ args: [receiver, header, lowerer.coerceToExpected(value, DYN)],
5505
+ type: VOID,
5506
+ loc,
5507
+ };
5508
+ }
5096
5509
  if (name === "writeHead") {
5097
5510
  if (args.length < 1 || args.length > 3) {
5098
5511
  lowerer.noLowering(`writeHead with ${args.length} arguments`, call, "the supported forms are writeHead(status[, statusMessage][, headers]) — headers as a literal object, a Record, or a flat [name, value, ...] array");
@@ -5299,10 +5712,9 @@ function lowerHttpResMethodCall(lowerer, call, access) {
5299
5712
  }
5300
5713
  if (name === "getHeader" || name === "hasHeader" || name === "removeHeader") {
5301
5714
  // The header CRUD trio (setHeader's readers): getHeader answers the
5302
- // value as SET — `string | undefined` here, where Node can also
5303
- // answer numbers/arrays it was handed (this surface stores strings);
5304
- // removeHeader drops every case-insensitive match before the head
5305
- // goes out; hasHeader is the boolean probe.
5715
+ // value as set (a number, string or string[]); removeHeader drops
5716
+ // every case-insensitive match before the head goes out; hasHeader is
5717
+ // the boolean probe.
5306
5718
  if (name === "removeHeader")
5307
5719
  requireStatementPosition(lowerer, call, "res.removeHeader(...)");
5308
5720
  if (args.length !== 1) {
@@ -5311,13 +5723,19 @@ function lowerHttpResMethodCall(lowerer, call, access) {
5311
5723
  const receiver = coerceToHandle(lowerer, access.expression, HTTPRES_T);
5312
5724
  const header = lowerer.lowerExprExpecting(args[0], STRING);
5313
5725
  if (name === "getHeader") {
5314
- return {
5726
+ // The value as set: number, string or string[] (undefined when
5727
+ // absent), checked against the declared result type.
5728
+ const value = {
5315
5729
  kind: "libCall",
5316
- fn: "http.resGetHeader",
5730
+ fn: "http.resGetHeaderDyn",
5317
5731
  args: [receiver, header],
5318
- type: lowerer.envValueType(),
5732
+ type: DYN,
5319
5733
  loc,
5320
5734
  };
5735
+ const declared = lowerer.mapTypeOf(lowerer.typeOf(call));
5736
+ return declared === null || declared.kind === "dyn"
5737
+ ? value
5738
+ : lowerer.coerceInto(call, value, declared);
5321
5739
  }
5322
5740
  if (name === "hasHeader") {
5323
5741
  return {
@@ -5366,6 +5784,6 @@ function lowerHttpResMethodCall(lowerer, call, access) {
5366
5784
  }
5367
5785
  lowerer.noLowering(`res.${name}(${event === null ? "non-literal event" : `"${event}"`}, ...)`, args[0], '"close" and "finish" are the supported response events (as literals)');
5368
5786
  }
5369
- lowerer.noLowering(`ServerResponse.${name}`, call, "setHeader, getHeader, hasHeader, removeHeader, writeHead, writeContinue, writeProcessing, writeEarlyHints, setTimeout, write, end, destroy, response state reads, and on/once of close are the supported ServerResponse members", lowerer.checker.getSymbolAtLocation(access.name));
5787
+ lowerer.noLowering(`ServerResponse.${name}`, call, "setHeader, appendHeader, getHeader, hasHeader, removeHeader, writeHead, writeContinue, writeProcessing, writeEarlyHints, setTimeout, write, end, destroy, response state reads, and on/once of close are the supported ServerResponse members", lowerer.checker.getSymbolAtLocation(access.name));
5370
5788
  }
5371
5789
  //# sourceMappingURL=lower-server.js.map