@@ -158,29 +158,34 @@ pub fn ast_node(
158158 let mut item = TokenStream :: new ( ) ;
159159 match input. data {
160160 Data :: Enum ( ..) => {
161- struct EnumArgs {
162- clone : bool ,
163- }
164- impl parse:: Parse for EnumArgs {
165- fn parse ( i : parse:: ParseStream < ' _ > ) -> syn:: Result < Self > {
166- let name: Ident = i. parse ( ) ?;
167- if name != "no_clone" {
168- return Err ( i. error ( "unknown attribute" ) ) ;
169- }
170- Ok ( EnumArgs { clone : false } )
161+ use syn:: parse:: Parser ;
162+
163+ let attrs = <syn:: punctuated:: Punctuated < syn:: Ident , syn:: Token ![ , ] > >:: parse_terminated
164+ . parse ( args)
165+ . expect ( "failed to parse #[ast_node]" ) ;
166+
167+ let mut has_no_clone = false ;
168+ let mut has_no_unknown = false ;
169+ for attr in & attrs {
170+ if attr == "no_clone" {
171+ has_no_clone = true ;
172+ } else if attr == "no_unknown" {
173+ has_no_unknown = true ;
174+ } else {
175+ panic ! ( "unknown attribute: {attr:?}" )
171176 }
172177 }
173- let args = if args. is_empty ( ) {
174- EnumArgs { clone : true }
175- } else {
176- parse ( args) . expect ( "failed to parse args of #[ast_node]" )
177- } ;
178178
179- let clone = if args . clone {
179+ let clone = if !has_no_clone {
180180 Some ( quote ! ( #[ derive( Clone ) ] ) )
181181 } else {
182182 None
183183 } ;
184+ let non_exhaustive = if !has_no_unknown {
185+ Some ( quote ! ( #[ non_exhaustive] ) )
186+ } else {
187+ None
188+ } ;
184189
185190 item. extend ( quote ! (
186191 #[ allow( clippy:: derive_partial_eq_without_eq) ]
@@ -198,6 +203,7 @@ pub fn ast_node(
198203 :: swc_common:: DeserializeEnum ,
199204 ) ]
200205 #clone
206+ #non_exhaustive
201207 #[ cfg_attr(
202208 feature = "rkyv-impl" ,
203209 derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize )
0 commit comments