perf(es/ast): Implement Clone without inline for some enums (#3878)

This commit is contained in:
Philip Craig 2022-03-06 19:12:23 +10:00 committed by GitHub
parent 308d1b42ee
commit 3b04789a57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 154 additions and 8 deletions

View File

@ -171,20 +171,42 @@ pub fn ast_node(
let mut item = Quote::new(Span::call_site());
item = match input.data {
Data::Enum(..) => {
if !args.is_empty() {
panic!("#[ast_node] on enum does not accept any argument")
struct EnumArgs {
clone: bool,
}
impl parse::Parse for EnumArgs {
fn parse(i: parse::ParseStream<'_>) -> syn::Result<Self> {
let name: Ident = i.parse()?;
if name.to_string() != "no_clone" {
return Err(i.error("unknown attribute"));
}
Ok(EnumArgs { clone: false })
}
}
let args = if args.is_empty() {
EnumArgs { clone: true }
} else {
parse(args).expect("failed to parse args of #[ast_node]")
};
item.quote_with(smart_quote!(Vars { input }, {
let clone = if args.clone {
Some(Quote::new_call_site().quote_with(smart_quote!(Vars {}, {
#[derive(Clone)]
})))
} else {
None
};
item.quote_with(smart_quote!(Vars { input, clone }, {
#[derive(
::swc_common::FromVariant,
::swc_common::Spanned,
Clone,
Debug,
PartialEq,
::serde::Serialize,
::swc_common::DeserializeEnum,
)]
clone
#[cfg_attr(
feature = "rkyv",
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)

View File

@ -21,7 +21,7 @@ use crate::{
ComputedPropName, Id, Invalid,
};
#[ast_node]
#[ast_node(no_clone)]
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum Expr {
@ -160,6 +160,53 @@ pub enum Expr {
Invalid(Invalid),
}
// Implement Clone without inline to avoid multiple copies of the
// implementation.
impl Clone for Expr {
fn clone(&self) -> Self {
use Expr::*;
match self {
This(e) => This(e.clone()),
Array(e) => Array(e.clone()),
Object(e) => Object(e.clone()),
Fn(e) => Fn(e.clone()),
Unary(e) => Unary(e.clone()),
Update(e) => Update(e.clone()),
Bin(e) => Bin(e.clone()),
Assign(e) => Assign(e.clone()),
Member(e) => Member(e.clone()),
SuperProp(e) => SuperProp(e.clone()),
Cond(e) => Cond(e.clone()),
Call(e) => Call(e.clone()),
New(e) => New(e.clone()),
Seq(e) => Seq(e.clone()),
Ident(e) => Ident(e.clone()),
Lit(e) => Lit(e.clone()),
Tpl(e) => Tpl(e.clone()),
TaggedTpl(e) => TaggedTpl(e.clone()),
Arrow(e) => Arrow(e.clone()),
Class(e) => Class(e.clone()),
Yield(e) => Yield(e.clone()),
MetaProp(e) => MetaProp(e.clone()),
Await(e) => Await(e.clone()),
Paren(e) => Paren(e.clone()),
JSXMember(e) => JSXMember(e.clone()),
JSXNamespacedName(e) => JSXNamespacedName(e.clone()),
JSXEmpty(e) => JSXEmpty(e.clone()),
JSXElement(e) => JSXElement(e.clone()),
JSXFragment(e) => JSXFragment(e.clone()),
TsTypeAssertion(e) => TsTypeAssertion(e.clone()),
TsConstAssertion(e) => TsConstAssertion(e.clone()),
TsNonNull(e) => TsNonNull(e.clone()),
TsAs(e) => TsAs(e.clone()),
TsInstantiation(e) => TsInstantiation(e.clone()),
PrivateName(e) => PrivateName(e.clone()),
OptChain(e) => OptChain(e.clone()),
Invalid(e) => Invalid(e.clone()),
}
}
}
impl Take for Expr {
fn dummy() -> Self {
Expr::Invalid(Invalid { span: DUMMY_SP })

View File

@ -6,6 +6,7 @@
#![deny(unreachable_pub)]
#![deny(clippy::all)]
#![allow(clippy::enum_variant_names)]
#![allow(clippy::clone_on_copy)]
// #![deny(variant_size_differences)]

View File

@ -9,7 +9,7 @@ use crate::{
Invalid,
};
#[ast_node]
#[ast_node(no_clone)]
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum Pat {
@ -36,6 +36,23 @@ pub enum Pat {
Expr(Box<Expr>),
}
// Implement Clone without inline to avoid multiple copies of the
// implementation.
impl Clone for Pat {
fn clone(&self) -> Self {
use Pat::*;
match self {
Ident(p) => Ident(p.clone()),
Array(p) => Array(p.clone()),
Rest(p) => Rest(p.clone()),
Object(p) => Object(p.clone()),
Assign(p) => Assign(p.clone()),
Invalid(p) => Invalid(p.clone()),
Expr(p) => Expr(p.clone()),
}
}
}
impl Take for Pat {
fn dummy() -> Self {
Pat::Invalid(Invalid { span: DUMMY_SP })

View File

@ -28,7 +28,7 @@ impl Take for BlockStmt {
}
}
#[ast_node]
#[ast_node(no_clone)]
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum Stmt {
@ -104,6 +104,35 @@ pub enum Stmt {
Expr(ExprStmt),
}
// Implement Clone without inline to avoid multiple copies of the
// implementation.
impl Clone for Stmt {
fn clone(&self) -> Self {
use Stmt::*;
match self {
Block(s) => Block(s.clone()),
Empty(s) => Empty(s.clone()),
Debugger(s) => Debugger(s.clone()),
With(s) => With(s.clone()),
Return(s) => Return(s.clone()),
Labeled(s) => Labeled(s.clone()),
Break(s) => Break(s.clone()),
Continue(s) => Continue(s.clone()),
If(s) => If(s.clone()),
Switch(s) => Switch(s.clone()),
Throw(s) => Throw(s.clone()),
Try(s) => Try(s.clone()),
While(s) => While(s.clone()),
DoWhile(s) => DoWhile(s.clone()),
For(s) => For(s.clone()),
ForIn(s) => ForIn(s.clone()),
ForOf(s) => ForOf(s.clone()),
Decl(s) => Decl(s.clone()),
Expr(s) => Expr(s.clone()),
}
}
}
impl Take for Stmt {
fn dummy() -> Self {
Self::Empty(EmptyStmt { span: DUMMY_SP })

View File

@ -241,7 +241,7 @@ pub struct TsIndexSignature {
// TypeScript types
// ================
#[ast_node]
#[ast_node(no_clone)]
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum TsType {
@ -308,6 +308,36 @@ pub enum TsType {
TsImportType(TsImportType),
}
// Implement Clone without inline to avoid multiple copies of the
// implementation.
impl Clone for TsType {
fn clone(&self) -> Self {
use TsType::*;
match self {
TsKeywordType(t) => TsKeywordType(t.clone()),
TsThisType(t) => TsThisType(t.clone()),
TsFnOrConstructorType(t) => TsFnOrConstructorType(t.clone()),
TsTypeRef(t) => TsTypeRef(t.clone()),
TsTypeQuery(t) => TsTypeQuery(t.clone()),
TsTypeLit(t) => TsTypeLit(t.clone()),
TsArrayType(t) => TsArrayType(t.clone()),
TsTupleType(t) => TsTupleType(t.clone()),
TsOptionalType(t) => TsOptionalType(t.clone()),
TsRestType(t) => TsRestType(t.clone()),
TsUnionOrIntersectionType(t) => TsUnionOrIntersectionType(t.clone()),
TsConditionalType(t) => TsConditionalType(t.clone()),
TsInferType(t) => TsInferType(t.clone()),
TsParenthesizedType(t) => TsParenthesizedType(t.clone()),
TsTypeOperator(t) => TsTypeOperator(t.clone()),
TsIndexedAccessType(t) => TsIndexedAccessType(t.clone()),
TsMappedType(t) => TsMappedType(t.clone()),
TsLitType(t) => TsLitType(t.clone()),
TsTypePredicate(t) => TsTypePredicate(t.clone()),
TsImportType(t) => TsImportType(t.clone()),
}
}
}
#[ast_node]
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]