oxc-project
oxc
BlogDocsChangelog

fix(semantic): add scope tracking for `with` statements

#14652Merged
Comparing
fix/with-statement-scope
(
be94bfd
) with
main
(
c69201c
)
CodSpeed Performance Gauge
0%
Untouched
37

Benchmarks

Passed

semantic[RadixUIAdoptionSection.jsx]
tasks/benchmark/benches/semantic.rs::semantic::bench_semantic
CodSpeed Performance Gauge
0%
71.6 µs*71.3 µs
parser[RadixUIAdoptionSection.jsx]
tasks/benchmark/benches/parser.rs::parser::bench_parser
CodSpeed Performance Gauge
0%
87.2 µs*87 µs
mangler[react.development.js]
tasks/benchmark/benches/minifier.rs::minifier::bench_mangler
CodSpeed Performance Gauge
0%
262.9 µs*262.4 µs
linter[RadixUIAdoptionSection.jsx]
tasks/benchmark/benches/linter.rs::linter::bench_linter
CodSpeed Performance Gauge
0%
975.4 µs973.9 µs
lexer[RadixUIAdoptionSection.jsx]
tasks/benchmark/benches/lexer.rs::lexer::bench_lexer
CodSpeed Performance Gauge
0%
19.9 µs*19.9 µs
transformer[binder.ts]
tasks/benchmark/benches/transformer.rs::transformer::bench_transformer
CodSpeed Performance Gauge
0%
1.7 ms*1.7 ms
mangler[cal.com.tsx]
tasks/benchmark/benches/minifier.rs::minifier::bench_mangler
CodSpeed Performance Gauge
0%
2.8 ms*2.8 ms
formatter[binder.ts]
tasks/benchmark/benches/formatter.rs::formatter::bench_formatter
CodSpeed Performance Gauge
0%
23.7 ms*23.6 ms
mangler[binder.ts]
tasks/benchmark/benches/minifier.rs::minifier::bench_mangler
CodSpeed Performance Gauge
0%
746.2 µs*746 µs
transformer[react.development.js]
tasks/benchmark/benches/transformer.rs::transformer::bench_transformer
CodSpeed Performance Gauge
0%
715 µs*714.8 µs
lexer[binder.ts]
tasks/benchmark/benches/lexer.rs::lexer::bench_lexer
CodSpeed Performance Gauge
0%
863.4 µs*863.3 µs
parser[cal.com.tsx]
tasks/benchmark/benches/parser.rs::parser::bench_parser
CodSpeed Performance Gauge
0%
26.6 ms*26.6 ms
lexer[cal.com.tsx]
tasks/benchmark/benches/lexer.rs::lexer::bench_lexer
CodSpeed Performance Gauge
0%
5.3 ms*5.3 ms
estree[checker.ts]
tasks/benchmark/benches/parser.rs::parser::bench_estree
CodSpeed Performance Gauge
0%
104.5 ms*104.5 ms
linter[binder.ts]
tasks/benchmark/benches/linter.rs::linter::bench_linter
CodSpeed Performance Gauge
0%
58.1 ms58.1 ms
minifier[cal.com.tsx]
tasks/benchmark/benches/minifier.rs::minifier::bench_minifier
CodSpeed Performance Gauge
0%
35.5 ms*35.5 ms
lexer[react.development.js]
tasks/benchmark/benches/lexer.rs::lexer::bench_lexer
CodSpeed Performance Gauge
0%
354.5 µs*354.5 µs
parser[react.development.js]
tasks/benchmark/benches/parser.rs::parser::bench_parser
CodSpeed Performance Gauge
0%
1.3 ms*1.3 ms
isolated-declarations[vue-id.ts]
tasks/benchmark/benches/transformer.rs::transformer::bench_isolated_declarations
CodSpeed Performance Gauge
0%
56.4 ms*56.4 ms
codegen[cal.com.tsx]
tasks/benchmark/benches/codegen.rs::codegen::bench_codegen
CodSpeed Performance Gauge
0%
33.8 ms*33.8 ms
codegen[binder.ts]
tasks/benchmark/benches/codegen.rs::codegen::bench_codegen
CodSpeed Performance Gauge
0%
4.3 ms*4.3 ms
formatter[react.development.js]
tasks/benchmark/benches/formatter.rs::formatter::bench_formatter
CodSpeed Performance Gauge
0%
12.1 ms*12.1 ms
codegen[react.development.js]
tasks/benchmark/benches/codegen.rs::codegen::bench_codegen
CodSpeed Performance Gauge
0%
1.9 ms*1.9 ms
linter[cal.com.tsx]
tasks/benchmark/benches/linter.rs::linter::bench_linter
CodSpeed Performance Gauge
0%
542 ms542.1 ms
semantic[cal.com.tsx]
tasks/benchmark/benches/semantic.rs::semantic::bench_semantic
CodSpeed Performance Gauge
0%
26.4 ms*26.4 ms
parser[binder.ts]
tasks/benchmark/benches/parser.rs::parser::bench_parser
CodSpeed Performance Gauge
0%
3.3 ms*3.3 ms
semantic[react.development.js]
tasks/benchmark/benches/semantic.rs::semantic::bench_semantic
CodSpeed Performance Gauge
0%
1.6 ms*1.6 ms
transformer[cal.com.tsx]
tasks/benchmark/benches/transformer.rs::transformer::bench_transformer
CodSpeed Performance Gauge
0%
26.4 ms*26.4 ms
semantic[binder.ts]
tasks/benchmark/benches/semantic.rs::semantic::bench_semantic
CodSpeed Performance Gauge
0%
4.1 ms*4.1 ms
linter[react.development.js]
tasks/benchmark/benches/linter.rs::linter::bench_linter
CodSpeed Performance Gauge
0%
21.9 ms21.9 ms
formatter[RadixUIAdoptionSection.jsx]
tasks/benchmark/benches/formatter.rs::formatter::bench_formatter
CodSpeed Performance Gauge
0%
580.5 µs*581 µs
formatter[cal.com.tsx]
tasks/benchmark/benches/formatter.rs::formatter::bench_formatter
CodSpeed Performance Gauge
0%
210.9 ms*211.1 ms
codegen[RadixUIAdoptionSection.jsx]
tasks/benchmark/benches/codegen.rs::codegen::bench_codegen
CodSpeed Performance Gauge
0%
122.4 µs*122.6 µs
minifier[react.development.js]
tasks/benchmark/benches/minifier.rs::minifier::bench_minifier
CodSpeed Performance Gauge
0%
2.5 ms*2.5 ms
transformer[RadixUIAdoptionSection.jsx]
tasks/benchmark/benches/transformer.rs::transformer::bench_transformer
CodSpeed Performance Gauge
0%
133.7 µs*134.1 µs
mangler[RadixUIAdoptionSection.jsx]
tasks/benchmark/benches/minifier.rs::minifier::bench_mangler
CodSpeed Performance Gauge
0%
13.2 µs*13.3 µs
minifier[binder.ts]
tasks/benchmark/benches/minifier.rs::minifier::bench_minifier
CodSpeed Performance Gauge
-1%
4 ms*4 ms

