mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-31 07:23:06 +08:00
Static semantics reject a program before it runs. Until now the compiler
borrowed that rejection from whatever tsc happened to report, and Test262's
negative-parse suites show where the borrowing stops: programs the spec
makes SyntaxErrors compile and run. This adds the two largest families the
grab-bag misses (plan §7.7 D-4, option c), each under its own preflight
code, so a checker relaxation can never remove the only rejection a
parse-negative program had:
SC0005 a statement list declares one lexical name twice
(`{ class f {} async function f() {} }`)
SC0006 a lexical name is `var`-declared in the same statement list
(`switch (1) { case 1: let x; case 2: var x; }`)
SC0007 a declaration where the grammar admits only a Statement
(`while (false) function f() {}`, `l: class c {}`,
`if (x) async function f() {}`)
frontend/early-errors.ts is a preflight walk over JavaScript sources, so a
rejected program fails where a tsc parse error fails, before any lowering.
A case block is one lexical scope across its clauses; a list's
VarDeclaredNames reach into nested blocks but never into a function or a
class body; and Annex B's allowances are honored exactly: two plain
function declarations may repeat in a sloppy block (B.3.3.1), and a plain
function may be an if/else body or a labelled statement in sloppy code
(B.3.2) — an async function, a generator or a class never gets either
allowance, and neither does any function as a loop or 'with' body.
Strictness comes from Node's own module classification (isNodeEsmFile7),
not from the checker's external-module bit: moduleDetection=force gives
every file module scope, CommonJS included, and taking that bit as
strictness cost the Annex B exemption on the annexB
function-redeclaration tests. Typed sources are untouched — their checker
diagnostics (TS2451 and friends) remain the gate, and re-reporting a
collision under a second code would only duplicate them.
tests/test262/support.mjs counts one of these codes at a location inside
the test's own source as the parse-negative match, the same standard the
helper already applies to tsc's early errors. The diagnostics fixtures pin
both families, including the strict half of SC0007 where Node refuses the
two Annex B shapes as well.
The pass only reads the AST and only refuses programs, so no typed
program's IR changes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
9 lines
382 B
JavaScript
9 lines
382 B
JavaScript
// The strict half of SC0007: Annex B's allowance for a plain function
|
|
// declaration in an if/else body or a labelled statement is non-strict code
|
|
// only, so a "use strict" prologue takes it away — Node agrees on both
|
|
// shapes. The sloppy fixture beside this one pins the refusals that hold in
|
|
// both modes.
|
|
"use strict";
|
|
if (true) function inIf() {}
|
|
l: function inLabel() {}
|