Skip to content

Commit ab3101c

Browse files
committed
generate: remove leaf_rust_field.
1 parent 2056cef commit ab3101c

File tree

1 file changed

+41
-30
lines changed

1 file changed

+41
-30
lines changed

src/generate/rust.rs

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,42 @@ impl<Pat: RustInputPat> RuleWithFieldsMethods<Pat> for RuleWithFields {
116116
let children = match &cx[self.fields] {
117117
Fields::Leaf(None) => return indexmap! {},
118118
Fields::Leaf(Some(field)) => {
119+
let mut sub = RuleWithFields {
120+
rule: self.rule,
121+
fields: field.sub,
122+
};
123+
119124
// FIXME(eddyb) support this properly (see issue #128).
120-
assert_eq!(cx[field.sub], Fields::Leaf(None));
125+
assert_eq!(cx[sub.fields], Fields::Leaf(None));
126+
127+
let mut refutable = false;
128+
while let Rule::Opt(child) = cx[sub.rule] {
129+
refutable = true;
130+
sub.rule = child;
131+
}
132+
133+
let repeat = match cx[sub.rule] {
134+
Rule::RepeatMany(elem, _) | Rule::RepeatMore(elem, _) => {
135+
sub.rule = elem;
136+
true
137+
}
138+
_ => false,
139+
};
140+
141+
let ty = match cx[sub.rule] {
142+
Rule::Call(r) => {
143+
let ident = Src::ident(&cx[r]);
144+
quote!(#ident<'a, 'i, I>)
145+
}
146+
_ => quote!(()),
147+
};
121148

122-
return indexmap! { field.name => self.rule.leaf_rust_field(cx) };
149+
return indexmap! {
150+
field.name => RustField {
151+
ty: if repeat { quote!([#ty]) } else { ty },
152+
refutable,
153+
},
154+
};
123155
}
124156
Fields::Aggregate(children) => children,
125157
};
@@ -203,7 +235,13 @@ impl<Pat: RustInputPat> RuleWithFieldsMethods<Pat> for RuleWithFields {
203235
};
204236
let subfields = child.rust_fields(cx);
205237
let variant = if subfields.is_empty() {
206-
RustVariant::Newtype(rule.leaf_rust_field(cx))
238+
let variant = RuleWithFields {
239+
rule,
240+
fields: children[i],
241+
};
242+
let variant_fields = variant.rust_fields(cx);
243+
assert_eq!(variant_fields.len(), 1);
244+
RustVariant::Newtype(variant_fields.into_iter().next().unwrap().1)
207245
} else {
208246
RustVariant::StructLike(subfields)
209247
};
@@ -278,37 +316,10 @@ impl<Pat: RustInputPat> RuleWithFieldsMethods<Pat> for RuleWithFields {
278316
}
279317

280318
trait RuleMethods<Pat>: Sized {
281-
fn leaf_rust_field(self, cx: &Context<Pat>) -> RustField;
282319
fn node_kind(self, cx: &Context<Pat>, rules: &mut RuleMap<'_>) -> NodeKind;
283320
}
284321

285322
impl<Pat: RustInputPat> RuleMethods<Pat> for IRule {
286-
fn leaf_rust_field(self, cx: &Context<Pat>) -> RustField {
287-
let ty = match cx[self] {
288-
Rule::Empty | Rule::Eat(_) | Rule::Concat(_) | Rule::Or(_) => quote!(()),
289-
290-
Rule::Call(r) => {
291-
let ident = Src::ident(&cx[r]);
292-
quote!(#ident<'a, 'i, I>)
293-
}
294-
295-
Rule::Opt(rule) => {
296-
let mut field = rule.leaf_rust_field(cx);
297-
field.refutable = true;
298-
return field;
299-
}
300-
301-
Rule::RepeatMany(elem, _) | Rule::RepeatMore(elem, _) => {
302-
let elem = elem.leaf_rust_field(cx).ty;
303-
quote!([#elem])
304-
}
305-
};
306-
RustField {
307-
ty,
308-
refutable: false,
309-
}
310-
}
311-
312323
fn node_kind(self, cx: &Context<Pat>, rules: &mut RuleMap<'_>) -> NodeKind {
313324
if let Rule::Call(r) = cx[self] {
314325
return NodeKind::NamedRule(cx[r].to_string());

0 commit comments

Comments
 (0)