refactor(ast, ast_codegen): CloneIn implementations now initialize semantic related cells with Default value. (#4819)

closes #4809
This commit is contained in:
rzvxa 2024-08-11 19:10:56 +00:00
parent 74af8e230a
commit 0ea697b4e9
8 changed files with 103 additions and 26 deletions

View file

@ -44,6 +44,7 @@ pub struct Program<'a> {
pub hashbang: Option<Hashbang<'a>>, pub hashbang: Option<Hashbang<'a>>,
pub directives: Vec<'a, Directive<'a>>, pub directives: Vec<'a, Directive<'a>>,
pub body: Vec<'a, Statement<'a>>, pub body: Vec<'a, Statement<'a>>,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -235,12 +236,14 @@ pub struct IdentifierReference<'a> {
/// set in the bind step of semantic analysis, and will always be [`None`] /// set in the bind step of semantic analysis, and will always be [`None`]
/// immediately after parsing. /// immediately after parsing.
#[serde(skip)] #[serde(skip)]
#[clone_in(default)]
pub reference_id: Cell<Option<ReferenceId>>, pub reference_id: Cell<Option<ReferenceId>>,
/// Flags indicating how the reference is used. /// Flags indicating how the reference is used.
/// ///
/// This gets set in the bind step of semantic analysis, and will always be /// This gets set in the bind step of semantic analysis, and will always be
/// [`ReferenceFlag::None`] immediately after parsing. /// [`ReferenceFlag::None`] immediately after parsing.
#[serde(skip)] #[serde(skip)]
#[clone_in(default)]
pub reference_flag: ReferenceFlag, pub reference_flag: ReferenceFlag,
} }
@ -266,6 +269,7 @@ pub struct BindingIdentifier<'a> {
/// ///
/// [`semantic analysis`]: <https://docs.rs/oxc_semantic/latest/oxc_semantic/struct.SemanticBuilder.html> /// [`semantic analysis`]: <https://docs.rs/oxc_semantic/latest/oxc_semantic/struct.SemanticBuilder.html>
#[serde(skip)] #[serde(skip)]
#[clone_in(default)]
pub symbol_id: Cell<Option<SymbolId>>, pub symbol_id: Cell<Option<SymbolId>>,
} }
@ -1183,6 +1187,7 @@ pub struct BlockStatement<'a> {
#[serde(flatten)] #[serde(flatten)]
pub span: Span, pub span: Span,
pub body: Vec<'a, Statement<'a>>, pub body: Vec<'a, Statement<'a>>,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -1357,6 +1362,7 @@ pub struct ForStatement<'a> {
pub test: Option<Expression<'a>>, pub test: Option<Expression<'a>>,
pub update: Option<Expression<'a>>, pub update: Option<Expression<'a>>,
pub body: Statement<'a>, pub body: Statement<'a>,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -1392,6 +1398,7 @@ pub struct ForInStatement<'a> {
pub left: ForStatementLeft<'a>, pub left: ForStatementLeft<'a>,
pub right: Expression<'a>, pub right: Expression<'a>,
pub body: Statement<'a>, pub body: Statement<'a>,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -1427,6 +1434,7 @@ pub struct ForOfStatement<'a> {
pub left: ForStatementLeft<'a>, pub left: ForStatementLeft<'a>,
pub right: Expression<'a>, pub right: Expression<'a>,
pub body: Statement<'a>, pub body: Statement<'a>,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -1492,6 +1500,7 @@ pub struct SwitchStatement<'a> {
pub discriminant: Expression<'a>, pub discriminant: Expression<'a>,
#[scope(enter_before)] #[scope(enter_before)]
pub cases: Vec<'a, SwitchCase<'a>>, pub cases: Vec<'a, SwitchCase<'a>>,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -1558,6 +1567,7 @@ pub struct CatchClause<'a> {
pub span: Span, pub span: Span,
pub param: Option<CatchParameter<'a>>, pub param: Option<CatchParameter<'a>>,
pub body: Box<'a, BlockStatement<'a>>, pub body: Box<'a, BlockStatement<'a>>,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -1725,6 +1735,7 @@ pub struct Function<'a> {
pub params: Box<'a, FormalParameters<'a>>, pub params: Box<'a, FormalParameters<'a>>,
pub return_type: Option<Box<'a, TSTypeAnnotation<'a>>>, pub return_type: Option<Box<'a, TSTypeAnnotation<'a>>>,
pub body: Option<Box<'a, FunctionBody<'a>>>, pub body: Option<Box<'a, FunctionBody<'a>>>,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -1821,6 +1832,7 @@ pub struct ArrowFunctionExpression<'a> {
pub return_type: Option<Box<'a, TSTypeAnnotation<'a>>>, pub return_type: Option<Box<'a, TSTypeAnnotation<'a>>>,
/// See `expression` for whether this arrow expression returns an expression. /// See `expression` for whether this arrow expression returns an expression.
pub body: Box<'a, FunctionBody<'a>>, pub body: Box<'a, FunctionBody<'a>>,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -1907,6 +1919,7 @@ pub struct Class<'a> {
pub declare: bool, pub declare: bool,
/// Id of the scope created by the [`Class`], including type parameters and /// Id of the scope created by the [`Class`], including type parameters and
/// statements within the [`ClassBody`]. /// statements within the [`ClassBody`].
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -2163,6 +2176,7 @@ pub struct StaticBlock<'a> {
#[serde(flatten)] #[serde(flatten)]
pub span: Span, pub span: Span,
pub body: Vec<'a, Statement<'a>>, pub body: Vec<'a, Statement<'a>>,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }

