fix(javascript): parse JavaScript sources with JavaScript grammar (#3782)

parserPluginsForPath enabled Babel's typescript plugin for .js, .jsx,
.mjs and .cjs sources. TypeScript reads some valid JavaScript
differently: a conditional whose consequent is an arrow with a
parenthesized body (c?x=>(a):y=>(b)) throws as a return-type
annotation, and a<b>(c) becomes a generic call. VS Code's 20 MB
workbench bundles therefore returned no AST at all.

Select JavaScript grammar (JSX plus legacy decorators) for explicit
JavaScript extensions. TypeScript dialects and unnamed sources keep the
existing TypeScript-capable contract.

Fixes #3780
Refs #3670

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kaoru0822
2026-10-14 18:12:30 -07:00
committed by GitHub
parent 59f528f0e5
commit 44b197f924
3 changed files with 53 additions and 4 deletions
@@ -9,17 +9,21 @@ export type ParsedJavaScriptSource = ReturnType<typeof parse>;
*
* - `dts:true` only for `.d.ts/.d.mts/.d.cts` ambient declarations;
* ordinary `.ts` keeps the missing-initializer diagnostic.
* - JSX enabled for `.tsx`, `.jsx`, `.js`, and unknown paths; disabled for
* plain `.ts/.cts/.mts` (angle-bracket assertions, not JSX) and for all
* - `.js/.jsx/.mjs/.cjs` use JavaScript grammar with JSX. TypeScript reads
* some valid JavaScript differently (`c?x=>(a):y=>(b)` as a return type,
* `a<b>(c)` as a generic call), so it must not select their meaning.
* - JSX enabled for `.tsx` and unknown paths; disabled for plain
* `.ts/.cts/.mts` (angle-bracket assertions, not JSX) and for all
* declaration files. `.mts` (including `.d.mts`) sets
* `disallowAmbiguousJSXLike`, matching tsc's `.mts` mode.
* - `decorators-legacy` always present: without it decorated sources fail
* hard instead of reporting recovered syntax, losing every derived fact.
* - Unknown paths retain the existing JSX-capable contract (best-effort
* parse; failures surface via `errorRecovery`, never silent misparse).
* - Unknown paths retain the existing JSX- and TypeScript-capable contract
* (best-effort parse; failures surface via `errorRecovery`).
*/
export const parserPluginsForPath = (sourcePath?: string): ParserPlugin[] => {
const path = sourcePath ?? "";
if (/\.(?:js|jsx|mjs|cjs)$/iu.test(path)) return ["decorators-legacy", "jsx"];
const dts = /\.d\.(?:ts|mts|cts)$/iu.test(path);
const isTsLike = /\.(?:ts|cts|mts)$/iu.test(path);
const isTsx = /\.tsx$/iu.test(path);