Commit Graph

4 Commits

Author SHA1 Message Date
camc314 059784d96b fix(semantic): respect shadowed Infinity and NaN in enum evaluation (#25604)
## Summary

Fix enum evaluation to resolve identifiers before treating `Infinity` and `NaN` as unbound globals.
2026-08-14 02:36:24 +00:00
Boshen 777f02ae10 refactor(diagnostics)!: return a Diagnostics type instead of Vec<OxcDiagnostic> (#23217)
## Summary

Introduces `oxc_diagnostics::Diagnostics` — a `Vec<OxcDiagnostic>` newtype that knows the difference between errors and warnings — and makes it the standard diagnostics return value across oxc.

- **New type**: `Diagnostics` with `has_errors()`, `has_warnings()`, `errors()`, `warnings()`, plus `Vec`-like ergonomics (Deref, `IntoIterator`, `Extend`, `From`/`Into<Vec>`) so most call sites are unchanged.
- **Return types**: `ParserReturn`, `SemanticBuilderReturn`, `IsolatedDeclarationsReturn`, the React Compiler `TransformResult`/`LintResult`, and `TransformerReturn` now expose `diagnostics: Diagnostics` instead of `errors: Vec<OxcDiagnostic>` (the React Compiler's separate `errors`/`warnings` are merged into one severity-tagged list).
- **Behaviour**: a React Compiler **error** now stops the transform (no output), while **warnings** flow through and the transform continues. `compile()` aborts codegen only when `diagnostics.has_errors()` — warnings alone no longer abort (previously any diagnostic did).

## Breaking change

Consumers reading `*.errors` on these return values must read `*.diagnostics`. React Compiler consumers that read `.errors`/`.warnings` separately should use `diagnostics.has_errors()` / `diagnostics.errors()` / `diagnostics.warnings()`.

Parser/semantic/isolated-declarations fatality is otherwise unchanged. Builds on the React Compiler transform feature (#23201).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-06-10 14:46:52 +00:00
Dunqing dfa931d3bc fix(semantic): propagate unresolved auto-increment enum value instead of defaulting to 0 (#22646)
## Summary

- When a TypeScript enum member with no initializer follows one whose initializer could not be evaluated to a constant, the auto-increment value previously fell back to `0`. It now propagates "unresolved" (`None`) like the existing `Some(String) => None` arm, matching tsc 6.0.3 (which errors on this construct and emits `void 0`, never `0`).
- The bug surfaced via rolldown's cross-module enum inliner (rolldown/rolldown#9494). Rolldown reads `Scoping::get_enum_member_value` to populate its `enum_member_value_map`; once the wrong `0` landed in the map, every call-site reference to the affected member was inlined to `0`. After this fix the map omits the entry and rolldown leaves the reference alone — matching tsc's call-site behavior.
- Adopts the existing `prev = Some(Number(-1.0))` sentinel pattern from `oxc_isolated_declarations/src/enum.rs` and `oxc_transformer/src/typescript/enum.rs`, so the first-member-defaults-to-0 case still resolves naturally and the auto-increment branch shrinks to two arms.

## Example

Input:

```ts
import { External } from './external'; // External.X = 0, External.Y = 1
enum Local { A = External.X, B = External.Y, C }
```

`Scoping::get_enum_member_value` before:

- A → None, B → None, C → Some(Number(0.0))  (wrong)

After:

- A → None, B → None, C → None

Covered by new test `crates/oxc_semantic/tests/integration/enum_values.rs::auto_increment_after_unresolvable_fails`; existing `auto_increment` (first member defaults to 0) and `auto_increment_after_string_fails` continue to pass.

AI disclosure: drafted with Claude Code, reviewed manually.
2026-05-22 10:02:55 +00:00
Dunqing 75663c077d feat(semantic): add enum member value evaluation for const enum support (#20602)
## Summary

Part of https://github.com/oxc-project/oxc/issues/6073 and #11844

- Add `ConstantValue` type in `oxc_syntax` for representing enum member values (number/string)
- Implement enum member value evaluation in `oxc_semantic` supporting numeric auto-increment, string values, binary/unary expressions, cross-member and cross-enum references, template literals, and merged enum declarations
- Store evaluated enum member values in `Scoping` via `EnumData` struct with getter/setter APIs and enum body scope tracking
- All enum evaluation code is gated behind the `enum_eval` Cargo feature (enabled by `oxc_transformer`)

### Feature gate

The `enum_eval` feature controls:
- `ts_enum` module (evaluator + data types)
- `EnumData` field and enum-related methods on `Scoping`
- `oxc_syntax/to_js_string` dependency

Consumers that don't need enum values (linter, language server) pay zero cost.

### Babel alignment

Unary operators on strings follow Babel's JS-coercion semantics (`+"s"` → `"s"`, `-"s"` → `NaN`, `~"s"` → `-1`), which differs from TypeScript (unevaluated). This is documented in the source.

## Test plan

- [x] Integration tests in `crates/oxc_semantic/tests/integration/enum_values.rs`
- [x] Semantic TypeScript conformance snapshot updated
- [x] `cargo check -p oxc_semantic` passes (without feature)
- [x] `cargo check -p oxc_semantic --features enum_eval` passes (with feature)
- [x] `cargo check -p oxc_transformer` passes (enables feature transitively)
2026-04-07 08:52:19 +00:00