Commits

Click on a commit to change the comparison range
Base
main
c69201c
-0.02%
fix(semantic): add scope tracking for `with` statements (#14652) Fixes #8365 ## Summary The `with` statement was not creating a scope in the semantic analysis, causing `is_global_reference` to incorrectly return `true` for references inside `with` blocks. This could lead to incorrect minification. ## Problem According to the ECMAScript specification, `with` statements should create an Object Environment Record that extends the lexical environment. Without proper scope tracking: - `is_global_reference()` incorrectly returns `true` for identifiers inside `with` blocks - This can cause minification to incorrectly treat local references as global - The scope tree doesn't accurately represent the program structure ## Solution ### Changes Made 1. **AST Definition** (`crates/oxc_ast/src/ast/js.rs`): - Added `#[scope]` attribute to `WithStatement` struct - Added `scope_id: Cell<Option<ScopeId>>` field 2. **Semantic Builder** (`crates/oxc_semantic/src/builder.rs`): - Modified `visit_with_statement` to call `enter_scope()` before visiting the body - Added `leave_scope()` call after visiting the body - Uses `ScopeFlags::empty()` similar to block statements 3. **Test Coverage** (`crates/oxc_semantic/tests/integration/scopes.rs`): - Added `test_with_statement` to verify scope creation - Tests both simple expressions and block statement bodies - Verifies proper scope tree structure ### Example ```javascript const foo = { Object: class { constructor() { console.log('Constructor') } } } with (foo) { console.log(new Object()) // should print "Constructor" } ``` Before this fix, `Object` inside the `with` block would be incorrectly identified as a global reference, potentially causing minification errors. ## Implementation Notes While this implementation doesn't fully model the complex object environment semantics (where property lookups can dynamically affect identifier resolution at runtime), it ensures: - References inside `with` blocks are no longer incorrectly marked as global - The scope tree properly represents the lexical structure - Provides a foundation for future improvements to object environment handling ## Testing All existing tests pass, plus the new test verifies: - `with` statements create scopes - Scopes are properly nested in the scope tree - Works correctly with both simple and block statement bodies
be94bfd
29 days ago
by Boshen
© 2025 CodSpeed Technology
Home Terms Privacy Docs