Add (not working) support for Range and FileId in struct nodes.
This commit is contained in:
		
							parent
							
								
									eaebf8c926
								
							
						
					
					
						commit
						583136711a
					
				| @ -36,6 +36,7 @@ pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 MemberChildBuild::Boolean(_) => None, |                 MemberChildBuild::Boolean(_) => None, | ||||||
|  |                 MemberChildBuild::Special(_) => None, | ||||||
|             }, |             }, | ||||||
|         }) |         }) | ||||||
|         .filter(Option::is_some) |         .filter(Option::is_some) | ||||||
|  | |||||||
| @ -1,8 +1,6 @@ | |||||||
| use crate::deserialize::util::{make_build_fn_name, make_build_pair}; | use crate::deserialize::util::{make_build_fn_name, make_build_pair}; | ||||||
| use crate::spec::struct_spec::{ | use crate::spec::struct_spec::{MemberChildBuild, NodeMemberBuild, SpecialMemberBuild, StructChild, StructSpec, VecChild, VecChildBuild}; | ||||||
|     MemberChildBuild, NodeMemberBuild, StructChild, StructSpec, VecChild, VecChildBuild, | use proc_macro2::{Ident, TokenStream}; | ||||||
| }; |  | ||||||
| use proc_macro2::TokenStream; |  | ||||||
| use quote::{format_ident, quote}; | use quote::{format_ident, quote}; | ||||||
| 
 | 
 | ||||||
