@scriptc/compiler 0.1.1 → 0.1.2

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 (209) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +45 -17
  2. package/ambient/scriptc.d.ts +2 -1
  3. package/dist/backend/build-cache.js.map +1 -1
  4. package/dist/backend/c/async.js +24 -2
  5. package/dist/backend/c/async.js.map +1 -1
  6. package/dist/backend/c/c-emitter.d.ts +22 -10
  7. package/dist/backend/c/c-emitter.js +60 -15
  8. package/dist/backend/c/c-emitter.js.map +1 -1
  9. package/dist/backend/c/exprs.js +220 -10
  10. package/dist/backend/c/exprs.js.map +1 -1
  11. package/dist/backend/c/island.js.map +1 -1
  12. package/dist/backend/c/may-throw.js.map +1 -1
  13. package/dist/backend/c/stmts.d.ts +3 -5
  14. package/dist/backend/c/stmts.js +58 -17
  15. package/dist/backend/c/stmts.js.map +1 -1
  16. package/dist/backend/c/types.js.map +1 -1
  17. package/dist/backend/c/walkers.js +31 -5
  18. package/dist/backend/c/walkers.js.map +1 -1
  19. package/dist/backend/external-c.js.map +1 -1
  20. package/dist/backend/linker.js.map +1 -1
  21. package/dist/backend/llvm/blocks.js.map +1 -1
  22. package/dist/backend/llvm/dyn.js +56 -3
  23. package/dist/backend/llvm/dyn.js.map +1 -1
  24. package/dist/backend/llvm/emitter.js +98 -19
  25. package/dist/backend/llvm/emitter.js.map +1 -1
  26. package/dist/backend/llvm/expr-async.js +85 -3
  27. package/dist/backend/llvm/expr-async.js.map +1 -1
  28. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  29. package/dist/backend/llvm/expr-calls.js.map +1 -1
  30. package/dist/backend/llvm/expr-containers.js.map +1 -1
  31. package/dist/backend/llvm/expr-context.d.ts +1 -0
  32. package/dist/backend/llvm/expr-control.js.map +1 -1
  33. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  34. package/dist/backend/llvm/expr-dynamic.js +6 -3
  35. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  36. package/dist/backend/llvm/expr-island.js.map +1 -1
  37. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  38. package/dist/backend/llvm/expr-records.js.map +1 -1
  39. package/dist/backend/llvm/expr-stream-bridges.js +220 -9
  40. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  41. package/dist/backend/llvm/lib-dispatch.js +2 -0
  42. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  43. package/dist/backend/llvm/lib-shared.js +18 -0
  44. package/dist/backend/llvm/lib-shared.js.map +1 -1
  45. package/dist/backend/llvm/lib-stream.js +6 -3
  46. package/dist/backend/llvm/lib-stream.js.map +1 -1
  47. package/dist/backend/llvm/split.js.map +1 -1
  48. package/dist/backend/llvm/unsupported.js.map +1 -1
  49. package/dist/backend/llvm/walkers.js.map +1 -1
  50. package/dist/backend/native-codegen.js.map +1 -1
  51. package/dist/backend/native-codegen.test.js +2 -0
  52. package/dist/backend/native-codegen.test.js.map +1 -1
  53. package/dist/backend/native-toolchain.js.map +1 -1
  54. package/dist/backend/native-toolchain.test.js.map +1 -1
  55. package/dist/backend/runtime-pack.js.map +1 -1
  56. package/dist/backend/targets.js.map +1 -1
  57. package/dist/backend/vendor-archives.js.map +1 -1
  58. package/dist/compat/fetch-profile.js +4 -2
  59. package/dist/compat/fetch-profile.js.map +1 -1
  60. package/dist/coverage/report.js.map +1 -1
  61. package/dist/coverage/surface-manifest.js +12 -0
  62. package/dist/coverage/surface-manifest.js.map +1 -1
  63. package/dist/diagnostics/diagnostic.d.ts +6 -5
  64. package/dist/diagnostics/diagnostic.js +7 -6
  65. package/dist/diagnostics/diagnostic.js.map +1 -1
  66. package/dist/diagnostics/render.js.map +1 -1
  67. package/dist/ffi/ffi-manifest.js.map +1 -1
  68. package/dist/frontend/cjs-lexer.js.map +1 -1
  69. package/dist/frontend/dts-paths.js.map +1 -1
  70. package/dist/frontend/input-tracker.d.ts +10 -0
  71. package/dist/frontend/input-tracker.js +26 -3
  72. package/dist/frontend/input-tracker.js.map +1 -1
  73. package/dist/frontend/input-tracker.test.js +8 -1
  74. package/dist/frontend/input-tracker.test.js.map +1 -1
  75. package/dist/frontend/lib-contract.js.map +1 -1
  76. package/dist/frontend/lowering/array-values.d.ts +4 -0
  77. package/dist/frontend/lowering/array-values.js +18 -2
  78. package/dist/frontend/lowering/array-values.js.map +1 -1
  79. package/dist/frontend/lowering/callback-arg.js.map +1 -1
  80. package/dist/frontend/lowering/containers/bytes.d.ts +35 -0
  81. package/dist/frontend/lowering/containers/bytes.js +1021 -0
  82. package/dist/frontend/lowering/containers/bytes.js.map +1 -0
  83. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +17 -0
  84. package/dist/frontend/lowering/containers/string-and-regexp.js +345 -0
  85. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -0
  86. package/dist/frontend/lowering/expressions/evaluation-safety.d.ts +13 -0
  87. package/dist/frontend/lowering/expressions/evaluation-safety.js +76 -0
  88. package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -0
  89. package/dist/frontend/lowering/expressions/object-literals.d.ts +44 -0
  90. package/dist/frontend/lowering/expressions/object-literals.js +1815 -0
  91. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -0
  92. package/dist/frontend/lowering/expressions/optional-chains.d.ts +31 -0
  93. package/dist/frontend/lowering/expressions/optional-chains.js +382 -0
  94. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -0
  95. package/dist/frontend/lowering/expressions/try-lower-expression.d.ts +7 -0
  96. package/dist/frontend/lowering/expressions/try-lower-expression.js +26 -0
  97. package/dist/frontend/lowering/expressions/try-lower-expression.js.map +1 -0
  98. package/dist/frontend/lowering/lib-boundary.js +7 -2
  99. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  100. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  101. package/dist/frontend/lowering/lower-async-iteration.d.ts +7 -0
  102. package/dist/frontend/lowering/lower-async-iteration.js +657 -0
  103. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -0
  104. package/dist/frontend/lowering/lower-builtins.d.ts +18 -0
  105. package/dist/frontend/lowering/lower-builtins.js +219 -48
  106. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  107. package/dist/frontend/lowering/lower-calls.d.ts +13 -4
  108. package/dist/frontend/lowering/lower-calls.js +407 -64
  109. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  110. package/dist/frontend/lowering/lower-classes.d.ts +7 -13
  111. package/dist/frontend/lowering/lower-classes.js +128 -35
  112. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  113. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  114. package/dist/frontend/lowering/lower-containers.d.ts +1 -47
  115. package/dist/frontend/lowering/lower-containers.js +135 -1467
  116. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  117. package/dist/frontend/lowering/lower-event-emitter.js +51 -5
  118. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  119. package/dist/frontend/lowering/lower-exprs.d.ts +0 -78
  120. package/dist/frontend/lowering/lower-exprs.js +402 -2351
  121. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  122. package/dist/frontend/lowering/lower-generators.d.ts +18 -3
  123. package/dist/frontend/lowering/lower-generators.js +145 -9
  124. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  125. package/dist/frontend/lowering/lower-inspect.js +3 -3
  126. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  127. package/dist/frontend/lowering/lower-island.d.ts +6 -0
  128. package/dist/frontend/lowering/lower-island.js +37 -5
  129. package/dist/frontend/lowering/lower-island.js.map +1 -1
  130. package/dist/frontend/lowering/lower-modules.js +52 -15
  131. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  132. package/dist/frontend/lowering/lower-node-module.d.ts +18 -0
  133. package/dist/frontend/lowering/lower-node-module.js +302 -0
  134. package/dist/frontend/lowering/lower-node-module.js.map +1 -0
  135. package/dist/frontend/lowering/lower-server.js +1 -1
  136. package/dist/frontend/lowering/lower-server.js.map +1 -1
  137. package/dist/frontend/lowering/lower-stmts.d.ts +5 -24
  138. package/dist/frontend/lowering/lower-stmts.js +519 -253
  139. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  140. package/dist/frontend/lowering/lower-stream.js +4 -4
  141. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  142. package/dist/frontend/lowering/lowerer.d.ts +37 -34
  143. package/dist/frontend/lowering/lowerer.js +143 -57
  144. package/dist/frontend/lowering/lowerer.js.map +1 -1
  145. package/dist/frontend/lowering/optional-arguments.d.ts +9 -0
  146. package/dist/frontend/lowering/optional-arguments.js +57 -0
  147. package/dist/frontend/lowering/optional-arguments.js.map +1 -0
  148. package/dist/frontend/npm-static-declarations.d.ts +35 -0
  149. package/dist/frontend/npm-static-declarations.js +506 -0
  150. package/dist/frontend/npm-static-declarations.js.map +1 -0
  151. package/dist/frontend/npm-static-declarations.test.d.ts +1 -0
  152. package/dist/frontend/npm-static-declarations.test.js +122 -0
  153. package/dist/frontend/npm-static-declarations.test.js.map +1 -0
  154. package/dist/frontend/npm-static.d.ts +2 -0
  155. package/dist/frontend/npm-static.js +26 -10
  156. package/dist/frontend/npm-static.js.map +1 -1
  157. package/dist/frontend/npm.d.ts +60 -0
  158. package/dist/frontend/npm.js +38 -4
  159. package/dist/frontend/npm.js.map +1 -1
  160. package/dist/frontend/npm.test.d.ts +1 -0
  161. package/dist/frontend/npm.test.js +50 -0
  162. package/dist/frontend/npm.test.js.map +1 -0
  163. package/dist/frontend/program.d.ts +3 -2
  164. package/dist/frontend/program.js +495 -68
  165. package/dist/frontend/program.js.map +1 -1
  166. package/dist/frontend/resolve.d.ts +10 -2
  167. package/dist/frontend/resolve.js +90 -14
  168. package/dist/frontend/resolve.js.map +1 -1
  169. package/dist/frontend/resolve.test.js +4 -1
  170. package/dist/frontend/resolve.test.js.map +1 -1
  171. package/dist/frontend/runtime-resolve.d.ts +22 -0
  172. package/dist/frontend/runtime-resolve.js +101 -0
  173. package/dist/frontend/runtime-resolve.js.map +1 -0
  174. package/dist/frontend/runtime-resolve.test.d.ts +1 -0
  175. package/dist/frontend/runtime-resolve.test.js +18 -0
  176. package/dist/frontend/runtime-resolve.test.js.map +1 -0
  177. package/dist/frontend/ts7/adapter.js +12 -13
  178. package/dist/frontend/ts7/adapter.js.map +1 -1
  179. package/dist/frontend/ts7/ast.js.map +1 -1
  180. package/dist/frontend/ts7/census-check.js +3 -3
  181. package/dist/frontend/ts7/census-check.js.map +1 -1
  182. package/dist/frontend/ts7/checker.d.ts +3 -0
  183. package/dist/frontend/ts7/checker.js +12 -3
  184. package/dist/frontend/ts7/checker.js.map +1 -1
  185. package/dist/frontend/ts7/enums.js.map +1 -1
  186. package/dist/frontend/ts7/program-adapter.js +42 -3
  187. package/dist/frontend/ts7/program-adapter.js.map +1 -1
  188. package/dist/frontend/type-mapper.js +120 -7
  189. package/dist/frontend/type-mapper.js.map +1 -1
  190. package/dist/index.js +5 -5
  191. package/dist/index.js.map +1 -1
  192. package/dist/ir/analysis.js.map +1 -1
  193. package/dist/ir/ir.d.ts +60 -30
  194. package/dist/ir/ir.js +57 -6
  195. package/dist/ir/ir.js.map +1 -1
  196. package/dist/ir/validate.js +44 -59
  197. package/dist/ir/validate.js.map +1 -1
  198. package/dist/library/cache-primitives.js.map +1 -1
  199. package/dist/library/cache-reset.test.js.map +1 -1
  200. package/dist/library/compiler-self-identity.js.map +1 -1
  201. package/dist/library/int-infer.js.map +1 -1
  202. package/dist/library/int-infer.test.js.map +1 -1
  203. package/dist/library/library-profile.js.map +1 -1
  204. package/dist/library/sidecar-validate.js.map +1 -1
  205. package/dist/library/sidecar.js.map +1 -1
  206. package/dist/startup-cache.js.map +1 -1
  207. package/dist/wasi-paths.js.map +1 -1
  208. package/package.json +18 -18
  209. package/surface-manifest.json +60 -4
