Skip to content

Commit 29edb34

Browse files
committed
refactor(semantic)!: combine SymbolTable and ScopeTree into Scoping
part of #9607
1 parent d42b7d6 commit 29edb34

File tree

146 files changed

+1440
-1580
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

146 files changed

+1440
-1580
lines changed

crates/oxc/src/compiler.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use oxc_isolated_declarations::{IsolatedDeclarations, IsolatedDeclarationsOption
88
use oxc_mangler::{MangleOptions, Mangler};
99
use oxc_minifier::{CompressOptions, Compressor};
1010
use oxc_parser::{ParseOptions, Parser, ParserReturn};
11-
use oxc_semantic::{Scoping, SemanticBuilder, SemanticBuilderReturn, SymbolTable};
11+
use oxc_semantic::{Scoping, SemanticBuilder, SemanticBuilderReturn};
1212
use oxc_span::SourceType;
1313
use oxc_transformer::{
1414
InjectGlobalVariables, InjectGlobalVariablesConfig, ReplaceGlobalDefines,
@@ -270,21 +270,21 @@ pub trait CompilerInterface {
270270
Compressor::new(allocator, options).build(program);
271271
}
272272

273-
fn mangle(&self, program: &mut Program<'_>, options: MangleOptions) -> SymbolTable {
273+
fn mangle(&self, program: &mut Program<'_>, options: MangleOptions) -> Scoping {
274274
Mangler::new().with_options(options).build(program)
275275
}
276276

277277
fn codegen(
278278
&self,
279279
program: &Program<'_>,
280280
source_path: &Path,
281-
symbol_table: Option<SymbolTable>,
281+
scoping: Option<Scoping>,
282282
options: CodegenOptions,
283283
) -> CodegenReturn {
284284
let mut options = options;
285285
if self.enable_sourcemap() {
286286
options.source_map_path = Some(source_path.to_path_buf());
287287
}
288-
CodeGenerator::new().with_options(options).with_symbol_table(symbol_table).build(program)
288+
CodeGenerator::new().with_options(options).with_scoping(scoping).build(program)
289289
}
290290
}

crates/oxc_codegen/src/lib.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use oxc_ast::ast::{
1919
Statement, StringLiteral,
2020
};
2121
use oxc_data_structures::{code_buffer::CodeBuffer, stack::Stack};
22-
use oxc_semantic::SymbolTable;
22+
use oxc_semantic::Scoping;
2323
use oxc_span::{GetSpan, SPAN, Span};
2424
use oxc_syntax::{
2525
identifier::{LS, PS, is_identifier_part, is_identifier_part_ascii},
@@ -79,7 +79,7 @@ pub struct Codegen<'a> {
7979
/// Original source code of the AST
8080
source_text: &'a str,
8181

82-
symbol_table: Option<SymbolTable>,
82+
scoping: Option<Scoping>,
8383

8484
/// Output Code
8585
code: CodeBuffer,
@@ -149,7 +149,7 @@ impl<'a> Codegen<'a> {
149149
Self {
150150
options,
151151
source_text: "",
152-
symbol_table: None,
152+
scoping: None,
153153
code: CodeBuffer::default(),
154154
needs_semicolon: false,
155155
need_space_before_dot: 0,
@@ -184,8 +184,8 @@ impl<'a> Codegen<'a> {
184184
///
185185
/// Can be used for easy renaming of variables (based on semantic analysis).
186186
#[must_use]
187-
pub fn with_symbol_table(mut self, symbol_table: Option<SymbolTable>) -> Self {
188-
self.symbol_table = symbol_table;
187+
pub fn with_scoping(mut self, scoping: Option<Scoping>) -> Self {
188+
self.scoping = scoping;
189189
self
190190
}
191191

@@ -503,9 +503,9 @@ impl<'a> Codegen<'a> {
503503
}
504504

505505
fn get_identifier_reference_name(&self, reference: &IdentifierReference<'a>) -> &'a str {
506-
if let Some(symbol_table) = &self.symbol_table {
506+
if let Some(scoping) = &self.scoping {
507507
if let Some(reference_id) = reference.reference_id.get() {
508-
if let Some(name) = symbol_table.get_reference_name(reference_id) {
508+
if let Some(name) = scoping.get_reference_name(reference_id) {
509509
// SAFETY: Hack the lifetime to be part of the allocator.
510510
return unsafe { std::mem::transmute_copy(&name) };
511511
}
@@ -515,9 +515,9 @@ impl<'a> Codegen<'a> {
515515
}
516516

517517
fn get_binding_identifier_name(&self, ident: &BindingIdentifier<'a>) -> &'a str {
518-
if let Some(symbol_table) = &self.symbol_table {
518+
if let Some(scoping) = &self.scoping {
519519
if let Some(symbol_id) = ident.symbol_id.get() {
520-
let name = symbol_table.symbol_name(symbol_id);
520+
let name = scoping.symbol_name(symbol_id);
521521
// SAFETY: Hack the lifetime to be part of the allocator.
522522
return unsafe { std::mem::transmute_copy(&name) };
523523
}

crates/oxc_linter/src/ast_util.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -283,15 +283,15 @@ pub fn get_declaration_of_variable<'a, 'b>(
283283
semantic: &'b Semantic<'a>,
284284
) -> Option<&'b AstNode<'a>> {
285285
let symbol_id = get_symbol_id_of_variable(ident, semantic)?;
286-
let symbol_table = semantic.symbols();
286+
let symbol_table = semantic.scoping();
287287
Some(semantic.nodes().get_node(symbol_table.get_symbol_declaration(symbol_id)))
288288
}
289289

290290
pub fn get_declaration_from_reference_id<'a, 'b>(
291291
reference_id: ReferenceId,
292292
semantic: &'b Semantic<'a>,
293293
) -> Option<&'b AstNode<'a>> {
294-
let symbol_table = semantic.symbols();
294+
let symbol_table = semantic.scoping();
295295
let symbol_id = symbol_table.get_reference(reference_id).symbol_id()?;
296296
Some(semantic.nodes().get_node(symbol_table.get_symbol_declaration(symbol_id)))
297297
}
@@ -300,7 +300,7 @@ pub fn get_symbol_id_of_variable(
300300
ident: &IdentifierReference,
301301
semantic: &Semantic<'_>,
302302
) -> Option<SymbolId> {
303-
semantic.symbols().get_reference(ident.reference_id()).symbol_id()
303+
semantic.scoping().get_reference(ident.reference_id()).symbol_id()
304304
}
305305

306306
pub fn extract_regex_flags<'a>(
@@ -421,7 +421,7 @@ pub fn is_global_require_call(call_expr: &CallExpression, ctx: &Semantic) -> boo
421421
if call_expr.arguments.len() != 1 {
422422
return false;
423423
}
424-
call_expr.callee.is_global_reference_name("require", ctx.symbols())
424+
call_expr.callee.is_global_reference_name("require", ctx.scoping())
425425
}
426426

427427
pub fn is_function_node(node: &AstNode) -> bool {
@@ -565,11 +565,11 @@ pub fn could_be_error(ctx: &LintContext, expr: &Expression) -> bool {
565565
could_be_error(ctx, &expr.consequent) || could_be_error(ctx, &expr.alternate)
566566
}
567567
Expression::Identifier(ident) => {
568-
let reference = ctx.symbols().get_reference(ident.reference_id());
568+
let reference = ctx.scoping().get_reference(ident.reference_id());
569569
let Some(symbol_id) = reference.symbol_id() else {
570570
return true;
571571
};
572-
let decl = ctx.nodes().get_node(ctx.symbols().get_symbol_declaration(symbol_id));
572+
let decl = ctx.nodes().get_node(ctx.scoping().get_symbol_declaration(symbol_id));
573573
match decl.kind() {
574574
AstKind::VariableDeclarator(decl) => {
575575
if let Some(init) = &decl.init {

crates/oxc_linter/src/context/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,13 @@ impl<'a> LintContext<'a> {
155155
/// Checks if the provided identifier is a reference to a global variable.
156156
pub fn is_reference_to_global_variable(&self, ident: &IdentifierReference) -> bool {
157157
let name = ident.name.as_str();
158-
self.scopes().root_unresolved_references().contains_key(name)
158+
self.scoping().root_unresolved_references().contains_key(name)
159159
&& !self.globals().get(name).is_some_and(|value| *value == GlobalValue::Off)
160160
}
161161

162162
/// Checks if the provided identifier is a reference to a global variable.
163163
pub fn get_global_variable_value(&self, name: &str) -> Option<GlobalValue> {
164-
if !self.scopes().root_unresolved_references().contains_key(name) {
164+
if !self.scoping().root_unresolved_references().contains_key(name) {
165165
return None;
166166
}
167167

crates/oxc_linter/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl Linter {
167167
rule.run_once(ctx);
168168
}
169169

170-
for symbol in semantic.symbols().symbol_ids() {
170+
for symbol in semantic.scoping().symbol_ids() {
171171
for (rule, ctx) in &rules {
172172
rule.run_on_symbol(symbol, ctx);
173173
}
@@ -190,7 +190,7 @@ impl Linter {
190190
for (rule, ref ctx) in rules {
191191
rule.run_once(ctx);
192192

193-
for symbol in semantic.symbols().symbol_ids() {
193+
for symbol in semantic.scoping().symbol_ids() {
194194
rule.run_on_symbol(symbol, ctx);
195195
}
196196

crates/oxc_linter/src/rules/eslint/func_names.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ impl Rule for FuncNames {
329329
|name| {
330330
// if this name shadows a variable in the outer scope **and** that name is referenced
331331
// inside the function body, it is unsafe to add a name to this function
332-
if ctx.scopes().find_binding(func.scope_id(), &name).is_some_and(
332+
if ctx.scoping().find_binding(func.scope_id(), &name).is_some_and(
333333
|shadowed_var| {
334334
ctx.semantic().symbol_references(shadowed_var).any(
335335
|reference| {

crates/oxc_linter/src/rules/eslint/no_alert.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ fn is_global_this_ref_or_global_window<'a>(
6666
expr: &Expression<'a>,
6767
) -> bool {
6868
if let Expression::ThisExpression(_) = expr {
69-
if ctx.scopes().scope_flags(scope_id).is_top() {
69+
if ctx.scoping().scope_flags(scope_id).is_top() {
7070
return true;
7171
}
7272
}
@@ -85,7 +85,7 @@ fn is_global_this_ref_or_global_window<'a>(
8585
}
8686

8787
fn is_shadowed<'a>(scope_id: ScopeId, name: &'a str, ctx: &LintContext<'a>) -> bool {
88-
ctx.scopes().find_binding(scope_id, name).is_some()
88+
ctx.scoping().find_binding(scope_id, name).is_some()
8989
}
9090

9191
impl Rule for NoAlert {

crates/oxc_linter/src/rules/eslint/no_array_constructor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ impl Rule for NoArrayConstructor {
7373
return;
7474
};
7575

76-
if ident.is_global_reference_name("Array", ctx.symbols())
76+
if ident.is_global_reference_name("Array", ctx.scoping())
7777
&& arguments.len() != 1
7878
&& type_parameters.is_none()
7979
&& !optional

crates/oxc_linter/src/rules/eslint/no_class_assign.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ declare_oxc_lint!(
3636

3737
impl Rule for NoClassAssign {
3838
fn run_on_symbol(&self, symbol_id: SymbolId, ctx: &LintContext<'_>) {
39-
let symbol_table = ctx.semantic().symbols();
39+
let symbol_table = ctx.semantic().scoping();
4040
if symbol_table.symbol_flags(symbol_id).is_class() {
4141
for reference in symbol_table.get_resolved_references(symbol_id) {
4242
if reference.is_write() {

crates/oxc_linter/src/rules/eslint/no_console.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl Rule for NoConsole {
132132
};
133133

134134
if ident.name == "console"
135-
&& ctx.scopes().root_unresolved_references().contains_key(ident.name.as_str())
135+
&& ctx.scoping().root_unresolved_references().contains_key(ident.name.as_str())
136136
&& !self.allow.iter().any(|s| mem.static_property_name().is_some_and(|f| f == s))
137137
{
138138
if let Some((mem_span, _)) = mem.static_property_info() {

crates/oxc_linter/src/rules/eslint/no_const_assign.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ declare_oxc_lint!(
5252

5353
impl Rule for NoConstAssign {
5454
fn run_on_symbol(&self, symbol_id: SymbolId, ctx: &LintContext<'_>) {
55-
let symbol_table = ctx.semantic().symbols();
55+
let symbol_table = ctx.semantic().scoping();
5656
if symbol_table.symbol_flags(symbol_id).is_const_variable() {
5757
for reference in symbol_table.get_resolved_references(symbol_id) {
5858
if reference.is_write() {

crates/oxc_linter/src/rules/eslint/no_constant_binary_expression.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ impl NoConstantBinaryExpression {
169169
if let Expression::Identifier(ident) = &call_expr.callee {
170170
return ["Boolean", "String", "Number"].contains(&ident.name.as_str())
171171
&& ctx
172-
.scopes()
172+
.scoping()
173173
.root_unresolved_references()
174174
.contains_key(ident.name.as_str());
175175
}
@@ -294,7 +294,7 @@ impl NoConstantBinaryExpression {
294294
},
295295
Expression::CallExpression(call_expr) => {
296296
if let Expression::Identifier(ident) = &call_expr.callee {
297-
let unresolved_references = ctx.scopes().root_unresolved_references();
297+
let unresolved_references = ctx.scoping().root_unresolved_references();
298298
if (ident.name == "String" || ident.name == "Number")
299299
&& unresolved_references.contains_key(ident.name.as_str())
300300
{
@@ -346,7 +346,7 @@ impl NoConstantBinaryExpression {
346346
if let Expression::Identifier(ident) = &call_expr.callee {
347347
return ctx.env_contains_var(ident.name.as_str())
348348
&& ctx
349-
.scopes()
349+
.scoping()
350350
.root_unresolved_references()
351351
.contains_key(ident.name.as_str());
352352
}

crates/oxc_linter/src/rules/eslint/no_else_return.rs

+19-19
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use oxc_ast::{AstKind, ast::Statement};
22
use oxc_diagnostics::OxcDiagnostic;
33
use oxc_macros::declare_oxc_lint;
4-
use oxc_semantic::{ScopeId, ScopeTree};
4+
use oxc_semantic::ScopeId;
55
use oxc_span::{GetSpan, Span};
66

77
use crate::{AstNode, context::LintContext, rule::Rule};
@@ -181,7 +181,7 @@ fn is_safe_from_name_collisions(
181181
stmt: &Statement,
182182
parent_scope_id: ScopeId,
183183
) -> bool {
184-
let scopes: &ScopeTree = ctx.scopes();
184+
let scopes = ctx.scoping();
185185

186186
match stmt {
187187
Statement::BlockStatement(block) => {
@@ -492,41 +492,41 @@ fn test() {
492492
),
493493
("function foo10() { if (foo) return bar; else (foo).bar(); }", None),
494494
(
495-
"function foo11() { if (foo) return bar
495+
"function foo11() { if (foo) return bar
496496
else { [1, 2, 3].map(foo) } }",
497497
None,
498498
),
499499
(
500-
"function foo12() { if (foo) return bar
501-
else { baz() }
500+
"function foo12() { if (foo) return bar
501+
else { baz() }
502502
[1, 2, 3].map(foo) }",
503503
None,
504504
),
505505
(
506-
"function foo13() { if (foo) return bar;
506+
"function foo13() { if (foo) return bar;
507507
else { [1, 2, 3].map(foo) } }",
508508
None,
509509
),
510510
(
511-
"function foo14() { if (foo) return bar
512-
else { baz(); }
511+
"function foo14() { if (foo) return bar
512+
else { baz(); }
513513
[1, 2, 3].map(foo) }",
514514
None,
515515
),
516516
("function foo15() { if (foo) return bar; else { baz() } qaz() }", None),
517517
(
518-
"function foo16() { if (foo) return bar
518+
"function foo16() { if (foo) return bar
519519
else { baz() } qaz() }",
520520
None,
521521
),
522522
(
523-
"function foo17() { if (foo) return bar
524-
else { baz() }
523+
"function foo17() { if (foo) return bar
524+
else { baz() }
525525
qaz() }",
526526
None,
527527
),
528528
(
529-
"function foo18() { if (foo) return function() {}
529+
"function foo18() { if (foo) return function() {}
530530
else [1, 2, 3].map(bar) }",
531531
None,
532532
),
@@ -727,24 +727,24 @@ fn test() {
727727
None,
728728
),
729729
(
730-
"function foo13() { if (foo) return bar;
730+
"function foo13() { if (foo) return bar;
731731
else { [1, 2, 3].map(foo) } }",
732732
"function foo13() { if (foo) return bar; [1, 2, 3].map(foo) }",
733733
None,
734734
),
735735
(
736-
"function foo14() { if (foo) return bar
737-
else { baz(); }
736+
"function foo14() { if (foo) return bar
737+
else { baz(); }
738738
[1, 2, 3].map(foo) }",
739-
"function foo14() { if (foo) return bar\n baz();
739+
"function foo14() { if (foo) return bar\n baz();
740740
[1, 2, 3].map(foo) }",
741741
None,
742742
),
743743
(
744-
"function foo17() { if (foo) return bar
745-
else { baz() }
744+
"function foo17() { if (foo) return bar
745+
else { baz() }
746746
qaz() }",
747-
"function foo17() { if (foo) return bar\n baz()
747+
"function foo17() { if (foo) return bar\n baz()
748748
qaz() }",
749749
None,
750750
),

0 commit comments

Comments
 (0)