fix(repl): report descriptive syntax error instead of "Unexpected token '<'" (#35016)
## Problem
Malformed input that swc can recover from produces a misleading error.
For example:
```ts
const test = (i, 2 * i) => console.log(i);
```
Both in the REPL and when run from a `.ts` file, Deno reports:
```
error: Uncaught SyntaxError: Unexpected token '<'
```
even though there is no `<` anywhere in the source.
## Root cause
swc's parser *recovers* from the malformed arrow parameters by inserting
an
`Invalid` placeholder node into the AST (emitting a non-fatal
`SyntaxError: Not a pattern`, but still returning a successfully-parsed
program). `swc_ecma_codegen` then emits each `Invalid` node as the
literal
text `<invalid>`, so the transpiled JavaScript contains a stray `<` that
V8
rejects with `Unexpected token '<'`.
`deno_ast`'s transpile only aborts on a hard-coded set of *fatal* syntax
errors, which does not include the recoverable errors that leave
`Invalid`
nodes behind — so the broken output is emitted and executed.
## Fix
Add `deno_resolver::emit::invalid_syntax_parse_diagnostics`, which
returns the
recovered-from parse diagnostics when the parsed program still contains
an
`Invalid` node (it fast-paths the common case of a well-formed source
with no
recovered diagnostics, so the AST is only walked when swc actually
recovered
from an error). It is wired into:
- the module emit path (`libs/resolver/emit.rs`), covering `deno run`,
`deno
bundle`, `deno compile`, etc.;
- the REPL (`cli/tools/repl/session.rs`). Because the REPL parses as
`.tsx`
first, it now falls back to a TypeScript parse when the `.tsx` parse
only
recovered with an `Invalid` node, so TypeScript type assertions like
`<string>x` (which look like JSX in `.tsx`) keep working.
This only ever newly-rejects code that already produced `<invalid>`
output
(which was never valid JavaScript), so it is not a behavior regression.
After the fix:
```
$ deno run main.ts
error: SyntaxError: Not a pattern
|
1 | const test = (i, 2 * i) => console.log(i);
| ~~~~~
at file:///.../main.ts:1:18
```
```
> const test = (i, 2 * i) => console.log(i);
parse error: Not a pattern at 1:18
```
## Tests
- `tests/specs/run/error_syntax_invalid_arrow_params` — `deno run` of
the
malformed file.
- `tests/integration/repl_tests.rs`:
- `syntax_error_invalid_arrow_params` — REPL regression test.
- `type_assertion_still_parses` — guards the `.tsx` → TypeScript
fallback so
`<string>x` type assertions still evaluate.
Closes #19457
Closes denoland/divybot#526
Co-authored-by: divybot <divybot@users.noreply.github.com>
Co-authored-by: Divy Srivastava <me@littledivy.com>