@@ -114,7 +114,9 @@ fn node_src_to_schema_class(
114114 let ( ty, child) = match & f. ty {
115115 FieldType :: String => ( "optional[string]" . to_string ( ) , false ) ,
116116 FieldType :: Predicate => ( "predicate" . to_string ( ) , false ) ,
117- FieldType :: Optional ( ty) => ( format ! ( "optional[\" {}\" ]" , class_name( ty) ) , true ) ,
117+ FieldType :: Optional ( ty) | FieldType :: Body ( ty) => {
118+ ( format ! ( "optional[\" {}\" ]" , class_name( ty) ) , true )
119+ }
118120 FieldType :: List ( ty) => ( format ! ( "list[\" {}\" ]" , class_name( ty) ) , true ) ,
119121 } ;
120122 SchemaField {
@@ -169,6 +171,7 @@ enum FieldType {
169171 String ,
170172 Predicate ,
171173 Optional ( String ) ,
174+ Body ( String ) ,
172175 List ( String ) ,
173176}
174177
@@ -177,158 +180,95 @@ struct FieldInfo {
177180 ty : FieldType ,
178181}
179182
183+ impl FieldInfo {
184+ pub fn optional ( name : & str , ty : & str ) -> FieldInfo {
185+ FieldInfo {
186+ name : name. to_string ( ) ,
187+ ty : FieldType :: Optional ( ty. to_string ( ) ) ,
188+ }
189+ }
190+
191+ pub fn body ( name : & str , ty : & str ) -> FieldInfo {
192+ FieldInfo {
193+ name : name. to_string ( ) ,
194+ ty : FieldType :: Body ( ty. to_string ( ) ) ,
195+ }
196+ }
197+
198+ pub fn string ( name : & str ) -> FieldInfo {
199+ FieldInfo {
200+ name : name. to_string ( ) ,
201+ ty : FieldType :: String ,
202+ }
203+ }
204+
205+ pub fn predicate ( name : & str ) -> FieldInfo {
206+ FieldInfo {
207+ name : name. to_string ( ) ,
208+ ty : FieldType :: Predicate ,
209+ }
210+ }
211+
212+ pub fn list ( name : & str , ty : & str ) -> FieldInfo {
213+ FieldInfo {
214+ name : name. to_string ( ) ,
215+ ty : FieldType :: List ( ty. to_string ( ) ) ,
216+ }
217+ }
218+ }
219+
180220fn get_additional_fields ( node : & AstNodeSrc ) -> Vec < FieldInfo > {
181221 match node. name . as_str ( ) {
182- "Name" | "NameRef" | "Lifetime" => vec ! [ FieldInfo {
183- name: "text" . to_string( ) ,
184- ty: FieldType :: String ,
185- } ] ,
186- "Abi" => vec ! [ FieldInfo {
187- name: "abi_string" . to_string( ) ,
188- ty: FieldType :: String ,
189- } ] ,
190- "Literal" => vec ! [ FieldInfo {
191- name: "text_value" . to_string( ) ,
192- ty: FieldType :: String ,
193- } ] ,
194- "PrefixExpr" => vec ! [ FieldInfo {
195- name: "operator_name" . to_string( ) ,
196- ty: FieldType :: String ,
197- } ] ,
222+ "Name" | "NameRef" | "Lifetime" => vec ! [ FieldInfo :: string( "text" ) ] ,
223+ "Abi" => vec ! [ FieldInfo :: string( "abi_string" ) ] ,
224+ "Literal" => vec ! [ FieldInfo :: string( "text_value" ) ] ,
225+ "PrefixExpr" => vec ! [ FieldInfo :: string( "operator_name" ) ] ,
198226 "BinExpr" => vec ! [
199- FieldInfo {
200- name: "lhs" . to_string( ) ,
201- ty: FieldType :: Optional ( "Expr" . to_string( ) ) ,
202- } ,
203- FieldInfo {
204- name: "rhs" . to_string( ) ,
205- ty: FieldType :: Optional ( "Expr" . to_string( ) ) ,
206- } ,
207- FieldInfo {
208- name: "operator_name" . to_string( ) ,
209- ty: FieldType :: String ,
210- } ,
227+ FieldInfo :: optional( "lhs" , "Expr" ) ,
228+ FieldInfo :: optional( "rhs" , "Expr" ) ,
229+ FieldInfo :: string( "operator_name" ) ,
211230 ] ,
212231 "IfExpr" => vec ! [
213- FieldInfo {
214- name: "then_branch" . to_string( ) ,
215- ty: FieldType :: Optional ( "BlockExpr" . to_string( ) ) ,
216- } ,
217- FieldInfo {
218- name: "else_branch" . to_string( ) ,
219- ty: FieldType :: Optional ( "ElseBranch" . to_string( ) ) ,
220- } ,
221- FieldInfo {
222- name: "condition" . to_string( ) ,
223- ty: FieldType :: Optional ( "Expr" . to_string( ) ) ,
224- } ,
232+ FieldInfo :: optional( "then_branch" , "BlockExpr" ) ,
233+ FieldInfo :: optional( "else_branch" , "ElseBranch" ) ,
234+ FieldInfo :: optional( "condition" , "Expr" ) ,
225235 ] ,
226236 "RangeExpr" => vec ! [
227- FieldInfo {
228- name: "start" . to_string( ) ,
229- ty: FieldType :: Optional ( "Expr" . to_string( ) ) ,
230- } ,
231- FieldInfo {
232- name: "end" . to_string( ) ,
233- ty: FieldType :: Optional ( "Expr" . to_string( ) ) ,
234- } ,
235- FieldInfo {
236- name: "operator_name" . to_string( ) ,
237- ty: FieldType :: String ,
238- } ,
237+ FieldInfo :: optional( "start" , "Expr" ) ,
238+ FieldInfo :: optional( "end" , "Expr" ) ,
239+ FieldInfo :: string( "operator_name" ) ,
239240 ] ,
240241 "RangePat" => vec ! [
241- FieldInfo {
242- name: "start" . to_string( ) ,
243- ty: FieldType :: Optional ( "Pat" . to_string( ) ) ,
244- } ,
245- FieldInfo {
246- name: "end" . to_string( ) ,
247- ty: FieldType :: Optional ( "Pat" . to_string( ) ) ,
248- } ,
249- FieldInfo {
250- name: "operator_name" . to_string( ) ,
251- ty: FieldType :: String ,
252- } ,
242+ FieldInfo :: optional( "start" , "Pat" ) ,
243+ FieldInfo :: optional( "end" , "Pat" ) ,
244+ FieldInfo :: string( "operator_name" ) ,
253245 ] ,
254246 "IndexExpr" => vec ! [
255- FieldInfo {
256- name: "index" . to_string( ) ,
257- ty: FieldType :: Optional ( "Expr" . to_string( ) ) ,
258- } ,
259- FieldInfo {
260- name: "base" . to_string( ) ,
261- ty: FieldType :: Optional ( "Expr" . to_string( ) ) ,
262- } ,
247+ FieldInfo :: optional( "index" , "Expr" ) ,
248+ FieldInfo :: optional( "base" , "Expr" ) ,
263249 ] ,
264250 "Impl" => vec ! [
265- FieldInfo {
266- name: "trait_" . to_string( ) ,
267- ty: FieldType :: Optional ( "Type" . to_string( ) ) ,
268- } ,
269- FieldInfo {
270- name: "self_ty" . to_string( ) ,
271- ty: FieldType :: Optional ( "Type" . to_string( ) ) ,
272- } ,
251+ FieldInfo :: optional( "trait_" , "Type" ) ,
252+ FieldInfo :: optional( "self_ty" , "Type" ) ,
273253 ] ,
274- "ForExpr" => vec ! [ FieldInfo {
275- name: "iterable" . to_string( ) ,
276- ty: FieldType :: Optional ( "Expr" . to_string( ) ) ,
277- } ] ,
278- "WhileExpr" => vec ! [ FieldInfo {
279- name: "condition" . to_string( ) ,
280- ty: FieldType :: Optional ( "Expr" . to_string( ) ) ,
281- } ] ,
282- "MatchGuard" => vec ! [ FieldInfo {
283- name: "condition" . to_string( ) ,
284- ty: FieldType :: Optional ( "Expr" . to_string( ) ) ,
285- } ] ,
254+ "ForExpr" => vec ! [ FieldInfo :: optional( "iterable" , "Expr" ) ] ,
255+ "WhileExpr" => vec ! [ FieldInfo :: optional( "condition" , "Expr" ) ] ,
256+ "MatchGuard" => vec ! [ FieldInfo :: optional( "condition" , "Expr" ) ] ,
286257 "MacroDef" => vec ! [
287- FieldInfo {
288- name: "args" . to_string( ) ,
289- ty: FieldType :: Optional ( "TokenTree" . to_string( ) ) ,
290- } ,
291- FieldInfo {
292- name: "body" . to_string( ) ,
293- ty: FieldType :: Optional ( "TokenTree" . to_string( ) ) ,
294- } ,
258+ FieldInfo :: body( "args" , "TokenTree" ) ,
259+ FieldInfo :: body( "body" , "TokenTree" ) ,
295260 ] ,
296- "FormatArgsExpr" => vec ! [ FieldInfo {
297- name: "args" . to_string( ) ,
298- ty: FieldType :: List ( "FormatArgsArg" . to_string( ) ) ,
299- } ] ,
300- "ArgList" => vec ! [ FieldInfo {
301- name: "args" . to_string( ) ,
302- ty: FieldType :: List ( "Expr" . to_string( ) ) ,
303- } ] ,
304- "Fn" => vec ! [ FieldInfo {
305- name: "body" . to_string( ) ,
306- ty: FieldType :: Optional ( "BlockExpr" . to_string( ) ) ,
307- } ] ,
308- "Const" => vec ! [ FieldInfo {
309- name: "body" . to_string( ) ,
310- ty: FieldType :: Optional ( "Expr" . to_string( ) ) ,
311- } ] ,
312- "Static" => vec ! [ FieldInfo {
313- name: "body" . to_string( ) ,
314- ty: FieldType :: Optional ( "Expr" . to_string( ) ) ,
315- } ] ,
316- "ClosureExpr" => vec ! [ FieldInfo {
317- name: "body" . to_string( ) ,
318- ty: FieldType :: Optional ( "Expr" . to_string( ) ) ,
319- } ] ,
320- "ArrayExpr" => vec ! [ FieldInfo {
321- name: "is_semicolon" . to_string( ) ,
322- ty: FieldType :: Predicate ,
323- } ] ,
324- "SelfParam" => vec ! [ FieldInfo {
325- name: "is_amp" . to_string( ) ,
326- ty: FieldType :: Predicate ,
327- } ] ,
328- "UseTree" => vec ! [ FieldInfo {
329- name: "is_star" . to_string( ) ,
330- ty: FieldType :: Predicate ,
331- } ] ,
261+ "MacroCall" => vec ! [ FieldInfo :: body( "token_tree" , "TokenTree" ) ] ,
262+ "FormatArgsExpr" => vec ! [ FieldInfo :: list( "args" , "FormatArgsArg" ) ] ,
263+ "ArgList" => vec ! [ FieldInfo :: list( "args" , "Expr" ) ] ,
264+ "Fn" => vec ! [ FieldInfo :: body( "body" , "BlockExpr" ) ] ,
265+ "Const" => vec ! [ FieldInfo :: body( "body" , "Expr" ) ] ,
266+ "Static" => vec ! [ FieldInfo :: body( "body" , "Expr" ) ] ,
267+ "Param" => vec ! [ FieldInfo :: body( "pat" , "Pat" ) ] ,
268+ "ClosureExpr" => vec ! [ FieldInfo :: optional( "body" , "Expr" ) ] ,
269+ "ArrayExpr" => vec ! [ FieldInfo :: predicate( "is_semicolon" ) ] ,
270+ "SelfParam" => vec ! [ FieldInfo :: predicate( "is_amp" ) ] ,
271+ "UseTree" => vec ! [ FieldInfo :: predicate( "is_star" ) ] ,
332272 _ => vec ! [ ] ,
333273 }
334274}
@@ -352,9 +292,11 @@ fn get_fields(node: &AstNodeSrc) -> Vec<FieldInfo> {
352292 result. extend ( get_additional_fields ( node) ) ;
353293
354294 for field in & node. fields {
355- match ( node. name . as_str ( ) , field. method_name ( ) . as_str ( ) ) {
295+ let name = field. method_name ( ) ;
296+ match ( node. name . as_str ( ) , name. as_str ( ) ) {
356297 ( "ArrayExpr" , "expr" ) // The ArrayExpr type also has an 'exprs' field
357298 | ( "PathSegment" , "ty" | "path_type" ) // these are broken, handling them manually
299+ | ( "Param" , "pat" ) | ( "MacroCall" , "token_tree" ) // handled manually to use `body`
358300 => continue ,
359301 _ => { }
360302 }
@@ -367,61 +309,30 @@ fn get_fields(node: &AstNodeSrc) -> Vec<FieldInfo> {
367309 Cardinality :: Many => FieldType :: List ( ty. clone ( ) ) ,
368310 } ,
369311 } ;
370- result. push ( FieldInfo {
371- name : field. method_name ( ) ,
372- ty,
373- } ) ;
312+ result. push ( FieldInfo { name, ty } ) ;
374313 }
375314 for trait_ in & node. traits {
376315 match trait_. as_str ( ) {
377- "HasAttrs" => result. push ( FieldInfo {
378- name : "attrs" . to_owned ( ) ,
379- ty : FieldType :: List ( "Attr" . to_owned ( ) ) ,
380- } ) ,
381- "HasName" => result. push ( FieldInfo {
382- name : "name" . to_owned ( ) ,
383- ty : FieldType :: Optional ( "Name" . to_owned ( ) ) ,
384- } ) ,
385- "HasVisibility" => result. push ( FieldInfo {
386- name : "visibility" . to_owned ( ) ,
387- ty : FieldType :: Optional ( "Visibility" . to_owned ( ) ) ,
388- } ) ,
316+ "HasAttrs" => result. push ( FieldInfo :: list ( "attrs" , "Attr" ) ) ,
317+ "HasName" => result. push ( FieldInfo :: optional ( "name" , "Name" ) ) ,
318+ "HasVisibility" => result. push ( FieldInfo :: optional ( "visibility" , "Visibility" ) ) ,
389319 "HasGenericParams" => {
390- result. push ( FieldInfo {
391- name : "generic_param_list" . to_owned ( ) ,
392- ty : FieldType :: Optional ( "GenericParamList" . to_owned ( ) ) ,
393- } ) ;
394- result. push ( FieldInfo {
395- name : "where_clause" . to_owned ( ) ,
396- ty : FieldType :: Optional ( "WhereClause" . to_owned ( ) ) ,
397- } )
320+ result. push ( FieldInfo :: optional (
321+ "generic_param_list" ,
322+ "GenericParamList" ,
323+ ) ) ;
324+ result. push ( FieldInfo :: optional ( "where_clause" , "WhereClause" ) )
325+ }
326+ "HasGenericArgs" => {
327+ result . push ( FieldInfo :: optional ( "generic_arg_list" , "GenericArgList" ) )
398328 }
399- "HasGenericArgs" => result. push ( FieldInfo {
400- name : "generic_arg_list" . to_owned ( ) ,
401- ty : FieldType :: Optional ( "GenericArgList" . to_owned ( ) ) ,
402- } ) ,
403- "HasTypeBounds" => result. push ( FieldInfo {
404- name : "type_bound_list" . to_owned ( ) ,
405- ty : FieldType :: Optional ( "TypeBoundList" . to_owned ( ) ) ,
406- } ) ,
407- "HasModuleItem" => result. push ( FieldInfo {
408- name : "items" . to_owned ( ) ,
409- ty : FieldType :: List ( "Item" . to_owned ( ) ) ,
410- } ) ,
329+ "HasTypeBounds" => result. push ( FieldInfo :: optional ( "type_bound_list" , "TypeBoundList" ) ) ,
330+ "HasModuleItem" => result. push ( FieldInfo :: list ( "items" , "Item" ) ) ,
411331 "HasLoopBody" => {
412- result. push ( FieldInfo {
413- name : "label" . to_owned ( ) ,
414- ty : FieldType :: Optional ( "Label" . to_owned ( ) ) ,
415- } ) ;
416- result. push ( FieldInfo {
417- name : "loop_body" . to_owned ( ) ,
418- ty : FieldType :: Optional ( "BlockExpr" . to_owned ( ) ) ,
419- } )
332+ result. push ( FieldInfo :: optional ( "label" , "Label" ) ) ;
333+ result. push ( FieldInfo :: optional ( "loop_body" , "BlockExpr" ) )
420334 }
421- "HasArgList" => result. push ( FieldInfo {
422- name : "arg_list" . to_owned ( ) ,
423- ty : FieldType :: Optional ( "ArgList" . to_owned ( ) ) ,
424- } ) ,
335+ "HasArgList" => result. push ( FieldInfo :: optional ( "arg_list" , "ArgList" ) ) ,
425336 "HasDocComments" => { }
426337
427338 _ => panic ! ( "Unknown trait {}" , trait_) ,
@@ -455,6 +366,7 @@ struct ExtractorNodeFieldInfo {
455366 predicate : bool ,
456367 optional : bool ,
457368 list : bool ,
369+ body : bool ,
458370}
459371
460372#[ derive( Serialize ) ]
@@ -518,6 +430,13 @@ fn field_info_to_extractor_info(name: &str, field: &FieldInfo) -> ExtractorNodeF
518430 optional : true ,
519431 ..Default :: default ( )
520432 } ,
433+ FieldType :: Body ( ty) => ExtractorNodeFieldInfo {
434+ name,
435+ method : field. name . clone ( ) ,
436+ snake_case_ty : to_lower_snake_case ( ty) ,
437+ body : true ,
438+ ..Default :: default ( )
439+ } ,
521440 FieldType :: List ( ty) => ExtractorNodeFieldInfo {
522441 name,
523442 method : field. name . clone ( ) ,
0 commit comments