@@ -116,10 +116,42 @@ impl<Pat: RustInputPat> RuleWithFieldsMethods<Pat> for RuleWithFields {
116
116
let children = match & cx[ self . fields ] {
117
117
Fields :: Leaf ( None ) => return indexmap ! { } ,
118
118
Fields :: Leaf ( Some ( field) ) => {
119
+ let mut sub = RuleWithFields {
120
+ rule : self . rule ,
121
+ fields : field. sub ,
122
+ } ;
123
+
119
124
// 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
+ } ;
121
148
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
+ } ;
123
155
}
124
156
Fields :: Aggregate ( children) => children,
125
157
} ;
@@ -203,7 +235,13 @@ impl<Pat: RustInputPat> RuleWithFieldsMethods<Pat> for RuleWithFields {
203
235
} ;
204
236
let subfields = child. rust_fields ( cx) ;
205
237
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 )
207
245
} else {
208
246
RustVariant :: StructLike ( subfields)
209
247
} ;
@@ -278,37 +316,10 @@ impl<Pat: RustInputPat> RuleWithFieldsMethods<Pat> for RuleWithFields {
278
316
}
279
317
280
318
trait RuleMethods < Pat > : Sized {
281
- fn leaf_rust_field ( self , cx : & Context < Pat > ) -> RustField ;
282
319
fn node_kind ( self , cx : & Context < Pat > , rules : & mut RuleMap < ' _ > ) -> NodeKind ;
283
320
}
284
321
285
322
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
-
312
323
fn node_kind ( self , cx : & Context < Pat > , rules : & mut RuleMap < ' _ > ) -> NodeKind {
313
324
if let Rule :: Call ( r) = cx[ self ] {
314
325
return NodeKind :: NamedRule ( cx[ r] . to_string ( ) ) ;
0 commit comments