@@ -0,0 +1,657 @@
1
+ /* Static async-iterator consumers shared by Node Readable and Web
2
+ * ReadableStream. Both lower through one completion discipline: an
3
+ * `active` flag is set only while user loop-body code owns a yielded value,
4
+ * and a try/finally performs IteratorClose on every abrupt completion while
5
+ * leaving normal exhaustion alone. */
6
+ import * as ts from "../ts7/adapter.js";
7
+ import { InternalCompilerError } from "../../errors.js";
8
+ import { BOOL, DYN, VOID } from "../../ir/ir.js";
9
+ import { locOf } from "../program.js";
10
+ import { dynUndefinedExpr } from "./lowerer.js";
11
+ import { extractIteratorValue } from "./lower-generators.js";
12
+ import { streamSidesOf } from "./lower-stream.js";
13
+ import { staticReadableStreamElementType } from "./lower-island.js";
14
+ import { genResultRecord } from "../type-mapper.js";
15
+ import { sideEffectFreeOptionValue } from "./surfaces.js";
16
+ function unwrapExpression(node) {
17
+ let expression = node;
18
+ while (ts.isParenthesizedExpression(expression) ||
19
+ ts.isAsExpression(expression) ||
20
+ ts.isTypeAssertion(expression) ||
21
+ ts.isNonNullExpression(expression)) {
22
+ expression = expression.expression;
23
+ }
24
+ return expression;
25
+ }
26
+ function propertyName(node) {
27
+ if (!ts.isPropertyAssignment(node) && !ts.isShorthandPropertyAssignment(node)) {
28
+ return null;
29
+ }
30
+ const name = node.name;
31
+ if (ts.isIdentifier(name) || ts.isStringLiteralLike(name))
32
+ return name.text;
33
+ return null;
34
+ }
35
+ /** The iterator options are deliberately static: a literal boolean decides
36
+ * which cleanup graph is emitted. Unknown keys follow Node/WebIDL's ignore
37
+ * rule only when dropping their value is observably safe. */
38
+ function literalBooleanOption(lowerer, call, option, fallback, api) {
39
+ if (call.arguments.length === 0)
40
+ return fallback;
41
+ const argumentNode = call.arguments[0];
42
+ if (call.arguments.length !== 1 ||
43
+ argumentNode === undefined ||
44
+ ts.isSpreadElement(argumentNode)) {
45
+ lowerer.unsupported("SC1090", call, `${api} with this argument shape`);
46
+ return fallback;
47
+ }
48
+ const argument = unwrapExpression(argumentNode);
49
+ if (!ts.isObjectLiteralExpression(argument)) {
50
+ lowerer.unsupported("SC1090", argumentNode, `${api} with runtime-computed options (use an object literal with a boolean '${option}')`);
51
+ return fallback;
52
+ }
53
+ let answer = fallback;
54
+ for (const member of argument.properties) {
55
+ const name = propertyName(member);
56
+ if (name !== option) {
57
+ const value = ts.isPropertyAssignment(member) ? member.initializer : null;
58
+ if (value === null || !sideEffectFreeOptionValue(value)) {
59
+ lowerer.unsupported("SC1090", member, `${api} option entries outside the static '${option}' boolean`);
60
+ }
61
+ continue;
62
+ }
63
+ if (!ts.isPropertyAssignment(member)) {
64
+ lowerer.unsupported("SC1090", member, `${api} with a runtime '${option}' value (write '${option}: true' or '${option}: false')`);
65
+ }
66
+ const value = unwrapExpression(member.initializer);
67
+ if (value.kind === ts.SyntaxKind.TrueKeyword)
68
+ answer = true;
69
+ else if (value.kind === ts.SyntaxKind.FalseKeyword)
70
+ answer = false;
71
+ else {
72
+ lowerer.unsupported("SC1090", member.initializer, `${api} with a runtime '${option}' value (use a boolean literal)`);
73
+ }
74
+ }
75
+ return answer;
76
+ }
77
+ function nodeReadablePlan(lowerer, expression) {
78
+ const direct = lowerer.mapTypeOf(lowerer.typeOf(expression));
79
+ if (direct?.kind === "object") {
80
+ const sides = streamSidesOf(lowerer, lowerer.classes.get(direct.className));
81
+ if (sides === "r" || sides === "rw") {
82
+ return { source: expression, type: direct, destroyOnReturn: true };
83
+ }
84
+ }
85
+ const call = unwrapExpression(expression);
86
+ if (!ts.isCallExpression(call) || call.questionDotToken)
87
+ return null;
88
+ const iteratorCall = ts.isPropertyAccessExpression(call.expression) &&
89
+ !call.expression.questionDotToken &&
90
+ call.expression.name.text === "iterator";
91
+ const asyncIteratorCall = symbolAsyncIteratorCall(lowerer, expression) !== null;
92
+ if (!iteratorCall && !asyncIteratorCall)
93
+ return null;
94
+ const source = call.expression.expression;
95
+ const type = lowerer.mapTypeOf(lowerer.typeOf(source));
96
+ if (type?.kind !== "object")
97
+ return null;
98
+ const sides = streamSidesOf(lowerer, lowerer.classes.get(type.className));
99
+ if (sides !== "r" && sides !== "rw")
100
+ return null;
101
+ return {
102
+ source,
103
+ type,
104
+ destroyOnReturn: iteratorCall
105
+ ? literalBooleanOption(lowerer, call, "destroyOnReturn", true, "readable.iterator")
106
+ : true,
107
+ };
108
+ }
109
+ function symbolAsyncIteratorCall(lowerer, expression) {
110
+ const call = unwrapExpression(expression);
111
+ if (!ts.isCallExpression(call) ||
112
+ call.questionDotToken ||
113
+ !ts.isElementAccessExpression(call.expression) ||
114
+ call.expression.questionDotToken) {
115
+ return null;
116
+ }
117
+ const key = unwrapExpression(call.expression.argumentExpression);
118
+ if (!ts.isPropertyAccessExpression(key) ||
119
+ key.name.text !== "asyncIterator" ||
120
+ !lowerer.isStdlibGlobal(key.expression, "Symbol")) {
121
+ return null;
122
+ }
123
+ return call;
124
+ }
125
+ function webReadablePlan(lowerer, expression) {
126
+ const directElement = staticReadableStreamElementType(lowerer, expression);
127
+ if (directElement) {
128
+ return { source: expression, element: directElement, preventCancel: false };
129
+ }
130
+ const unwrapped = unwrapExpression(expression);
131
+ const propertyCall = ts.isCallExpression(unwrapped) &&
132
+ !unwrapped.questionDotToken &&
133
+ ts.isPropertyAccessExpression(unwrapped.expression) &&
134
+ !unwrapped.expression.questionDotToken &&
135
+ unwrapped.expression.name.text === "values"
136
+ ? unwrapped
137
+ : null;
138
+ const symbolCall = symbolAsyncIteratorCall(lowerer, expression);
139
+ const call = propertyCall ?? symbolCall;
140
+ if (!call)
141
+ return null;
142
+ const access = call.expression;
143
+ const source = access.expression;
144
+ const element = staticReadableStreamElementType(lowerer, source);
145
+ if (!element)
146
+ return null;
147
+ return {
148
+ source,
149
+ element,
150
+ preventCancel: literalBooleanOption(lowerer, call, "preventCancel", false, propertyCall ? "ReadableStream.values" : "ReadableStream[Symbol.asyncIterator]"),
151
+ };
152
+ }
153
+ function classAsyncIteratorPlan(lowerer, expression) {
154
+ const sourceType = lowerer.mapTypeOf(lowerer.typeOf(expression));
155
+ if (sourceType?.kind !== "object")
156
+ return null;
157
+ const sourceInfo = lowerer.classes.get(sourceType.className);
158
+ const open = sourceInfo
159
+ ? lowerer.findMethodOn(sourceInfo, "sym:asyncIterator")
160
+ : null;
161
+ if (!open ||
162
+ open.sig.abstract === true ||
163
+ open.sig.params.length !== 0 ||
164
+ open.sig.ret.kind !== "object") {
165
+ return null;
166
+ }
167
+ const iteratorType = open.sig.ret;
168
+ const iteratorInfo = lowerer.classes.get(iteratorType.className);
169
+ const next = iteratorInfo ? lowerer.findMethodOn(iteratorInfo, "next") : null;
170
+ if (!next ||
171
+ next.sig.abstract === true ||
172
+ next.sig.params.length !== 0 ||
173
+ next.sig.ret.kind !== "promise" ||
174
+ next.sig.ret.inner.kind !== "record") {
175
+ return null;
176
+ }
177
+ const resultType = next.sig.ret.inner;
178
+ const resultShape = lowerer.shapes.get(resultType.shapeId);
179
+ const value = resultShape?.fields.find((field) => field.name === "value");
180
+ const done = resultShape?.fields.find((field) => field.name === "done");
181
+ if (!resultShape || !value || (done && done.type.kind !== "bool"))
182
+ return null;
183
+ const close = iteratorInfo ? lowerer.findMethodOn(iteratorInfo, "return") : null;
184
+ let closeResult = null;
185
+ if (close) {
186
+ if (close.sig.abstract === true ||
187
+ close.sig.params.length !== 0 ||
188
+ close.sig.ret.kind !== "promise" ||
189
+ close.sig.ret.inner.kind !== "record") {
190
+ return null;
191
+ }
192
+ closeResult = close.sig.ret.inner;
193
+ }
194
+ return {
195
+ source: expression,
196
+ sourceType,
197
+ iteratorType,
198
+ resultType,
199
+ valueType: value.type,
200
+ hasDone: done !== undefined,
201
+ closeResult,
202
+ };
203
+ }
204
+ function checkForAwaitBinding(lowerer, stmt) {
205
+ if (!lowerer.ctx.isAsync) {
206
+ lowerer.unsupported("SC1090", stmt, "top-level 'for await' (await outside async functions)");
207
+ }
208
+ if (!ts.isVariableDeclarationList(stmt.initializer)) {
209
+ lowerer.unsupported("SC1090", stmt.initializer, "for-await over a pre-declared variable (declare the loop variable in the loop: for await (const value of ...))");
210
+ }
211
+ const list = stmt.initializer;
212
+ if ((list.flags & ts.NodeFlags.Using) !== 0) {
213
+ lowerer.unsupported("SC1090", list, "'await using' loop bindings over async iterators");
214
+ }
215
+ const isConst = (list.flags & ts.NodeFlags.Const) !== 0;
216
+ const isLet = (list.flags & ts.NodeFlags.Let) !== 0;
217
+ if (!isConst && !isLet) {
218
+ lowerer.unsupported("SC1030", list, "'var' loop bindings in 'for await' (use const)");
219
+ }
220
+ const declaration = list.declarations[0];
221
+ if (!declaration)
222
+ throw new InternalCompilerError("for-await declaration list has no binding");
223
+ if (!ts.isIdentifier(declaration.name))
224
+ lowerer.unsupported("SC1031", declaration.name);
225
+ return {
226
+ declaration: declaration,
227
+ mutable: isLet,
228
+ };
229
+ }
230
+ function boolRef(localId, loc) {
231
+ return { kind: "varRef", localId, type: BOOL, loc };
232
+ }
233
+ function lowerNodeReadable(lowerer, stmt, plan) {
234
+ const binding = checkForAwaitBinding(lowerer, stmt);
235
+ const loc = locOf(stmt);
236
+ lowerer.scopes.push(new Map());
237
+ try {
238
+ const stream = lowerer.declareHiddenLocal("%faStream", plan.type);
239
+ const active = lowerer.declareHiddenLocal("%faActive", BOOL);
240
+ active.mutable = true;
241
+ const promiseT = { kind: "promise", inner: DYN };
242
+ const promise = lowerer.declareHiddenLocal("%streamNext", promiseT);
243
+ const chunk = lowerer.declareLocal(binding.declaration.name, binding.declaration.name.text, DYN, binding.mutable);
244
+ const streamRef = () => ({ kind: "varRef", localId: stream.id, type: plan.type, loc });
245
+ const chunkRef = { kind: "varRef", localId: chunk.id, type: DYN, loc };
246
+ const body = lowerer.inCtl("loop", () => lowerer.lowerScopedBlock(stmt.statement));
247
+ const loop = {
248
+ kind: "while",
249
+ cond: { kind: "boolLit", value: true, type: BOOL, loc },
250
+ body: [
251
+ { kind: "assign", localId: active.id, value: { kind: "boolLit", value: false, type: BOOL, loc }, loc },
252
+ {
253
+ kind: "varDecl",
254
+ localId: promise.id,
255
+ init: {
256
+ kind: "libCall",
257
+ fn: "readable.nextChunkDyn",
258
+ args: [streamRef()],
259
+ type: promiseT,
260
+ loc,
261
+ },
262
+ loc,
263
+ },
264
+ {
265
+ kind: "varDecl",
266
+ localId: chunk.id,
267
+ init: {
268
+ kind: "awaitExpr",
269
+ value: { kind: "varRef", localId: promise.id, type: promiseT, loc },
270
+ type: DYN,
271
+ loc,
272
+ },
273
+ loc,
274
+ },
275
+ {
276
+ kind: "if",
277
+ cond: { kind: "dynTest", test: "undefined", value: chunkRef, type: BOOL, loc },
278
+ then: [{ kind: "break", loc }],
279
+ else_: null,
280
+ loc,
281
+ },
282
+ { kind: "assign", localId: active.id, value: { kind: "boolLit", value: true, type: BOOL, loc }, loc },
283
+ ...body,
284
+ ],
285
+ loc,
286
+ };
287
+ const guarded = plan.destroyOnReturn
288
+ ? {
289
+ kind: "tryCatch",
290
+ tryBody: [loop],
291
+ catchBody: null,
292
+ catchLocalId: null,
293
+ finallyBody: [
294
+ {
295
+ kind: "if",
296
+ cond: boolRef(active.id, loc),
297
+ then: [
298
+ {
299
+ kind: "exprStmt",
300
+ expr: {
301
+ kind: "libCall",
302
+ fn: "stream.iteratorClose",
303
+ args: [streamRef()],
304
+ type: plan.type,
305
+ loc,
306
+ },
307
+ loc,
308
+ },
309
+ ],
310
+ else_: null,
311
+ loc,
312
+ },
313
+ ],
314
+ loc,
315
+ }
316
+ : loop;
317
+ return {
318
+ kind: "block",
319
+ body: [
320
+ { kind: "varDecl", localId: stream.id, init: lowerer.lowerExpr(plan.source), loc },
321
+ { kind: "varDecl", localId: active.id, init: { kind: "boolLit", value: false, type: BOOL, loc }, loc },
322
+ guarded,
323
+ ],
324
+ loc,
325
+ };
326
+ }
327
+ finally {
328
+ lowerer.scopes.pop();
329
+ }
330
+ }
331
+ function lowerWebReadable(lowerer, stmt, plan) {
332
+ const binding = checkForAwaitBinding(lowerer, stmt);
333
+ const loc = locOf(stmt);
334
+ const resultT = genResultRecord(plan.element, VOID, lowerer.shapes, lowerer.unions);
335
+ if (!resultT) {
336
+ lowerer.unsupported("SC1090", stmt.expression, `for-await over a ReadableStream yielding '${lowerer.fmt(plan.element)}' (no IteratorResult representation exists)`);
337
+ throw new InternalCompilerError("ReadableStream iteration has no result record");
338
+ }
339
+ const shape = lowerer.shapes.get(resultT.shapeId);
340
+ if (!shape)
341
+ throw new InternalCompilerError("ReadableStream iteration result shape is missing");
342
+ const valueField = shape.fields.find((field) => field.name === "value");
343
+ if (!valueField)
344
+ throw new InternalCompilerError("ReadableStream iteration result has no value field");
345
+ const valueT = valueField.type;
346
+ const promiseT = { kind: "promise", inner: resultT };
347
+ lowerer.scopes.push(new Map());
348
+ try {
349
+ const stream = lowerer.declareHiddenLocal("%faWebStream", DYN);
350
+ const reader = lowerer.declareHiddenLocal("%faWebReader", DYN);
351
+ const active = lowerer.declareHiddenLocal("%faActive", BOOL);
352
+ active.mutable = true;
353
+ const promise = lowerer.declareHiddenLocal("%webStreamNext", promiseT);
354
+ const result = lowerer.declareHiddenLocal("%webStreamResult", resultT);
355
+ const value = lowerer.declareLocal(binding.declaration.name, binding.declaration.name.text, plan.element, binding.mutable);
356
+ const streamRef = () => ({ kind: "varRef", localId: stream.id, type: DYN, loc });
357
+ const readerRef = () => ({ kind: "varRef", localId: reader.id, type: DYN, loc });
358
+ const resultRef = () => ({ kind: "varRef", localId: result.id, type: resultT, loc });
359
+ const rawValue = {
360
+ kind: "recordGet",
361
+ obj: resultRef(),
362
+ shapeId: resultT.shapeId,
363
+ field: "value",
364
+ type: valueT,
365
+ loc,
366
+ };
367
+ const extracted = extractIteratorValue(lowerer, plan.element, valueT, rawValue, loc);
368
+ if (!extracted) {
369
+ lowerer.unsupported("SC1090", stmt.expression, `for-await over a ReadableStream yielding '${lowerer.fmt(plan.element)}' (no per-element extraction exists)`);
370
+ throw new InternalCompilerError("ReadableStream iteration cannot extract its value");
371
+ }
372
+ const body = lowerer.inCtl("loop", () => lowerer.lowerScopedBlock(stmt.statement));
373
+ const loop = {
374
+ kind: "while",
375
+ cond: { kind: "boolLit", value: true, type: BOOL, loc },
376
+ body: [
377
+ { kind: "assign", localId: active.id, value: { kind: "boolLit", value: false, type: BOOL, loc }, loc },
378
+ {
379
+ kind: "varDecl",
380
+ localId: promise.id,
381
+ init: { kind: "libCall", fn: "fetch.readerRead", args: [readerRef()], type: promiseT, loc },
382
+ loc,
383
+ },
384
+ {
385
+ kind: "varDecl",
386
+ localId: result.id,
387
+ init: {
388
+ kind: "awaitExpr",
389
+ value: { kind: "varRef", localId: promise.id, type: promiseT, loc },
390
+ type: resultT,
391
+ loc,
392
+ },
393
+ loc,
394
+ },
395
+ {
396
+ kind: "if",
397
+ cond: {
398
+ kind: "recordGet",
399
+ obj: resultRef(),
400
+ shapeId: resultT.shapeId,
401
+ field: "done",
402
+ type: BOOL,
403
+ loc,
404
+ },
405
+ then: [{ kind: "break", loc }],
406
+ else_: null,
407
+ loc,
408
+ },
409
+ { kind: "varDecl", localId: value.id, init: extracted, loc },
410
+ { kind: "assign", localId: active.id, value: { kind: "boolLit", value: true, type: BOOL, loc }, loc },
411
+ ...body,
412
+ ],
413
+ loc,
414
+ };
415
+ const cancel = {
416
+ kind: "if",
417
+ cond: boolRef(active.id, loc),
418
+ then: [
419
+ {
420
+ kind: "exprStmt",
421
+ expr: {
422
+ kind: "libCall",
423
+ fn: "async.awaitDyn",
424
+ args: [
425
+ {
426
+ kind: "dynInvoke",
427
+ recv: readerRef(),
428
+ method: "cancel",
429
+ calleeName: "ReadableStream async iterator return",
430
+ args: [dynUndefinedExpr(loc)],
431
+ type: DYN,
432
+ loc,
433
+ },
434
+ ],
435
+ type: DYN,
436
+ loc,
437
+ },
438
+ loc,
439
+ },
440
+ ],
441
+ else_: null,
442
+ loc,
443
+ };
444
+ const release = {
445
+ kind: "exprStmt",
446
+ expr: {
447
+ kind: "dynInvoke",
448
+ recv: readerRef(),
449
+ method: "releaseLock",
450
+ calleeName: "ReadableStream async iterator releaseLock",
451
+ args: [],
452
+ type: DYN,
453
+ loc,
454
+ },
455
+ loc,
456
+ };
457
+ const cleanup = plan.preventCancel
458
+ ? release
459
+ : {
460
+ kind: "tryCatch",
461
+ tryBody: [cancel],
462
+ catchBody: null,
463
+ catchLocalId: null,
464
+ finallyBody: [release],
465
+ loc,
466
+ };
467
+ return {
468
+ kind: "block",
469
+ body: [
470
+ { kind: "varDecl", localId: stream.id, init: lowerer.lowerExprExpecting(plan.source, DYN), loc },
471
+ {
472
+ kind: "varDecl",
473
+ localId: reader.id,
474
+ init: {
475
+ kind: "dynInvoke",
476
+ recv: streamRef(),
477
+ method: "getReader",
478
+ calleeName: "ReadableStream async iterator",
479
+ args: [],
480
+ type: DYN,
481
+ loc,
482
+ },
483
+ loc,
484
+ },
485
+ { kind: "varDecl", localId: active.id, init: { kind: "boolLit", value: false, type: BOOL, loc }, loc },
486
+ {
487
+ kind: "tryCatch",
488
+ tryBody: [loop],
489
+ catchBody: null,
490
+ catchLocalId: null,
491
+ finallyBody: [cleanup],
492
+ loc,
493
+ },
494
+ ],
495
+ loc,
496
+ };
497
+ }
498
+ finally {
499
+ lowerer.scopes.pop();
500
+ }
501
+ }
502
+ function lowerClassAsyncIterator(lowerer, stmt, plan) {
503
+ const binding = checkForAwaitBinding(lowerer, stmt);
504
+ const loc = locOf(stmt);
505
+ const nextPromiseT = { kind: "promise", inner: plan.resultType };
506
+ lowerer.scopes.push(new Map());
507
+ try {
508
+ const source = lowerer.declareHiddenLocal("%faSource", plan.sourceType);
509
+ const iterator = lowerer.declareHiddenLocal("%faIterator", plan.iteratorType);
510
+ const active = lowerer.declareHiddenLocal("%faActive", BOOL);
511
+ active.mutable = true;
512
+ const promise = lowerer.declareHiddenLocal("%faNext", nextPromiseT);
513
+ const result = lowerer.declareHiddenLocal("%faResult", plan.resultType);
514
+ const value = lowerer.declareLocal(binding.declaration.name, binding.declaration.name.text, plan.valueType, binding.mutable);
515
+ const sourceRef = () => ({
516
+ kind: "varRef",
517
+ localId: source.id,
518
+ type: plan.sourceType,
519
+ loc,
520
+ });
521
+ const iteratorRef = () => ({
522
+ kind: "varRef",
523
+ localId: iterator.id,
524
+ type: plan.iteratorType,
525
+ loc,
526
+ });
527
+ const resultRef = () => ({
528
+ kind: "varRef",
529
+ localId: result.id,
530
+ type: plan.resultType,
531
+ loc,
532
+ });
533
+ const body = lowerer.inCtl("loop", () => lowerer.lowerScopedBlock(stmt.statement));
534
+ const loopBody = [
535
+ { kind: "assign", localId: active.id, value: { kind: "boolLit", value: false, type: BOOL, loc }, loc },
536
+ {
537
+ kind: "varDecl",
538
+ localId: promise.id,
539
+ init: lowerer.accessorCall(plan.iteratorType.className, "next", iteratorRef(), [], nextPromiseT, loc),
540
+ loc,
541
+ },
542
+ {
543
+ kind: "varDecl",
544
+ localId: result.id,
545
+ init: {
546
+ kind: "awaitExpr",
547
+ value: { kind: "varRef", localId: promise.id, type: nextPromiseT, loc },
548
+ type: plan.resultType,
549
+ loc,
550
+ },
551
+ loc,
552
+ },
553
+ ...(plan.hasDone
554
+ ? [
555
+ {
556
+ kind: "if",
557
+ cond: {
558
+ kind: "recordGet",
559
+ obj: resultRef(),
560
+ shapeId: plan.resultType.shapeId,
561
+ field: "done",
562
+ type: BOOL,
563
+ loc,
564
+ },
565
+ then: [{ kind: "break", loc }],
566
+ else_: null,
567
+ loc,
568
+ },
569
+ ]
570
+ : []),
571
+ {
572
+ kind: "varDecl",
573
+ localId: value.id,
574
+ init: {
575
+ kind: "recordGet",
576
+ obj: resultRef(),
577
+ shapeId: plan.resultType.shapeId,
578
+ field: "value",
579
+ type: plan.valueType,
580
+ loc,
581
+ },
582
+ loc,
583
+ },
584
+ { kind: "assign", localId: active.id, value: { kind: "boolLit", value: true, type: BOOL, loc }, loc },
585
+ ...body,
586
+ ];
587
+ const loop = {
588
+ kind: "while",
589
+ cond: { kind: "boolLit", value: true, type: BOOL, loc },
590
+ body: loopBody,
591
+ loc,
592
+ };
593
+ const guarded = plan.closeResult
594
+ ? {
595
+ kind: "tryCatch",
596
+ tryBody: [loop],
597
+ catchBody: null,
598
+ catchLocalId: null,
599
+ finallyBody: [
600
+ {
601
+ kind: "if",
602
+ cond: boolRef(active.id, loc),
603
+ then: [
604
+ {
605
+ kind: "exprStmt",
606
+ expr: {
607
+ kind: "awaitExpr",
608
+ value: lowerer.accessorCall(plan.iteratorType.className, "return", iteratorRef(), [], { kind: "promise", inner: plan.closeResult }, loc),
609
+ type: plan.closeResult,
610
+ loc,
611
+ },
612
+ loc,
613
+ },
614
+ ],
615
+ else_: null,
616
+ loc,
617
+ },
618
+ ],
619
+ loc,
620
+ }
621
+ : loop;
622
+ return {
623
+ kind: "block",
624
+ body: [
625
+ { kind: "varDecl", localId: source.id, init: lowerer.lowerExpr(plan.source), loc },
626
+ {
627
+ kind: "varDecl",
628
+ localId: iterator.id,
629
+ init: lowerer.accessorCall(plan.sourceType.className, "sym:asyncIterator", sourceRef(), [], plan.iteratorType, loc),
630
+ loc,
631
+ },
632
+ { kind: "varDecl", localId: active.id, init: { kind: "boolLit", value: false, type: BOOL, loc }, loc },
633
+ guarded,
634
+ ],
635
+ loc,
636
+ };
637
+ }
638
+ finally {
639
+ lowerer.scopes.pop();
640
+ }
641
+ }
642
+ /** Claims the built-in static async-iterator families. Typed async
643
+ * generators and process.stdin retain their specialized drivers; this is
644
+ * the common stream protocol path. */
645
+ export function lowerForAwaitBuiltin(lowerer, stmt) {
646
+ const node = nodeReadablePlan(lowerer, stmt.expression);
647
+ if (node)
648
+ return lowerNodeReadable(lowerer, stmt, node);
649
+ const web = webReadablePlan(lowerer, stmt.expression);
650
+ if (web)
651
+ return lowerWebReadable(lowerer, stmt, web);
652
+ const classIterator = classAsyncIteratorPlan(lowerer, stmt.expression);
653
+ if (classIterator)
654
+ return lowerClassAsyncIterator(lowerer, stmt, classIterator);
655
+ return null;
656
+ }
657
+ //# sourceMappingURL=lower-async-iteration.js.map