@scriptc/compiler 0.0.29 → 0.0.31
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 +201 -37
- 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 +27 -13
- 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 +398 -49
- 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 +74 -11
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +50 -12
- package/dist/frontend/lowering/lowerer.js +84 -15
- 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
|
|
@@ -3158,12 +3166,13 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
3158
3166
|
// adopt the initializer's type. Checker-`any[]` decls take the same
|
|
3159
3167
|
// rule (`const tlds = Array.isArray(u) ? u : [u]` — tsc's readonly
|
|
3160
3168
|
// Array.isArray quirk types the ternary any[], while the arms lower
|
|
3161
|
-
// to the union's real array arm
|
|
3169
|
+
// to the union's real array arm; readonly fixed-tuple narrows adopt
|
|
3170
|
+
// their tuple record likewise). Const only — an evolving-`any`
|
|
3162
3171
|
// `let` may be reassigned a different shape later; genuine `any`
|
|
3163
3172
|
// only — every other unmappable keeps its own diagnostic.
|
|
3164
3173
|
if (type === null && !isLet &&
|
|
3165
3174
|
((L.typeOf(decl.name).flags & ts.TypeFlags.Any) !== 0 ||
|
|
3166
|
-
(L.checkerAnyArray(decl.name) && init.type
|
|
3175
|
+
(L.checkerAnyArray(decl.name) && L.isArrayValueType(init.type)) ||
|
|
3167
3176
|
// JS declarations carry no annotations: an unmappable inferred
|
|
3168
3177
|
// type (a union with a fence-folded arm — the typeof-'bigint'
|
|
3169
3178
|
// dual-mode ternary) adopts the initializer's static type, the
|
|
@@ -3275,8 +3284,59 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
3275
3284
|
// subtyping (`const p: {a: number} = wider;`) is rejected, not coerced.
|
|
3276
3285
|
init = L.coerceInto(decl.initializer, init, type);
|
|
3277
3286
|
const local = L.declareLocal(decl.name, decl.name.text, type, isLet);
|
|
3287
|
+
if (runtimeOptional) {
|
|
3288
|
+
const runtimeOptionalRoot = L.runtimeOptionalRootOf(local);
|
|
3289
|
+
L.runtimeOptionalLocals.add(runtimeOptionalRoot);
|
|
3290
|
+
L.runtimeOptionalStorageLocals.add(runtimeOptionalRoot);
|
|
3291
|
+
}
|
|
3278
3292
|
return { kind: "varDecl", localId: local.id, init, loc: locOf(decl) };
|
|
3279
3293
|
}
|
|
3294
|
+
function immediatelyGuardedAbsenceProbe(L, decl) {
|
|
3295
|
+
if (decl.type || !ts.isIdentifier(decl.name) || !decl.initializer)
|
|
3296
|
+
return false;
|
|
3297
|
+
const statement = decl.parent?.parent;
|
|
3298
|
+
if (!statement || !ts.isVariableStatement(statement))
|
|
3299
|
+
return false;
|
|
3300
|
+
const container = statement.parent;
|
|
3301
|
+
const statements = ts.isBlock(container) || ts.isSourceFile(container) ? container.statements : null;
|
|
3302
|
+
if (!statements)
|
|
3303
|
+
return false;
|
|
3304
|
+
const index = statements.indexOf(statement);
|
|
3305
|
+
const next = index >= 0 ? statements[index + 1] : undefined;
|
|
3306
|
+
if (!next || !ts.isIfStatement(next))
|
|
3307
|
+
return false;
|
|
3308
|
+
let condition = next.expression;
|
|
3309
|
+
while (ts.isParenthesizedExpression(condition))
|
|
3310
|
+
condition = condition.expression;
|
|
3311
|
+
if (!ts.isPrefixUnaryExpression(condition) || condition.operator !== ts.SyntaxKind.ExclamationToken)
|
|
3312
|
+
return false;
|
|
3313
|
+
let operand = condition.operand;
|
|
3314
|
+
while (ts.isParenthesizedExpression(operand))
|
|
3315
|
+
operand = operand.expression;
|
|
3316
|
+
return ts.isIdentifier(operand) && L.resolveValueSymbol(operand) === L.resolveValueSymbol(decl.name);
|
|
3317
|
+
}
|
|
3318
|
+
function falsyExitRuntimeOptionalLocal(L, stmt) {
|
|
3319
|
+
if (stmt.elseStatement)
|
|
3320
|
+
return null;
|
|
3321
|
+
let condition = stmt.expression;
|
|
3322
|
+
while (ts.isParenthesizedExpression(condition))
|
|
3323
|
+
condition = condition.expression;
|
|
3324
|
+
if (!ts.isPrefixUnaryExpression(condition) || condition.operator !== ts.SyntaxKind.ExclamationToken)
|
|
3325
|
+
return null;
|
|
3326
|
+
let operand = condition.operand;
|
|
3327
|
+
while (ts.isParenthesizedExpression(operand))
|
|
3328
|
+
operand = operand.expression;
|
|
3329
|
+
if (!ts.isIdentifier(operand))
|
|
3330
|
+
return null;
|
|
3331
|
+
const local = L.resolveLocal(operand);
|
|
3332
|
+
if (!local || !L.runtimeOptionalLocals.has(L.runtimeOptionalRootOf(local)))
|
|
3333
|
+
return null;
|
|
3334
|
+
const exits = ts.isReturnStatement(stmt.thenStatement) || ts.isThrowStatement(stmt.thenStatement) ||
|
|
3335
|
+
(ts.isBlock(stmt.thenStatement) && stmt.thenStatement.statements.length > 0 &&
|
|
3336
|
+
(ts.isReturnStatement(stmt.thenStatement.statements[stmt.thenStatement.statements.length - 1]) ||
|
|
3337
|
+
ts.isThrowStatement(stmt.thenStatement.statements[stmt.thenStatement.statements.length - 1])));
|
|
3338
|
+
return exits ? local : null;
|
|
3339
|
+
}
|
|
3280
3340
|
/** JS-exact switch (see docs/ir.md): one shared lexical scope for all case
|
|
3281
3341
|
* bodies, lazy source-order test evaluation, fall-through. tsc has already
|
|
3282
3342
|
* checked case-test comparability (TS2678) — the kind check below is the
|
|
@@ -4261,6 +4321,9 @@ export function lowerExprStatement(L, expr) {
|
|
|
4261
4321
|
if (!target)
|
|
4262
4322
|
L.rejectUnresolved(expr.left, `assignment to '${expr.left.text}' (not a writable local or module global)`);
|
|
4263
4323
|
const value = L.lowerExprExpecting(expr.right, target.type);
|
|
4324
|
+
const runtimeOptionalRoot = L.runtimeOptionalRootOf(target);
|
|
4325
|
+
if (L.runtimeOptionalStorageLocals.has(runtimeOptionalRoot))
|
|
4326
|
+
L.runtimeOptionalLocals.add(runtimeOptionalRoot);
|
|
4264
4327
|
return { kind: "assign", localId: target.id, value, loc: locOf(expr) };
|
|
4265
4328
|
}
|
|
4266
4329
|
if (opKind === ts.SyntaxKind.QuestionQuestionEqualsToken) {
|