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>
harness/assert.js defines `compareArray(a, b)` beside `assert`: a plain
function that RETURNS a boolean, whose throwing counterpart is
`assert.compareArray` (already hosted). The adapter now injects the bare
name into every prepared test and implements the upstream comparison:
read both `.length`s, so a nullish operand throws the same TypeError,
return false on a length mismatch, otherwise compare elements by
SameValue.
That also admits the compareArray.js include when the only use is a
direct call. A value reference or property read stays excluded, because
it would need the upstream function object and its `format` expando.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Expand static Test262 harness and exception semantics
* Ignore ASan fiber warning in dev source test
* Refresh TS7 parity baselines after main rebase