View file

@ -76,6 +76,7 @@ pub struct TSEnumDeclaration<'a> {
pub members: Vec<'a, TSEnumMember<'a>>, pub members: Vec<'a, TSEnumMember<'a>>,
pub r#const: bool, pub r#const: bool,
pub declare: bool, pub declare: bool,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -313,6 +314,7 @@ pub struct TSConditionalType<'a> {
pub extends_type: TSType<'a>, pub extends_type: TSType<'a>,
pub true_type: TSType<'a>, pub true_type: TSType<'a>,
pub false_type: TSType<'a>, pub false_type: TSType<'a>,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -757,6 +759,7 @@ pub struct TSTypeAliasDeclaration<'a> {
pub type_parameters: Option<Box<'a, TSTypeParameterDeclaration<'a>>>, pub type_parameters: Option<Box<'a, TSTypeParameterDeclaration<'a>>>,
pub type_annotation: TSType<'a>, pub type_annotation: TSType<'a>,
pub declare: bool, pub declare: bool,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -802,6 +805,7 @@ pub struct TSInterfaceDeclaration<'a> {
pub type_parameters: Option<Box<'a, TSTypeParameterDeclaration<'a>>>, pub type_parameters: Option<Box<'a, TSTypeParameterDeclaration<'a>>>,
pub body: Box<'a, TSInterfaceBody<'a>>, pub body: Box<'a, TSInterfaceBody<'a>>,
pub declare: bool, pub declare: bool,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -910,6 +914,7 @@ pub struct TSMethodSignature<'a> {
pub params: Box<'a, FormalParameters<'a>>, pub params: Box<'a, FormalParameters<'a>>,
pub return_type: Option<Box<'a, TSTypeAnnotation<'a>>>, pub return_type: Option<Box<'a, TSTypeAnnotation<'a>>>,
pub type_parameters: Option<Box<'a, TSTypeParameterDeclaration<'a>>>, pub type_parameters: Option<Box<'a, TSTypeParameterDeclaration<'a>>>,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -925,6 +930,7 @@ pub struct TSConstructSignatureDeclaration<'a> {
pub params: Box<'a, FormalParameters<'a>>, pub params: Box<'a, FormalParameters<'a>>,
pub return_type: Option<Box<'a, TSTypeAnnotation<'a>>>, pub return_type: Option<Box<'a, TSTypeAnnotation<'a>>>,
pub type_parameters: Option<Box<'a, TSTypeParameterDeclaration<'a>>>, pub type_parameters: Option<Box<'a, TSTypeParameterDeclaration<'a>>>,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -1001,6 +1007,7 @@ pub struct TSModuleDeclaration<'a> {
/// ``` /// ```
pub kind: TSModuleDeclarationKind, pub kind: TSModuleDeclarationKind,
pub declare: bool, pub declare: bool,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }
@ -1198,6 +1205,7 @@ pub struct TSMappedType<'a> {
pub type_annotation: Option<TSType<'a>>, pub type_annotation: Option<TSType<'a>>,
pub optional: TSMappedTypeModifierOperator, pub optional: TSMappedTypeModifierOperator,
pub readonly: TSMappedTypeModifierOperator, pub readonly: TSMappedTypeModifierOperator,
#[clone_in(default)]
pub scope_id: Cell<Option<ScopeId>>, pub scope_id: Cell<Option<ScopeId>>,
} }

View file

