@scriptc/compiler 0.1.4 → 0.1.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.
- package/ambient/scriptc-node-fallback.d.ts +75 -11
- package/dist/backend/c/c-emitter.d.ts +5 -1
- package/dist/backend/c/c-emitter.js +22 -9
- package/dist/backend/c/c-emitter.js.map +1 -1
- package/dist/backend/c/exprs.d.ts +2 -2
- package/dist/backend/c/exprs.js +264 -21
- package/dist/backend/c/exprs.js.map +1 -1
- package/dist/backend/c/stmts.js +5 -3
- package/dist/backend/c/stmts.js.map +1 -1
- package/dist/backend/c/types.d.ts +2 -3
- package/dist/backend/c/types.js +8 -1
- package/dist/backend/c/types.js.map +1 -1
- package/dist/backend/c/walkers.js +1 -1
- package/dist/backend/c/walkers.js.map +1 -1
- package/dist/backend/link-plan.d.ts +1 -0
- package/dist/backend/link-plan.js +2 -1
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/llvm/dyn.js +1 -1
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +25 -9
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +1 -2
- package/dist/backend/llvm/expr-bytes.js +22 -17
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +1 -0
- package/dist/backend/llvm/expr-containers.js +32 -4
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +6 -2
- package/dist/backend/llvm/expr-primitives.js +22 -7
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +12 -0
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +53 -10
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +64 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +2 -0
- package/dist/backend/native-toolchain.js +2 -1
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/targets.d.ts +3 -0
- package/dist/backend/targets.js +13 -0
- package/dist/backend/targets.js.map +1 -1
- package/dist/coverage/surface-manifest.js +6 -4
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +2 -0
- package/dist/executable/executable-cache.js +3 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +3 -3
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.d.ts +1 -1
- package/dist/frontend/lowering/containers/bytes.js +6 -5
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +7 -6
- package/dist/frontend/lowering/containers/string-and-regexp.js +237 -28
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +8 -0
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +4 -5
- package/dist/frontend/lowering/lower-builtins.js +18 -10
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +3 -2
- package/dist/frontend/lowering/lower-calls.js +265 -88
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +2 -2
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +7 -9
- package/dist/frontend/lowering/lower-containers.js +143 -51
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +12 -0
- package/dist/frontend/lowering/lower-exprs.js +128 -10
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-island.js +17 -6
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +2 -4
- package/dist/frontend/lowering/lower-server.js +288 -32
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +4 -4
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.js +37 -2
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/optional-arguments.d.ts +9 -1
- package/dist/frontend/lowering/optional-arguments.js +67 -1
- package/dist/frontend/lowering/optional-arguments.js.map +1 -1
- package/dist/frontend/lowering/pairs-snapshot.d.ts +3 -1
- package/dist/frontend/lowering/pairs-snapshot.js +12 -4
- package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +8 -14
- package/dist/frontend/lowering/surfaces.js +37 -27
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm-static-prune.d.ts +6 -0
- package/dist/frontend/npm-static-prune.js +203 -0
- package/dist/frontend/npm-static-prune.js.map +1 -0
- package/dist/frontend/npm-static-prune.test.d.ts +1 -0
- package/dist/frontend/npm-static-prune.test.js +48 -0
- package/dist/frontend/npm-static-prune.test.js.map +1 -0
- package/dist/frontend/npm.js +7 -6
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/program.js +15 -4
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/provenance.js +8 -3
- package/dist/frontend/provenance.js.map +1 -1
- package/dist/frontend/type-mapper.js +16 -5
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +13 -41
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.d.ts +5 -3
- package/dist/ir/analysis.js +25 -11
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/analysis.test.js +50 -2
- package/dist/ir/analysis.test.js.map +1 -1
- package/dist/ir/constant-tables.d.ts +17 -0
- package/dist/ir/constant-tables.js +99 -0
- package/dist/ir/constant-tables.js.map +1 -0
- package/dist/ir/constant-tables.test.d.ts +1 -0
- package/dist/ir/constant-tables.test.js +78 -0
- package/dist/ir/constant-tables.test.js.map +1 -0
- package/dist/ir/integer-ranges.d.ts +13 -0
- package/dist/ir/integer-ranges.js +122 -0
- package/dist/ir/integer-ranges.js.map +1 -0
- package/dist/ir/integer-ranges.test.d.ts +1 -0
- package/dist/ir/integer-ranges.test.js +63 -0
- package/dist/ir/integer-ranges.test.js.map +1 -0
- package/dist/ir/ir.d.ts +42 -34
- package/dist/ir/ir.js +7 -1
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +6 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/scalar-records.d.ts +8 -0
- package/dist/ir/scalar-records.js +216 -0
- package/dist/ir/scalar-records.js.map +1 -0
- package/dist/ir/scalar-records.test.d.ts +1 -0
- package/dist/ir/scalar-records.test.js +142 -0
- package/dist/ir/scalar-records.test.js.map +1 -0
- package/dist/ir/validate.js +92 -8
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.d.ts +1 -0
- package/dist/ir/validate.test.js +31 -0
- package/dist/ir/validate.test.js.map +1 -0
- package/dist/library/cache-primitives.d.ts +1 -1
- package/dist/library/cache-primitives.js +3 -3
- package/dist/library/cache-primitives.js.map +1 -1
- package/dist/library/fence-eval.js +11 -4
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/library-cache.js +0 -1
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +3 -3
- package/dist/library/library-cache.test.js.map +1 -1
- package/package.json +17 -17
- package/surface-manifest.json +55 -42
|
@@ -164,10 +164,22 @@ export declare function lowerRecordKeyRead(lowerer: Lowerer, expr: ts.ElementAcc
|
|
|
164
164
|
* around the read are erased here because this context handles the missing
|
|
165
165
|
* arm instead of consuming it as the asserted type. */
|
|
166
166
|
export declare function lowerAbsenceProbe(lowerer: Lowerer, node: ts.Expression): IrExpr | null;
|
|
167
|
+
/** `a[i] op= rhs` over native arrays and byte views. A compound assignment
|
|
168
|
+
* evaluates the receiver and index, reads the old element, evaluates rhs,
|
|
169
|
+
* then writes. Capture each stage so a call in the index or rhs cannot
|
|
170
|
+
* change the target or the value used by the operator. The expression yields
|
|
171
|
+
* the computed value before a typed array or Buffer coerces it for storage. */
|
|
172
|
+
export declare function lowerElementCompound(lowerer: Lowerer, expr: ts.BinaryExpression, op: CompoundOp): IrExpr;
|
|
167
173
|
/** `a[i] = v` in statement position → arraySet (element writes, like local
|
|
168
174
|
* assignment, produce no value in our subset). */
|
|
169
175
|
export declare function lowerElementWrite(lowerer: Lowerer, expr: ts.BinaryExpression): IrStmt;
|
|
170
176
|
export declare function ensureString(lowerer: Lowerer, e: IrExpr, node: ts.Node): IrExpr;
|
|
177
|
+
/** `new String(x)` (stdlib provenance, ≤1 argument) in a ToString
|
|
178
|
+
* position: the wrapper's only distinguishers are typeof and identity —
|
|
179
|
+
* neither is observable where the value immediately stringifies — so the
|
|
180
|
+
* span lowers as the argument's own ToString (`new String()` is "").
|
|
181
|
+
* Every other position keeps the wrapper-object constructor fence. */
|
|
182
|
+
export declare function stringWrapperToString(lowerer: Lowerer, node: ts.Expression): IrExpr | null;
|
|
171
183
|
export declare function lowerTemplate(lowerer: Lowerer, expr: ts.TemplateExpression): IrExpr;
|
|
172
184
|
/** `x as T`. Non-dyn inner values ordinarily erase; a record assertion
|
|
173
185
|
* changing monomorphic shape rebuilds through the established width-copy
|
|
@@ -11,11 +11,11 @@ import { pathToFileURL } from "node:url";
|
|
|
11
11
|
import { wasiGuestPath } from "../../wasi-paths.js";
|
|
12
12
|
import { BIGINT_T, BOOL, CAUGHT, DYN, DYN_HANDLE_KINDS, F64, JSVAL, NULL_T, REF_TRUTHY_KINDS, REGEX, RUNTIME_ERROR_CLASSES, SEARCH_PARAMS_T, STRING, UNDEFINED_T, VOID, arrayOf, canAdaptDynFuncTo, canBoxFuncIntoDyn, funcOf, isDynTypedRefType, isJsonSafeType, isSupportedArrayElem, isUnitType, jsOpResultKind, shapeHasAccessorSlots, typeEquals, typeKey, unionFuncSetArmsOk } from "../../ir/ir.js";
|
|
13
13
|
import { cjsClassExprWholeExportOf, cjsExportAssignmentOf, cjsExportDiscardReason, isCjsExportTableLiteral, isCjsJsFile, isJsSourceFile, isModuleExportsAccess, isNodeEsmFile, locOf } from "../program.js";
|
|
14
|
-
import { ARRAY_METHODS, builtinConstLit, builtinFenceHintOf, builtinModuleConstOf, builtinModulesArrayLit, builtinModuleFnOf, ISLAND_SURFACE, isChildSurfaceMember, MAP_METHODS, NARROW_FIRST, SET_METHODS, STR_METHODS, UNSUPPORTED_EXPR, sideEffectFreeOptionValue, stdlibGlobalNameOf } from "./surfaces.js";
|
|
14
|
+
import { ARRAY_METHODS, builtinConstLit, builtinFenceHintOf, builtinModuleConstOf, builtinModulesArrayLit, builtinModuleFnOf, COMPOUND_ASSIGN_OPS, ISLAND_SURFACE, isChildSurfaceMember, MAP_METHODS, NARROW_FIRST, SET_METHODS, STR_METHODS, UNSUPPORTED_EXPR, sideEffectFreeOptionValue, stdlibGlobalNameOf } from "./surfaces.js";
|
|
15
15
|
import { blockedBindingUseDiag, requiresDynamicPackageDiag, unsupportedDiag } from "../../diagnostics/diagnostic.js";
|
|
16
16
|
import { PoisonError, dynUndefinedExpr, jsFuncNameOf, neverTaintedJsType, nodeThrowExpr, own } from "./lowerer.js";
|
|
17
|
-
import { lowerNpmStaticSafeIndexRead, lowerSafeIndexRead, strCharsCall } from "./lower-containers.js";
|
|
18
|
-
import { arrayValueStore } from "./array-values.js";
|
|
17
|
+
import { lowerNpmStaticSafeIndexRead, lowerSafeIndexRead, strCharsCall, tryLowerNumericIndexRead } from "./lower-containers.js";
|
|
18
|
+
import { arrayValueRead, arrayValueStore } from "./array-values.js";
|
|
19
19
|
import { npmStaticPackageOfPath } from "../npm-static.js";
|
|
20
20
|
import { unsupportedModuleFeatureOf } from "../builtin-modules.js";
|
|
21
21
|
import { fenceEnumObjectValue, lowerEnumAccess } from "./lower-enums.js";
|
|
@@ -35,6 +35,7 @@ import { conditionalSpreadOf, foldedStringKeyOf } from "./expressions/object-lit
|
|
|
35
35
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
36
36
|
import { fenceNodeModuleMutation, isNodeModuleValue, lowerNodeModuleIdentifier, lowerNodeModuleProperty, lowerRequireCacheElement, lowerRequireCacheHas, lowerRequireMainProperty } from "./lower-node-module.js";
|
|
37
37
|
import { lowerAbstractEquality } from "./abstract-equality.js";
|
|
38
|
+
import { coerceStringSearchValue, defaultAfterUndefined, lowerStaticallyUndefinedArgument } from "./optional-arguments.js";
|
|
38
39
|
/** A template piece's RAW text (String.raw's contract: escapes stay
|
|
39
40
|
* characters). 7's client AST ships no rawText at runtime (the typing
|
|
40
41
|
* declares it; the serialized node data omits it), so the raw span comes
|
|
@@ -871,6 +872,12 @@ function lowerExprInner(lowerer, expr) {
|
|
|
871
872
|
if (bi.module === "module" && bi.member === "builtinModules") {
|
|
872
873
|
return builtinModulesArrayLit(loc);
|
|
873
874
|
}
|
|
875
|
+
if (bi.module === "http" && bi.member === "METHODS") {
|
|
876
|
+
return { kind: "libCall", fn: "http.methods", args: [], type: arrayOf(STRING), loc };
|
|
877
|
+
}
|
|
878
|
+
if (bi.module === "http" && bi.member === "STATUS_CODES") {
|
|
879
|
+
return { kind: "libCall", fn: "http.statusCodes", args: [], type: DYN, loc };
|
|
880
|
+
}
|
|
874
881
|
// tls.rootCertificates: a runtime-valued module constant (the
|
|
875
882
|
// cached bundled-CA array) — the one member read that lowers
|
|
876
883
|
// to a libCall instead of a baked literal.
|
|
@@ -3804,6 +3811,11 @@ export function lowerOptionalNumber(lowerer, operand, loc, narrowedNode) {
|
|
|
3804
3811
|
if (operand.type.kind !== "union" || lowerer.armTag(operand.type.unionId, UNDEFINED_T) < 0)
|
|
3805
3812
|
return operand;
|
|
3806
3813
|
const directNumber = lowerer.stripUndefinedArm(operand.type).kind === "f64";
|
|
3814
|
+
if (directNumber) {
|
|
3815
|
+
const scalarRead = tryLowerNumericIndexRead(lowerer, operand, loc);
|
|
3816
|
+
if (scalarRead)
|
|
3817
|
+
return scalarRead;
|
|
3818
|
+
}
|
|
3807
3819
|
const checkerNumber = narrowedNode !== undefined && lowerer.mapTypeOf(lowerer.typeOf(narrowedNode))?.kind === "f64";
|
|
3808
3820
|
if (!directNumber && (!checkerNumber || lowerer.armTag(operand.type.unionId, F64) < 0))
|
|
3809
3821
|
return operand;
|
|
@@ -4582,6 +4594,78 @@ function tupleLiteralIndex(node) {
|
|
|
4582
4594
|
const n = Number(e.text);
|
|
4583
4595
|
return Number.isInteger(n) && n >= 0 ? n : null;
|
|
4584
4596
|
}
|
|
4597
|
+
/** `a[i] op= rhs` over native arrays and byte views. A compound assignment
|
|
4598
|
+
* evaluates the receiver and index, reads the old element, evaluates rhs,
|
|
4599
|
+
* then writes. Capture each stage so a call in the index or rhs cannot
|
|
4600
|
+
* change the target or the value used by the operator. The expression yields
|
|
4601
|
+
* the computed value before a typed array or Buffer coerces it for storage. */
|
|
4602
|
+
export function lowerElementCompound(lowerer, expr, op) {
|
|
4603
|
+
const target = expr.left;
|
|
4604
|
+
fenceNodeModuleMutation(lowerer, target, "assignment");
|
|
4605
|
+
const loc = locOf(expr);
|
|
4606
|
+
const receiverType = lowerer.mapTypeOf(lowerer.typeOf(target.expression));
|
|
4607
|
+
if (receiverType?.kind !== "array" && receiverType?.kind !== "bytes") {
|
|
4608
|
+
lowerer.unsupported("SC1090", target, "compound assignment to non-array elements");
|
|
4609
|
+
}
|
|
4610
|
+
let receiver = lowerer.lowerExpr(target.expression);
|
|
4611
|
+
if (receiver.type.kind === "union" && lowerer.armTag(receiver.type.unionId, UNDEFINED_T) >= 0) {
|
|
4612
|
+
const present = lowerer.stripUndefinedArm(receiver.type);
|
|
4613
|
+
const helper = present.kind === receiverType.kind
|
|
4614
|
+
? lowerer.narrowedArmHelper(receiver.type.unionId, present, locOf(target.expression))
|
|
4615
|
+
: null;
|
|
4616
|
+
if (helper)
|
|
4617
|
+
receiver = { kind: "call", callee: helper, args: [receiver], type: present, loc: locOf(target.expression) };
|
|
4618
|
+
}
|
|
4619
|
+
if (receiver.type.kind !== receiverType.kind) {
|
|
4620
|
+
lowerer.unsupported("SC1090", target.expression, "compound assignment through a non-native array or byte view");
|
|
4621
|
+
}
|
|
4622
|
+
const index = lowerer.lowerExpr(target.argumentExpression);
|
|
4623
|
+
if (index.type.kind !== "f64")
|
|
4624
|
+
lowerer.unsupported("SC1090", target.argumentExpression, "indexing with non-number keys");
|
|
4625
|
+
const receiverLocal = lowerer.declareHiddenLocal("%compoundArray", receiver.type);
|
|
4626
|
+
const indexLocal = lowerer.declareHiddenLocal("%compoundIndex", F64);
|
|
4627
|
+
const receiverRef = () => varRef(receiverLocal.id, receiver.type, loc);
|
|
4628
|
+
const indexRef = () => varRef(indexLocal.id, F64, loc);
|
|
4629
|
+
const oldValue = receiver.type.kind === "array"
|
|
4630
|
+
? arrayValueRead(lowerer, receiverRef(), indexRef(), receiver.type.elem, locOf(target))
|
|
4631
|
+
: { kind: "bytesIntrinsic", method: "get", receiver: receiverRef(), args: [indexRef()], type: F64, loc: locOf(target) };
|
|
4632
|
+
const oldLocal = lowerer.declareHiddenLocal("%compoundOld", oldValue.type);
|
|
4633
|
+
const oldRef = () => varRef(oldLocal.id, oldValue.type, loc);
|
|
4634
|
+
const rhs = lowerer.lowerExpr(expr.right);
|
|
4635
|
+
const numericRhs = lowerOptionalNumber(lowerer, rhs, loc);
|
|
4636
|
+
const elementType = receiver.type.kind === "array" ? receiver.type.elem : F64;
|
|
4637
|
+
const valueType = elementType.kind === "union" && lowerer.armTag(elementType.unionId, UNDEFINED_T) >= 0
|
|
4638
|
+
? lowerer.stripUndefinedArm(elementType)
|
|
4639
|
+
: elementType;
|
|
4640
|
+
let computed;
|
|
4641
|
+
if (op === "+" && valueType.kind === "string") {
|
|
4642
|
+
computed = { kind: "strConcat", left: lowerer.ensureString(oldRef(), target), right: lowerer.ensureString(rhs, expr.right), type: STRING, loc };
|
|
4643
|
+
}
|
|
4644
|
+
else if (valueType.kind === "f64" && numericRhs.type.kind === "f64") {
|
|
4645
|
+
computed = { kind: "bin", op, left: lowerOptionalNumber(lowerer, oldRef(), loc), right: numericRhs, type: F64, loc };
|
|
4646
|
+
}
|
|
4647
|
+
else {
|
|
4648
|
+
lowerer.unsupported("SC1043", expr);
|
|
4649
|
+
}
|
|
4650
|
+
const resultLocal = lowerer.declareHiddenLocal("%compoundResult", computed.type);
|
|
4651
|
+
const resultRef = () => varRef(resultLocal.id, computed.type, loc);
|
|
4652
|
+
const write = receiver.type.kind === "array"
|
|
4653
|
+
? arrayValueStore(lowerer, receiverRef(), indexRef(), resultRef(), receiver.type.elem, loc)
|
|
4654
|
+
: { kind: "bytesSet", arr: receiverRef(), index: indexRef(), value: resultRef(), loc };
|
|
4655
|
+
return {
|
|
4656
|
+
kind: "seqExpr",
|
|
4657
|
+
stmts: [
|
|
4658
|
+
{ kind: "varDecl", localId: receiverLocal.id, init: receiver, loc },
|
|
4659
|
+
{ kind: "varDecl", localId: indexLocal.id, init: index, loc },
|
|
4660
|
+
{ kind: "varDecl", localId: oldLocal.id, init: oldValue, loc },
|
|
4661
|
+
{ kind: "varDecl", localId: resultLocal.id, init: computed, loc },
|
|
4662
|
+
write,
|
|
4663
|
+
],
|
|
4664
|
+
result: resultRef(),
|
|
4665
|
+
type: computed.type,
|
|
4666
|
+
loc,
|
|
4667
|
+
};
|
|
4668
|
+
}
|
|
4585
4669
|
/** `a[i] = v` in statement position → arraySet (element writes, like local
|
|
4586
4670
|
* assignment, produce no value in our subset). */
|
|
4587
4671
|
export function lowerElementWrite(lowerer, expr) {
|
|
@@ -4953,6 +5037,18 @@ export function ensureString(lowerer, e, node) {
|
|
|
4953
5037
|
if (stringable) {
|
|
4954
5038
|
return { kind: "toString", operand: e, type: STRING, loc: e.loc };
|
|
4955
5039
|
}
|
|
5040
|
+
// Runtime-optional locals can retain their stored union after the
|
|
5041
|
+
// checker has narrowed this use to a primitive arm. Validate that
|
|
5042
|
+
// arm before converting it; an unguarded object arm stays fenced.
|
|
5043
|
+
const narrowed = lowerer.mapTypeOf(lowerer.typeOf(node));
|
|
5044
|
+
if (narrowed &&
|
|
5045
|
+
(narrowed.kind === "string" || narrowed.kind === "f64" ||
|
|
5046
|
+
narrowed.kind === "bool" || narrowed.kind === "bigint")) {
|
|
5047
|
+
const helper = lowerer.narrowedArmHelper(e.type.unionId, narrowed, e.loc);
|
|
5048
|
+
if (helper) {
|
|
5049
|
+
return ensureString(lowerer, { kind: "call", callee: helper, args: [e], type: narrowed, loc: e.loc }, node);
|
|
5050
|
+
}
|
|
5051
|
+
}
|
|
4956
5052
|
lowerer.unsupported("SC1090", node, `string conversions of unions with object arms (${NARROW_FIRST})`);
|
|
4957
5053
|
}
|
|
4958
5054
|
if (e.type.kind === "symbol") {
|
|
@@ -5004,7 +5100,7 @@ export function ensureString(lowerer, e, node) {
|
|
|
5004
5100
|
* neither is observable where the value immediately stringifies — so the
|
|
5005
5101
|
* span lowers as the argument's own ToString (`new String()` is "").
|
|
5006
5102
|
* Every other position keeps the wrapper-object constructor fence. */
|
|
5007
|
-
function stringWrapperToString(lowerer, node) {
|
|
5103
|
+
export function stringWrapperToString(lowerer, node) {
|
|
5008
5104
|
let e = node;
|
|
5009
5105
|
while (ts.isParenthesizedExpression(e))
|
|
5010
5106
|
e = e.expression;
|
|
@@ -5018,7 +5114,11 @@ function stringWrapperToString(lowerer, node) {
|
|
|
5018
5114
|
return null;
|
|
5019
5115
|
if (args.length === 0)
|
|
5020
5116
|
return { kind: "strLit", value: "", type: STRING, loc: locOf(e) };
|
|
5021
|
-
|
|
5117
|
+
const undefinedArg = lowerStaticallyUndefinedArgument(lowerer, args[0]);
|
|
5118
|
+
if (undefinedArg)
|
|
5119
|
+
return defaultAfterUndefined(undefinedArg, { kind: "strLit", value: "undefined", type: STRING, loc: locOf(e) });
|
|
5120
|
+
return lowerer.caughtToString(args[0]) ??
|
|
5121
|
+
coerceStringSearchValue(lowerer, lowerer.lowerExpr(args[0]), args[0], locOf(e));
|
|
5022
5122
|
}
|
|
5023
5123
|
export function lowerTemplate(lowerer, expr) {
|
|
5024
5124
|
const loc = locOf(expr);
|
|
@@ -5410,8 +5510,9 @@ export function lowerBinary(lowerer, expr) {
|
|
|
5410
5510
|
// globals, captured/boxed included); the RHS coerces into the binding's
|
|
5411
5511
|
// type exactly like statement position, and the expression's value is
|
|
5412
5512
|
// the coerced binding-typed value (representation change only — never
|
|
5413
|
-
// observably different from JS's raw-RHS yield).
|
|
5414
|
-
//
|
|
5513
|
+
// observably different from JS's raw-RHS yield). Indexed compounds
|
|
5514
|
+
// use a sequenced read/modify/write; other member targets and
|
|
5515
|
+
// destructuring targets stay fenced.
|
|
5415
5516
|
if (op === ts.SyntaxKind.EqualsToken && ts.isIdentifier(expr.left)) {
|
|
5416
5517
|
const target = lowerer.resolveWritable(expr.left);
|
|
5417
5518
|
if (!target) {
|
|
@@ -5423,6 +5524,10 @@ export function lowerBinary(lowerer, expr) {
|
|
|
5423
5524
|
lowerer.runtimeOptionalLocals.add(runtimeOptionalRoot);
|
|
5424
5525
|
return { kind: "assignExpr", localId: target.id, value, type: target.type, loc };
|
|
5425
5526
|
}
|
|
5527
|
+
const indexedCompound = COMPOUND_ASSIGN_OPS[op];
|
|
5528
|
+
if (indexedCompound !== undefined && ts.isElementAccessExpression(expr.left)) {
|
|
5529
|
+
return lowerElementCompound(lowerer, expr, indexedCompound);
|
|
5530
|
+
}
|
|
5426
5531
|
// `events.defaultMaxListeners = v` — the module-property write
|
|
5427
5532
|
// Node validates (validateNumber(n, 'defaultMaxListeners', 0)):
|
|
5428
5533
|
// the value crosses into the checked-dynamic tree and the runtime ladder throws
|
|
@@ -8739,7 +8844,20 @@ export function fieldGetExpr(lowerer, target, loc, blame) {
|
|
|
8739
8844
|
// construction), typed as the index value armed with undefined under
|
|
8740
8845
|
// noUncheckedIndexedAccess (mirroring lowerRecordKeyRead).
|
|
8741
8846
|
if (target.container === "recordOvf") {
|
|
8742
|
-
let
|
|
8847
|
+
let obj = target.obj;
|
|
8848
|
+
if (obj.type.kind === "union" && ts.isPropertyAccessExpression(blame)) {
|
|
8849
|
+
const present = lowerer.stripUndefinedArm(obj.type);
|
|
8850
|
+
if (present.kind === "record") {
|
|
8851
|
+
obj = lowerer.runtimeOptionalPropertyReceiver(blame.expression, obj, present, target.field) ?? obj;
|
|
8852
|
+
}
|
|
8853
|
+
}
|
|
8854
|
+
if (obj.type.kind !== "record") {
|
|
8855
|
+
lowerer.unsupported("SC1090", blame, `reading '${target.field}' on a non-record receiver (narrow first)`);
|
|
8856
|
+
}
|
|
8857
|
+
const shape = lowerer.shapes.get(obj.type.shapeId);
|
|
8858
|
+
if (!shape?.indexValue)
|
|
8859
|
+
lowerer.unsupported("SC1090", blame, `reading '${target.field}' on a record without an index signature`);
|
|
8860
|
+
let t = shape.indexValue;
|
|
8743
8861
|
if (lowerer.program.getCompilerOptions().noUncheckedIndexedAccess) {
|
|
8744
8862
|
const armed = lowerer.withUndefinedArmOf(t);
|
|
8745
8863
|
if (!armed)
|
|
@@ -8748,8 +8866,8 @@ export function fieldGetExpr(lowerer, target, loc, blame) {
|
|
|
8748
8866
|
}
|
|
8749
8867
|
return {
|
|
8750
8868
|
kind: "recordKeyGet",
|
|
8751
|
-
obj
|
|
8752
|
-
shapeId:
|
|
8869
|
+
obj,
|
|
8870
|
+
shapeId: obj.type.shapeId,
|
|
8753
8871
|
key: { kind: "strLit", value: target.field, type: STRING, loc },
|
|
8754
8872
|
overflowOnly: true,
|
|
8755
8873
|
type: t,
|