refactor(span): deal only in owned Atoms (#8641)

#8596 made `Atom` a `Copy` type. Now we can deal exclusively in owned `Atom`s. Refactor code to not pass `&Atom` into functions etc.
This commit is contained in:
overlookmotel 2025-01-21 14:20:06 +00:00
parent 20f52b1fee
commit b8d9a51462
16 changed files with 57 additions and 60 deletions

View file

@ -45,10 +45,10 @@ impl<'a> IsolatedDeclarations<'a> {
if let Some(value) = &value { if let Some(value) = &value {
let member_name = match &member.id { let member_name = match &member.id {
TSEnumMemberName::Identifier(id) => &id.name, TSEnumMemberName::Identifier(id) => id.name,
TSEnumMemberName::String(str) => &str.value, TSEnumMemberName::String(str) => str.value,
}; };
prev_members.insert(*member_name, value.clone()); prev_members.insert(member_name, value.clone());
} }
let member = self.ast.ts_enum_member( let member = self.ast.ts_enum_member(

View file

@ -435,7 +435,7 @@ impl<'a> IsolatedDeclarations<'a> {
stmts.retain(move |stmt| match stmt { stmts.retain(move |stmt| match stmt {
Statement::FunctionDeclaration(ref func) => { Statement::FunctionDeclaration(ref func) => {
let name = &func let name = func
.id .id
.as_ref() .as_ref()
.unwrap_or_else(|| { .unwrap_or_else(|| {
@ -446,17 +446,17 @@ impl<'a> IsolatedDeclarations<'a> {
.name; .name;
if func.body.is_some() { if func.body.is_some() {
if last_function_name.as_ref().is_some_and(|last_name| last_name == name) { if last_function_name.as_ref().is_some_and(|&last_name| last_name == name) {
return false; return false;
} }
} else { } else {
last_function_name = Some(*name); last_function_name = Some(name);
} }
true true
} }
Statement::ExportNamedDeclaration(ref decl) => { Statement::ExportNamedDeclaration(ref decl) => {
if let Some(Declaration::FunctionDeclaration(ref func)) = decl.declaration { if let Some(Declaration::FunctionDeclaration(ref func)) = decl.declaration {
let name = &func let name = func
.id .id
.as_ref() .as_ref()
.unwrap_or_else(|| { .unwrap_or_else(|| {
@ -466,11 +466,11 @@ impl<'a> IsolatedDeclarations<'a> {
}) })
.name; .name;
if func.body.is_some() { if func.body.is_some() {
if last_function_name.as_ref().is_some_and(|last_name| last_name == name) { if last_function_name.as_ref().is_some_and(|&last_name| last_name == name) {
return false; return false;
} }
} else { } else {
last_function_name = Some(*name); last_function_name = Some(name);
} }
true true
} else { } else {

View file

@ -586,7 +586,7 @@ fn get_computed_member_name(computed_member: &ComputedMemberExpression) -> Optio
Expression::TemplateLiteral(lit) if lit.expressions.is_empty() && lit.quasis.len() == 1 => { Expression::TemplateLiteral(lit) if lit.expressions.is_empty() && lit.quasis.len() == 1 => {
Some(lit.quasis[0].value.raw.as_ref().into()) Some(lit.quasis[0].value.raw.as_ref().into())
} }
Expression::RegExpLiteral(lit) => lit.raw.as_ref().map(|x| (*x).into_compact_str()), Expression::RegExpLiteral(lit) => lit.raw.as_ref().map(|&x| x.into_compact_str()),
_ => None, _ => None,
} }
} }

View file

@ -104,13 +104,12 @@ impl Rule for NoUselessRename {
BindingPatternKind::AssignmentPattern(assignment_pattern) => { BindingPatternKind::AssignmentPattern(assignment_pattern) => {
match &assignment_pattern.left.kind { match &assignment_pattern.left.kind {
BindingPatternKind::BindingIdentifier(binding_ident) => { BindingPatternKind::BindingIdentifier(binding_ident) => {
&binding_ident.name binding_ident.name
} }
_ => continue, _ => continue,
} }
} }
BindingPatternKind::BindingIdentifier(binding_ident) => binding_ident.name,
BindingPatternKind::BindingIdentifier(binding_ident) => &binding_ident.name,
_ => continue, _ => continue,
}; };
@ -134,7 +133,7 @@ impl Rule for NoUselessRename {
let Some(key) = property.name.static_name() else { let Some(key) = property.name.static_name() else {
continue; continue;
}; };
let Some(renamed_key) = property.binding.identifier().map(|ident| &ident.name) let Some(renamed_key) = property.binding.identifier().map(|ident| ident.name)
else { else {
continue; continue;
}; };

View file

@ -504,7 +504,7 @@ impl Rule for ExhaustiveDeps {
return false; return false;
} }
if !is_identifier_a_dependency(&dep.name, dep.reference_id, ctx, component_scope_id) { if !is_identifier_a_dependency(dep.name, dep.reference_id, ctx, component_scope_id) {
return false; return false;
}; };
true true
@ -764,7 +764,7 @@ fn concat_members<'a, 'b>(
} }
fn is_identifier_a_dependency<'a>( fn is_identifier_a_dependency<'a>(
ident_name: &Atom<'a>, ident_name: Atom<'a>,
ident_reference_id: ReferenceId, ident_reference_id: ReferenceId,
ctx: &'_ LintContext<'a>, ctx: &'_ LintContext<'a>,
component_scope_id: ScopeId, component_scope_id: ScopeId,
@ -824,7 +824,7 @@ fn is_identifier_a_dependency<'a>(
// https://github.com/facebook/react/blob/fee786a057774ab687aff765345dd86fce534ab2/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js#L164 // https://github.com/facebook/react/blob/fee786a057774ab687aff765345dd86fce534ab2/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js#L164
fn is_stable_value<'a, 'b>( fn is_stable_value<'a, 'b>(
node: &'b AstNode<'a>, node: &'b AstNode<'a>,
ident_name: &Atom<'a>, ident_name: Atom<'a>,
ident_reference_id: ReferenceId, ident_reference_id: ReferenceId,
ctx: &'b LintContext<'a>, ctx: &'b LintContext<'a>,
component_scope_id: ScopeId, component_scope_id: ScopeId,
@ -943,9 +943,8 @@ fn is_function_stable<'a, 'b>(
collector.found_dependencies collector.found_dependencies
}; };
deps.iter().all(|dep| { deps.iter()
!is_identifier_a_dependency(&dep.name, dep.reference_id, ctx, component_scope_id) .all(|dep| !is_identifier_a_dependency(dep.name, dep.reference_id, ctx, component_scope_id))
})
} }
// https://github.com/facebook/react/blob/fee786a057774ab687aff765345dd86fce534ab2/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js#L1742 // https://github.com/facebook/react/blob/fee786a057774ab687aff765345dd86fce534ab2/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js#L1742

View file

@ -66,15 +66,15 @@ impl Rule for JsxPropsNoSpreadMulti {
let spread_attrs = let spread_attrs =
jsx_opening_el.attributes.iter().filter_map(JSXAttributeItem::as_spread); jsx_opening_el.attributes.iter().filter_map(JSXAttributeItem::as_spread);
let mut identifier_names: FxHashMap<&Atom, Span> = FxHashMap::default(); let mut identifier_names: FxHashMap<Atom, Span> = FxHashMap::default();
let mut member_expressions = Vec::new(); let mut member_expressions = Vec::new();
let mut duplicate_spreads: FxHashMap<&Atom, Vec<Span>> = FxHashMap::default(); let mut duplicate_spreads: FxHashMap<Atom, Vec<Span>> = FxHashMap::default();
for spread_attr in spread_attrs { for spread_attr in spread_attrs {
let argument_without_parenthesized = spread_attr.argument.without_parentheses(); let argument_without_parenthesized = spread_attr.argument.without_parentheses();
if let Some(identifier_name) = if let Some(identifier_name) =
argument_without_parenthesized.get_identifier_reference().map(|arg| &arg.name) argument_without_parenthesized.get_identifier_reference().map(|arg| arg.name)
{ {
identifier_names identifier_names
.entry(identifier_name) .entry(identifier_name)
@ -97,7 +97,7 @@ impl Rule for JsxPropsNoSpreadMulti {
ctx.diagnostic_with_fix( ctx.diagnostic_with_fix(
jsx_props_no_spread_multiple_identifiers_diagnostic( jsx_props_no_spread_multiple_identifiers_diagnostic(
spans.clone(), spans.clone(),
identifier_name, &identifier_name,
), ),
|_fixer| { |_fixer| {
spans spans

View file

@ -47,8 +47,8 @@ declare_oxc_lint!(
impl Rule for PreferNodeProtocol { impl Rule for PreferNodeProtocol {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
let string_lit_value_with_span = match node.kind() { let string_lit_value_with_span = match node.kind() {
AstKind::ImportExpression(import) => match import.source { AstKind::ImportExpression(import) => match &import.source {
Expression::StringLiteral(ref str_lit) => Some((str_lit.value, str_lit.span)), Expression::StringLiteral(str_lit) => Some((str_lit.value, str_lit.span)),
_ => None, _ => None,
}, },
AstKind::TSImportEqualsDeclaration(import) => match &import.module_reference { AstKind::TSImportEqualsDeclaration(import) => match &import.module_reference {

View file

@ -65,10 +65,10 @@ impl<'a> ModuleRecordBuilder<'a> {
errors errors
} }
fn add_module_request(&mut self, name: &Atom<'a>, requested_module: RequestedModule) { fn add_module_request(&mut self, name: Atom<'a>, requested_module: RequestedModule) {
self.module_record self.module_record
.requested_modules .requested_modules
.entry(*name) .entry(name)
.or_insert_with(|| oxc_allocator::Vec::new_in(self.allocator)) .or_insert_with(|| oxc_allocator::Vec::new_in(self.allocator))
.push(requested_module); .push(requested_module);
} }
@ -240,7 +240,7 @@ impl<'a> ModuleRecordBuilder<'a> {
} }
} }
self.add_module_request( self.add_module_request(
&module_request.name, module_request.name,
RequestedModule { RequestedModule {
statement_span: decl.span, statement_span: decl.span,
span: module_request.span, span: module_request.span,
@ -271,7 +271,7 @@ impl<'a> ModuleRecordBuilder<'a> {
self.add_export_binding(exported_name.name(), exported_name.span()); self.add_export_binding(exported_name.name(), exported_name.span());
} }
self.add_module_request( self.add_module_request(
&module_request.name, module_request.name,
RequestedModule { RequestedModule {
statement_span: decl.span, statement_span: decl.span,
span: module_request.span, span: module_request.span,
@ -330,7 +330,7 @@ impl<'a> ModuleRecordBuilder<'a> {
if let Some(module_request) = &module_request { if let Some(module_request) = &module_request {
self.add_module_request( self.add_module_request(
&module_request.name, module_request.name,
RequestedModule { RequestedModule {
statement_span: decl.span, statement_span: decl.span,
span: module_request.span, span: module_request.span,

View file

@ -58,20 +58,20 @@ impl<'a> Binder<'a> for VariableDeclarator<'a> {
self.id.bound_names(&mut |ident| { self.id.bound_names(&mut |ident| {
let span = ident.span; let span = ident.span;
let name = &ident.name; let name = ident.name;
let mut declared_symbol_id = None; let mut declared_symbol_id = None;
for &scope_id in &var_scope_ids { for &scope_id in &var_scope_ids {
if let Some(symbol_id) = if let Some(symbol_id) =
builder.check_redeclaration(scope_id, span, name, excludes, true) builder.check_redeclaration(scope_id, span, &name, excludes, true)
{ {
builder.add_redeclare_variable(symbol_id, span); builder.add_redeclare_variable(symbol_id, span);
declared_symbol_id = Some(symbol_id); declared_symbol_id = Some(symbol_id);
// remove current scope binding and add to target scope // remove current scope binding and add to target scope
// avoid same symbols appear in multi-scopes // avoid same symbols appear in multi-scopes
builder.scope.remove_binding(scope_id, name); builder.scope.remove_binding(scope_id, &name);
builder.scope.add_binding(target_scope_id, name, symbol_id); builder.scope.add_binding(target_scope_id, &name, symbol_id);
builder.symbols.scope_ids[symbol_id] = target_scope_id; builder.symbols.scope_ids[symbol_id] = target_scope_id;
break; break;
} }
@ -81,14 +81,14 @@ impl<'a> Binder<'a> for VariableDeclarator<'a> {
// we don't need to create another symbol with the same name // we don't need to create another symbol with the same name
// to make sure they point to the same symbol. // to make sure they point to the same symbol.
let symbol_id = declared_symbol_id.unwrap_or_else(|| { let symbol_id = declared_symbol_id.unwrap_or_else(|| {
builder.declare_symbol_on_scope(span, name, target_scope_id, includes, excludes) builder.declare_symbol_on_scope(span, &name, target_scope_id, includes, excludes)
}); });
ident.symbol_id.set(Some(symbol_id)); ident.symbol_id.set(Some(symbol_id));
// Finally, add the variable to all hoisted scopes // Finally, add the variable to all hoisted scopes
// to support redeclaration checks when declaring variables with the same name later. // to support redeclaration checks when declaring variables with the same name later.
for &scope_id in &var_scope_ids { for &scope_id in &var_scope_ids {
builder.hoisting_variables.entry(scope_id).or_default().insert(*name, symbol_id); builder.hoisting_variables.entry(scope_id).or_default().insert(name, symbol_id);
} }
}); });
} }

View file

@ -222,7 +222,7 @@ pub fn check_number_literal(lit: &NumericLiteral, ctx: &SemanticBuilder<'_>) {
// NumericLiteral :: legacy_octalIntegerLiteral // NumericLiteral :: legacy_octalIntegerLiteral
// DecimalIntegerLiteral :: NonOctalDecimalIntegerLiteral // DecimalIntegerLiteral :: NonOctalDecimalIntegerLiteral
// * It is a Syntax Error if the source text matched by this production is strict mode code. // * It is a Syntax Error if the source text matched by this production is strict mode code.
fn leading_zero(s: Option<&Atom>) -> bool { fn leading_zero(s: Option<Atom>) -> bool {
if let Some(s) = s { if let Some(s) = s {
let mut chars = s.bytes(); let mut chars = s.bytes();
if let Some(first) = chars.next() { if let Some(first) = chars.next() {
@ -236,10 +236,10 @@ pub fn check_number_literal(lit: &NumericLiteral, ctx: &SemanticBuilder<'_>) {
if ctx.strict_mode() { if ctx.strict_mode() {
match lit.base { match lit.base {
NumberBase::Octal if leading_zero(lit.raw.as_ref()) => { NumberBase::Octal if leading_zero(lit.raw) => {
ctx.error(legacy_octal(lit.span)); ctx.error(legacy_octal(lit.span));
} }
NumberBase::Decimal | NumberBase::Float if leading_zero(lit.raw.as_ref()) => { NumberBase::Decimal | NumberBase::Float if leading_zero(lit.raw) => {
ctx.error(leading_zero_decimal(lit.span)); ctx.error(leading_zero_decimal(lit.span));
} }
_ => {} _ => {}

View file

@ -73,7 +73,7 @@ impl<'new_alloc> CloneIn<'new_alloc> for Atom<'_> {
impl<'alloc> FromIn<'alloc, &Atom<'alloc>> for Atom<'alloc> { impl<'alloc> FromIn<'alloc, &Atom<'alloc>> for Atom<'alloc> {
fn from_in(s: &Atom<'alloc>, _: &'alloc Allocator) -> Self { fn from_in(s: &Atom<'alloc>, _: &'alloc Allocator) -> Self {
Self::from(s.0) *s
} }
} }

View file

@ -347,9 +347,9 @@ impl<'a> ExportLocalName<'a> {
} }
/// Get the bound name of this export. [`None`] for [`ExportLocalName::Null`]. /// Get the bound name of this export. [`None`] for [`ExportLocalName::Null`].
pub fn name(&self) -> Option<&Atom<'a>> { pub fn name(&self) -> Option<Atom<'a>> {
match self { match self {
Self::Name(name) | Self::Default(name) => Some(&name.name), Self::Name(name) | Self::Default(name) => Some(name.name),
Self::Null => None, Self::Null => None,
} }
} }

View file

@ -451,7 +451,7 @@ impl<'a> ClassProperties<'a, '_> {
// TODO: Only call `insert_many_before` if some private *props* // TODO: Only call `insert_many_before` if some private *props*
self.ctx.statement_injector.insert_many_before( self.ctx.statement_injector.insert_many_before(
&stmt_address, &stmt_address,
private_props.iter().filter_map(|(name, prop)| { private_props.iter().filter_map(|(&name, prop)| {
// TODO: Output `var _C_brand = new WeakSet();` for private instance method // TODO: Output `var _C_brand = new WeakSet();` for private instance method
if prop.is_method() || prop.is_accessor { if prop.is_method() || prop.is_accessor {
return None; return None;
@ -592,7 +592,7 @@ impl<'a> ClassProperties<'a, '_> {
// `c = class C { #x = 1; static y = 2; }` -> `var _C, _x;` // `c = class C { #x = 1; static y = 2; }` -> `var _C, _x;`
// TODO(improve-on-babel): Simplify this. // TODO(improve-on-babel): Simplify this.
if self.private_fields_as_properties { if self.private_fields_as_properties {
exprs.extend(private_props.iter().filter_map(|(name, prop)| { exprs.extend(private_props.iter().filter_map(|(&name, prop)| {
// TODO: Output `_C_brand = new WeakSet()` for private instance method // TODO: Output `_C_brand = new WeakSet()` for private instance method
if prop.is_method() || prop.is_accessor { if prop.is_method() || prop.is_accessor {
return None; return None;
@ -796,14 +796,14 @@ impl<'a> ClassProperties<'a, '_> {
/// `_classPrivateFieldLooseKey("prop")` /// `_classPrivateFieldLooseKey("prop")`
fn create_private_prop_key_loose( fn create_private_prop_key_loose(
name: &Atom<'a>, name: Atom<'a>,
transform_ctx: &TransformCtx<'a>, transform_ctx: &TransformCtx<'a>,
ctx: &mut TraverseCtx<'a>, ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> { ) -> Expression<'a> {
transform_ctx.helper_call_expr( transform_ctx.helper_call_expr(
Helper::ClassPrivateFieldLooseKey, Helper::ClassPrivateFieldLooseKey,
SPAN, SPAN,
ctx.ast.vec1(Argument::from(ctx.ast.expression_string_literal(SPAN, *name, None))), ctx.ast.vec1(Argument::from(ctx.ast.expression_string_literal(SPAN, name, None))),
ctx, ctx,
) )
} }

View file

@ -396,8 +396,8 @@ impl<'a> Pragma<'a> {
}; };
let mut expr = object; let mut expr = object;
for item in parts { for &item in parts {
let name = ctx.ast.identifier_name(SPAN, *item); let name = ctx.ast.identifier_name(SPAN, item);
expr = ctx.ast.member_expression_static(SPAN, expr, name, false).into(); expr = ctx.ast.member_expression_static(SPAN, expr, name, false).into();
} }
expr expr

View file

@ -249,12 +249,11 @@ impl<'a> InjectGlobalVariables<'a> {
) { ) {
// If this is first replacement made for this dot define, // If this is first replacement made for this dot define,
// create `Atom` for replacement, and record in `replaced_dot_defines` // create `Atom` for replacement, and record in `replaced_dot_defines`
let value_atom = value_atom.get_or_insert_with(|| { let value_atom = *value_atom.get_or_insert_with(|| {
self.replaced_dot_defines self.replaced_dot_defines
.push((dot_define.parts[0].clone(), dot_define.value.clone())); .push((dot_define.parts[0].clone(), dot_define.value.clone()));
self.ast.atom(dot_define.value.as_str()) self.ast.atom(dot_define.value.as_str())
}); });
let value_atom = *value_atom;
let value = self.ast.expression_identifier_reference(SPAN, value_atom); let value = self.ast.expression_identifier_reference(SPAN, value_atom);
*expr = value; *expr = value;

View file

@ -189,19 +189,19 @@ impl<'a> TypeScriptEnum<'a> {
let mut prev_constant_value = Some(ConstantValue::Number(-1.0)); let mut prev_constant_value = Some(ConstantValue::Number(-1.0));
let mut previous_enum_members = self.enums.entry(param_binding.name).or_default().clone(); let mut previous_enum_members = self.enums.entry(param_binding.name).or_default().clone();
let mut prev_member_name: Option<Atom<'a>> = None; let mut prev_member_name = None;
for member in members.iter_mut() { for member in members.iter_mut() {
let member_name: &Atom<'_> = match &member.id { let member_name = match &member.id {
TSEnumMemberName::Identifier(id) => &id.name, TSEnumMemberName::Identifier(id) => id.name,
TSEnumMemberName::String(str) => &str.value, TSEnumMemberName::String(str) => str.value,
}; };
let init = if let Some(initializer) = &mut member.initializer { let init = if let Some(initializer) = &mut member.initializer {
let constant_value = let constant_value =
self.computed_constant_value(initializer, &previous_enum_members); self.computed_constant_value(initializer, &previous_enum_members);
previous_enum_members.insert(*member_name, constant_value.clone()); previous_enum_members.insert(member_name, constant_value.clone());
// prev_constant_value = constant_value // prev_constant_value = constant_value
let init = match constant_value { let init = match constant_value {
@ -238,13 +238,13 @@ impl<'a> TypeScriptEnum<'a> {
let value = value + 1.0; let value = value + 1.0;
let constant_value = ConstantValue::Number(value); let constant_value = ConstantValue::Number(value);
prev_constant_value = Some(constant_value.clone()); prev_constant_value = Some(constant_value.clone());
previous_enum_members.insert(*member_name, Some(constant_value)); previous_enum_members.insert(member_name, Some(constant_value));
Self::get_initializer_expr(value, ctx) Self::get_initializer_expr(value, ctx)
} }
ConstantValue::String(_) => unreachable!(), ConstantValue::String(_) => unreachable!(),
} }
} else if let Some(prev_member_name) = prev_member_name { } else if let Some(prev_member_name) = prev_member_name {
previous_enum_members.insert(*member_name, None); previous_enum_members.insert(member_name, None);
let self_ref = { let self_ref = {
let obj = param_binding.create_read_expression(ctx); let obj = param_binding.create_read_expression(ctx);
let expr = ctx.ast.expression_string_literal(SPAN, prev_member_name, None); let expr = ctx.ast.expression_string_literal(SPAN, prev_member_name, None);
@ -255,7 +255,7 @@ impl<'a> TypeScriptEnum<'a> {
let one = Self::get_number_literal_expression(1.0, ctx); let one = Self::get_number_literal_expression(1.0, ctx);
ast.expression_binary(SPAN, one, BinaryOperator::Addition, self_ref) ast.expression_binary(SPAN, one, BinaryOperator::Addition, self_ref)
} else { } else {
previous_enum_members.insert(*member_name, Some(ConstantValue::Number(0.0))); previous_enum_members.insert(member_name, Some(ConstantValue::Number(0.0)));
Self::get_number_literal_expression(0.0, ctx) Self::get_number_literal_expression(0.0, ctx)
}; };
@ -284,7 +284,7 @@ impl<'a> TypeScriptEnum<'a> {
ast.expression_assignment(SPAN, AssignmentOperator::Assign, left.into(), right); ast.expression_assignment(SPAN, AssignmentOperator::Assign, left.into(), right);
} }
prev_member_name = Some(*member_name); prev_member_name = Some(member_name);
statements.push(ast.statement_expression(member.span, expr)); statements.push(ast.statement_expression(member.span, expr));
} }