@ -1,6 +1,7 @@
// Auto-generated code, DO NOT EDIT DIRECTLY! // Auto-generated code, DO NOT EDIT DIRECTLY!
// To edit this generated file you have to edit `tasks/ast_codegen/src/generators/derive_clone_in.rs` // To edit this generated file you have to edit `tasks/ast_codegen/src/generators/derive_clone_in.rs`
#![allow(clippy::default_trait_access)]
use oxc_allocator::{Allocator, CloneIn}; use oxc_allocator::{Allocator, CloneIn};
#[allow(clippy::wildcard_imports)] #[allow(clippy::wildcard_imports)]
@ -84,7 +85,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for Program<'old_alloc> {
hashbang: self.hashbang.clone_in(alloc), hashbang: self.hashbang.clone_in(alloc),
directives: self.directives.clone_in(alloc), directives: self.directives.clone_in(alloc),
body: self.body.clone_in(alloc), body: self.body.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -170,8 +171,8 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for IdentifierReference<'old_al
IdentifierReference { IdentifierReference {
span: self.span.clone_in(alloc), span: self.span.clone_in(alloc),
name: self.name.clone_in(alloc), name: self.name.clone_in(alloc),
reference_id: self.reference_id.clone_in(alloc), reference_id: Default::default(),
reference_flag: self.reference_flag.clone_in(alloc), reference_flag: Default::default(),
} }
} }
} }
@ -182,7 +183,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for BindingIdentifier<'old_allo
BindingIdentifier { BindingIdentifier {
span: self.span.clone_in(alloc), span: self.span.clone_in(alloc),
name: self.name.clone_in(alloc), name: self.name.clone_in(alloc),
symbol_id: self.symbol_id.clone_in(alloc), symbol_id: Default::default(),
} }
} }
} }
@ -1077,7 +1078,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for BlockStatement<'old_alloc>
BlockStatement { BlockStatement {
span: self.span.clone_in(alloc), span: self.span.clone_in(alloc),
body: self.body.clone_in(alloc), body: self.body.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -1212,7 +1213,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for ForStatement<'old_alloc> {
test: self.test.clone_in(alloc), test: self.test.clone_in(alloc),
update: self.update.clone_in(alloc), update: self.update.clone_in(alloc),
body: self.body.clone_in(alloc), body: self.body.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -1307,7 +1308,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for ForInStatement<'old_alloc>
left: self.left.clone_in(alloc), left: self.left.clone_in(alloc),
right: self.right.clone_in(alloc), right: self.right.clone_in(alloc),
body: self.body.clone_in(alloc), body: self.body.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -1362,7 +1363,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for ForOfStatement<'old_alloc>
left: self.left.clone_in(alloc), left: self.left.clone_in(alloc),
right: self.right.clone_in(alloc), right: self.right.clone_in(alloc),
body: self.body.clone_in(alloc), body: self.body.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -1406,7 +1407,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for SwitchStatement<'old_alloc>
span: self.span.clone_in(alloc), span: self.span.clone_in(alloc),
discriminant: self.discriminant.clone_in(alloc), discriminant: self.discriminant.clone_in(alloc),
cases: self.cases.clone_in(alloc), cases: self.cases.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -1459,7 +1460,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for CatchClause<'old_alloc> {
span: self.span.clone_in(alloc), span: self.span.clone_in(alloc),
param: self.param.clone_in(alloc), param: self.param.clone_in(alloc),
body: self.body.clone_in(alloc), body: self.body.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -1576,7 +1577,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for Function<'old_alloc> {
params: self.params.clone_in(alloc), params: self.params.clone_in(alloc),
return_type: self.return_type.clone_in(alloc), return_type: self.return_type.clone_in(alloc),
body: self.body.clone_in(alloc), body: self.body.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -1653,7 +1654,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for ArrowFunctionExpression<'ol
params: self.params.clone_in(alloc), params: self.params.clone_in(alloc),
return_type: self.return_type.clone_in(alloc), return_type: self.return_type.clone_in(alloc),
body: self.body.clone_in(alloc), body: self.body.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -1684,7 +1685,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for Class<'old_alloc> {
body: self.body.clone_in(alloc), body: self.body.clone_in(alloc),
r#abstract: self.r#abstract.clone_in(alloc), r#abstract: self.r#abstract.clone_in(alloc),
declare: self.declare.clone_in(alloc), declare: self.declare.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -1807,7 +1808,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for StaticBlock<'old_alloc> {
StaticBlock { StaticBlock {
span: self.span.clone_in(alloc), span: self.span.clone_in(alloc),
body: self.body.clone_in(alloc), body: self.body.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -2182,7 +2183,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for TSEnumDeclaration<'old_allo
members: self.members.clone_in(alloc), members: self.members.clone_in(alloc),
r#const: self.r#const.clone_in(alloc), r#const: self.r#const.clone_in(alloc),
declare: self.declare.clone_in(alloc), declare: self.declare.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -2374,7 +2375,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for TSConditionalType<'old_allo
extends_type: self.extends_type.clone_in(alloc), extends_type: self.extends_type.clone_in(alloc),
true_type: self.true_type.clone_in(alloc), true_type: self.true_type.clone_in(alloc),
false_type: self.false_type.clone_in(alloc), false_type: self.false_type.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -2718,7 +2719,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for TSTypeAliasDeclaration<'old
type_parameters: self.type_parameters.clone_in(alloc), type_parameters: self.type_parameters.clone_in(alloc),
type_annotation: self.type_annotation.clone_in(alloc), type_annotation: self.type_annotation.clone_in(alloc),
declare: self.declare.clone_in(alloc), declare: self.declare.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -2755,7 +2756,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for TSInterfaceDeclaration<'old
type_parameters: self.type_parameters.clone_in(alloc), type_parameters: self.type_parameters.clone_in(alloc),
body: self.body.clone_in(alloc), body: self.body.clone_in(alloc),
declare: self.declare.clone_in(alloc), declare: self.declare.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -2847,7 +2848,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for TSMethodSignature<'old_allo
params: self.params.clone_in(alloc), params: self.params.clone_in(alloc),
return_type: self.return_type.clone_in(alloc), return_type: self.return_type.clone_in(alloc),
type_parameters: self.type_parameters.clone_in(alloc), type_parameters: self.type_parameters.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -2860,7 +2861,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for TSConstructSignatureDeclara
params: self.params.clone_in(alloc), params: self.params.clone_in(alloc),
return_type: self.return_type.clone_in(alloc), return_type: self.return_type.clone_in(alloc),
type_parameters: self.type_parameters.clone_in(alloc), type_parameters: self.type_parameters.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -2918,7 +2919,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for TSModuleDeclaration<'old_al
body: self.body.clone_in(alloc), body: self.body.clone_in(alloc),
kind: self.kind.clone_in(alloc), kind: self.kind.clone_in(alloc),
declare: self.declare.clone_in(alloc), declare: self.declare.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }
@ -3090,7 +3091,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for TSMappedType<'old_alloc> {
type_annotation: self.type_annotation.clone_in(alloc), type_annotation: self.type_annotation.clone_in(alloc),
optional: self.optional.clone_in(alloc), optional: self.optional.clone_in(alloc),
readonly: self.readonly.clone_in(alloc), readonly: self.readonly.clone_in(alloc),
scope_id: self.scope_id.clone_in(alloc), scope_id: Default::default(),
} }
} }
} }

