## Summary
- report TypeScript diagnostic TS18041 for `return` statements in class static initialization blocks
- reuse the existing `NewTarget`/`Return` parser-context invariant without adding a new context flag
- update the TypeScript, Babel, and Test262 parser snapshots
## Root cause
Class static blocks disable the parser's `Return` context, so their `return` statements previously fell through to the generic top-level TS1108 diagnostic. Static blocks already enable `NewTarget`, which distinguishes this case when `Return` is absent.
## Summary
Adds context notes to `Cannot assign to '{x0}' in strict mode` diagnostics, explaining whether strict mode comes from an explicit directive, class body, or module.
## Summary
Reserved-keyword diagnostics now explain the language context that makes an identifier invalid, rather than only reporting that the keyword is reserved.
## Details
- Add context-aware notes for strict mode, classes, and modules.
- Add a dedicated note for `await` in module code.
- Update parser-conformance snapshots for the expanded diagnostics.
Before:
```text
× The keyword 'package' is reserved
```
After, for strict-mode code:
```text
× The keyword 'package' is reserved
note: This identifier is reserved in strict mode code
```
After, for class code:
```js
class Example {
method() {
const static = 1;
}
}
```
```text
× The keyword 'static' is reserved
note: Classes are always strict mode code
```
After, for module code:
```js
export const await = 1;
```
```text
× The keyword 'await' is reserved
note: The identifier `await` is reserved in module code
## Summary
- Report operator-specific diagnostics when unary and `await` expressions are used as exponentiation left operands.
- Reject unparenthesized TypeScript type assertions in the same position while preserving explicitly parenthesized forms.
- Add regression fixtures and update the affected conformance snapshots.
Reject `new import(...).prop`, `new import.source(...).prop`, and `new import.defer(...).prop` by treating member access on an unparenthesized import expression as invalid after `new`.
Fixes#23458
## What
Move the `MetaProperty` early-error checks from the semantic checker (`oxc_semantic`) into the parser:
- **`new.target` outside a valid context** — e.g. at the top level, in a top-level arrow, or in a computed class-member key.
- **`import.meta` outside a module** — i.e. in script / CommonJS code.
Consumers that only run the parser (without `SemanticBuilder`) now get these diagnostics.
## How
- `new.target` validity is tracked with a new inherited `Context::NewTarget` flag (widening `Context` from `u8` to `u16`). The flag is *added* by three constructs — a regular (non-arrow) function's parameters + body, a class static block, and a class field initializer — and *inherited* through arrow functions and class bodies. This naturally models the spec rule, including cases like `function g(){ class D { [new.target](){} } }` (valid, inherits `g`'s context).
- `import.meta` reuses the existing `error_on_script` deferral, so in unambiguous source `visit_import_meta` marks the file a module and the deferred error is discarded.
- `check_meta_property` and its now-unused diagnostics are removed from `oxc_semantic`.
## Spec correctness
Verified all cases against V8 (Node v24). One behavior change vs. the old semantic checker: a computed class **field** key such as `class C { [new.target] = 1 }` at the top level is now correctly a **SyntaxError**, matching V8 — the old checker accepted it due to a coarse `PropertyDefinition` AST-ancestor match.
| Source | V8 | this PR |
| --- | --- | --- |
| `new.target;` | SyntaxError | error |
| `function f(){ new.target; }` | ok | ok |
| `() => new.target;` | SyntaxError | error |
| `class C { x = new.target; }` | ok | ok |
| `class C { static { new.target; } }` | ok | ok |
| `class C { [new.target] = 1; }` | SyntaxError | error |
| `class C { [new.target](){} }` | SyntaxError | error |
| `function g(){ class D { [new.target](){} } }` | ok | ok |
| `import.meta` in script | SyntaxError | error |
| `import.meta` in module | ok | ok |
Parser & semantic conformance remain 100% positive / 100% negative on test262; all unit tests pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Made the errors for `({...[]} = {});` and `const {...[]} = obj;` a bit more easier to understand:
```
× Invalid rest element target in destructuring assignment
╭─[misc/fail/rest-assignment-target.js:1:6]
1 │ ({...[]} = {});
· ──
╰────
help: Expected an identifier or member expression, like `...rest` or `...obj.prop`.
```
```
× Invalid rest element target in destructuring pattern
╭─[misc/fail/rest-binding-element.js:1:11]
1 │ const {...[]} = obj;
· ──
╰────
help: Expected an identifier, like `...rest`.
```
This improves the parser diagnostic for invalid `import.<property>` access.
Previously, invalid properties like `import.sync("baz")` were reported as if only `import.meta` were valid, which is misleading now that `import.source()` and `import.defer()` are also supported.
Before:
```text
× The only valid meta property for import is import.meta
╭─[index.ts]
37 │
38 │ import.foo();
──────────
39 │
╰────
```
After:
```text
× The only valid property accesses on import are `import.meta`, `import.source()`, and `import.defer()`
╭─[index.ts]
37 │
38 │ import.foo();
──────────
39 │
╰────
```
Also adds a coverage fixture for the `import.sync("baz")` case and updates the parser coverage snapshots.
## 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)
## 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.
## Summary
Closes#18392
Support HTML-like comments (`<!--` and `-->`) per ECMAScript Annex B.1.1:
- **Script/CommonJS mode**: HTML comments recognized as single-line comments
- **Unambiguous mode (.js)**: HTML comments recognized; error deferred until ESM syntax detected
- **Module mode (.mjs)**: HTML comments at start of line emit "HTML comments are not allowed in modules" error; `<!--` in middle of expression (e.g. `foo <!--bar`) parses as operators
This enables proper detection of HTML comment injection vectors in security tools like [AikidoSec/zen-internals](https://github.com/AikidoSec/zen-internals/pull/125).
🤖 Generated with [Claude Code](https://claude.ai/code)
## Summary
- Allow `new.target` in class field initializers per the ES2022 spec
- `new.target` evaluates to `undefined` in this context, same as in static blocks
- This aligns Oxc with Babel's behavior
## Background
TypeScript incorrectly disallows `new.target` in class field initializers. Their validation was implemented in 2016 ([PR #12783](https://github.com/Microsoft/TypeScript/pull/12783)) before class fields were standardized, and was never updated when ES2022 landed.
The ES spec explicitly allows this - see the [TC39 class-fields proposal](https://github.com/tc39/proposal-class-fields) and [Babel issue #6243](https://github.com/babel/babel/issues/6243).
## Test case
```javascript
class X {
static a = new.target; // ✓ allowed (evaluates to undefined)
static b = () => new.target; // ✓ allowed (arrow inherits from field context)
e = new.target; // ✓ allowed
f = () => new.target; // ✓ allowed
}
```
## Test plan
- [x] Babel conformance test `es2022/class-properties/new-target` now passes
- [x] `cargo test -p oxc_semantic --lib` passes
- [x] `just check lint test` passes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
- Fix incorrect parsing of `1 + #a in b` which was parsed as `1 + (#a in b)` instead of `(1 + #a) in b`
- Add precedence check before parsing `#a in` as `PrivateInExpression`
- Report "Unexpected private identifier" error when precedence doesn't allow `in` operator
## Details
The parser was greedily parsing `#a in` as a `PrivateInExpression` without checking operator precedence. For example, when parsing the RHS of `+` in `1 + #a in b`, the `in` operator's precedence (`Compare = 13`) is lower than `+`'s precedence (`Add = 15`), so `#a in` should not be parsed as a unit.
The fix extracts private-in parsing into `parse_private_in_expression` and adds a check: if `lhs_precedence >= Precedence::Compare`, we reject the private identifier with a syntax error, matching V8 and Babel behavior.
## Test plan
- `cargo test -p oxc_parser` passes
- Conformance improved: Negative Passed 1648 → 1649 for Babel tests
- `invalid-private-followed-by-in-2` test case now correctly reports syntax error
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
- Skip annexB assignmenttargettype tests in test262 conformance suite
- These tests require call expressions to be valid assignment targets in non-strict mode (e.g., `f() = 1`, `f()++`, `for (f() in [1]) {}`)
- This is an Annex B "web reality" feature that oxc intentionally does not support
## Test plan
- [x] `cargo coverage -- parser` shows 100% pass rate (46556/46556)
- [x] All affected snapshots updated
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
- Fix parsing of `for (using of = null;;)` as a using declaration where `of` is the binding identifier
- Previously, the parser incorrectly treated `of` as the keyword starting a for-of loop
The fix uses a lookahead to check if the token after `of` is `=`, `;`, or `:`, matching TypeScript's parser behavior.
## Test plan
- `cargo coverage -- parser` - conformance tests pass
- `cargo test -p oxc_parser` - unit tests pass
🤖 Generated with [Claude Code](https://claude.ai/code)
## Summary
- Add check to error on `using` declarations at the top level of scripts
- `using` declarations require block scope semantics and are not allowed
at the top level of scripts
`using` declarations are allowed:
- At the top level of ES modules
- At the top level of CommonJS modules (files are wrapped in a function)
- Inside any block scope in scripts
But NOT at the top level of scripts.
Closes#11862
## Test plan
- [x] Added test case
`tasks/coverage/misc/fail/script-top-level-using.js` for invalid usage
- [x] Added test case
`tasks/coverage/misc/pass/script-using-in-block.js` for valid usage in
block
- [x] All existing tests pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>