@scriptc/compiler 0.3.4 → 0.3.6
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.
- package/ambient/scriptc-node-fallback.d.ts +409 -42
- package/dist/backend/llvm/array-search.js +1 -1
- package/dist/backend/llvm/array-search.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.d.ts +6 -0
- package/dist/backend/llvm/call-lifetimes.js +19 -0
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +2 -21
- package/dist/backend/llvm/constant-callbacks.js +36 -219
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +22 -0
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +9 -0
- package/dist/backend/llvm/dense-array-access.js +27 -1
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +6 -0
- package/dist/backend/llvm/dyn.js +71 -7
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +120 -2
- package/dist/backend/llvm/emitter.js +820 -142
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +17 -7
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +11 -0
- package/dist/backend/llvm/expr-callbacks.js +53 -0
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js +88 -2
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.js +50 -27
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.js +1 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +25 -1
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +20 -1
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +4 -0
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/integer-clones.d.ts +103 -0
- package/dist/backend/llvm/integer-clones.js +1336 -0
- package/dist/backend/llvm/integer-clones.js.map +1 -0
- package/dist/backend/llvm/integer-clones.test.d.ts +1 -0
- package/dist/backend/llvm/integer-clones.test.js +219 -0
- package/dist/backend/llvm/integer-clones.test.js.map +1 -0
- package/dist/backend/llvm/lib-datagram.js +14 -0
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +32 -1
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +61 -1
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +21 -3
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +34 -0
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +77 -2
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-test.js +16 -3
- package/dist/backend/llvm/lib-test.js.map +1 -1
- package/dist/backend/llvm/lib-tls.js +6 -0
- package/dist/backend/llvm/lib-tls.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +1 -1
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/map-entry-fusion.d.ts +28 -0
- package/dist/backend/llvm/map-entry-fusion.js +233 -0
- package/dist/backend/llvm/map-entry-fusion.js.map +1 -0
- package/dist/backend/llvm/map-entry-fusion.test.d.ts +1 -0
- package/dist/backend/llvm/map-entry-fusion.test.js +183 -0
- package/dist/backend/llvm/map-entry-fusion.test.js.map +1 -0
- package/dist/backend/llvm/map-number-lookup.d.ts +2 -0
- package/dist/backend/llvm/map-number-lookup.js +1 -1
- package/dist/backend/llvm/map-number-lookup.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.test.js +10 -11
- package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.d.ts +2 -0
- package/dist/backend/llvm/map-read-lifetimes.js +3 -0
- package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.test.js +2 -2
- package/dist/backend/llvm/nullable-unions.d.ts +6 -3
- package/dist/backend/llvm/nullable-unions.js +2 -0
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/publish.d.ts +16 -0
- package/dist/backend/llvm/publish.js +81 -10
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/publish.test.d.ts +1 -0
- package/dist/backend/llvm/publish.test.js +94 -0
- package/dist/backend/llvm/publish.test.js.map +1 -0
- package/dist/backend/llvm/record-results.d.ts +1 -1
- package/dist/backend/llvm/record-results.js +78 -4
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/record-sources.d.ts +7 -0
- package/dist/backend/llvm/record-sources.js +14 -0
- package/dist/backend/llvm/record-sources.js.map +1 -0
- package/dist/backend/llvm/reference-writes.js +1 -0
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/shapes.d.ts +12 -3
- package/dist/backend/llvm/shapes.js +23 -14
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +5 -3
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/speculative-integers.d.ts +74 -0
- package/dist/backend/llvm/speculative-integers.js +571 -0
- package/dist/backend/llvm/speculative-integers.js.map +1 -0
- package/dist/backend/llvm/speculative-integers.test.d.ts +1 -0
- package/dist/backend/llvm/speculative-integers.test.js +148 -0
- package/dist/backend/llvm/speculative-integers.test.js.map +1 -0
- package/dist/backend/llvm/string-lifetimes.test.js +75 -1
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +17 -0
- package/dist/backend/llvm/walkers.js +123 -0
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/may-throw.js +2 -0
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +2 -1
- package/dist/backend/native/executable.js +6 -1
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +1 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-targets.test.js +1 -1
- package/dist/backend/runtime-pack.d.ts +7 -3
- package/dist/backend/runtime-pack.js +12 -6
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +16 -7
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/contracts/check.js +1 -0
- package/dist/contracts/check.js.map +1 -1
- package/dist/coverage/surface-manifest.js +3 -3
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +1 -1
- package/dist/diagnostics/diagnostic.js +6 -2
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lowering/builtin-calls.js +13 -0
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/callable-aliases.js +82 -8
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-async.d.ts +8 -6
- package/dist/frontend/lowering/builtins/child-process-async.js +45 -29
- package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
- package/dist/frontend/lowering/builtins/compression.d.ts +9 -0
- package/dist/frontend/lowering/builtins/compression.js +145 -30
- package/dist/frontend/lowering/builtins/compression.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.js +12 -1
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.js +5 -3
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +6 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.js +16 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.d.ts +8 -0
- package/dist/frontend/lowering/builtins/filesystem.js +199 -2
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-streams.d.ts +26 -0
- package/dist/frontend/lowering/builtins/fs-streams.js +131 -0
- package/dist/frontend/lowering/builtins/fs-streams.js.map +1 -0
- package/dist/frontend/lowering/builtins/hash-stream.d.ts +12 -0
- package/dist/frontend/lowering/builtins/hash-stream.js +80 -0
- package/dist/frontend/lowering/builtins/hash-stream.js.map +1 -0
- package/dist/frontend/lowering/builtins/module-calls.js +17 -3
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.js +9 -2
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +45 -13
- package/dist/frontend/lowering/builtins/readline.js +812 -47
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/workers.d.ts +4 -0
- package/dist/frontend/lowering/builtins/workers.js +58 -0
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.js +150 -8
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.d.ts +55 -0
- package/dist/frontend/lowering/class-protocols.js +735 -0
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/containers/array-from-async.d.ts +18 -0
- package/dist/frontend/lowering/containers/array-from-async.js +282 -0
- package/dist/frontend/lowering/containers/array-from-async.js.map +1 -0
- package/dist/frontend/lowering/containers/bytes.js +33 -12
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-grouping.js +2 -1
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +27 -23
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/devirtualize.js +20 -7
- package/dist/frontend/lowering/devirtualize.js.map +1 -1
- package/dist/frontend/lowering/divergences.js +188 -15
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +129 -25
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +46 -1
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.js +55 -15
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +9 -1
- package/dist/frontend/lowering/lower-event-emitter.js +88 -1
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +4 -0
- package/dist/frontend/lowering/lower-exprs.js +239 -71
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +49 -3
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-mock.d.ts +11 -1
- package/dist/frontend/lowering/lower-mock.js +377 -61
- package/dist/frontend/lowering/lower-mock.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +1 -0
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +2 -1
- package/dist/frontend/lowering/lower-server.js +234 -21
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +60 -13
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +1 -3
- package/dist/frontend/lowering/lower-stream.js +325 -20
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.js +147 -48
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +13 -1
- package/dist/frontend/lowering/lowerer.js +10 -2
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/null-prototype.d.ts +13 -0
- package/dist/frontend/lowering/null-prototype.js +33 -0
- package/dist/frontend/lowering/null-prototype.js.map +1 -0
- package/dist/frontend/lowering/record-sources.d.ts +15 -0
- package/dist/frontend/lowering/record-sources.js +46 -0
- package/dist/frontend/lowering/record-sources.js.map +1 -0
- package/dist/frontend/lowering/surfaces.d.ts +3 -3
- package/dist/frontend/lowering/surfaces.js +59 -5
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/mock-shapes.d.ts +5 -0
- package/dist/frontend/mock-shapes.js +27 -2
- package/dist/frontend/mock-shapes.js.map +1 -1
- package/dist/frontend/program.js +5 -4
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +3 -0
- package/dist/frontend/type-mapper.js +148 -4
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.js +18 -8
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.d.ts +10 -0
- package/dist/ir/analysis.js +35 -0
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/analysis.test.js +69 -1
- package/dist/ir/analysis.test.js.map +1 -1
- package/dist/ir/builtin-effects.js +72 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +258 -13
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/capture-values.d.ts +107 -0
- package/dist/ir/capture-values.js +850 -0
- package/dist/ir/capture-values.js.map +1 -0
- package/dist/ir/capture-values.test.d.ts +1 -0
- package/dist/ir/capture-values.test.js +268 -0
- package/dist/ir/capture-values.test.js.map +1 -0
- package/dist/ir/field-values.d.ts +16 -0
- package/dist/ir/field-values.js +128 -0
- package/dist/ir/field-values.js.map +1 -0
- package/dist/ir/field-values.test.d.ts +1 -0
- package/dist/ir/field-values.test.js +160 -0
- package/dist/ir/field-values.test.js.map +1 -0
- package/dist/ir/final-fields.d.ts +4 -1
- package/dist/ir/final-fields.js +11 -3
- package/dist/ir/final-fields.js.map +1 -1
- package/dist/ir/function-references.test.js +2 -1
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/init-only-globals.d.ts +16 -0
- package/dist/ir/init-only-globals.js +121 -0
- package/dist/ir/init-only-globals.js.map +1 -0
- package/dist/ir/init-only-globals.test.d.ts +1 -0
- package/dist/ir/init-only-globals.test.js +115 -0
- package/dist/ir/init-only-globals.test.js.map +1 -0
- package/dist/ir/initializer-bindings.d.ts +18 -1
- package/dist/ir/initializer-bindings.js +91 -1
- package/dist/ir/initializer-bindings.js.map +1 -1
- package/dist/ir/initializer-bindings.test.js +57 -2
- package/dist/ir/initializer-bindings.test.js.map +1 -1
- package/dist/ir/int32-slots.d.ts +22 -0
- package/dist/ir/int32-slots.js +398 -13
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +119 -8
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-loop-facts.d.ts +27 -1
- package/dist/ir/integer-loop-facts.js +239 -7
- package/dist/ir/integer-loop-facts.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +8 -5
- package/dist/ir/integer-ranges.js +147 -59
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +285 -7
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/ir.d.ts +22 -1
- package/dist/ir/ir.js +4 -0
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/property-bags.d.ts +14 -0
- package/dist/ir/property-bags.js +121 -0
- package/dist/ir/property-bags.js.map +1 -0
- package/dist/ir/receiver-readers.d.ts +21 -0
- package/dist/ir/receiver-readers.js +217 -0
- package/dist/ir/receiver-readers.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +3 -1
- package/dist/ir/runtime-features.js +102 -7
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/runtime-features.test.js +62 -0
- package/dist/ir/runtime-features.test.js.map +1 -1
- package/dist/ir/traverse.js +4 -0
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/validate.js +71 -3
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +59 -0
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/int-infer.js +3 -0
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/ir-policy.js +5 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +57 -19
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { guardNullProto, nullProtoRecordShape, recordNullProtoTest } from "./null-prototype.js";
|
|
1
2
|
import { lowerProtocolPropertyRead } from "./class-protocol-dispatch.js";
|
|
2
3
|
import { generatorDrain } from "./iterator-adapters.js";
|
|
3
4
|
import { lowerEventObjectProperty, lowerEventObjectPropertyWrite } from "./lower-event-target.js";
|
|
@@ -5,6 +6,7 @@ import { lowerEventStaticProperty } from "./builtins/numbers.js";
|
|
|
5
6
|
import { lowerUnionEquality, tagEqualityMayMissAlias } from "./strict-equality.js";
|
|
6
7
|
import { isOptionalProcessStreamProperty } from "./builtins/process.js";
|
|
7
8
|
import { lowerWorkerMetadata } from "./builtins/workers.js";
|
|
9
|
+
import { lowerReadlineProperty } from "./builtins/readline.js";
|
|
8
10
|
import { lowerBlobInstanceof } from "./builtins/blob.js";
|
|
9
11
|
import { lowerKeyObjectInstanceof } from "./builtins/key-object.js";
|
|
10
12
|
import { STATS_TYPE_TESTS } from "./builtins/filesystem.js";
|
|
@@ -22,6 +24,7 @@ import { literalUnionArm } from "../union-discriminants.js";
|
|
|
22
24
|
* comparisons, nullish coalescing and optional chains, conditions and
|
|
23
25
|
* ToBoolean/ToString coercion helpers, and field/element reads and writes
|
|
24
26
|
* (FieldTarget). */
|
|
27
|
+
import { isFsStreamMember, lowerFsStreamProperty } from "./builtins/fs-streams.js";
|
|
25
28
|
import * as ts from "../ts7/adapter.js";
|
|
26
29
|
import { isZlibStreamMember, lowerZlibStreamBytesWritten } from "./builtins/compression.js";
|
|
27
30
|
import { constituentTypes } from "../ts7/checker.js";
|
|
@@ -599,7 +602,9 @@ function lowerExprInner(lowerer, expr) {
|
|
|
599
602
|
const sym = lowerer.resolveValueSymbol(expr);
|
|
600
603
|
const projection = sym ? lowerer.staticCallables.get(sym) : undefined;
|
|
601
604
|
if (projection?.kind === "promisified-exec-file" ||
|
|
602
|
-
projection?.kind === "promisified-
|
|
605
|
+
projection?.kind === "promisified-exec" ||
|
|
606
|
+
projection?.kind === "promisified-builtin" ||
|
|
607
|
+
projection?.kind === "promisified-zlib") {
|
|
603
608
|
lowerer.unsupported("SC1090", expr, `a promisified builtin as a value (call '${expr.text}' directly)`);
|
|
604
609
|
}
|
|
605
610
|
if (projection?.kind === "builtin-function") {
|
|
@@ -1554,6 +1559,18 @@ function lowerExprInner(lowerer, expr) {
|
|
|
1554
1559
|
});
|
|
1555
1560
|
return { kind: "closure", fnName: name, captures: [], type: funcOf([DYN], DYN), loc };
|
|
1556
1561
|
}
|
|
1562
|
+
// An Hmac has no copy() (Hash does): Node answers undefined, which
|
|
1563
|
+
// `typeof mac.copy` feature checks read. TypeScript rejects the read.
|
|
1564
|
+
if (expr.name.text === "copy" &&
|
|
1565
|
+
lowerer.mapTypeOf(lowerer.typeOf(expr.expression))?.kind === "cryptoHmac") {
|
|
1566
|
+
return {
|
|
1567
|
+
kind: "seqExpr",
|
|
1568
|
+
stmts: [{ kind: "exprStmt", expr: lowerer.lowerExpr(expr.expression), loc }],
|
|
1569
|
+
result: dynUndefinedExpr(loc),
|
|
1570
|
+
type: DYN,
|
|
1571
|
+
loc,
|
|
1572
|
+
};
|
|
1573
|
+
}
|
|
1557
1574
|
if (lowerer.stdlibGlobalMember(expr, "globalThis") === "console") {
|
|
1558
1575
|
return { kind: "libCall", fn: "console.native", args: [], type: DYN, loc };
|
|
1559
1576
|
}
|
|
@@ -1828,6 +1845,9 @@ function lowerExprInner(lowerer, expr) {
|
|
|
1828
1845
|
// diagnostics_channel Channel receivers — name/hasSubscribers
|
|
1829
1846
|
// over the f64 channel handle.
|
|
1830
1847
|
lowerer.lowerDiagnosticsChannelProperty(expr) ??
|
|
1848
|
+
// readline Interface receivers — the history and option members
|
|
1849
|
+
// over the f64 interface handle.
|
|
1850
|
+
lowerReadlineProperty(lowerer, expr) ??
|
|
1831
1851
|
// TracingChannel receivers — the five event channels and
|
|
1832
1852
|
// hasSubscribers over the f64 tracing handle.
|
|
1833
1853
|
lowerer.lowerTracingChannelProperty(expr) ??
|
|
@@ -4166,6 +4186,8 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
4166
4186
|
const numberMember = lowerer.stdlibGlobalMember(expr, "Number");
|
|
4167
4187
|
if (numberMember === "parseInt" || numberMember === "parseFloat")
|
|
4168
4188
|
return lowerNumberParserValue(lowerer, numberMember, locOf(expr));
|
|
4189
|
+
if (lowerer.stdlibGlobalMember(expr, "Buffer") === "poolSize")
|
|
4190
|
+
return { kind: "libCall", fn: "buffer.poolSize", args: [], type: F64, loc: locOf(expr) };
|
|
4169
4191
|
if (lowerer.stdlibGlobalMember(expr, "Buffer") === "isBuffer")
|
|
4170
4192
|
return lowerCheckedPredicateValue(lowerer, "Buffer.isBuffer", "buffer", locOf(expr));
|
|
4171
4193
|
if (lowerer.stdlibGlobalMember(expr, "Date") === "now")
|
|
@@ -6343,6 +6365,21 @@ function tupleLiteralIndex(node) {
|
|
|
6343
6365
|
* change the target or the value used by the operator. The expression yields
|
|
6344
6366
|
* the computed value before a typed array or Buffer coerces it for storage. */
|
|
6345
6367
|
export function lowerElementCompound(lowerer, expr, op) {
|
|
6368
|
+
const lowered = lowerElementCompoundParts(lowerer, expr, op, false);
|
|
6369
|
+
if (!lowered.expr)
|
|
6370
|
+
throw new InternalCompilerError("a compound element value lowered to statements");
|
|
6371
|
+
return lowered.expr;
|
|
6372
|
+
}
|
|
6373
|
+
/** `a[i] op= rhs` in statement position: a string array append becomes the
|
|
6374
|
+
* canonical `a[i] = a[i] + rhs` store (receiver and index saved first),
|
|
6375
|
+
* which the backend appends in place; other forms keep the value path. */
|
|
6376
|
+
export function lowerElementCompoundStatement(lowerer, expr, op) {
|
|
6377
|
+
const lowered = lowerElementCompoundParts(lowerer, expr, op, true);
|
|
6378
|
+
if (lowered.stmts)
|
|
6379
|
+
return { kind: "block", body: lowered.stmts, loc: locOf(expr) };
|
|
6380
|
+
return { kind: "exprStmt", expr: lowered.expr, loc: locOf(expr) };
|
|
6381
|
+
}
|
|
6382
|
+
function lowerElementCompoundParts(lowerer, expr, op, statement) {
|
|
6346
6383
|
const target = expr.left;
|
|
6347
6384
|
fenceNodeModuleMutation(lowerer, target, "assignment");
|
|
6348
6385
|
const loc = locOf(expr);
|
|
@@ -6377,7 +6414,7 @@ export function lowerElementCompound(lowerer, expr, op) {
|
|
|
6377
6414
|
},
|
|
6378
6415
|
loc,
|
|
6379
6416
|
});
|
|
6380
|
-
return { kind: "seqExpr", stmts, result: value, type: DYN, loc };
|
|
6417
|
+
return { expr: { kind: "seqExpr", stmts, result: value, type: DYN, loc }, stmts: null };
|
|
6381
6418
|
}
|
|
6382
6419
|
const receiverType = checked.type.kind === "array" || checked.type.kind === "bytes"
|
|
6383
6420
|
? checked.type
|
|
@@ -6435,6 +6472,27 @@ export function lowerElementCompound(lowerer, expr, op) {
|
|
|
6435
6472
|
const valueType = elementType.kind === "union" && lowerer.armTag(elementType.unionId, UNDEFINED_T) >= 0
|
|
6436
6473
|
? lowerer.stripUndefinedArm(elementType)
|
|
6437
6474
|
: elementType;
|
|
6475
|
+
if (statement &&
|
|
6476
|
+
op === "+" &&
|
|
6477
|
+
receiver.type.kind === "array" &&
|
|
6478
|
+
receiver.type.elem.kind === "string") {
|
|
6479
|
+
// Receiver, index, old element (read inside the concat), rhs, write.
|
|
6480
|
+
const appended = {
|
|
6481
|
+
kind: "strConcat",
|
|
6482
|
+
left: oldValue,
|
|
6483
|
+
right: lowerer.ensureString(rhs, expr.right),
|
|
6484
|
+
type: STRING,
|
|
6485
|
+
loc,
|
|
6486
|
+
};
|
|
6487
|
+
return {
|
|
6488
|
+
expr: null,
|
|
6489
|
+
stmts: [
|
|
6490
|
+
{ kind: "varDecl", localId: receiverLocal.id, init: receiver, loc },
|
|
6491
|
+
{ kind: "varDecl", localId: indexLocal.id, init: index, loc },
|
|
6492
|
+
{ kind: "arraySet", arr: receiverRef(), index: indexRef(), value: appended, loc },
|
|
6493
|
+
],
|
|
6494
|
+
};
|
|
6495
|
+
}
|
|
6438
6496
|
let computed;
|
|
6439
6497
|
if (op === "+" && valueType.kind === "string") {
|
|
6440
6498
|
computed = {
|
|
@@ -6457,17 +6515,18 @@ export function lowerElementCompound(lowerer, expr, op) {
|
|
|
6457
6515
|
}
|
|
6458
6516
|
else if (valueType.kind === "dyn" && isJsSourceFile(expr.getSourceFile())) {
|
|
6459
6517
|
const left = lowerer.coerceToExpected(oldRef(), DYN), right = lowerer.coerceToExpected(rhs, DYN);
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6518
|
+
computed = dynCompoundValue(op, left, right, loc);
|
|
6519
|
+
}
|
|
6520
|
+
else if (rhs.type.kind === "dyn" &&
|
|
6521
|
+
receiver.type.kind === "array" &&
|
|
6522
|
+
lowerer.dynConvertible(oldValue.type) &&
|
|
6523
|
+
lowerer.dynConvertible(valueType)) {
|
|
6524
|
+
// An untyped right operand: the expanded `a[i] = a[i] op rhs`, checked
|
|
6525
|
+
// back into the element type.
|
|
6526
|
+
computed = lowerer.coerceInto(expr, dynCompoundValue(op, lowerer.coerceToExpected(oldRef(), DYN), lowerer.coerceToExpected(rhs, DYN), loc), valueType);
|
|
6468
6527
|
}
|
|
6469
6528
|
else {
|
|
6470
|
-
lowerer.
|
|
6529
|
+
compoundUnsupported(lowerer, expr, op, oldValue.type, rhs.type);
|
|
6471
6530
|
}
|
|
6472
6531
|
const resultLocal = lowerer.declareHiddenLocal("%compoundResult", computed.type);
|
|
6473
6532
|
const resultRef = () => varRef(resultLocal.id, computed.type, loc);
|
|
@@ -6475,17 +6534,20 @@ export function lowerElementCompound(lowerer, expr, op) {
|
|
|
6475
6534
|
? arrayValueStore(lowerer, receiverRef(), indexRef(), resultRef(), receiver.type.elem, loc)
|
|
6476
6535
|
: { kind: "bytesSet", arr: receiverRef(), index: indexRef(), value: resultRef(), loc };
|
|
6477
6536
|
return {
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6537
|
+
expr: {
|
|
6538
|
+
kind: "seqExpr",
|
|
6539
|
+
stmts: [
|
|
6540
|
+
{ kind: "varDecl", localId: receiverLocal.id, init: receiver, loc },
|
|
6541
|
+
{ kind: "varDecl", localId: indexLocal.id, init: index, loc },
|
|
6542
|
+
{ kind: "varDecl", localId: oldLocal.id, init: oldValue, loc },
|
|
6543
|
+
{ kind: "varDecl", localId: resultLocal.id, init: computed, loc },
|
|
6544
|
+
write,
|
|
6545
|
+
],
|
|
6546
|
+
result: resultRef(),
|
|
6547
|
+
type: computed.type,
|
|
6548
|
+
loc,
|
|
6549
|
+
},
|
|
6550
|
+
stmts: null,
|
|
6489
6551
|
};
|
|
6490
6552
|
}
|
|
6491
6553
|
/** ToString of one stabilized `string[]` element read for `+=`: a missing
|
|
@@ -7176,6 +7238,11 @@ export function ensureString(lowerer, e, node) {
|
|
|
7176
7238
|
if (isPerfEntryType(lowerer, e.type))
|
|
7177
7239
|
return perfEntryTag(lowerer, e, e.type, e.loc);
|
|
7178
7240
|
if (shape && !shape.tuple && !shape.fields.some((f) => f.name === "toString")) {
|
|
7241
|
+
// A null-prototype record (Object.groupBy) has no toString or
|
|
7242
|
+
// valueOf: ToPrimitive throws Node's TypeError.
|
|
7243
|
+
const nullProtoT = nullProtoRecordShape(lowerer, e.type);
|
|
7244
|
+
if (nullProtoT)
|
|
7245
|
+
return nullProtoToString(lowerer, e, nullProtoT);
|
|
7179
7246
|
return { kind: "toString", operand: e, type: STRING, loc: e.loc };
|
|
7180
7247
|
}
|
|
7181
7248
|
}
|
|
@@ -7183,6 +7250,34 @@ export function ensureString(lowerer, e, node) {
|
|
|
7183
7250
|
lowerer.badType(node, lowerer.typeOf(node));
|
|
7184
7251
|
return { kind: "toString", operand: e, type: STRING, loc: e.loc };
|
|
7185
7252
|
}
|
|
7253
|
+
/** String(r) over a record that may have a null prototype: an interned
|
|
7254
|
+
* helper that throws Node's TypeError for a null-prototype record and
|
|
7255
|
+
* answers "[object Object]" otherwise. */
|
|
7256
|
+
function nullProtoToString(lowerer, e, t) {
|
|
7257
|
+
const loc = e.loc;
|
|
7258
|
+
const key = `nullProtoToString:${t.shapeId}`;
|
|
7259
|
+
let helper = lowerer.valueHelpers.get(key);
|
|
7260
|
+
if (!helper) {
|
|
7261
|
+
helper = `%rec.tostr.${lowerer.valueHelpers.size}`;
|
|
7262
|
+
lowerer.valueHelpers.set(key, helper);
|
|
7263
|
+
const r = varRef("r.0", t, loc);
|
|
7264
|
+
lowerer.liftedFns.push({
|
|
7265
|
+
name: helper,
|
|
7266
|
+
params: [{ localId: "r.0", name: "r", type: t }],
|
|
7267
|
+
returnType: STRING,
|
|
7268
|
+
locals: [{ id: "r.0", name: "r", type: t, mutable: false }],
|
|
7269
|
+
body: [
|
|
7270
|
+
{
|
|
7271
|
+
kind: "return",
|
|
7272
|
+
value: guardNullProto(r, t.shapeId, "Cannot convert object to primitive value", { kind: "toString", operand: r, type: STRING, loc }, loc),
|
|
7273
|
+
loc,
|
|
7274
|
+
},
|
|
7275
|
+
],
|
|
7276
|
+
loc,
|
|
7277
|
+
});
|
|
7278
|
+
}
|
|
7279
|
+
return { kind: "call", callee: helper, args: [e], type: STRING, loc };
|
|
7280
|
+
}
|
|
7186
7281
|
/** `new String(x)` (stdlib provenance, ≤1 argument) in a ToString
|
|
7187
7282
|
* position: the wrapper's only distinguishers are typeof and identity —
|
|
7188
7283
|
* neither is observable where the value immediately stringifies — so the
|
|
@@ -7319,6 +7414,11 @@ export function lowerAsExpression(lowerer, expr) {
|
|
|
7319
7414
|
// object. Box a live reference instead of erasing the assertion and
|
|
7320
7415
|
// handing native storage to a checked-dynamic property operation.
|
|
7321
7416
|
if (target?.kind === "dyn" && (targetTs0.flags & ts.TypeFlags.Object) !== 0) {
|
|
7417
|
+
// A class instance asserted to a class-backed protocol view (a type
|
|
7418
|
+
// class instances flow into): the same identity-keeping box an
|
|
7419
|
+
// implicit flow into the view uses.
|
|
7420
|
+
if (inner.type.kind === "object" && lowerer.classImplementedProtocol(targetTs0))
|
|
7421
|
+
return lowerer.coerceInto(expr, inner, DYN);
|
|
7322
7422
|
const sourceShape = inner.type.kind === "record" ? lowerer.shapes.get(inner.type.shapeId) : undefined;
|
|
7323
7423
|
if (hasClassPayload(lowerer, inner.type) ||
|
|
7324
7424
|
(sourceShape && shapeHasAccessorSlots(sourceShape))) {
|
|
@@ -7477,7 +7577,7 @@ export function lowerPrefixUnary(lowerer, expr) {
|
|
|
7477
7577
|
? { kind: "dynCheck", value: raw, type: F64, loc }
|
|
7478
7578
|
: lowerOptionalNumber(lowerer, raw, loc, expr.operand);
|
|
7479
7579
|
if (operand.type.kind !== "f64")
|
|
7480
|
-
lowerer
|
|
7580
|
+
operatorUnsupported(lowerer, expr, "-", [raw.type]);
|
|
7481
7581
|
if (operand.kind === "numLit")
|
|
7482
7582
|
return { ...operand, value: -operand.value, loc };
|
|
7483
7583
|
return { kind: "unary", op: "-", operand, type: F64, loc };
|
|
@@ -7495,7 +7595,7 @@ export function lowerPrefixUnary(lowerer, expr) {
|
|
|
7495
7595
|
}
|
|
7496
7596
|
const operand = lowerOptionalNumber(lowerer, raw, loc, expr.operand);
|
|
7497
7597
|
if (operand.type.kind !== "f64")
|
|
7498
|
-
lowerer
|
|
7598
|
+
operatorUnsupported(lowerer, expr, "+", [raw.type]);
|
|
7499
7599
|
return operand;
|
|
7500
7600
|
}
|
|
7501
7601
|
case ts.SyntaxKind.ExclamationToken: {
|
|
@@ -7524,7 +7624,7 @@ export function lowerPrefixUnary(lowerer, expr) {
|
|
|
7524
7624
|
// otherwise numeric slot to the checked-dynamic tree.
|
|
7525
7625
|
const operand = lowerOptionalNumber(lowerer, raw, loc, expr.operand);
|
|
7526
7626
|
if (operand.type.kind !== "f64")
|
|
7527
|
-
lowerer
|
|
7627
|
+
operatorUnsupported(lowerer, expr, "~", [raw.type]);
|
|
7528
7628
|
return { kind: "unary", op: "~", operand, type: F64, loc };
|
|
7529
7629
|
}
|
|
7530
7630
|
case ts.SyntaxKind.PlusPlusToken:
|
|
@@ -7633,12 +7733,19 @@ export function lowerIncDec(lowerer, expr, prefix) {
|
|
|
7633
7733
|
loc,
|
|
7634
7734
|
});
|
|
7635
7735
|
}
|
|
7636
|
-
|
|
7736
|
+
// A TS member statically typed number on a checked-dynamic receiver (a
|
|
7737
|
+
// class-backed protocol view): the expanded form `o.v = o.v + 1`, its
|
|
7738
|
+
// read checked into number like any other read of the member.
|
|
7739
|
+
const checkedNumber = !isJsSourceFile(expr.getSourceFile()) &&
|
|
7740
|
+
raw.type.kind === "dyn" &&
|
|
7741
|
+
lowerer.mapTypeOf(lowerer.typeOf(access))?.kind === "f64";
|
|
7742
|
+
if ((isJsSourceFile(expr.getSourceFile()) || checkedNumber) && raw.type.kind === "dyn") {
|
|
7637
7743
|
const receiver = save(raw, "%incrementReceiver");
|
|
7638
7744
|
const key = save(ts.isElementAccessExpression(access)
|
|
7639
7745
|
? lowerer.lowerExprExpecting(access.argumentExpression, DYN)
|
|
7640
7746
|
: lowerer.coerceInto(access, { kind: "strLit", value: access.name.text, type: STRING, loc }, DYN), "%incrementKey");
|
|
7641
|
-
|
|
7747
|
+
const read = { kind: "dynKeyGet", value: receiver, key, type: DYN, loc };
|
|
7748
|
+
return finish(checkedNumber ? lowerer.coerceInto(access, read, F64) : read, (value) => ({
|
|
7642
7749
|
kind: "exprStmt",
|
|
7643
7750
|
expr: {
|
|
7644
7751
|
kind: "libCall",
|
|
@@ -7781,7 +7888,7 @@ export function lowerIncDecTarget(lowerer, expr, target, prefix) {
|
|
|
7781
7888
|
};
|
|
7782
7889
|
}
|
|
7783
7890
|
if (target.type.kind !== "f64")
|
|
7784
|
-
lowerer
|
|
7891
|
+
operatorUnsupported(lowerer, expr, op === "+" ? "++" : "--", [target.type]);
|
|
7785
7892
|
return { kind: "incDec", op, prefix, localId: target.id, type: F64, loc };
|
|
7786
7893
|
}
|
|
7787
7894
|
/** Whether a lowered statement can live inside a seqExpr. These statements
|
|
@@ -7874,26 +7981,51 @@ export function lowerCompoundValueToTarget(lowerer, expr, compound, target) {
|
|
|
7874
7981
|
if (numericRead.type.kind === "f64" && numericRhs.type.kind === "f64") {
|
|
7875
7982
|
return lowerer.coerceInto(expr, { kind: "bin", op: compound, left: numericRead, right: numericRhs, type: F64, loc }, target.type);
|
|
7876
7983
|
}
|
|
7984
|
+
// An untyped operand: exactly the expanded `x = x op rhs` — the runtime
|
|
7985
|
+
// operator on both values, then the checked conversion into the
|
|
7986
|
+
// target's declared type (a string result for a number target throws the
|
|
7987
|
+
// catchable TypeError, as the expanded assignment does).
|
|
7877
7988
|
if ((target.type.kind === "dyn" || rhs.type.kind === "dyn") &&
|
|
7878
|
-
isJsSourceFile(expr.getSourceFile())
|
|
7989
|
+
(isJsSourceFile(expr.getSourceFile()) ||
|
|
7990
|
+
(lowerer.dynConvertible(read.type) && lowerer.dynConvertible(rhs.type)))) {
|
|
7879
7991
|
const left = lowerer.coerceInto(expr.left, read, DYN);
|
|
7880
7992
|
const right = lowerer.coerceInto(expr.right, rhs, DYN);
|
|
7881
|
-
|
|
7882
|
-
const computed = {
|
|
7883
|
-
kind: "libCall",
|
|
7884
|
-
fn: compound === "+" ? "dyn.add" : numeric ? "dyn.arithmetic" : "dyn.bitwise",
|
|
7885
|
-
args: compound === "+"
|
|
7886
|
-
? [left, right]
|
|
7887
|
-
: [left, right, { kind: "strLit", value: compound, type: STRING, loc }],
|
|
7888
|
-
type: DYN,
|
|
7889
|
-
loc,
|
|
7890
|
-
};
|
|
7891
|
-
return lowerer.coerceInto(expr, computed, target.type);
|
|
7993
|
+
return lowerer.coerceInto(expr, dynCompoundValue(compound, left, right, loc), target.type);
|
|
7892
7994
|
}
|
|
7893
7995
|
const bigint = bigintCompoundValue(compound, read, rhs, loc);
|
|
7894
7996
|
if (bigint)
|
|
7895
7997
|
return bigint;
|
|
7896
|
-
lowerer.
|
|
7998
|
+
compoundUnsupported(lowerer, expr, compound, read.type, rhs.type);
|
|
7999
|
+
}
|
|
8000
|
+
/** The runtime operator of a compound assignment over two checked-dynamic
|
|
8001
|
+
* operands (Node's ToPrimitive/ToNumeric order lives in the runtime). */
|
|
8002
|
+
function dynCompoundValue(op, left, right, loc) {
|
|
8003
|
+
const numeric = ["-", "*", "/", "%", "**"].includes(op);
|
|
8004
|
+
return {
|
|
8005
|
+
kind: "libCall",
|
|
8006
|
+
fn: op === "+" ? "dyn.add" : numeric ? "dyn.arithmetic" : "dyn.bitwise",
|
|
8007
|
+
args: op === "+" ? [left, right] : [left, right, strLit(op, loc)],
|
|
8008
|
+
type: DYN,
|
|
8009
|
+
loc,
|
|
8010
|
+
};
|
|
8011
|
+
}
|
|
8012
|
+
/** An operand type in an SC1043 message: checked-dynamic values (`any`,
|
|
8013
|
+
* `unknown`) are "untyped", everything else its quoted type. */
|
|
8014
|
+
function operandText(lowerer, t) {
|
|
8015
|
+
return t.kind === "dyn" ? "untyped" : `'${lowerer.fmt(t)}'`;
|
|
8016
|
+
}
|
|
8017
|
+
/** SC1043 for a compound assignment whose operand types have no lowering,
|
|
8018
|
+
* naming the operator and both types rather than the comparison wording. */
|
|
8019
|
+
function compoundUnsupported(lowerer, node, op, target, value) {
|
|
8020
|
+
lowerer.unsupported("SC1043", node, `compound '${op}=' assignments of ${operandText(lowerer, value)} values to ${operandText(lowerer, target)} targets`);
|
|
8021
|
+
}
|
|
8022
|
+
/** SC1043 for an arithmetic, unary or update operator whose operand types
|
|
8023
|
+
* have no lowering (comparisons keep the registry wording). */
|
|
8024
|
+
function operatorUnsupported(lowerer, node, op, operands) {
|
|
8025
|
+
const [first, second] = operands;
|
|
8026
|
+
lowerer.unsupported("SC1043", node, second === undefined
|
|
8027
|
+
? `'${op}' operations on ${operandText(lowerer, first)} values`
|
|
8028
|
+
: `'${op}' operations on ${operandText(lowerer, first)} and ${operandText(lowerer, second)} values`);
|
|
7897
8029
|
}
|
|
7898
8030
|
/** Equality of two NaN-coded values (nan-coded-reads.ts), each of which may
|
|
7899
8031
|
* stand for undefined and never holds a genuine NaN: Node's undefined equals
|
|
@@ -8782,7 +8914,7 @@ export function lowerBinary(lowerer, expr) {
|
|
|
8782
8914
|
};
|
|
8783
8915
|
}
|
|
8784
8916
|
}
|
|
8785
|
-
lowerer
|
|
8917
|
+
operatorUnsupported(lowerer, expr, "+", [left.type, right.type]);
|
|
8786
8918
|
break;
|
|
8787
8919
|
case ts.SyntaxKind.MinusToken:
|
|
8788
8920
|
case ts.SyntaxKind.AsteriskToken:
|
|
@@ -8790,7 +8922,7 @@ export function lowerBinary(lowerer, expr) {
|
|
|
8790
8922
|
case ts.SyntaxKind.PercentToken:
|
|
8791
8923
|
case ts.SyntaxKind.AsteriskAsteriskToken: {
|
|
8792
8924
|
if (!bothNum)
|
|
8793
|
-
lowerer.
|
|
8925
|
+
operatorUnsupported(lowerer, expr, ts.tokenToString(op) ?? "?", [left.type, right.type]);
|
|
8794
8926
|
const binOp = op === ts.SyntaxKind.MinusToken
|
|
8795
8927
|
? "-"
|
|
8796
8928
|
: op === ts.SyntaxKind.AsteriskToken
|
|
@@ -8820,7 +8952,7 @@ export function lowerBinary(lowerer, expr) {
|
|
|
8820
8952
|
case ts.SyntaxKind.GreaterThanGreaterThanToken:
|
|
8821
8953
|
case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: {
|
|
8822
8954
|
if (!bothNum)
|
|
8823
|
-
lowerer.
|
|
8955
|
+
operatorUnsupported(lowerer, expr, ts.tokenToString(op) ?? "?", [left.type, right.type]);
|
|
8824
8956
|
const bitOp = op === ts.SyntaxKind.AmpersandToken
|
|
8825
8957
|
? "&"
|
|
8826
8958
|
: op === ts.SyntaxKind.BarToken
|
|
@@ -10533,10 +10665,12 @@ export function lowerInstanceOf(lowerer, expr, loc) {
|
|
|
10533
10665
|
if (left.type.kind === "union") {
|
|
10534
10666
|
const unionId = left.type.unionId;
|
|
10535
10667
|
const arms = lowerer.unions.get(unionId)?.arms;
|
|
10536
|
-
// Ordinary records and scalar values do not carry a class
|
|
10537
|
-
//
|
|
10668
|
+
// Ordinary records, arrays and scalar values do not carry a class
|
|
10669
|
+
// prototype (no program class extends Array). Dynamic/opaque runtime
|
|
10670
|
+
// objects keep their existing instanceof fences.
|
|
10538
10671
|
if (arms?.every((arm) => arm.kind === "object" ||
|
|
10539
10672
|
arm.kind === "record" ||
|
|
10673
|
+
arm.kind === "array" ||
|
|
10540
10674
|
arm.kind === "f64" ||
|
|
10541
10675
|
arm.kind === "string" ||
|
|
10542
10676
|
arm.kind === "bool" ||
|
|
@@ -10595,6 +10729,10 @@ export function lowerInstanceOf(lowerer, expr, loc) {
|
|
|
10595
10729
|
}
|
|
10596
10730
|
return { kind: "call", callee: helper, args: [left], type: BOOL, loc };
|
|
10597
10731
|
}
|
|
10732
|
+
// A class arm could hold an instance: the test cannot be decided
|
|
10733
|
+
// statically.
|
|
10734
|
+
if (arms?.some((arm) => arm.kind === "object"))
|
|
10735
|
+
lowerer.unsupported("SC1090", expr, "'instanceof' on a union of class instances and values without a class prototype test");
|
|
10598
10736
|
}
|
|
10599
10737
|
if (left.type.kind !== "object") {
|
|
10600
10738
|
return readsClassAfter(lowerer, target, expr.right, [{ kind: "exprStmt", expr: left, loc }], {
|
|
@@ -11182,6 +11320,17 @@ function lowerInExpression(lowerer, expr, loc) {
|
|
|
11182
11320
|
recv.kind === "recordGet" ||
|
|
11183
11321
|
recv.kind === "fieldGet" ||
|
|
11184
11322
|
pureRecvNode) {
|
|
11323
|
+
// A null-prototype record (Object.groupBy) has no inherited names.
|
|
11324
|
+
const nullProtoT = inherited ? nullProtoRecordShape(lowerer, recv.type) : null;
|
|
11325
|
+
if (nullProtoT) {
|
|
11326
|
+
return {
|
|
11327
|
+
kind: "unary",
|
|
11328
|
+
op: "!",
|
|
11329
|
+
operand: recordNullProtoTest(recv, nullProtoT.shapeId, loc),
|
|
11330
|
+
type: BOOL,
|
|
11331
|
+
loc,
|
|
11332
|
+
};
|
|
11333
|
+
}
|
|
11185
11334
|
return { kind: "boolLit", value: inherited, type: BOOL, loc };
|
|
11186
11335
|
}
|
|
11187
11336
|
lowerer.unsupported("SC1090", expr, "statically-decided 'in' on computed receivers (bind the value to a variable first)");
|
|
@@ -11243,20 +11392,34 @@ function lowerRuntimeKeyIn(lowerer, expr, loc) {
|
|
|
11243
11392
|
type: BOOL,
|
|
11244
11393
|
loc,
|
|
11245
11394
|
};
|
|
11246
|
-
// A miss in the record's own keys still finds Object.prototype's
|
|
11247
|
-
|
|
11395
|
+
// A miss in the record's own keys still finds Object.prototype's,
|
|
11396
|
+
// unless the record has a null prototype (Object.groupBy).
|
|
11397
|
+
let protoName = null;
|
|
11248
11398
|
for (const name of OBJECT_PROTOTYPE_KEYS) {
|
|
11249
11399
|
if (shape.fields.some((f) => f.name === name))
|
|
11250
11400
|
continue;
|
|
11251
|
-
|
|
11401
|
+
const eq = {
|
|
11402
|
+
kind: "strEq",
|
|
11403
|
+
negated: false,
|
|
11404
|
+
left: k,
|
|
11405
|
+
right: { kind: "strLit", value: name, type: STRING, loc },
|
|
11406
|
+
type: BOOL,
|
|
11407
|
+
loc,
|
|
11408
|
+
};
|
|
11409
|
+
protoName =
|
|
11410
|
+
protoName === null
|
|
11411
|
+
? eq
|
|
11412
|
+
: { kind: "logical", op: "||", left: protoName, right: eq, type: BOOL, loc };
|
|
11413
|
+
}
|
|
11414
|
+
if (protoName !== null && nullProtoRecordShape(lowerer, recT)) {
|
|
11415
|
+
protoName = {
|
|
11252
11416
|
kind: "logical",
|
|
11253
|
-
op: "
|
|
11254
|
-
left:
|
|
11417
|
+
op: "&&",
|
|
11418
|
+
left: protoName,
|
|
11255
11419
|
right: {
|
|
11256
|
-
kind: "
|
|
11257
|
-
|
|
11258
|
-
|
|
11259
|
-
right: { kind: "strLit", value: name, type: STRING, loc },
|
|
11420
|
+
kind: "unary",
|
|
11421
|
+
op: "!",
|
|
11422
|
+
operand: recordNullProtoTest(r, recvT.shapeId, loc),
|
|
11260
11423
|
type: BOOL,
|
|
11261
11424
|
loc,
|
|
11262
11425
|
},
|
|
@@ -11264,7 +11427,9 @@ function lowerRuntimeKeyIn(lowerer, expr, loc) {
|
|
|
11264
11427
|
loc,
|
|
11265
11428
|
};
|
|
11266
11429
|
}
|
|
11267
|
-
body.push(ret(
|
|
11430
|
+
body.push(ret(protoName === null
|
|
11431
|
+
? ovfHas
|
|
11432
|
+
: { kind: "logical", op: "||", left: ovfHas, right: protoName, type: BOOL, loc }));
|
|
11268
11433
|
lowerer.liftedFns.push({
|
|
11269
11434
|
name: helper,
|
|
11270
11435
|
params: [
|
|
@@ -11587,6 +11752,10 @@ function lowerMatchGroupsRead(lowerer, expr) {
|
|
|
11587
11752
|
if (!recvT || !isMatchSliceType(lowerer, recvT) || !lowerer.isStdlibMember(expr))
|
|
11588
11753
|
return null;
|
|
11589
11754
|
const groups = matchResultNamedGroupsOf(lowerer, expr.expression);
|
|
11755
|
+
// An untraced regex: TypeScript reaches the member fence; JavaScript
|
|
11756
|
+
// would otherwise read the slice's absent expando as undefined.
|
|
11757
|
+
if (groups === null && isJsSourceFile(expr.getSourceFile()))
|
|
11758
|
+
lowerer.stdlibMemberFence(expr);
|
|
11590
11759
|
if (groups === null)
|
|
11591
11760
|
return null;
|
|
11592
11761
|
if (groups.length === 0) {
|
|
@@ -13143,7 +13312,7 @@ function lowerFieldCompoundValue(lowerer, access, op, rhsNode, loc) {
|
|
|
13143
13312
|
? { kind: "dynCheck", value: rhs, type: F64, loc: rhs.loc }
|
|
13144
13313
|
: lowerOptionalNumber(lowerer, rhs, loc);
|
|
13145
13314
|
if (numericRhs.type.kind !== "f64")
|
|
13146
|
-
lowerer
|
|
13315
|
+
compoundUnsupported(lowerer, access, op, F64, numericRhs.type);
|
|
13147
13316
|
const value = save({ kind: "bin", op, left: cur, right: numericRhs, type: F64, loc }, "%compoundResult");
|
|
13148
13317
|
const boxed = { kind: "dynFrom", value, type: DYN, loc };
|
|
13149
13318
|
body.push({
|
|
@@ -13204,22 +13373,16 @@ function lowerFieldCompoundValue(lowerer, access, op, rhsNode, loc) {
|
|
|
13204
13373
|
else if (bigintValue) {
|
|
13205
13374
|
value = bigintValue;
|
|
13206
13375
|
}
|
|
13207
|
-
else if (target.fieldType.kind === "dyn" && isJsSourceFile(access.getSourceFile()))
|
|
13208
|
-
|
|
13209
|
-
|
|
13210
|
-
|
|
13211
|
-
|
|
13212
|
-
|
|
13213
|
-
|
|
13214
|
-
args: op === "+"
|
|
13215
|
-
? [left, right]
|
|
13216
|
-
: [left, right, { kind: "strLit", value: op, type: STRING, loc }],
|
|
13217
|
-
type: DYN,
|
|
13218
|
-
loc,
|
|
13219
|
-
};
|
|
13376
|
+
else if ((target.fieldType.kind === "dyn" && isJsSourceFile(access.getSourceFile())) ||
|
|
13377
|
+
// An untyped right operand: the expanded `o.f = o.f op rhs`; the field
|
|
13378
|
+
// write below checks the result into the declared field type.
|
|
13379
|
+
(rhs.type.kind === "dyn" &&
|
|
13380
|
+
lowerer.dynConvertible(read.type) &&
|
|
13381
|
+
lowerer.dynConvertible(target.fieldType))) {
|
|
13382
|
+
value = dynCompoundValue(op, lowerer.coerceToExpected(read, DYN), lowerer.coerceToExpected(rhs, DYN), loc);
|
|
13220
13383
|
}
|
|
13221
13384
|
else {
|
|
13222
|
-
lowerer.
|
|
13385
|
+
compoundUnsupported(lowerer, access, op, read.type, rhs.type);
|
|
13223
13386
|
}
|
|
13224
13387
|
if (storedString && rhs.type.kind === "string" && read.kind === "varRef" && appended !== null) {
|
|
13225
13388
|
// The field gives up its value before the concat (no code runs in
|
|
@@ -13260,6 +13423,11 @@ function lowerStreamObjectProperty(lowerer, expr) {
|
|
|
13260
13423
|
if (expr.name.text === "bytesWritten" && isZlibStreamMember(lowerer, expr)) {
|
|
13261
13424
|
return lowerZlibStreamBytesWritten(lowerer, expr);
|
|
13262
13425
|
}
|
|
13426
|
+
if (isFsStreamMember(lowerer, expr)) {
|
|
13427
|
+
const member = lowerFsStreamProperty(lowerer, expr);
|
|
13428
|
+
if (member)
|
|
13429
|
+
return member;
|
|
13430
|
+
}
|
|
13263
13431
|
return lowerStreamProperty(lowerer, expr, info);
|
|
13264
13432
|
}
|
|
13265
13433
|
/** The primitive-constructor closure (`String`/`Number`/`Boolean` as a
|