mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
perf(transformer): React display name transform reduce Atom allocations (#3616)
Re-use existing `Atom`s in React Display Name transform rather than writing duplicate strings into the arena. Also add comments for where our implementation diverges from Babel's (in my opinion, ours is an improvement).
This commit is contained in:
parent
8d237c49a9
commit
3a59294c72
2 changed files with 31 additions and 21 deletions
|
|
@ -810,17 +810,9 @@ impl<'a> MemberExpression<'a> {
|
|||
|
||||
pub fn static_property_name(&self) -> Option<&str> {
|
||||
match self {
|
||||
MemberExpression::ComputedMemberExpression(expr) => match &expr.expression {
|
||||
Expression::StringLiteral(lit) => Some(&lit.value),
|
||||
Expression::TemplateLiteral(lit) => {
|
||||
if lit.expressions.is_empty() && lit.quasis.len() == 1 {
|
||||
Some(&lit.quasis[0].value.raw)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
MemberExpression::ComputedMemberExpression(expr) => {
|
||||
expr.static_property_name().map(|name| name.as_str())
|
||||
}
|
||||
MemberExpression::StaticMemberExpression(expr) => Some(expr.property.name.as_str()),
|
||||
MemberExpression::PrivateFieldExpression(_) => None,
|
||||
}
|
||||
|
|
@ -883,6 +875,20 @@ pub struct ComputedMemberExpression<'a> {
|
|||
pub optional: bool, // for optional chaining
|
||||
}
|
||||
|
||||
impl<'a> ComputedMemberExpression<'a> {
|
||||
pub fn static_property_name(&self) -> Option<Atom<'a>> {
|
||||
match &self.expression {
|
||||
Expression::StringLiteral(lit) => Some(lit.value.clone()),
|
||||
Expression::TemplateLiteral(lit)
|
||||
if lit.expressions.is_empty() && lit.quasis.len() == 1 =>
|
||||
{
|
||||
Some(lit.quasis[0].value.raw.clone())
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `MemberExpression[?Yield, ?Await] . IdentifierName`
|
||||
#[visited_node]
|
||||
#[derive(Debug, Hash)]
|
||||
|
|
|
|||
|
|
@ -37,21 +37,22 @@ impl<'a> ReactDisplayName<'a> {
|
|||
let name = ctx.find_ancestor(|ancestor| {
|
||||
match ancestor {
|
||||
// `foo = React.createClass({})`
|
||||
Ancestor::AssignmentExpressionRight(assign_expr) => match &assign_expr.left() {
|
||||
Ancestor::AssignmentExpressionRight(assign_expr) => match assign_expr.left() {
|
||||
AssignmentTarget::AssignmentTargetIdentifier(ident) => {
|
||||
FinderRet::Found(ident.name.clone())
|
||||
}
|
||||
target => {
|
||||
if let Some(target) = target.as_member_expression() {
|
||||
if let Some(name) = target.static_property_name() {
|
||||
FinderRet::Found(ctx.ast.new_atom(name))
|
||||
} else {
|
||||
FinderRet::Stop
|
||||
}
|
||||
} else {
|
||||
FinderRet::Stop
|
||||
AssignmentTarget::StaticMemberExpression(expr) => {
|
||||
FinderRet::Found(expr.property.name.clone())
|
||||
}
|
||||
// Babel does not handle computed member expressions e.g. `foo["bar"]`,
|
||||
// so we diverge from Babel here, but that's probably an improvement
|
||||
AssignmentTarget::ComputedMemberExpression(expr) => {
|
||||
match expr.static_property_name() {
|
||||
Some(name) => FinderRet::Found(name),
|
||||
None => FinderRet::Stop,
|
||||
}
|
||||
}
|
||||
_ => FinderRet::Stop,
|
||||
},
|
||||
// `let foo = React.createClass({})`
|
||||
Ancestor::VariableDeclaratorInit(declarator) => match &declarator.id().kind {
|
||||
|
|
@ -62,6 +63,9 @@ impl<'a> ReactDisplayName<'a> {
|
|||
},
|
||||
// `{foo: React.createClass({})}`
|
||||
Ancestor::ObjectPropertyValue(prop) => {
|
||||
// Babel only handles static identifiers e.g. `{foo: React.createClass({})}`,
|
||||
// whereas we also handle e.g. `{"foo-bar": React.createClass({})}`,
|
||||
// so we diverge from Babel here, but that's probably an improvement
|
||||
if let Some(name) = prop.key().static_name() {
|
||||
FinderRet::Found(ctx.ast.new_atom(&name))
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in a new issue