@scriptc/compiler 0.1.3 → 0.1.4
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 +200 -51
- package/dist/backend/c/async.d.ts +25 -0
- package/dist/backend/c/async.js +167 -0
- package/dist/backend/c/async.js.map +1 -1
- package/dist/backend/c/c-emitter.d.ts +10 -0
- package/dist/backend/c/c-emitter.js +14 -2
- package/dist/backend/c/c-emitter.js.map +1 -1
- package/dist/backend/c/exprs.js +293 -51
- package/dist/backend/c/exprs.js.map +1 -1
- package/dist/backend/c/types.js +2 -0
- package/dist/backend/c/types.js.map +1 -1
- package/dist/backend/link-plan.d.ts +2 -1
- package/dist/backend/link-plan.js +2 -1
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/llvm/emitter.js +20 -6
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +1 -1
- package/dist/backend/llvm/expr-bytes.js +8 -8
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +9 -0
- package/dist/backend/llvm/expr-callbacks.js +125 -0
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +14 -2
- package/dist/backend/llvm/expr-dispatch.js +1 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +30 -9
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.d.ts +1 -0
- package/dist/backend/llvm/expr-primitives.test.js +38 -0
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -0
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +3 -0
- package/dist/backend/llvm/expr-stream-callbacks.js +69 -0
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +68 -10
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +18 -2
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +156 -6
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +36 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +23 -0
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +3 -0
- package/dist/backend/native-toolchain.js +3 -1
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +28 -10
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/targets.d.ts +4 -0
- package/dist/backend/targets.js +13 -0
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +8 -1
- package/dist/backend/targets.test.js.map +1 -1
- package/dist/coverage/surface-manifest.js +8 -0
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.js +1 -1
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +2 -0
- package/dist/executable/executable-cache.js +3 -0
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/frontend/fork-target.d.ts +17 -0
- package/dist/frontend/fork-target.js +256 -0
- package/dist/frontend/fork-target.js.map +1 -0
- package/dist/frontend/lowering/abstract-equality.d.ts +6 -0
- package/dist/frontend/lowering/abstract-equality.js +250 -0
- package/dist/frontend/lowering/abstract-equality.js.map +1 -0
- package/dist/frontend/lowering/lower-assert.js +71 -2
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +50 -23
- package/dist/frontend/lowering/lower-builtins.js +939 -106
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +29 -21
- package/dist/frontend/lowering/lower-calls.js +573 -121
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +39 -8
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.js +150 -0
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.js +212 -21
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.js +135 -83
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +4 -0
- package/dist/frontend/lowering/lower-inspect.js +1 -1
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +6 -3
- package/dist/frontend/lowering/lower-island.js +165 -6
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +6 -0
- package/dist/frontend/lowering/lower-modules.js +184 -38
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.js +7 -0
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +1 -1
- package/dist/frontend/lowering/lower-server.js +130 -27
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +118 -15
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +3 -0
- package/dist/frontend/lowering/lower-stream.js +7 -0
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +86 -9
- package/dist/frontend/lowering/lowerer.js +412 -72
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +26 -0
- package/dist/frontend/lowering/surfaces.js +140 -77
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm-static-declarations.d.ts +4 -0
- package/dist/frontend/npm-static-declarations.js +56 -0
- package/dist/frontend/npm-static-declarations.js.map +1 -1
- package/dist/frontend/npm-static-declarations.test.js +23 -2
- package/dist/frontend/npm-static-declarations.test.js.map +1 -1
- package/dist/frontend/npm-static.js +6 -5
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +15 -3
- package/dist/frontend/npm.js +80 -8
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.js +76 -9
- package/dist/frontend/npm.test.js.map +1 -1
- package/dist/frontend/program.js +92 -10
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/resolve.d.ts +6 -0
- package/dist/frontend/resolve.js +7 -4
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +5 -0
- package/dist/frontend/type-mapper.js +64 -24
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +24 -3
- package/dist/index.js.map +1 -1
- package/dist/ir/ir.d.ts +93 -47
- package/dist/ir/ir.js +63 -4
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +14 -1
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +1 -1
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/validate.js +165 -13
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/int-infer.test.js.map +1 -1
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/library-cache.test.js.map +1 -1
- package/package.json +17 -17
- package/surface-manifest.json +132 -38
|
@@ -23,7 +23,7 @@ import { ambientNsRootOf, ambientUndefReadType, ambientUndefVarRootOf, ambientUn
|
|
|
23
23
|
import { expandoMemberRead, expandoWritableTarget } from "./lower-expando.js";
|
|
24
24
|
import { lowerSocketInstanceOf, lowerTlsRootCertificates } from "./lower-server.js";
|
|
25
25
|
import { findGenericMethodOn, lowerStaticFieldRead } from "./lower-classes.js";
|
|
26
|
-
import { bindingNeverReassigned, implicitMonoFile, lowerTaggedTemplate, nullishGenericBindingUnitOf, objLitGenericFnInfoOf, objLitGenericFnNodeOf, requireObjLitGenericReceiver } from "./lower-calls.js";
|
|
26
|
+
import { bindingNeverReassigned, funcTypeFromParamShapes, implicitMonoFile, lowerTaggedTemplate, nullishGenericBindingUnitOf, objLitGenericFnInfoOf, objLitGenericFnNodeOf, requireObjLitGenericReceiver } from "./lower-calls.js";
|
|
27
27
|
import { mixinFnOfCallee } from "./lower-mixins.js";
|
|
28
28
|
import { isConstAssertionTypeNode, isGenericCallableMemberType, isParseArgsDynTypeName, underConstAssertion, unitOnlyUnion } from "../type-mapper.js";
|
|
29
29
|
import { lowerYield } from "./lower-generators.js";
|
|
@@ -34,6 +34,7 @@ import { hasOptionalChainGuard, isOptionalChainTail, isRequireMainFilename } fro
|
|
|
34
34
|
import { conditionalSpreadOf, foldedStringKeyOf } from "./expressions/object-literals.js";
|
|
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
|
+
import { lowerAbstractEquality } from "./abstract-equality.js";
|
|
37
38
|
/** A template piece's RAW text (String.raw's contract: escapes stay
|
|
38
39
|
* characters). 7's client AST ships no rawText at runtime (the typing
|
|
39
40
|
* declares it; the serialized node data omits it), so the raw span comes
|
|
@@ -598,6 +599,7 @@ function lowerExprInner(lowerer, expr) {
|
|
|
598
599
|
symbol: "symbol",
|
|
599
600
|
map: "object", set: "object", promise: "object", bytes: "object",
|
|
600
601
|
regexp: "object", generator: "object", classval: "function",
|
|
602
|
+
moduleNs: "object",
|
|
601
603
|
undefinedT: "undefined", nullT: "object",
|
|
602
604
|
};
|
|
603
605
|
const folded = FOLD[operand.type.kind];
|
|
@@ -649,13 +651,22 @@ function lowerExprInner(lowerer, expr) {
|
|
|
649
651
|
if (expr.text === "arguments" && lowerer.ctx.argumentsLocal) {
|
|
650
652
|
return { kind: "varRef", localId: lowerer.ctx.argumentsLocal.id, type: DYN, loc };
|
|
651
653
|
}
|
|
652
|
-
// A
|
|
653
|
-
//
|
|
654
|
-
//
|
|
654
|
+
// A compiler-projected adapter as a VALUE: the adapter has no
|
|
655
|
+
// runtime function object (its calls rewrite directly) — call it
|
|
656
|
+
// through its immutable binding instead.
|
|
655
657
|
{
|
|
656
658
|
const sym = lowerer.resolveValueSymbol(expr);
|
|
657
|
-
|
|
658
|
-
|
|
659
|
+
const projection = sym ? lowerer.staticCallables.get(sym) : undefined;
|
|
660
|
+
if (projection?.kind === "promisified-exec-file" || projection?.kind === "promisified-builtin") {
|
|
661
|
+
lowerer.unsupported("SC1090", expr, `a promisified builtin as a value (call '${expr.text}' directly)`);
|
|
662
|
+
}
|
|
663
|
+
if (projection?.kind === "builtin-function") {
|
|
664
|
+
if (!isJsSourceFile(expr.getSourceFile())) {
|
|
665
|
+
const callable = lowerer.lowerBuiltinCallableValue(projection, loc);
|
|
666
|
+
if (callable)
|
|
667
|
+
return callable;
|
|
668
|
+
}
|
|
669
|
+
lowerer.unsupported("SC1090", expr, `a builtin function alias as an escaping value (call '${expr.text}' directly)`);
|
|
659
670
|
}
|
|
660
671
|
}
|
|
661
672
|
// Union-typed bindings read through tsc's control-flow narrowing:
|
|
@@ -809,17 +820,12 @@ function lowerExprInner(lowerer, expr) {
|
|
|
809
820
|
if (sig && lowerer.isTopLevelFnSymbol(expr)) {
|
|
810
821
|
// A declared function used as a value: a zero-capture closure. The
|
|
811
822
|
// backend interns one per function so `f === f` holds (JS identity).
|
|
812
|
-
// The value's type is the completed ABI signature
|
|
813
|
-
//
|
|
823
|
+
// The value's type is the completed ABI signature; optional/default
|
|
824
|
+
// slots and typed rest arrays pass the value fence first.
|
|
814
825
|
lowerer.noteEdge(sig.name);
|
|
815
826
|
// dynRest slots stay out of the VALUE type's param list (fn.length
|
|
816
827
|
// semantics); the rest marker carries the trailing dyn-array ABI.
|
|
817
|
-
const funcType =
|
|
818
|
-
kind: "func",
|
|
819
|
-
params: sig.params.filter((p) => p.mode !== "dynRest").map((p) => p.type),
|
|
820
|
-
ret: sig.returnType,
|
|
821
|
-
...(sig.params.some((p) => p.mode === "dynRest") ? { rest: true } : {}),
|
|
822
|
-
};
|
|
828
|
+
const funcType = funcTypeFromParamShapes(sig.params, sig.returnType);
|
|
823
829
|
lowerer.requireExactArityValue(expr, expr, sig.params, funcType);
|
|
824
830
|
return { kind: "closure", fnName: sig.name, captures: [], type: funcType, loc };
|
|
825
831
|
}
|
|
@@ -879,6 +885,11 @@ function lowerExprInner(lowerer, expr) {
|
|
|
879
885
|
if (isJsSourceFile(expr.getSourceFile())) {
|
|
880
886
|
return { kind: "strLit", value: `[builtin ${bi.module}.${bi.member}]`, type: STRING, loc };
|
|
881
887
|
}
|
|
888
|
+
{
|
|
889
|
+
const callable = lowerer.lowerBuiltinCallableValue(bi, loc);
|
|
890
|
+
if (callable)
|
|
891
|
+
return callable;
|
|
892
|
+
}
|
|
882
893
|
if (builtinModuleFnOf(lowerer, bi.module, bi.member)) {
|
|
883
894
|
lowerer.unsupported("SC1090", expr, `library functions as values (call '${expr.text}' directly)`);
|
|
884
895
|
}
|
|
@@ -889,7 +900,12 @@ function lowerExprInner(lowerer, expr) {
|
|
|
889
900
|
// the namespace object has no representation — members lower at
|
|
890
901
|
// their access sites only. The CommonJS namespace binding
|
|
891
902
|
// (`const lib = require("./lib.js")`) gets the same fence.
|
|
892
|
-
|
|
903
|
+
const builtinNamespace = lowerer.builtinNamespaceModuleOf(expr);
|
|
904
|
+
if (builtinNamespace !== null) {
|
|
905
|
+
const type = { kind: "moduleNs", moduleId: `builtin:${builtinNamespace}` };
|
|
906
|
+
return { kind: "moduleNsRef", moduleId: type.moduleId, type, loc };
|
|
907
|
+
}
|
|
908
|
+
if (lowerer.cjsLocalModuleBindingOf(expr)) {
|
|
893
909
|
lowerer.unsupported("SC1090", expr, `module namespace objects as values (access '${expr.text}' members directly)`);
|
|
894
910
|
}
|
|
895
911
|
if (lowerer.islandGlobalFnOf(expr)) {
|
|
@@ -941,11 +957,14 @@ function lowerExprInner(lowerer, expr) {
|
|
|
941
957
|
// type-mapper.ts pins the one concrete signature `(value: string) =>
|
|
942
958
|
// primitive`; direct calls `String(x)` never reach here — the call
|
|
943
959
|
// lowering intercepts them with the wider static coercions).
|
|
944
|
-
|
|
960
|
+
const jsPrimitiveCtorSelector = isJsSourceFile(expr.getSourceFile()) &&
|
|
961
|
+
expr.parent !== undefined &&
|
|
962
|
+
ts.isArrowFunction(expr.parent) &&
|
|
963
|
+
expr.parent.body === expr;
|
|
945
964
|
if ((expr.text === "String" || expr.text === "Number" || expr.text === "Boolean") &&
|
|
946
|
-
!isJsSourceFile(expr.getSourceFile()) &&
|
|
965
|
+
(!isJsSourceFile(expr.getSourceFile()) || jsPrimitiveCtorSelector) &&
|
|
947
966
|
lowerer.isStdlibSymbol(lowerer.checker.getSymbolAtLocation(expr))) {
|
|
948
|
-
return primitiveCtorClosure(lowerer, expr.text, loc);
|
|
967
|
+
return primitiveCtorClosure(lowerer, expr.text, loc, jsPrimitiveCtorSelector);
|
|
949
968
|
}
|
|
950
969
|
// The lib fence's IDENTIFIER chokepoint: the real standard library
|
|
951
970
|
// resolves names the old minimal ambient world never declared
|
|
@@ -1081,6 +1100,15 @@ function lowerExprInner(lowerer, expr) {
|
|
|
1081
1100
|
// representation (ambient namespaces compile to Node's
|
|
1082
1101
|
// ReferenceError instead — the object never exists at runtime).
|
|
1083
1102
|
{
|
|
1103
|
+
const moduleNs = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
1104
|
+
if (moduleNs?.kind === "moduleNs") {
|
|
1105
|
+
return { kind: "moduleNsRef", moduleId: moduleNs.moduleId, type: moduleNs, loc };
|
|
1106
|
+
}
|
|
1107
|
+
const builtinNs = lowerer.builtinNamespaceModuleOf(expr);
|
|
1108
|
+
if (builtinNs !== null) {
|
|
1109
|
+
const type = { kind: "moduleNs", moduleId: `builtin:${builtinNs}` };
|
|
1110
|
+
return { kind: "moduleNsRef", moduleId: type.moduleId, type, loc };
|
|
1111
|
+
}
|
|
1084
1112
|
const ns = lowerNsIdentifierValue(lowerer, expr);
|
|
1085
1113
|
if (ns)
|
|
1086
1114
|
return ns;
|
|
@@ -3084,10 +3112,10 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
3084
3112
|
const receiver = lowerer.lowerExpr(expr.expression);
|
|
3085
3113
|
return { kind: "libCall", fn: "child.killed", args: [receiver], type: BOOL, loc };
|
|
3086
3114
|
}
|
|
3087
|
-
if (name === "on" || name === "kill" || name === "unref") {
|
|
3115
|
+
if (name === "on" || name === "once" || name === "kill" || name === "unref") {
|
|
3088
3116
|
lowerer.unsupported("SC1090", expr, `child methods as values (call '${name}' directly)`);
|
|
3089
3117
|
}
|
|
3090
|
-
lowerer.noLowering(`ChildProcess.${name}`, expr, "on(\"exit\" | \"error\", cb), pid, exitCode, killed, kill(signal?), and unref() are the supported ChildProcess members", lowerer.checker.getSymbolAtLocation(expr.name));
|
|
3118
|
+
lowerer.noLowering(`ChildProcess.${name}`, expr, "on/once(\"exit\" | \"close\" | \"error\", cb), pid, exitCode, killed, kill(signal?), and unref() are the supported ChildProcess members", lowerer.checker.getSymbolAtLocation(expr.name));
|
|
3091
3119
|
}
|
|
3092
3120
|
if (kind === "spawnRes") {
|
|
3093
3121
|
// The spawnSync-result reads. status is the interned `number | null`
|
|
@@ -3137,7 +3165,7 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
3137
3165
|
if (name === "isFile" || name === "isDirectory") {
|
|
3138
3166
|
lowerer.unsupported("SC1090", expr, `Stats methods as values (call '${name}' directly)`);
|
|
3139
3167
|
}
|
|
3140
|
-
lowerer.noLowering(`Stats.${name}`, expr, "isFile(), isDirectory(), isSymbolicLink(), size, blocks, nlink, atimeMs, and
|
|
3168
|
+
lowerer.noLowering(`Stats.${name}`, expr, "isFile(), isDirectory(), isSymbolicLink(), dev, ino, size, blocks, nlink, atimeMs, mtimeMs, and ctimeMs are the supported Stats members", lowerer.checker.getSymbolAtLocation(expr.name));
|
|
3141
3169
|
}
|
|
3142
3170
|
if (kind === "date") {
|
|
3143
3171
|
const methods = new Set([
|
|
@@ -3178,22 +3206,30 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
3178
3206
|
// serialization: lowercased hostname, `:port` appended exactly when
|
|
3179
3207
|
// a non-default port is present (scr_url_host — Node-exact,
|
|
3180
3208
|
// opaque-path URLs answer ""); `hostname` is the stored port-less
|
|
3181
|
-
// host field verbatim
|
|
3182
|
-
|
|
3183
|
-
// never sees one).
|
|
3184
|
-
if (name === "protocol" || name === "pathname" || name === "href" || name === "host" || name === "hostname" || name === "search") {
|
|
3209
|
+
// host field verbatim, including IPv6 brackets.
|
|
3210
|
+
if (name === "protocol" || name === "origin" || name === "username" || name === "password" || name === "pathname" || name === "href" || name === "host" || name === "hostname" || name === "port" || name === "search" || name === "hash") {
|
|
3185
3211
|
const receiver = lowerer.lowerExpr(expr.expression);
|
|
3186
3212
|
const fn = name === "protocol"
|
|
3187
3213
|
? "url.protocol"
|
|
3188
|
-
: name === "
|
|
3189
|
-
? "url.
|
|
3190
|
-
: name === "
|
|
3191
|
-
? "url.
|
|
3192
|
-
: name === "
|
|
3193
|
-
? "url.
|
|
3194
|
-
: name === "
|
|
3195
|
-
? "url.
|
|
3196
|
-
: "
|
|
3214
|
+
: name === "origin"
|
|
3215
|
+
? "url.origin"
|
|
3216
|
+
: name === "username"
|
|
3217
|
+
? "url.username"
|
|
3218
|
+
: name === "password"
|
|
3219
|
+
? "url.password"
|
|
3220
|
+
: name === "pathname"
|
|
3221
|
+
? "url.pathname"
|
|
3222
|
+
: name === "host"
|
|
3223
|
+
? "url.host"
|
|
3224
|
+
: name === "hostname"
|
|
3225
|
+
? "url.hostname"
|
|
3226
|
+
: name === "port"
|
|
3227
|
+
? "url.port"
|
|
3228
|
+
: name === "search"
|
|
3229
|
+
? "url.search"
|
|
3230
|
+
: name === "hash"
|
|
3231
|
+
? "url.hash"
|
|
3232
|
+
: "url.href";
|
|
3197
3233
|
return { kind: "libCall", fn, args: [receiver], type: STRING, loc: locOf(expr) };
|
|
3198
3234
|
}
|
|
3199
3235
|
// `u.searchParams`: the LIVE cached view (one identity per URL —
|
|
@@ -3206,7 +3242,7 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
3206
3242
|
if (name === "toString" || name === "toJSON") {
|
|
3207
3243
|
lowerer.unsupported("SC1090", expr, `URL methods as values (call '${name}' directly)`);
|
|
3208
3244
|
}
|
|
3209
|
-
lowerer.noLowering(`URL.${name}`, expr, "protocol, pathname, href, host, hostname, search, searchParams, and toString() are the supported URL members", lowerer.checker.getSymbolAtLocation(expr.name));
|
|
3245
|
+
lowerer.noLowering(`URL.${name}`, expr, "protocol, origin, username, password, pathname, href, host, hostname, port, search, hash, searchParams, and toString() are the supported URL members", lowerer.checker.getSymbolAtLocation(expr.name));
|
|
3210
3246
|
}
|
|
3211
3247
|
if (kind === "searchParams") {
|
|
3212
3248
|
const SEARCH_PARAMS_METHODS = new Set(["get", "getAll", "set", "append", "delete", "has", "sort", "toString", "forEach", "keys", "values", "entries"]);
|
|
@@ -5229,7 +5265,14 @@ export function lowerPrefixUnary(lowerer, expr) {
|
|
|
5229
5265
|
if (raw.type.kind === "bigint") {
|
|
5230
5266
|
return { kind: "libCall", fn: "bigint.not", args: [raw], type: BIGINT_T, loc };
|
|
5231
5267
|
}
|
|
5232
|
-
|
|
5268
|
+
// A checked-dynamic value retains enough JavaScript structure to
|
|
5269
|
+
// run exact ToNumber, including the object valueOf/toString
|
|
5270
|
+
// protocol. This is the static `any`/JS-lane answer for idioms
|
|
5271
|
+
// such as `while (~index)`, where inference may have widened an
|
|
5272
|
+
// otherwise numeric slot to the checked-dynamic tree.
|
|
5273
|
+
const operand = raw.type.kind === "dyn"
|
|
5274
|
+
? { kind: "libCall", fn: "dyn.toNumberCoerce", args: [raw], type: F64, loc }
|
|
5275
|
+
: lowerOptionalNumber(lowerer, raw, loc, expr.operand);
|
|
5233
5276
|
if (operand.type.kind !== "f64")
|
|
5234
5277
|
lowerer.unsupported("SC1043", expr);
|
|
5235
5278
|
return { kind: "unary", op: "~", operand, type: F64, loc };
|
|
@@ -5518,23 +5561,10 @@ export function lowerBinary(lowerer, expr) {
|
|
|
5518
5561
|
const nullTest = lowerLooseNullCompare(lowerer, expr, loc);
|
|
5519
5562
|
if (nullTest)
|
|
5520
5563
|
return nullTest;
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
{
|
|
5526
|
-
const negated = op === ts.SyntaxKind.ExclamationEqualsToken;
|
|
5527
|
-
const left = lowerer.lowerExpr(expr.left);
|
|
5528
|
-
const right = lowerer.lowerExpr(expr.right);
|
|
5529
|
-
if (left.type.kind === "string" && right.type.kind === "string") {
|
|
5530
|
-
return { kind: "strEq", negated, left, right, type: BOOL, loc };
|
|
5531
|
-
}
|
|
5532
|
-
if ((left.type.kind === "f64" && right.type.kind === "f64") ||
|
|
5533
|
-
(left.type.kind === "bool" && right.type.kind === "bool")) {
|
|
5534
|
-
return { kind: "bin", op: negated ? "!==" : "===", left, right, type: BOOL, loc };
|
|
5535
|
-
}
|
|
5536
|
-
}
|
|
5537
|
-
lowerer.unsupported("SC1040", expr);
|
|
5564
|
+
const loose = lowerAbstractEquality(lowerer, lowerer.lowerExpr(expr.left), lowerer.lowerExpr(expr.right), op === ts.SyntaxKind.ExclamationEqualsToken, loc);
|
|
5565
|
+
if (loose)
|
|
5566
|
+
return loose;
|
|
5567
|
+
lowerer.unsupported("SC1040", expr, undefined, "object-to-primitive loose equality can call user-defined valueOf/toString methods — compare explicit primitive conversions instead");
|
|
5538
5568
|
}
|
|
5539
5569
|
if (op === ts.SyntaxKind.AmpersandAmpersandToken || op === ts.SyntaxKind.BarBarToken) {
|
|
5540
5570
|
if (op === ts.SyntaxKind.BarBarToken) {
|
|
@@ -5558,6 +5588,15 @@ export function lowerBinary(lowerer, expr) {
|
|
|
5558
5588
|
if (left.kind === "unitLit") {
|
|
5559
5589
|
return op === ts.SyntaxKind.BarBarToken ? right : left;
|
|
5560
5590
|
}
|
|
5591
|
+
// JS objects and symbols are always truthy. In `ref || fallback`
|
|
5592
|
+
// the fallback is therefore unreachable and the result is the
|
|
5593
|
+
// already-evaluated left value — the browser-fallback idiom used by
|
|
5594
|
+
// packages for `process.argv || []` and `process.env || {}`. The
|
|
5595
|
+
// operand itself remains in the IR, preserving reads/calls that
|
|
5596
|
+
// produce the reference; only the unreachable right lowering drops.
|
|
5597
|
+
if (op === ts.SyntaxKind.BarBarToken && REF_TRUTHY_KINDS.has(left.type.kind)) {
|
|
5598
|
+
return left;
|
|
5599
|
+
}
|
|
5561
5600
|
if (left.type.kind === "dyn" || right.type.kind === "dyn") {
|
|
5562
5601
|
// A checked-dynamic operand (`fn.name || '<anonymous>'` —
|
|
5563
5602
|
// test/common's _mustCallInner): both sides live in the checked-dynamic tree and
|
|
@@ -6253,6 +6292,9 @@ export function lowerBinary(lowerer, expr) {
|
|
|
6253
6292
|
if (idLeft.type.kind === "classval" && idRight.type.kind === "classval") {
|
|
6254
6293
|
return { kind: "bin", op: negated ? "!==" : "===", left: idLeft, right: idRight, type: BOOL, loc };
|
|
6255
6294
|
}
|
|
6295
|
+
if (idLeft.type.kind === "moduleNs" && idRight.type.kind === "moduleNs") {
|
|
6296
|
+
return { kind: "bin", op: negated ? "!==" : "===", left: idLeft, right: idRight, type: BOOL, loc };
|
|
6297
|
+
}
|
|
6256
6298
|
if ((idLeft.type.kind === "array" ||
|
|
6257
6299
|
idLeft.type.kind === "map" ||
|
|
6258
6300
|
idLeft.type.kind === "set" ||
|
|
@@ -7359,10 +7401,10 @@ function lowerInExpression(lowerer, expr, loc) {
|
|
|
7359
7401
|
// Compile-time-known STRING keys fold — literals, and the same
|
|
7360
7402
|
// const/enum-literal and template folding computed property keys get
|
|
7361
7403
|
// (foldedStringKeyOf); runtime-valued keys keep the fence.
|
|
7362
|
-
// NUMERIC literal keys answer on ARRAY receivers
|
|
7363
|
-
//
|
|
7364
|
-
//
|
|
7365
|
-
//
|
|
7404
|
+
// NUMERIC literal keys answer on ARRAY receivers through the shared
|
|
7405
|
+
// presence query. Arrays retain holes independently from length, and
|
|
7406
|
+
// noncanonical numeric keys live in their ordinary-property table, so
|
|
7407
|
+
// a length comparison is not an honest `in` answer.
|
|
7366
7408
|
{
|
|
7367
7409
|
let kNode = expr.left;
|
|
7368
7410
|
while (ts.isParenthesizedExpression(kNode))
|
|
@@ -7370,12 +7412,14 @@ function lowerInExpression(lowerer, expr, loc) {
|
|
|
7370
7412
|
if (ts.isNumericLiteral(kNode) && lowerer.mapTypeOf(lowerer.typeOf(expr.right))?.kind === "array") {
|
|
7371
7413
|
const recvArr = lowerer.lowerExpr(expr.right);
|
|
7372
7414
|
if (recvArr.type.kind === "array") {
|
|
7373
|
-
const len = { kind: "arrIntrinsic", method: "length", receiver: recvArr, args: [], type: F64, loc };
|
|
7374
7415
|
const n = Number(kNode.text);
|
|
7375
|
-
|
|
7376
|
-
|
|
7377
|
-
|
|
7378
|
-
|
|
7416
|
+
return {
|
|
7417
|
+
kind: "arrayHas",
|
|
7418
|
+
arr: recvArr,
|
|
7419
|
+
index: { kind: "numLit", value: n, type: F64, loc },
|
|
7420
|
+
type: BOOL,
|
|
7421
|
+
loc,
|
|
7422
|
+
};
|
|
7379
7423
|
}
|
|
7380
7424
|
}
|
|
7381
7425
|
}
|
|
@@ -9011,32 +9055,40 @@ function lowerStreamObjectProperty(lowerer, expr) {
|
|
|
9011
9055
|
return lowerStreamProperty(lowerer, expr, info);
|
|
9012
9056
|
}
|
|
9013
9057
|
/** The primitive-constructor closure (`String`/`Number`/`Boolean` as a
|
|
9014
|
-
* VALUE): interns one synthesized module function per constructor
|
|
9015
|
-
*
|
|
9016
|
-
*
|
|
9017
|
-
* (`(
|
|
9018
|
-
*
|
|
9019
|
-
*
|
|
9020
|
-
* every reference the SAME immortal closure,
|
|
9021
|
-
* compares like JS function identity. */
|
|
9022
|
-
function primitiveCtorClosure(lowerer, name, loc) {
|
|
9058
|
+
* VALUE): interns one synthesized module function per constructor/ABI and
|
|
9059
|
+
* returns the zero-capture closure over it. Typed sources use the mapped
|
|
9060
|
+
* `(value: string) => primitive` signature; a recognized JavaScript
|
|
9061
|
+
* concise-arrow selector (`() => String`, the picocolors fallback) takes
|
|
9062
|
+
* dyn so its ordinary coercion signature survives inference residue. The
|
|
9063
|
+
* dyn bodies run exact ToString/ToNumber/ToBoolean, including object hooks.
|
|
9064
|
+
* Interning makes every reference under one ABI the SAME immortal closure,
|
|
9065
|
+
* so `opt.type === String` compares like JS function identity. */
|
|
9066
|
+
function primitiveCtorClosure(lowerer, name, loc, dynamicInput) {
|
|
9023
9067
|
const ret = name === "String" ? STRING : name === "Number" ? F64 : BOOL;
|
|
9024
|
-
const
|
|
9025
|
-
|
|
9068
|
+
const input = dynamicInput ? DYN : STRING;
|
|
9069
|
+
const fnT = funcOf([input], ret);
|
|
9070
|
+
const key = `${name}:${dynamicInput ? "dyn" : "string"}`;
|
|
9071
|
+
let fnName = lowerer.primitiveCtorFns.get(key);
|
|
9026
9072
|
if (!fnName) {
|
|
9027
|
-
fnName = `%builtin.${name}`;
|
|
9028
|
-
lowerer.primitiveCtorFns.set(
|
|
9029
|
-
const
|
|
9030
|
-
const value =
|
|
9031
|
-
?
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
9073
|
+
fnName = `%builtin.${name}${dynamicInput ? ".dyn" : ""}`;
|
|
9074
|
+
lowerer.primitiveCtorFns.set(key, fnName);
|
|
9075
|
+
const v = { kind: "varRef", localId: "v.0", type: input, loc };
|
|
9076
|
+
const value = dynamicInput
|
|
9077
|
+
? name === "String"
|
|
9078
|
+
? { kind: "libCall", fn: "dyn.toStringCoerce", args: [v], type: STRING, loc }
|
|
9079
|
+
: name === "Number"
|
|
9080
|
+
? { kind: "libCall", fn: "dyn.toNumberCoerce", args: [v], type: F64, loc }
|
|
9081
|
+
: { kind: "dynTest", test: "truthy", value: v, type: BOOL, loc }
|
|
9082
|
+
: name === "String"
|
|
9083
|
+
? v
|
|
9084
|
+
: name === "Number"
|
|
9085
|
+
? { kind: "libCall", fn: "num.fromString", args: [v], type: F64, loc }
|
|
9086
|
+
: { kind: "strEq", negated: true, left: v, right: { kind: "strLit", value: "", type: STRING, loc }, type: BOOL, loc };
|
|
9035
9087
|
const fn = {
|
|
9036
9088
|
name: fnName,
|
|
9037
|
-
params: [{ localId: "v.0", name: "value", type:
|
|
9089
|
+
params: [{ localId: "v.0", name: "value", type: input }],
|
|
9038
9090
|
returnType: ret,
|
|
9039
|
-
locals: [{ id: "v.0", name: "value", type:
|
|
9091
|
+
locals: [{ id: "v.0", name: "value", type: input, mutable: false }],
|
|
9040
9092
|
body: [{ kind: "return", value, loc }],
|
|
9041
9093
|
loc,
|
|
9042
9094
|
};
|