@scriptc/compiler 0.0.29 → 0.0.30
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 +5 -13
- package/dist/backend/emission/emit-async.d.ts +1 -0
- package/dist/backend/emission/emit-async.js +27 -1
- package/dist/backend/emission/emit-async.js.map +1 -1
- package/dist/backend/emission/emit-exprs.js +109 -18
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emitter.d.ts +1 -0
- package/dist/backend/emission/emitter.js +25 -3
- package/dist/backend/emission/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.js +152 -0
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/mangle.d.ts +1 -0
- package/dist/backend/mangle.js +3 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +23 -1
- package/dist/diagnostics/diagnostic.js +34 -0
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +3 -1
- package/dist/frontend/lowering/lower-calls.js +196 -33
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +6 -5
- package/dist/frontend/lowering/lower-containers.js +15 -11
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +11 -1
- package/dist/frontend/lowering/lower-exprs.js +366 -25
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +5 -0
- package/dist/frontend/lowering/lower-server.js +105 -55
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +71 -9
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +24 -5
- package/dist/frontend/lowering/lowerer.js +28 -4
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +52 -19
- package/dist/ir/nodes.js +2 -2
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +67 -9
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/profile.d.ts +33 -0
- package/dist/library/profile.js +161 -3
- package/dist/library/profile.js.map +1 -1
- package/dist/library/sidecar.d.ts +3 -2
- package/dist/library/sidecar.js +7 -3
- package/dist/library/sidecar.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +1 -1
|
@@ -20,7 +20,7 @@ import { lowerStreamUnderscoreAssign, streamClassAliasDecl, streamSidesOf } from
|
|
|
20
20
|
import { lowerHttpResPropertyAssignment, lowerHttpServerTimeoutAssignment, lowerServerCloseOverrideAssignment } from "./lower-server.js";
|
|
21
21
|
import { builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireCalleeFileOf, createRequireNamespaceDecl, textCodecBindingDecl } from "./lower-builtins.js";
|
|
22
22
|
import { lowerEnumDeclaration } from "./lower-enums.js";
|
|
23
|
-
import { abstractPropertyDeclOf, aliasTypeofNarrows, isMatchSliceType, lowerGroupsProjection, matchResultNamedGroupsOf, probeLower, pureReemittable, symbolFieldInfo } from "./lower-exprs.js";
|
|
23
|
+
import { abstractPropertyDeclOf, aliasTypeofNarrows, isMatchSliceType, lowerAbsenceProbe, lowerGroupsProjection, matchResultNamedGroupsOf, probeLower, pureReemittable, runtimeOptionalTrueIds, symbolFieldInfo, withRuntimeOptionalNarrowed } from "./lower-exprs.js";
|
|
24
24
|
import { checkerPanicDiag, isCheckerPanic, requiresDynamicDiag } from "../../diagnostics/diagnostic.js";
|
|
25
25
|
import { isParseArgsDynTypeName, isUnitOnlyTsType, unitOnlyUnion } from "../types.js";
|
|
26
26
|
import { canonicalBuiltinModule, isRelativeSpecifier } from "../shared.js";
|
|
@@ -704,16 +704,19 @@ export function lowerStmt(L, stmt) {
|
|
|
704
704
|
// then-branch lowers under what a TRUE condition proves, the
|
|
705
705
|
// else-branch under a FALSE one — the var/let alias narrowing the
|
|
706
706
|
// checker only performs for consts (aliasTypeofNarrows).
|
|
707
|
-
const then = L.narrowingAliases(aliasTypeofNarrows(L, stmt.expression, true), () => L.lowerScopedBlock(stmt.thenStatement));
|
|
707
|
+
const then = L.narrowingAliases(aliasTypeofNarrows(L, stmt.expression, true), () => withRuntimeOptionalNarrowed(L, runtimeOptionalTrueIds(L, stmt.expression), () => L.lowerScopedBlock(stmt.thenStatement)));
|
|
708
708
|
const else_ = stmt.elseStatement
|
|
709
709
|
? L.narrowingAliases(aliasTypeofNarrows(L, stmt.expression, false), () => L.lowerScopedBlock(stmt.elseStatement))
|
|
710
710
|
: null;
|
|
711
|
+
const narrowedAfter = falsyExitRuntimeOptionalLocal(L, stmt);
|
|
712
|
+
if (narrowedAfter !== null)
|
|
713
|
+
L.runtimeOptionalLocals.delete(L.runtimeOptionalRootOf(narrowedAfter));
|
|
711
714
|
return { kind: "if", cond, then, else_, loc: locOf(stmt) };
|
|
712
715
|
}
|
|
713
716
|
if (ts.isWhileStatement(stmt)) {
|
|
714
717
|
const labels = L.takeLabels();
|
|
715
718
|
const cond = L.lowerCondition(stmt.expression);
|
|
716
|
-
const body = L.inCtl("loop", () => L.lowerScopedBlock(stmt.statement), labels);
|
|
719
|
+
const body = L.inCtl("loop", () => withRuntimeOptionalNarrowed(L, runtimeOptionalTrueIds(L, stmt.expression), () => L.lowerScopedBlock(stmt.statement)), labels);
|
|
717
720
|
return { kind: "while", cond, body, ...(labels && { labels }), loc: locOf(stmt) };
|
|
718
721
|
}
|
|
719
722
|
if (ts.isDoStatement(stmt)) {
|
|
@@ -3054,7 +3057,9 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
3054
3057
|
// later references to this name don't produce cascading errors.
|
|
3055
3058
|
let init;
|
|
3056
3059
|
try {
|
|
3057
|
-
init = L
|
|
3060
|
+
init = immediatelyGuardedAbsenceProbe(L, decl)
|
|
3061
|
+
? (lowerAbsenceProbe(L, decl.initializer) ?? L.lowerExpr(decl.initializer))
|
|
3062
|
+
: L.lowerExpr(decl.initializer);
|
|
3058
3063
|
}
|
|
3059
3064
|
catch (e) {
|
|
3060
3065
|
if (e instanceof PoisonError) {
|
|
@@ -3134,14 +3139,17 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
3134
3139
|
}
|
|
3135
3140
|
}
|
|
3136
3141
|
}
|
|
3137
|
-
//
|
|
3138
|
-
//
|
|
3139
|
-
//
|
|
3140
|
-
//
|
|
3141
|
-
|
|
3142
|
+
// An unannotated binding holding an OOB-SAFE indexed read (`elem |
|
|
3143
|
+
// undefined`) where the checker spells the bare element: the binding
|
|
3144
|
+
// adopts the runtime-honest union. This covers both inferred package JS
|
|
3145
|
+
// and TypeScript's fresh-array probe idioms; an explicit annotation keeps
|
|
3146
|
+
// the caller's checked slot contract.
|
|
3147
|
+
let runtimeOptional = false;
|
|
3148
|
+
if (!decl.type && type !== null && init.type.kind === "union" &&
|
|
3142
3149
|
L.armTag(init.type.unionId, UNDEFINED_T) >= 0 &&
|
|
3143
3150
|
typeEquals(L.stripUndefinedArm(init.type), type)) {
|
|
3144
3151
|
type = init.type;
|
|
3152
|
+
runtimeOptional = true;
|
|
3145
3153
|
}
|
|
3146
3154
|
// A JS binding whose checker type spells a FUNCTION but whose VALUE is
|
|
3147
3155
|
// already checked-dynamic (`const cb = mustCall(fn)` — the helper's
|
|
@@ -3275,8 +3283,59 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
3275
3283
|
// subtyping (`const p: {a: number} = wider;`) is rejected, not coerced.
|
|
3276
3284
|
init = L.coerceInto(decl.initializer, init, type);
|
|
3277
3285
|
const local = L.declareLocal(decl.name, decl.name.text, type, isLet);
|
|
3286
|
+
if (runtimeOptional) {
|
|
3287
|
+
const runtimeOptionalRoot = L.runtimeOptionalRootOf(local);
|
|
3288
|
+
L.runtimeOptionalLocals.add(runtimeOptionalRoot);
|
|
3289
|
+
L.runtimeOptionalStorageLocals.add(runtimeOptionalRoot);
|
|
3290
|
+
}
|
|
3278
3291
|
return { kind: "varDecl", localId: local.id, init, loc: locOf(decl) };
|
|
3279
3292
|
}
|
|
3293
|
+
function immediatelyGuardedAbsenceProbe(L, decl) {
|
|
3294
|
+
if (decl.type || !ts.isIdentifier(decl.name) || !decl.initializer)
|
|
3295
|
+
return false;
|
|
3296
|
+
const statement = decl.parent?.parent;
|
|
3297
|
+
if (!statement || !ts.isVariableStatement(statement))
|
|
3298
|
+
return false;
|
|
3299
|
+
const container = statement.parent;
|
|
3300
|
+
const statements = ts.isBlock(container) || ts.isSourceFile(container) ? container.statements : null;
|
|
3301
|
+
if (!statements)
|
|
3302
|
+
return false;
|
|
3303
|
+
const index = statements.indexOf(statement);
|
|
3304
|
+
const next = index >= 0 ? statements[index + 1] : undefined;
|
|
3305
|
+
if (!next || !ts.isIfStatement(next))
|
|
3306
|
+
return false;
|
|
3307
|
+
let condition = next.expression;
|
|
3308
|
+
while (ts.isParenthesizedExpression(condition))
|
|
3309
|
+
condition = condition.expression;
|
|
3310
|
+
if (!ts.isPrefixUnaryExpression(condition) || condition.operator !== ts.SyntaxKind.ExclamationToken)
|
|
3311
|
+
return false;
|
|
3312
|
+
let operand = condition.operand;
|
|
3313
|
+
while (ts.isParenthesizedExpression(operand))
|
|
3314
|
+
operand = operand.expression;
|
|
3315
|
+
return ts.isIdentifier(operand) && L.resolveValueSymbol(operand) === L.resolveValueSymbol(decl.name);
|
|
3316
|
+
}
|
|
3317
|
+
function falsyExitRuntimeOptionalLocal(L, stmt) {
|
|
3318
|
+
if (stmt.elseStatement)
|
|
3319
|
+
return null;
|
|
3320
|
+
let condition = stmt.expression;
|
|
3321
|
+
while (ts.isParenthesizedExpression(condition))
|
|
3322
|
+
condition = condition.expression;
|
|
3323
|
+
if (!ts.isPrefixUnaryExpression(condition) || condition.operator !== ts.SyntaxKind.ExclamationToken)
|
|
3324
|
+
return null;
|
|
3325
|
+
let operand = condition.operand;
|
|
3326
|
+
while (ts.isParenthesizedExpression(operand))
|
|
3327
|
+
operand = operand.expression;
|
|
3328
|
+
if (!ts.isIdentifier(operand))
|
|
3329
|
+
return null;
|
|
3330
|
+
const local = L.resolveLocal(operand);
|
|
3331
|
+
if (!local || !L.runtimeOptionalLocals.has(L.runtimeOptionalRootOf(local)))
|
|
3332
|
+
return null;
|
|
3333
|
+
const exits = ts.isReturnStatement(stmt.thenStatement) || ts.isThrowStatement(stmt.thenStatement) ||
|
|
3334
|
+
(ts.isBlock(stmt.thenStatement) && stmt.thenStatement.statements.length > 0 &&
|
|
3335
|
+
(ts.isReturnStatement(stmt.thenStatement.statements[stmt.thenStatement.statements.length - 1]) ||
|
|
3336
|
+
ts.isThrowStatement(stmt.thenStatement.statements[stmt.thenStatement.statements.length - 1])));
|
|
3337
|
+
return exits ? local : null;
|
|
3338
|
+
}
|
|
3280
3339
|
/** JS-exact switch (see docs/ir.md): one shared lexical scope for all case
|
|
3281
3340
|
* bodies, lazy source-order test evaluation, fall-through. tsc has already
|
|
3282
3341
|
* checked case-test comparability (TS2678) — the kind check below is the
|
|
@@ -4261,6 +4320,9 @@ export function lowerExprStatement(L, expr) {
|
|
|
4261
4320
|
if (!target)
|
|
4262
4321
|
L.rejectUnresolved(expr.left, `assignment to '${expr.left.text}' (not a writable local or module global)`);
|
|
4263
4322
|
const value = L.lowerExprExpecting(expr.right, target.type);
|
|
4323
|
+
const runtimeOptionalRoot = L.runtimeOptionalRootOf(target);
|
|
4324
|
+
if (L.runtimeOptionalStorageLocals.has(runtimeOptionalRoot))
|
|
4325
|
+
L.runtimeOptionalLocals.add(runtimeOptionalRoot);
|
|
4264
4326
|
return { kind: "assign", localId: target.id, value, loc: locOf(expr) };
|
|
4265
4327
|
}
|
|
4266
4328
|
if (opKind === ts.SyntaxKind.QuestionQuestionEqualsToken) {
|