| fn make_vec_child_holder(vec_child: &VecChild) -> TokenStream { | fn make_vec_child_holder(vec_child: &VecChild) -> TokenStream { | ||||||
| @ -46,6 +44,7 @@ fn make_child_holder(child_spec: &StructChild) -> Option<TokenStream> { | |||||||
|                 Some(make_node_child_holder(member_child.name(), node_child)) |                 Some(make_node_child_holder(member_child.name(), node_child)) | ||||||
|             } |             } | ||||||
|             MemberChildBuild::Boolean(_) => Some(make_boolean_child_holder(member_child.name())), |             MemberChildBuild::Boolean(_) => Some(make_boolean_child_holder(member_child.name())), | ||||||
|  |             MemberChildBuild::Special(_) => None, | ||||||
|         }, |         }, | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -83,33 +82,38 @@ fn make_boolean_member_child_match_action(name: &str) -> TokenStream { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn make_match_action(child_spec: &StructChild) -> TokenStream { | fn make_rule_matcher(child_spec: &StructChild) -> Option<TokenStream> {    
 | ||||||
|     match child_spec { |     match child_spec { | ||||||
|         StructChild::SkipChild(_) => quote! {}, |         StructChild::SkipChild(_) => None, | ||||||
|         StructChild::VecChild(vec_child) => make_vec_child_match_action(vec_child), |         StructChild::VecChild(vec_child) => { | ||||||
|         StructChild::MemberChild(member_child) => match member_child.build() { |             let rule_ident = format_ident!("{}", vec_child.rule()); | ||||||
|             MemberChildBuild::Node(node_child) => { |             let action = make_vec_child_match_action(vec_child); | ||||||
|                 make_node_member_child_match_action(member_child.name(), node_child) |             Some(quote! { | ||||||
|  |                 Rule::#rule_ident => { #action } | ||||||
|  |             }) | ||||||
|  |         } | ||||||
|  |         StructChild::MemberChild(member_child) => { | ||||||
|  |             match member_child.build() { | ||||||
|  |                 MemberChildBuild::Node(node_member_build) => { | ||||||
|  |                     let rule_ident = format_ident!("{}", member_child.rule()); | ||||||
|  |                     let action = make_node_member_child_match_action( | ||||||
|  |                         member_child.name(), | ||||||
|  |                         node_member_build | ||||||
|  |                     ); | ||||||
|  |                     Some(quote! { | ||||||
|  |                         Rule::#rule_ident => { #action } | ||||||
|  |                     }) | ||||||
|                 } |                 } | ||||||
|                 MemberChildBuild::Boolean(_) => { |                 MemberChildBuild::Boolean(_) => { | ||||||
|                 make_boolean_member_child_match_action(member_child.name()) |                     let rule_ident = format_ident!("{}", member_child.rule()); | ||||||
|  |                     let action = make_boolean_member_child_match_action(member_child.name()); | ||||||
|  |                     Some(quote! { | ||||||
|  |                         Rule::#rule_ident => { #action } | ||||||
|  |                     }) | ||||||
|                 } |                 } | ||||||
|         }, |                 MemberChildBuild::Special(_) => None | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 |  | ||||||
| fn make_rule_matcher(child_spec: &StructChild) -> TokenStream { |  | ||||||
|     let rule_ident = match child_spec { |  | ||||||
|         StructChild::SkipChild(skip_child) => format_ident!("{}", skip_child.rule()), |  | ||||||
|         StructChild::VecChild(vec_child) => format_ident!("{}", vec_child.rule()), |  | ||||||
|         StructChild::MemberChild(single_child) => format_ident!("{}", single_child.rule()), |  | ||||||
|     }; |  | ||||||
|     let action = make_match_action(child_spec); |  | ||||||
| 
 |  | ||||||
|     quote! { |  | ||||||
|         Rule::#rule_ident => { |  | ||||||
|             #action; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -142,7 +146,7 @@ fn make_boolean_member_child_arg(name: &str) -> TokenStream { | |||||||
|     quote! { #child_ident } |     quote! { #child_ident } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn make_child_arg(child_spec: &StructChild) -> Option<TokenStream> { | fn make_child_arg(child_spec: &StructChild, pair_ident: &Ident) -> Option<TokenStream> { | ||||||
|     match child_spec { |     match child_spec { | ||||||
|         StructChild::SkipChild(_) => None, |         StructChild::SkipChild(_) => None, | ||||||
|         StructChild::VecChild(vec_child) => Some(make_vec_child_arg(vec_child)), |         StructChild::VecChild(vec_child) => Some(make_vec_child_arg(vec_child)), | ||||||
| @ -154,16 +158,31 @@ fn make_child_arg(child_spec: &StructChild) -> Option<TokenStream> { | |||||||
|             )), |             )), | ||||||
|             MemberChildBuild::Boolean(_) => { |             MemberChildBuild::Boolean(_) => { | ||||||
|                 Some(make_boolean_member_child_arg(member_child.name())) |                 Some(make_boolean_member_child_arg(member_child.name())) | ||||||
|  |             }, | ||||||
|  |             MemberChildBuild::Special(special_member_build) => { | ||||||
|  |                 match special_member_build { | ||||||
|  |                     SpecialMemberBuild::FileId => { | ||||||
|  |                         Some(quote! { file_id }) | ||||||
|                     } |                     } | ||||||
|  |                     SpecialMemberBuild::Range => { | ||||||
|  |                         Some(quote! { 
 | ||||||
|  |                             Range { | ||||||
|  |                                 start: #pair_ident.as_span().start(), | ||||||
|  |                                 end: #pair_ident.as_span().end(), | ||||||
|  |                             } | ||||||
|  |                         }) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|         }, |         }, | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn make_return_value_stream(build_spec: &StructSpec) -> TokenStream { | fn make_return_value_stream(build_spec: &StructSpec, pair_ident: &Ident) -> TokenStream { | ||||||
|     let type_ident = format_ident!("{}", build_spec.build()); |     let type_ident = format_ident!("{}", build_spec.build()); | ||||||
|     let child_args = build_spec |     let child_args = build_spec | ||||||
|         .children() |         .children() | ||||||
|         .map(|child| make_child_arg(child)) |         .map(|child| make_child_arg(child, pair_ident)) | ||||||
|         .filter(|child_arg| child_arg.is_some()) |         .filter(|child_arg| child_arg.is_some()) | ||||||
|         .map(|child_arg| child_arg.unwrap()) |         .map(|child_arg| child_arg.unwrap()) | ||||||
|         .collect::<Vec<_>>(); |         .collect::<Vec<_>>(); | ||||||
| @ -201,7 +220,7 @@ pub fn make_struct_build_fn(build_spec: &StructSpec) -> TokenStream { | |||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     let new_stream = make_return_value_stream(build_spec); |     let new_stream = make_return_value_stream(build_spec, &pair_ident); | ||||||
| 
 | 
 | ||||||
|     quote! { |     quote! { | ||||||
|         fn #build_fn_ident(file_id: usize, #pair_ident: Pair<Rule>) -> #return_type_ident { |         fn #build_fn_ident(file_id: usize, #pair_ident: Pair<Rule>) -> #return_type_ident { | ||||||
|  | |||||||
| @ -12,22 +12,12 @@ fn deserialize_skip_child(props: &Yaml) -> StructChild { | |||||||
| 
 | 
 | ||||||
| fn deserialize_vec_child(child_name: &str, props: &Yaml) -> StructChild { | fn deserialize_vec_child(child_name: &str, props: &Yaml) -> StructChild { | ||||||
|     let rule = props["rule"].as_str().unwrap(); |     let rule = props["rule"].as_str().unwrap(); | ||||||
|     let kind = props["kind"].as_str() |     let kind = props["kind"].as_str().unwrap_or(rule); | ||||||
|         .unwrap_or(rule); |  | ||||||
|     if kind == "string" { |     if kind == "string" { | ||||||
|         let build = VecChildBuild::String(VecChildStringBuild::new( |         let build = VecChildBuild::String(VecChildStringBuild::new(&make_build_fn_name(rule))); | ||||||
|             &make_build_fn_name(rule) |         StructChild::VecChild(VecChild::new(child_name, rule, Box::new(build))) | ||||||
|         )); |  | ||||||
|         StructChild::VecChild(VecChild::new( |  | ||||||
|             child_name, |  | ||||||
|             rule, |  | ||||||
|             Box::new(build), |  | ||||||
|         )) |  | ||||||
|     } else { |     } else { | ||||||
|         let build = VecChildBuild::Node(VecChildNodeBuild::new( |         let build = VecChildBuild::Node(VecChildNodeBuild::new(rule, &make_build_fn_name(rule))); | ||||||
|             rule, |  | ||||||
|             &make_build_fn_name(rule) |  | ||||||
|         )); |  | ||||||
|         StructChild::VecChild(VecChild::new(child_name, rule, Box::new(build))) |         StructChild::VecChild(VecChild::new(child_name, rule, Box::new(build))) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -66,9 +56,15 @@ fn deserialize_member_build(child_name: &str, rule: &str, props: &Yaml) -> Membe | |||||||
|         } else { |         } else { | ||||||
|             panic!("Expected 'on' in 'boolean' in 'build' in {}", child_name); |             panic!("Expected 'on' in 'boolean' in 'build' in {}", child_name); | ||||||
|         } |         } | ||||||
|  |     } else if props["special"].is_hash() { | ||||||
|  |         match props["special"]["kind"].as_str().unwrap() { | ||||||
|  |             "file_id" => MemberChildBuild::Special(SpecialMemberBuild::FileId), | ||||||
|  |             "range" => MemberChildBuild::Special(SpecialMemberBuild::Range), | ||||||
|  |             _ => panic!(), | ||||||
|  |         } | ||||||
|     } else { |     } else { | ||||||
|         panic!( |         panic!( | ||||||
|             "Expected either of 'node' or 'boolean' in 'build' in {}", |             "Expected one of 'node', 'boolean', or 'special' in 'build' in {}", | ||||||
|             child_name |             child_name | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -231,6 +231,7 @@ fn make_struct_p2_impl(struct_build_spec: &StructSpec) -> TokenStream { | |||||||
|                         writer.writeln_indented(&format!(#format_string, self.#child_ident()))?; |                         writer.writeln_indented(&format!(#format_string, self.#child_ident()))?; | ||||||
|                     }) |                     }) | ||||||
|                 } |                 } | ||||||
|  |                 MemberChildBuild::Special(_) => None | ||||||
|             }, |             }, | ||||||
|         }) |         }) | ||||||
|         .filter(Option::is_some) |         .filter(Option::is_some) | ||||||
|  | |||||||
| @ -48,7 +48,7 @@ impl SkipChild { | |||||||
| pub struct VecChild { | pub struct VecChild { | ||||||
|     name: String, |     name: String, | ||||||
|     rule: String, |     rule: String, | ||||||
|     build: Box<VecChildBuild> |     build: Box<VecChildBuild>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl VecChild { | impl VecChild { | ||||||
| @ -56,7 +56,7 @@ impl VecChild { | |||||||
|         Self { |         Self { | ||||||
|             name: name.to_string(), |             name: name.to_string(), | ||||||
|             rule: rule.to_string(), |             rule: rule.to_string(), | ||||||
|             build |             build, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -77,16 +77,18 @@ impl VecChild { | |||||||
| 
 | 
 | ||||||
| pub enum VecChildBuild { | pub enum VecChildBuild { | ||||||
|     String(VecChildStringBuild), |     String(VecChildStringBuild), | ||||||
|     Node(VecChildNodeBuild) |     Node(VecChildNodeBuild), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct VecChildStringBuild { | pub struct VecChildStringBuild { | ||||||
|     with: String |     with: String, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl VecChildStringBuild { | impl VecChildStringBuild { | ||||||
|     pub fn new(with: &str) -> Self { |     pub fn new(with: &str) -> Self { | ||||||
|         Self { with: with.to_string() } |         Self { | ||||||
|  |             with: with.to_string(), | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn with(&self) -> &str { |     pub fn with(&self) -> &str { | ||||||
| @ -96,14 +98,14 @@ impl VecChildStringBuild { | |||||||
| 
 | 
 | ||||||
| pub struct VecChildNodeBuild { | pub struct VecChildNodeBuild { | ||||||
|     kind: String, |     kind: String, | ||||||
|     with: String |     with: String, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl VecChildNodeBuild { | impl VecChildNodeBuild { | ||||||
|     pub fn new(kind: &str, with: &str) -> Self { |     pub fn new(kind: &str, with: &str) -> Self { | ||||||
|         Self { |         Self { | ||||||
|             kind: kind.to_string(), |             kind: kind.to_string(), | ||||||
|             with: with.to_string() |             with: with.to_string(), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -158,6 +160,7 @@ impl MemberChild { | |||||||
| pub enum MemberChildBuild { | pub enum MemberChildBuild { | ||||||
|     Node(NodeMemberBuild), |     Node(NodeMemberBuild), | ||||||
|     Boolean(BooleanMemberBuild), |     Boolean(BooleanMemberBuild), | ||||||
|  |     Special(SpecialMemberBuild), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| @ -208,5 +211,11 @@ impl BooleanMemberBuild { | |||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub enum BooleanMemberBuildOn { | pub enum BooleanMemberBuildOn { | ||||||
|     RulePresent |     RulePresent, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub enum SpecialMemberBuild { | ||||||
|  |     FileId, | ||||||
|  |     Range, | ||||||
| } | } | ||||||
| @ -1,5 +1,6 @@ | |||||||
| use crate::spec::struct_spec::{ | use crate::spec::struct_spec::{ | ||||||
|     MemberChild, MemberChildBuild, StructChild, StructSpec, VecChild, VecChildBuild, |     MemberChild, MemberChildBuild, SpecialMemberBuild, StructChild, StructSpec, VecChild, | ||||||
|  |     VecChildBuild, | ||||||
| }; | }; | ||||||
| use proc_macro2::{Ident, TokenStream}; | use proc_macro2::{Ident, TokenStream}; | ||||||
| use quote::{format_ident, quote}; | use quote::{format_ident, quote}; | ||||||
| @ -75,6 +76,22 @@ fn make_member_child_accessors(member_child: &MemberChild) -> TokenStream { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         MemberChildBuild::Special(special_member_build) => match special_member_build { | ||||||
|  |             SpecialMemberBuild::FileId => { | ||||||
|  |                 quote! { | ||||||
|  |                     pub fn file_id(&self) -> usize { | ||||||
|  |                         self.file_id | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             SpecialMemberBuild::Range => { | ||||||
|  |                 quote! { | ||||||
|  |                     pub fn range(&self) -> Range<usize> { | ||||||
|  |                         self.range | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -118,6 +135,10 @@ fn make_member_child_type_ident(member_child: &MemberChild) -> TokenStream { | |||||||
|         MemberChildBuild::Boolean(_) => { |         MemberChildBuild::Boolean(_) => { | ||||||
|             quote! { bool } |             quote! { bool } | ||||||
|         } |         } | ||||||
|  |         MemberChildBuild::Special(special_member_build) => match special_member_build { | ||||||
|  |             SpecialMemberBuild::FileId => quote! { usize }, | ||||||
|  |             SpecialMemberBuild::Range => quote! { Range<usize> }, | ||||||
|  |         }, | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -148,6 +148,7 @@ $defs: | |||||||
|     oneOf: |     oneOf: | ||||||
|       - $ref: "#/$defs/StructChildMemberBuildNodeHash" |       - $ref: "#/$defs/StructChildMemberBuildNodeHash" | ||||||
|       - $ref: "#/$defs/StructChildMemberBuildBooleanHash" |       - $ref: "#/$defs/StructChildMemberBuildBooleanHash" | ||||||
|  |       - $ref: "#/$defs/StructChildMemberBuildSpecialHash" | ||||||
|   StructChildMemberBuildNodeHash: |   StructChildMemberBuildNodeHash: | ||||||
|     type: object |     type: object | ||||||
|     additionalProperties: false |     additionalProperties: false | ||||||
| @ -190,6 +191,24 @@ $defs: | |||||||
|           - rule_present |           - rule_present | ||||||
|     required: |     required: | ||||||
|       - on |       - on | ||||||
|  |   StructChildMemberBuildSpecialHash: | ||||||
|  |     type: object | ||||||
|  |     additionalProperties: false | ||||||
|  |     description: A special member to be built. | ||||||
|  |     properties:  | ||||||
|  |       special: | ||||||
|  |         type: object | ||||||
|  |         additionalProperties: false | ||||||
|  |         properties:  | ||||||
|  |           kind: | ||||||
|  |             type: string | ||||||
|  |             enum: | ||||||
|  |               - file_id | ||||||
|  |               - range | ||||||
|  |         required: | ||||||
|  |           - kind | ||||||
|  |     required: | ||||||
|  |       - special | ||||||
| 
 | 
 | ||||||
|   # Leaf Struct Node |   # Leaf Struct Node | ||||||
|   LeafStructNodeDefinition: |   LeafStructNodeDefinition: | ||||||
|  | |||||||
| @ -214,6 +214,16 @@ UseStatement: | |||||||
|       - suffix: |       - suffix: | ||||||
|           member: |           member: | ||||||
|             rule: UseStatementSuffix |             rule: UseStatementSuffix | ||||||
|  |       - file_id: | ||||||
|  |           member:  | ||||||
|  |             build: | ||||||
|  |               special: | ||||||
|  |                 kind: file_id | ||||||
|  |       - range: | ||||||
|  |           member:  | ||||||
|  |             build: | ||||||
|  |               special: | ||||||
|  |                 kind: range | ||||||
| UseStatementPrefix: | UseStatementPrefix: | ||||||
|   struct: |   struct: | ||||||
|     children: |     children: | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Jesse Brault
						Jesse Brault