Commit Graph

1582 Commits

Author SHA1 Message Date
overlookmotel 4b0611a5dd perf(estree/tokens): introduce ESTreeTokenConfig trait (#19842)
Introduce `ESTreeTokenConfig` trait and allow option for the "flavor" of tokens to be set at compile time.

When producing Espree-style tokens, this allows cutting out all the special-case logic related to `JSXIdentifier` tokens and removing 2 branches from `emit_identifier_at`.

Small effect on perf - only +0.3% on ESTree tokens benchmark.
2026-02-28 16:13:09 +00:00
camc314 5036bb69e8 feat(parser): report error on for await in static blocks (#19844) 2026-02-28 13:39:33 +00:00
camc314 42bd431db5 feat(parser): report error for missing initializer in using decl (#19824) 2026-02-28 13:12:03 +00:00
overlookmotel 6f676dcb5a refactor(estree/tokens): rename types (#19834)
Pure refactor. Rename types. Correct capitalization in `ESTreeSafeToken` etc.
2026-02-28 12:59:24 +00:00
Cameron a2f58e5ea4 feat(parser): report error for implements clause in non-ts files (#19820) 2026-02-28 10:33:46 +08:00
camc314 ef798af434 fix(parser): use TS8037 for satisfies expression in JS files diagnostic (#19819)
https://github.com/microsoft/typescript/blob/0208948c95817bd7491111b40d6cf05013b21c4a/src/compiler/diagnosticMessages.json#L7082-L7085
2026-02-27 17:39:32 +00:00
camc314 98ea5c5863 fix(parser): use TS8016 for type assertions in JS files diagnostic (#19818)
https://github.com/microsoft/typescript/blob/0208948c95817bd7491111b40d6cf05013b21c4a/src/compiler/diagnosticMessages.json#L7002-L7005

This should be a 8016 error code, not 8037
2026-02-27 17:39:32 +00:00
overlookmotel ec88f6a7f3 perf(estree/tokens): serialize tokens while visiting AST (#19726)
Previously we used a 3-pass process for serializing tokens in ESTree format.

* Pass 1: Walk AST and produce a list of "overrides" - which tokens need their `Kind` changed.
* Pass 2: Loop through all tokens, apply any overrides, convert to `ESTreeToken`s, and save them in a `Vec`.
* Pass 3: Serialize the `Vec<ESTreeToken>` with `ESTree` trait (JSON serializer).

Compress this all to a single pass:

* Create an `ESTreeSequenceSerializer` which can have items sent to it to serialize one-by-one (streaming).
* Walk AST.
* When encounter a token which needs its `Kind` altered:
  * Flush all previous tokens, serializing each in turn, using its default `Kind`.
  * Serialize the current token with the amended `Kind`.
  * Continue walking.
* At the end, flush any remaining tokens to the serializer.

This avoids multiple passes, and also removes the `Vec<ESTreeToken>` which was just intermediate data, and grew very large.

+18% perf improvement on ESTree tokens benchmark.
2026-02-25 20:32:38 +00:00
overlookmotel 8b030d948e refactor(estree/tokens): convert tokens spans before AST spans (#19723)
Refactor.

Previously we converted spans from UTF-8 to UTF-16 in AST first, then serialized tokens. This meant that when serializing tokens, we had to convert spans to UTF-16 before comparing offsets of overrides to the token's start offset (because the override offsets are taken from the AST nodes during the AST walk pass).

Instead, convert token spans first, *then* the AST. This removes span conversion from the critical path. On a CPU with instruction-level parallelism, other work can start without being blocked on waiting for the result of span conversion, and the two can happen in parallel.

This should be a slight perf improvement, though it likely won't show up on CodSpeed benchmarks as CodSpeed's CPU simulation to basic to emulate instruction-level parallelism.

But mainly, the motivation is that this makes the process simpler and easier to reason about.
2026-02-25 20:32:37 +00:00
Boshen 6a59a76961 fix(parser): improve error recovery for private identifiers in property names (#19710)
## Summary

- When `#ident` appears as a property key in invalid positions (object literals `{#x: 1}`, destructuring `const {#x} = y`, TS interface members), the parser previously fell into `parse_identifier_name()` producing an unhelpful "Unexpected token" error
- Added a `Kind::PrivateIdentifier` arm in `parse_property_name()` that creates a proper `PropertyKey::PrivateIdentifier` AST node and emits "Private identifier '#x' is not allowed in property names"
- This works correctly both inside and outside class bodies, with no conformance regressions

closes #19669

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-25 11:49:16 +00:00
overlookmotel 3569aabc5c test(estree): ESTree conformance check files with hashbangs (#19680)
Oxc's AST on JS side has a non-standard `hashbang` property. Previously in ESTree conformance tests, we skipped files with a hashbang.

Bump `estree-conformance` submodule to include https://github.com/oxc-project/estree-conformance/pull/183 which adds `hashbang` property to AST in snapshots.

We can now enable the tests which we previously skipped.
2026-02-24 16:04:11 +00:00
overlookmotel f5694ced32 fix(estree/tokens): reverse field order of regex object in tokens (#19679)
Our convention is that object properties are in source code order. Reverse `pattern` and `flags` properties of `regex` objects in ESTree tokens to align with this pattern.

Bump `estree-conformance` submodule to include https://github.com/oxc-project/estree-conformance/pull/182 which makes the same change in snapshots for conformance tests.
2026-02-24 16:04:11 +00:00
overlookmotel 8940f66861 perf(estree/tokens): serialize tokens to compact JSON (#19572)
Perf optimization to converting tokens to ESTree JSON. Previously we serialized to pretty-printed JSON. Instead use compact JSON - it's just passed to `JSON.parse` on JS side, so there's no need for whitespace.
2026-02-24 15:42:28 +00:00
overlookmotel b2b7a552f3 fix(estree/tokens): generate tokens for files with BOM (#19535)
Fix a bug where we didn't produce any tokens for files which start with a BOM.

As a side effect, re-use the existing `Utf8ToUtf16` span converter created for converting spans in the AST again for tokens, rather than creating another one.
2026-02-24 13:43:04 +00:00
overlookmotel b6fe80f315 refactor(estree/tokens): combine collect_token_context into to_estree_tokens_json (#19534)
Refactor. We had pointlessly complex logic where caller would call `collect_token_context` and then pass the result back into some other tokens code `to_estree_tokens_json`. Combine the 2 functions to make the call sites simpler.
2026-02-24 13:29:20 +00:00
overlookmotel 904718bec6 refactor(coverage): standardize ESTree tokens testing functions (#19532)
Pure refactor of conformance tests for ESTree and ESTree tokens. Use the same order of statements, and same variable names in each test function, to make it easier to follow.
2026-02-24 11:48:48 +00:00
overlookmotel d56f6cd9dd test(estree/tokens): do not skip tokens conformance tests for files with hashbangs (#19643)
We were skipping some ESTree tokens conformance tests for files containing hashbangs. We have to skip these tests for ESTree AST tests due to our non-standard `hashbang` field on `Program`, but we don't have to skip them for tokens tests - hashbangs are handled correctly.
2026-02-24 10:09:23 +00:00
overlookmotel 50a7514531 fix(estree): fix tokens for JSX (#19524)
Fix tokens when parsing JSX (not TSX) so they match `acorn-jsx` test cases. TS-ESLint's tokens are clearly wrong. We continue to match TS-ESLint bug-for-bug, but process plain JSX differently, so both the TS and JSX tests pass.

The only 2 remaining failing JSX test cases are due to #9667. Both these cases are also failing in the ESTree AST conformance tests.
2026-02-24 09:39:58 +00:00
Boshen 529fbac105 chore(submodules): update submodule SHAs to latest commits (#19662) 2026-02-24 15:34:23 +08:00
copilot-swe-agent 655c38fa38 feat(semantic): add "did you mean?" suggestions to undefined name errors (#19102)
## Improve `undefined_export` and related errors with name suggestions

This PR adds helpful "did you mean?" suggestions to errors where names are not found, using Levenshtein distance (threshold=2).

### Example Output

**undefined_export with suggestion:**
```
Export 'myVarible' is not defined
help: Did you mean 'myVariable'?
```

**private_field_undeclared with suggestion:**
```
Private field '#privateFild' must be declared in an enclosing class
help: Did you mean '#privateField'?
```

**invalid_label_target with suggestion:**
```
Use of undefined label
help: Did you mean 'outerLoop'?
```

### Implementation Details

- Moved Levenshtein edit distance calculation from `oxc_linter` to `oxc_span` for reuse across crates
- Uses a threshold of 2 for edit distance to suggest similar names
- Collects available names from appropriate scopes only when errors are found (performance optimization)

<!-- START COPILOT CODING AGENT SUFFIX -->

<!-- START COPILOT ORIGINAL PROMPT -->

<details>

<summary>Original prompt</summary>

> Improve `undefined_export` and some other errors to include a hint that suggests similar names that are defined

</details>

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.
2026-02-24 06:27:10 +00:00
overlookmotel b3b2d305f9 perf(parser): introduce ParserConfig (#19637)
### What this PR does

Introduce `ParserConfig` trait (another try at #16785).

The aim is to remove the large performance regression in parser that #19497 created, by making whether the parser generates tokens or not a compile-time option.

`ParserConfig::tokens` method replaces `ParseOptions::collect_tokens` property. The former can be const-folded at compile time, where the latter couldn't.

### 3 options

This PR also introduces 3 different config types that users can pass to the parser:

* `NoTokensParserConfig` (default)
* `TokensParserConfig`
* `RuntimeParserConfig`

The first 2 set whether tokens are collected or not at compile time. The last sets it at runtime.

All 3 implement `ParserConfig`.

`NoTokensParserConfig` is the default, and is what's used in compiler pipeline. It switches tokens off in the parser, and makes all the tokens-related code dead code, which the compiler eliminates. This makes the ability of the parser to generate tokens zero cost when it's not used (in the compiler pipeline).

`TokensParserConfig` is the one to use where you *always* want tokens. This is probably the config that linter will use.

`RuntimeParserConfig` is the one to use when an application decides whether to generate tokens or not at runtime. This config avoids compiling the parser twice, at the cost of runtime checks. This is what NAPI parser package will use.

### Future extension

#### Supporting additional features

In future we intend to build the UTF-8 to UTF-16 offsets conversion table in the parser. This will be more performant than searching through the source text for unicode characters in a 2nd pass later on. But this feature is only required for uses of the parser where we're interacting with JS side (NAPI parser package, linter with JS plugins).

`ParserConfig` can be extended to toggle this feature on/off at compile time or runtime, in the same way as you toggle on/off tokens.

#### Options and configs

This PR introduces `ParserConfig` but leaves `ParseOptions` as it is. So we now have 2 sets of options, passed to `Parser` with `with_options(...)` and `with_config(...)`. This is confusing.

We could merge the 2 by making `ParseOptions` implement `ParserConfig`, so then you'd define all options with one `with_options` call.

This would have the side effect of making all other parser options (e.g. `preserve_parens`) able to be set at either runtime or compile time, depending on the use case.

For users consuming `oxc_parser` as a library, with specific needs, they could also configure `Parser` to their needs e.g. create a parser which only handles plain JS code with all the code paths for JSX and TS shaken out as dead code. This would likely improve parsing speed significantly for these use cases.

### Implementation details

Why a trait instead of a cargo feature?

IMO a trait is preferable for the following reasons:

1. We have 3 different use cases we need to support (the 3 provided configs). 3 different Cargo features would be unwieldy.
2. This situation would become far worse once we introduce more features e.g. UTF-8 -> UTF-16 conversion.
3. No problems around feature unification. We found Cargo features caused headaches when we used them in linter for toggling on/off JS plugins support.
4. No clippy errors which only appear when the feature is/isn't disabled, requiring complex `#[cfg_attr(feature = "whatever", expect(clippy::unused_async))]` etc.

The introduction of a trait does not seem to significantly affect compile time:

```
# Before this PR
cargo build -p oxc_parser                             15.33s user 3.27s system 254% cpu 7.316 total
cargo build -p oxc_parser --release                   17.36s user 2.26s system 231% cpu 8.477 total
cargo build -p oxc_parser --example parser            18.43s user 3.75s system 271% cpu 8.156 total
cargo build -p oxc_parser --example parser --release  32.52s user 2.59s system 180% cpu 19.454 total

# After this PR
cargo build -p oxc_parser                             15.00s user 3.24s system 272% cpu 6.692 total
cargo build -p oxc_parser --release                   16.71s user 2.12s system 287% cpu 6.539 total
cargo build -p oxc_parser --example parser            18.50s user 3.91s system 285% cpu 7.845 total
cargo build -p oxc_parser --example parser --release  33.48s user 2.63s system 169% cpu 21.263 total
```

Measured on Mac Mini M4 Pro, `cargo clean` run before each. The difference appears to be mostly within the noise threshold.
2026-02-24 02:54:46 +00:00
camc314 9e11dc63a0 feat(parser,estree,coverage): collect tokens in parser and convert to ESTree format (#19497)
Implement a `collect_tokens` option for parser. When enabled, the parser stores all tokens produced during parsing in a `Vec`. Implement serializing the tokens to ESTree format.

Currently this is not hooked up to NAPI parser or linter. That happens in a later PR in this stack (#19498).

Serialization of tokens implementation is in new `oxc_estree_tokens` crate. Unfortunately it can't go in existing `oxc_estree` crate because `oxc_ast` depends on `oxc_estree`, and the tokens serialization code requires AST types - which would be a circular dependency. We may be able to move it into another crate (parser?) later on.
2026-02-24 02:35:12 +00:00
camc314 88a20819b6 feat(coverage): add estree token conformance scaffolding (#19496)
Add conformance tests for ESTree tokens. Currently all failing, because we've not implemented tokens yet.
2026-02-23 20:52:34 +00:00
camc314 c4a3677ad4 feat(parser): report error for initializer in ambient context (#19187) 2026-02-23 20:00:54 +00:00
camc314 933ff7227b fix(semantic): emit correct error code for reserved type name (#19545) 2026-02-19 16:57:26 +00:00
camc314 c2e1c0a39e fix(tasks/coverage): bring back acorn-jsx estree testing (#19516)
#18478 removed ESTree conformance tests for `acorn-jsx`. Add it back to conformance tests.
2026-02-18 15:05:36 +00:00
camc314 08b0218dd6 chore(submodules): update submodule SHAs to latest commits (#19518) 2026-02-18 14:56:36 +00:00
camc314 8e936717d9 refactor(tasks/coverage): use tasks_common for printing diff (#19510)
This makes the diffs more readable by including the surrouding lines.,

This aids debugging and makes the changes easier to comprehend
2026-02-18 01:32:30 +00:00
Dunqing dd0220feff perf(transformer): remove TS-only nodes earlier in enter_statements (#19166)
Move the removal of TS-only nodes earlier from `exit_statements` to `enter_statements` to avoid deep traversal into the TS-only child nodes, which are never used.
2026-02-11 15:32:08 +00:00
Boshen ed8c054b2d perf(oxc_str): add precomputed hash to Ident for fast HashMap lookups (#19143)
## Summary

- Replace `Ident<'a>` (transparent `&'a str` wrapper) with a `#[repr(C)]` struct storing `NonNull<u8>` + packed `len_and_hash: u64` on 64-bit (16 bytes, same as `&str`)
- Add ~1ns head-tail XOR hash function (`ident_hash`) that reads first 4 + last 4 bytes, discriminating identifiers like `useState`/`useEffect`
- Add `IdentBuildHasher`/`IdentHasher` custom hasher that handles both precomputed `Ident::hash()` and `str::hash()` lookup paths
- `PartialEq<Ident>` fast-rejects via single `u64` compare before byte comparison
- Parser creates `Ident` directly in `parse_identifier_kind` (hash computed once, not recomputed on Atom→Ident conversion)
- All `Ident`-keyed HashMaps use `IdentBuildHasher` (`IdentHashMap`, `ArenaIdentHashMap`, `IdentHashSet`)
- Generalize arena `HashMap::new_in` and `CloneIn` to work with any `S: Default + BuildHasher`

Ref: https://github.com/oxc-project/backlog/issues/193

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-10 03:45:59 +00:00
Boshen f32ea19e15 fix(semantic): report redeclaration error for import bindings conflicting with value declarations (#19068)
## Summary

- In JavaScript modules, `import { Foo } from './foo.js'; var Foo;` (and `let`, `const`, `class`, `function`) should report `"Identifier 'Foo' has already been declared"` per the [ES spec](https://tc39.es/ecma262/#sec-imports-static-semantics-early-errors)
- The existing excludes-based conflict detection in the binder doesn't catch this because `Import` is not in the `Value` bitset
- Added a checker function that runs at `Program` leave, scanning root scope bindings for symbols with both `Import` and a value flag, and reports a redeclaration error
- TypeScript is excluded since it has its own declaration merging rules

Closes #15961

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-06 15:03:47 +00:00
Boshen 25379248d1 perf(semantic): optimize scope resolution with fast paths and inlining (#19029)
## Summary

- Add early return when current scope has no unresolved references
- Skip resolution entirely for scopes with no bindings (if-blocks, try-blocks, loop bodies without `let`) — merge unresolved refs to parent using O(1) swap when possible
- Use union-by-size merge (drain smaller map into larger) for non-empty parents
- Add `#[inline]` to hot per-reference functions: `declare_reference`, `reference_identifier`, `create_reference`

### Benchmark results (semantic)

```
group                                  main                                   pr
-----                                  ----                                   --
semantic/RadixUIAdoptionSection.jsx    1.05      4.1±0.05µs        ? ?/sec    1.00      3.9±0.03µs        ? ?/sec
semantic/binder.ts                     1.03   469.3±26.69µs        ? ?/sec    1.00   456.3±17.59µs        ? ?/sec
semantic/cal.com.tsx                   1.00      3.6±0.03ms        ? ?/sec    1.01      3.6±0.04ms        ? ?/sec
semantic/react.development.js          1.01    171.9±3.86µs        ? ?/sec    1.00    170.0±9.19µs        ? ?/sec
```

### Benchmark results (pipeline)

```
group                                  main                                   pr
-----                                  ----                                   --
pipeline/RadixUIAdoptionSection.jsx    1.03     29.8±0.35µs        ? ?/sec    1.00     29.0±0.25µs        ? ?/sec
pipeline/binder.ts                     1.00      2.9±0.07ms        ? ?/sec    1.00      2.9±0.09ms        ? ?/sec
pipeline/cal.com.tsx                   1.00     25.0±0.32ms        ? ?/sec    1.01     25.2±0.36ms        ? ?/sec
pipeline/react.development.js          1.03  1317.1±96.08µs        ? ?/sec    1.00  1273.5±18.26µs        ? ?/sec
```

### Analysis

Scope resolution (`resolve_references_for_current_scope`) is called on every scope exit. Many scopes (if-blocks, try-blocks, loop bodies) have zero bindings, yet the current code still drains all unresolved references one-by-one through hash maps. The swap optimization makes this O(1) for the common case where the parent has no accumulated refs yet (first/only child scope).

The `#[inline]` additions target functions called per-identifier-reference (~hundreds to thousands of times per file) that were not previously inlined.

Note: 3 linter snapshot ordering changes expected (diagnostics emitted in different order due to hash map iteration order change from swap).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-06 12:09:11 +00:00
Boshen 142a1be9b6 feat(parser): detect binary files with TS1490 error (#19047)
## Summary

- Port TypeScript's binary file detection (`TS1490: File appears to be binary.`)
- When the scanner encounters U+FFFD (replacement character) as a standalone token, emit the error and stop parsing
- U+FFFD inside strings, comments, and templates is unaffected
- Reference: https://github.com/microsoft/TypeScript/blob/main/src/compiler/scanner.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-06 10:26:56 +00:00
Boshen 776eb197dc fix(coverage): ignore usingDeclarations.14.ts in TypeScript conformance (#19044)
## Summary

- Ignore `usingDeclarations.14.ts` in TypeScript conformance tests
- TypeScript allows top-level `using` in scripts (no import/export), but oxc rejects it per TC39 spec — `using` is not allowed at the top level of scripts
- This brings parser_typescript conformance to 100.00%

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-06 09:37:51 +00:00
Boshen 1fb3bc3627 fix(coverage): ignore asyncWithVarShadowing_es6.ts in TypeScript conformance (#19040)
## Summary
- Exclude `asyncWithVarShadowing_es6.ts` from TypeScript conformance tests
- TSC allows `catch({x}) { var x; }` (destructured catch param + var redeclaration), but per Annex B §B.3.4 only simple identifier catch params are exempt from the redeclaration error
- OXC correctly follows the spec, so this is a known behavioral difference

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-06 08:59:01 +00:00
Boshen 35e32c6e11 fix(coverage): match Babel's options.json inheritance for test fixtures (#19002)
## Summary

- Fix Babel test fixture options.json inheritance to match `@babel/helper-fixtures` behavior
- Babel's hierarchy: task → suite → category. Suite options.json REPLACES (not merges) category plugins
- Previously `expect-plugin` tests incorrectly inherited TypeScript plugin from parent category
- Fixes 3 tests: `export-interface`, `export-type`, `export-type-named`

**Results:** Negative Passed improved from 1660/1689 (98.28%) to 1663/1689 (98.46%)

🤖 Generated with [Claude Code](https://claude.ai/code)
2026-02-06 08:25:12 +00:00
Boshen 463d60dd4a fix(semantic): skip TS2391 for standalone computed-name class methods (#19025)
## Summary

- Don't report "Function implementation is missing" (TS2391) for computed property name methods like `[e]()` that aren't part of an overload group, matching TypeScript's behavior
- TypeScript only checks TS2391 when it can resolve the method to a symbol, which isn't possible for dynamic computed names
- Computed-name overload groups like `[Symbol.iterator]` still correctly report the error

**TypeScript**: Positive passed 9839 → 9841 (+2)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-06 06:29:38 +00:00
Boshen 56c086b775 fix(parser): add modifier ordering validation (TS1029) (#19024)
## Summary

- Replace `check_for_duplicate_modifiers` with `check_modifier` that
handles both duplicate detection and ordering validation in a single
match statement, following TypeScript's `checkGrammarModifiers` logic
- Correctly reports TS1029 (`'x' modifier must precede 'y' modifier`)
for out-of-order class member modifiers
- Remove redundant static/readonly ordering check for index signatures
in `class.rs` (now handled centrally)
- Remove unused `contains_all_flags` method from `Modifiers`

**Babel**: Negative passed 1660 → 1665 (+5)
**TypeScript**: Negative passed 1515 → 1529 (+14)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 13:45:47 +08:00
Boshen c5175fa1cf fix(coverage): implement package.json lookup for moduleDetection (#19022)
## Summary

- Implement package.json `"type"` field lookup for `moduleDetection: auto` in TypeScript conformance tests, matching TypeScript's `getPackageScopeForPath` behavior
- When `moduleDetection` is unset and `module` is `node16`..`nodenext`, default to `force` (matching TypeScript's `_computedOptions.moduleDetection`)
- Refactor stringly-typed `get_module_detection_mode` → `is_forced_module` returning `bool`

The estree_typescript snapshot regresses because the baselines in the estree-conformance submodule were generated with the same old incorrect logic. The JS port (`typescript-make-units-from-test.cjs`) needs the same fix and baselines need regeneration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-06 05:06:44 +00:00
Boshen 57917eef0f fix(parser): parse decorators on rest parameters (#18938)
## Summary
- Add `decorators` field to `FormalParameterRest` to support decorators on rest parameters in TypeScript
- Parse decorators before checking for rest parameters in formal parameter lists
- Update semantic builder to visit decorators on rest parameters

Fixes parsing of `typescript/tests/cases/compiler/sourceMapValidationDecorators.ts`

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-05 09:54:47 +00:00
camchenry f78c5251fd perf(parser): try hybrid parsing for jsx children and closing element/fragments (#18789)
+1-2% on parsing JSX files.

<img width="713" height="363" alt="Screenshot 2026-02-03 at 10 25 55 PM" src="https://github.com/user-attachments/assets/693c725d-460c-4bb0-bae4-4e85c44efd53" />

Previously, we were rewinding the parser state whenever we hit a closing fragment and then calling a different function to continue parsing the applicable type of closing tag. Now, we do all of the children and closing tag parsing in one function. This allows us to never rewind the parser state which should be faster. It also allows us to provide slightly better diagnostics as we know what state we are in.

Diagnostic changes are expected, it's a little bit more similar to TypeScript's diagnostics: https://www.typescriptlang.org/play/?#code/CYUwxgNghgTiAEA3W8BKIpgC4C55QDsBPAbgCgyAeAPgAsBLSgemHsWviafgFEYYA9jAoUaIAQDN40rr35CgA
2026-02-05 04:35:44 +00:00
Boshen be4f3d7f25 perf(coverage): extract path conversion and avoid unnecessary clones (#18921)
- Extract `path.to_string_lossy()` before error loops to avoid repeated conversions
- Use `as_str()` instead of `clone()` in BaselineFile::print()
- Remove unnecessary clone in BaselineFile::snapshot()
- Use `map_or_else` to avoid allocating "Panicked" string in success paths

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 09:17:43 +00:00
Boshen 576f930b77 perf(coverage): use mem::take and move semantics to reduce allocations (#18920) 2026-02-04 06:22:46 +00:00
Boshen c029522339 perf(coverage): use Cow and Arc to reduce string allocations in parser tests (#18896) 2026-02-04 05:55:48 +00:00
Boshen e387843344 perf(coverage): remove BOM without reallocating string (#18895) 2026-02-04 05:55:48 +00:00
Boshen 5c3666756d perf(coverage): use mem::take instead of clone in idempotency tests (#18894) 2026-02-04 05:55:47 +00:00
Boshen 0eff6be0a0 feat(parser): error JSX-like type assertions and generics in .mts/.cts (#18910)
## Summary

Implements TS7059 and TS7060 errors for JSX-like syntax in `.mts`/`.cts` files:

- **TS7059**: JSX-like type assertions (`<T>value`) - "Use an `as` expression instead"
- **TS7060**: JSX-like type parameters in arrow functions (`<T>() => {}`) - "Add a trailing comma or explicit constraint"

### Valid workarounds for TS7060:
- `<T,>() => {}` (trailing comma)
- `<T extends unknown>() => {}` (explicit constraint)
- `<T, U>() => {}` (multiple type parameters)

Closes #15184

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-04 05:21:42 +00:00
Boshen 1f6b1931c2 fix(parser): validate TypeScript import type options (#18889)
## Summary

- Add validation for TypeScript import type options (`typeof import("...", { with: {...} })`)
- Require `with` or `assert` keyword as identifier (not string, not escaped)
- Reject computed property keys in attributes object
- Reject spread elements in attributes object

This fixes 4 Babel conformance tests:
- `invalid-import-type-options-escaped-with`
- `invalid-import-type-options-string-with`
- `invalid-import-type-options-with-computed-properties`
- `invalid-import-type-options-with-spread-element`

**parser_babel Negative Passed**: 1655/1689 → 1659/1689 (+4)

🤖 Generated with [Claude Code](https://claude.ai/code)
2026-02-03 14:47:05 +00:00
Boshen 1663184979 fix(parser): allow conditional types in function type parameters (#18886)
## Summary

- Allow conditional types inside function type parameter annotations, even when the function type itself is being parsed in a `DisallowConditionalTypes` context
- Wrap `parse_formal_parameters` in `parse_function_or_constructor_type` with `context_remove(DisallowConditionalTypes, ...)`

This fixes parsing of nested conditional types like:
```typescript
type Equals = A extends (x: B extends C ? D : E) => 0 ? F : G;
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-03 13:11:26 +00:00
Boshen 5758046dd2 fix(parser): error on property access after instantiation expression (#18887)
## Summary

- Add TypeScript error TS1477: "An instantiation expression cannot be
followed by a property access"
- Check for `TSInstantiationExpression` before parsing property access
(static `.` or computed `[]`)

This fixes parsing of invalid syntax like:
- `a<b>.c` (static member access)
- `a<b>?.c` (optional static member access)  
- `a<b>?.[c]` (optional computed member access)
- `a?.b<c>.d` (chained)

Valid syntax like `a<b>?.(c)` (optional call) and `(a<b>).c`
(parenthesized) are not affected.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 20:58:15 +08:00