diff --git a/crates/oxc_linter/src/rules/eslint/no_global_assign.rs b/crates/oxc_linter/src/rules/eslint/no_global_assign.rs index 8f9f1ccdbcb63..750a8b570c1fe 100644 --- a/crates/oxc_linter/src/rules/eslint/no_global_assign.rs +++ b/crates/oxc_linter/src/rules/eslint/no_global_assign.rs @@ -63,8 +63,10 @@ impl Rule for NoGlobalAssign { for reference_id in reference_id_list { let reference = symbol_table.get_reference(reference_id); if reference.is_write() { - let name = reference.name(); - if !self.excludes.contains(name) && ctx.env_contains_var(name) { + let name = ctx.semantic().reference_name(reference); + if !self.excludes.contains(&CompactStr::from(name)) + && ctx.env_contains_var(name) + { ctx.diagnostic(no_global_assign_diagnostic(name, reference.span())); } } diff --git a/crates/oxc_linter/src/rules/eslint/no_undef.rs b/crates/oxc_linter/src/rules/eslint/no_undef.rs index 278ddf131c176..d748853002877 100644 --- a/crates/oxc_linter/src/rules/eslint/no_undef.rs +++ b/crates/oxc_linter/src/rules/eslint/no_undef.rs @@ -52,13 +52,13 @@ impl Rule for NoUndef { for reference_id_list in ctx.scopes().root_unresolved_references_ids() { for reference_id in reference_id_list { let reference = symbol_table.get_reference(reference_id); - let name = reference.name(); + let name = ctx.semantic().reference_name(reference); if ctx.env_contains_var(name) { continue; } - if ctx.globals().is_enabled(name.as_str()) { + if ctx.globals().is_enabled(name) { continue; } diff --git a/crates/oxc_linter/src/rules/jest/no_confusing_set_timeout.rs b/crates/oxc_linter/src/rules/jest/no_confusing_set_timeout.rs index 05880374caa19..bf7bd492b44ff 100644 --- a/crates/oxc_linter/src/rules/jest/no_confusing_set_timeout.rs +++ b/crates/oxc_linter/src/rules/jest/no_confusing_set_timeout.rs @@ -131,7 +131,8 @@ fn collect_jest_reference_id( for reference_id in reference_id_list { let reference = symbol_table.get_reference(reference_id); - if !is_jest_call(reference.name()) { + + if !is_jest_call(ctx.semantic().reference_name(reference)) { continue; } let Some(parent_node) = nodes.parent_node(reference.node_id()) else { @@ -162,7 +163,7 @@ fn handle_jest_set_time_out<'a>( continue; }; - if !is_jest_call(reference.name()) { + if !is_jest_call(ctx.semantic().reference_name(reference)) { if is_jest_fn_call(parent_node, id_to_jest_node_map, ctx) { for (jest_reference_id, span) in jest_reference_id_list { if jest_reference_id > &reference_id { diff --git a/crates/oxc_semantic/src/builder.rs b/crates/oxc_semantic/src/builder.rs index 4880ccaf265a6..06c59e95bed5f 100644 --- a/crates/oxc_semantic/src/builder.rs +++ b/crates/oxc_semantic/src/builder.rs @@ -351,13 +351,12 @@ impl<'a> SemanticBuilder<'a> { /// Declare an unresolved reference in the current scope. /// /// # Panics - pub fn declare_reference(&mut self, reference: Reference) -> ReferenceId { - let reference_name = reference.name().clone(); + pub fn declare_reference(&mut self, name: &str, reference: Reference) -> ReferenceId { let reference_flag = *reference.flag(); let reference_id = self.symbols.create_reference(reference); self.unresolved_references[self.current_scope_depth] - .entry(reference_name) + .entry(CompactStr::from(name)) .or_default() .push((reference_id, reference_flag)); reference_id @@ -1897,9 +1896,8 @@ impl<'a> SemanticBuilder<'a> { fn reference_identifier(&mut self, ident: &IdentifierReference) { let flag = self.resolve_reference_usages(); - let name = ident.name.to_compact_str(); - let reference = Reference::new(ident.span, name, self.current_node_id, flag); - let reference_id = self.declare_reference(reference); + let reference = Reference::new(ident.span, self.current_node_id, flag); + let reference_id = self.declare_reference(&ident.name, reference); ident.reference_id.set(Some(reference_id)); } @@ -1922,13 +1920,8 @@ impl<'a> SemanticBuilder<'a> { Some(AstKind::JSXMemberExpressionObject(_)) => {} _ => return, } - let reference = Reference::new( - ident.span, - ident.name.to_compact_str(), - self.current_node_id, - ReferenceFlag::read(), - ); - self.declare_reference(reference); + let reference = Reference::new(ident.span, self.current_node_id, ReferenceFlag::read()); + self.declare_reference(&ident.name, reference); } fn is_not_expression_statement_parent(&self) -> bool { diff --git a/crates/oxc_semantic/src/lib.rs b/crates/oxc_semantic/src/lib.rs index f812232ee27f1..368f5c44e6e7e 100644 --- a/crates/oxc_semantic/src/lib.rs +++ b/crates/oxc_semantic/src/lib.rs @@ -137,6 +137,15 @@ impl<'a> Semantic<'a> { pub fn is_reference_to_global_variable(&self, ident: &IdentifierReference) -> bool { self.scopes().root_unresolved_references().contains_key(ident.name.as_str()) } + + pub fn reference_name(&self, reference: &Reference) -> &str { + let node = self.nodes.get_node(reference.node_id()); + match node.kind() { + AstKind::IdentifierReference(id) => id.name.as_str(), + AstKind::JSXIdentifier(id) => id.name.as_str(), + _ => unreachable!(), + } + } } #[cfg(test)] diff --git a/crates/oxc_semantic/src/reference.rs b/crates/oxc_semantic/src/reference.rs index ed62050d4d45c..ea36782a56de4 100644 --- a/crates/oxc_semantic/src/reference.rs +++ b/crates/oxc_semantic/src/reference.rs @@ -1,7 +1,7 @@ // Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]` #![allow(non_snake_case)] -use oxc_span::{CompactStr, Span}; +use oxc_span::Span; pub use oxc_syntax::reference::{ReferenceFlag, ReferenceId}; #[cfg(feature = "serialize")] use serde::Serialize; @@ -15,8 +15,6 @@ use crate::{symbol::SymbolId, AstNodeId}; #[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] pub struct Reference { span: Span, - /// The name of the identifier that was referred to - name: CompactStr, node_id: AstNodeId, symbol_id: Option, /// Describes how this referenced is used by other AST nodes. References can @@ -25,28 +23,23 @@ pub struct Reference { } impl Reference { - pub fn new(span: Span, name: CompactStr, node_id: AstNodeId, flag: ReferenceFlag) -> Self { - Self { span, name, node_id, symbol_id: None, flag } + pub fn new(span: Span, node_id: AstNodeId, flag: ReferenceFlag) -> Self { + Self { span, node_id, symbol_id: None, flag } } pub fn new_with_symbol_id( span: Span, - name: CompactStr, node_id: AstNodeId, symbol_id: SymbolId, flag: ReferenceFlag, ) -> Self { - Self { span, name, node_id, symbol_id: Some(symbol_id), flag } + Self { span, node_id, symbol_id: Some(symbol_id), flag } } pub fn span(&self) -> Span { self.span } - pub fn name(&self) -> &CompactStr { - &self.name - } - pub fn node_id(&self) -> AstNodeId { self.node_id } diff --git a/crates/oxc_semantic/tests/main.rs b/crates/oxc_semantic/tests/main.rs index 3785974c84fb0..112438059d259 100644 --- a/crates/oxc_semantic/tests/main.rs +++ b/crates/oxc_semantic/tests/main.rs @@ -69,7 +69,9 @@ fn get_scope_snapshot(semantic: &Semantic, scopes: impl Iterator result.push('{'); result.push_str(format!("\"flag\": \"{:?}\",", reference.flag()).as_str()); result.push_str(format!("\"id\": {index:?},").as_str()); - result.push_str(format!("\"name\": {:?},", reference.name()).as_str()); + result.push_str( + format!("\"name\": {:?},", semantic.reference_name(reference)).as_str(), + ); result.push_str( format!("\"node_id\": {}", reference.node_id().index()).as_str(), ); diff --git a/crates/oxc_transformer/src/typescript/annotations.rs b/crates/oxc_transformer/src/typescript/annotations.rs index 182afb6a42c91..bc27245ddce78 100644 --- a/crates/oxc_transformer/src/typescript/annotations.rs +++ b/crates/oxc_transformer/src/typescript/annotations.rs @@ -522,11 +522,7 @@ struct Assignment<'a> { impl<'a> Assignment<'a> { // Creates `this.name = name` fn create_this_property_assignment(&self, ctx: &mut TraverseCtx<'a>) -> Statement<'a> { - let reference_id = ctx.create_bound_reference( - self.name.to_compact_str(), - self.symbol_id, - ReferenceFlag::Read, - ); + let reference_id = ctx.create_bound_reference(self.symbol_id, ReferenceFlag::Read); let id = IdentifierReference::new_read(self.span, self.name.clone(), Some(reference_id)); ctx.ast.statement_expression( diff --git a/crates/oxc_traverse/src/context/mod.rs b/crates/oxc_traverse/src/context/mod.rs index ee29961d53555..50fa7dfe65e06 100644 --- a/crates/oxc_traverse/src/context/mod.rs +++ b/crates/oxc_traverse/src/context/mod.rs @@ -351,11 +351,10 @@ impl<'a> TraverseCtx<'a> { /// This is a shortcut for `ctx.scoping.create_bound_reference`. pub fn create_bound_reference( &mut self, - name: CompactStr, symbol_id: SymbolId, flag: ReferenceFlag, ) -> ReferenceId { - self.scoping.create_bound_reference(name, symbol_id, flag) + self.scoping.create_bound_reference(symbol_id, flag) } /// Create an `IdentifierReference` bound to a `SymbolId`. diff --git a/crates/oxc_traverse/src/context/scoping.rs b/crates/oxc_traverse/src/context/scoping.rs index 26aa7e50213a2..dc2bed3784309 100644 --- a/crates/oxc_traverse/src/context/scoping.rs +++ b/crates/oxc_traverse/src/context/scoping.rs @@ -263,12 +263,10 @@ impl TraverseScoping { /// Create a reference bound to a `SymbolId` pub fn create_bound_reference( &mut self, - name: CompactStr, symbol_id: SymbolId, flag: ReferenceFlag, ) -> ReferenceId { - let reference = - Reference::new_with_symbol_id(SPAN, name, AstNodeId::DUMMY, symbol_id, flag); + let reference = Reference::new_with_symbol_id(SPAN, AstNodeId::DUMMY, symbol_id, flag); let reference_id = self.symbols.create_reference(reference); self.symbols.resolved_references[symbol_id].push(reference_id); reference_id @@ -282,7 +280,7 @@ impl TraverseScoping { symbol_id: SymbolId, flag: ReferenceFlag, ) -> IdentifierReference<'a> { - let reference_id = self.create_bound_reference(name.to_compact_str(), symbol_id, flag); + let reference_id = self.create_bound_reference(symbol_id, flag); IdentifierReference { span, name, @@ -297,7 +295,7 @@ impl TraverseScoping { name: CompactStr, flag: ReferenceFlag, ) -> ReferenceId { - let reference = Reference::new(SPAN, name.clone(), AstNodeId::DUMMY, flag); + let reference = Reference::new(SPAN, AstNodeId::DUMMY, flag); let reference_id = self.symbols.create_reference(reference); self.scopes.add_root_unresolved_reference(name, (reference_id, flag)); reference_id @@ -330,7 +328,7 @@ impl TraverseScoping { flag: ReferenceFlag, ) -> ReferenceId { if let Some(symbol_id) = symbol_id { - self.create_bound_reference(name, symbol_id, flag) + self.create_bound_reference(symbol_id, flag) } else { self.create_unbound_reference(name, flag) }