View file

@ -106,7 +106,7 @@ pub fn ast(_args: TokenStream, input: TokenStream) -> TokenStream {
/// Does not generate any code. /// Does not generate any code.
/// Only purpose is to allow using `#[scope]`, `#[visit]`, and other attrs in the AST node type defs. /// Only purpose is to allow using `#[scope]`, `#[visit]`, and other attrs in the AST node type defs.
/// These "marker" attributes are used in codegen. /// These "marker" attributes are used in codegen.
#[proc_macro_derive(Ast, attributes(scope, visit, span, serde, tsify, generate_derive))] #[proc_macro_derive(Ast, attributes(scope, visit, span, serde, tsify, generate_derive, clone_in))]
pub fn ast_derive(_item: TokenStream) -> TokenStream { pub fn ast_derive(_item: TokenStream) -> TokenStream {
TokenStream::new() TokenStream::new()
} }

View file

@ -5,6 +5,7 @@ use syn::Ident;
use crate::{ use crate::{
codegen::LateCtx, codegen::LateCtx,
markers::CloneInAttribute,
output, output,
schema::{EnumDef, GetIdent, StructDef, TypeDef}, schema::{EnumDef, GetIdent, StructDef, TypeDef},
GeneratorOutput, GeneratorOutput,
@ -35,6 +36,8 @@ impl Generator for DeriveCloneIn {
quote! { quote! {
#header #header
#![allow(clippy::default_trait_access)]
use oxc_allocator::{Allocator, CloneIn}; use oxc_allocator::{Allocator, CloneIn};
///@@line_break ///@@line_break
@ -83,7 +86,10 @@ fn derive_struct(def: &StructDef) -> TokenStream {
} else { } else {
let fields = def.fields.iter().map(|field| { let fields = def.fields.iter().map(|field| {
let ident = field.ident(); let ident = field.ident();
quote!(#ident: self.#ident.clone_in(alloc)) match field.markers.derive_attributes.clone_in {
CloneInAttribute::Default => quote!(#ident: Default::default()),
CloneInAttribute::None => quote!(#ident: self.#ident.clone_in(alloc)),
}
}); });
(format_ident!("alloc"), quote!(#ty_ident { #(#fields),* })) (format_ident!("alloc"), quote!(#ty_ident { #(#fields),* }))
}; };

View file

@ -1,4 +1,5 @@
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use serde::Serialize;
use syn::{ use syn::{
ext::IdentExt, ext::IdentExt,
parenthesized, parenthesized,
@ -65,6 +66,30 @@ pub struct ScopeMarkers {
pub enter_before: bool, pub enter_before: bool,
} }
/// A struct representing the `#[scope(...)]` attribute.
#[derive(Debug, Default, Serialize)]
pub struct DeriveAttributes {
pub clone_in: CloneInAttribute,
}
/// A enum representing the value passed in `#[clone_in(...)]` derive attribute.
#[derive(Debug, Default, Serialize)]
pub enum CloneInAttribute {
#[default]
None,
Default,
}
impl From<&Ident> for CloneInAttribute {
fn from(ident: &Ident) -> Self {
if ident == "default" {
Self::Default
} else {
panic!("Invalid argument used in `#[clone_in(...)]` attribute.");
}
}
}
/// A struct representing the `#[scope(...)]` attribute. /// A struct representing the `#[scope(...)]` attribute.
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct ScopeAttribute { pub struct ScopeAttribute {
@ -186,6 +211,27 @@ where
) )
} }
pub fn get_derive_attributes<'a, I>(attrs: I) -> crate::Result<DeriveAttributes>
where
I: IntoIterator<Item = &'a Attribute>,
{
fn try_parse_clone_in(attr: &Attribute) -> crate::Result<Option<CloneInAttribute>> {
if attr.path().is_ident("clone_in") {
let arg = attr.parse_args_with(Ident::parse).normalize()?;
Ok(Some(CloneInAttribute::from(&arg)))
} else {
Ok(None)
}
}
let mut clone_in = None;
for attr in attrs {
if let Some(attr) = try_parse_clone_in(attr)? {
assert!(clone_in.replace(attr).is_none(), "Duplicate `#[clone_in(...)]` attribute.");
}
}
Ok(DeriveAttributes { clone_in: clone_in.unwrap_or_default() })
}
pub fn get_scope_attribute<'a, I>(attrs: I) -> Option<crate::Result<ScopeAttribute>> pub fn get_scope_attribute<'a, I>(attrs: I) -> Option<crate::Result<ScopeAttribute>>
where where
I: IntoIterator<Item = &'a Attribute>, I: IntoIterator<Item = &'a Attribute>,

View file

@ -1,7 +1,7 @@
use serde::Serialize; use serde::Serialize;
use crate::{ use crate::{
markers::{ScopeAttribute, ScopeMarkers, VisitMarkers}, markers::{DeriveAttributes, ScopeAttribute, ScopeMarkers, VisitMarkers},
util::{ToIdent, TypeAnalysis, TypeWrapper}, util::{ToIdent, TypeAnalysis, TypeWrapper},
TypeId, TypeId,
}; };
@ -227,6 +227,7 @@ pub struct OuterMarkers {
pub struct InnerMarkers { pub struct InnerMarkers {
/// marker that hints to fold span in here /// marker that hints to fold span in here
pub span: bool, pub span: bool,
pub derive_attributes: DeriveAttributes,
#[serde(skip)] #[serde(skip)]
pub visit: VisitMarkers, pub visit: VisitMarkers,
#[serde(skip)] #[serde(skip)]

View file

@ -4,7 +4,7 @@ use serde::Serialize;
use crate::{ use crate::{
codegen, codegen,
layout::KnownLayout, layout::KnownLayout,
markers::{get_scope_attribute, get_scope_markers, get_visit_markers}, markers::{get_derive_attributes, get_scope_attribute, get_scope_markers, get_visit_markers},
rust_ast as rust, rust_ast as rust,
util::{unexpanded_macro_err, TypeExt}, util::{unexpanded_macro_err, TypeExt},
Result, TypeId, Result, TypeId,
@ -111,6 +111,7 @@ fn parse_inner_markers(attrs: &Vec<syn::Attribute>) -> Result<InnerMarkers> {
span: attrs.iter().any(|a| a.path().is_ident("span")), span: attrs.iter().any(|a| a.path().is_ident("span")),
visit: get_visit_markers(attrs)?, visit: get_visit_markers(attrs)?,
scope: get_scope_markers(attrs)?, scope: get_scope_markers(attrs)?,
derive_attributes: get_derive_attributes(attrs)?,
}) })
} }