@@ -945,6 +945,9 @@ where
945
945
}
946
946
}
947
947
948
+ // FIXME(eddyb) these two impls cannot be easily implemented by a trait
949
+ // because of how `Handle<'a, 'i, I, X<'a, 'i, I>>` links together the
950
+ // lifetime parameters of `Handle` and those of `X`.
948
951
impl <I : gll:: grammer:: input:: Input > OwnedHandle <I , #ident<' _, ' _, I >> {
949
952
pub fn with<R >( & self , f: impl for <' a, ' i> FnOnce ( Handle <' a, ' i, I , #ident<' a, ' i, I >>) -> R ) -> R {
950
953
self . forest_and_node. unpack_ref( |_, forest_and_node| {
@@ -957,6 +960,12 @@ where
957
960
} )
958
961
}
959
962
}
963
+
964
+ impl <I : gll:: grammer:: input:: Input > fmt:: Debug for OwnedHandle <I , #ident<' _, ' _, I >> {
965
+ fn fmt( & self , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
966
+ self . with( |handle| handle. fmt( f) )
967
+ }
968
+ }
960
969
)
961
970
}
962
971
@@ -1025,13 +1034,13 @@ where
1025
1034
}
1026
1035
} ;
1027
1036
rule_ty_def
1028
- + rule_debug_impls ( cx, name, & rust_adt)
1029
- + impl_rule_from_forest ( name, & rust_adt, cx, rules)
1030
- + impl_rule_one_and_all ( name, rule, & rust_adt, cx, rules)
1037
+ + rule_debug_impl ( cx, name, & rust_adt)
1038
+ + impl_rule_traverse_impl ( name, rule, & rust_adt, cx, rules)
1031
1039
}
1032
1040
1033
- fn impl_rule_from_forest < Pat > (
1041
+ fn impl_rule_traverse_impl < Pat > (
1034
1042
name : IStr ,
1043
+ rule : RuleWithFields ,
1035
1044
rust_adt : & RustAdt ,
1036
1045
cx : & Context < Pat > ,
1037
1046
rules : & mut RuleMap < ' _ > ,
@@ -1056,7 +1065,7 @@ where
1056
1065
}
1057
1066
} ;
1058
1067
1059
- let method = match rust_adt {
1068
+ let ( total_fields , shape , from_shape ) = match rust_adt {
1060
1069
RustAdt :: Enum ( variants) => {
1061
1070
let max_fields_len = variants
1062
1071
. values ( )
@@ -1075,6 +1084,15 @@ where
1075
1084
. iter ( )
1076
1085
. map ( |kind| kind. to_src ( ) )
1077
1086
. collect :: < Vec < _ > > ( ) ;
1087
+ let variants_shape = variants
1088
+ . values ( )
1089
+ . map ( |( v_rule, variant) | match variant {
1090
+ RustVariant :: Newtype ( _) => quote ! ( _) ,
1091
+ RustVariant :: StructLike ( v_fields) => {
1092
+ v_rule. generate_traverse_shape ( cx, rules, v_fields)
1093
+ }
1094
+ } )
1095
+ . collect :: < Vec < _ > > ( ) ;
1078
1096
let variants_expr = variants. iter ( ) . map ( |( & v_name, ( _, variant) ) | {
1079
1097
let variant_ident = Src :: ident ( & cx[ v_name] ) ;
1080
1098
match variant {
@@ -1093,139 +1111,56 @@ where
1093
1111
}
1094
1112
} ) ;
1095
1113
1096
- quote ! (
1097
- fn from_forest(
1098
- forest: & ' a gll:: grammer:: forest:: ParseForest <' i, _G, I >,
1099
- _r: [ Option <Node <' i, _G>>; #max_fields_len + 1 ] ,
1100
- ) -> Self {
1114
+ (
1115
+ max_fields_len + 1 ,
1116
+ quote ! ( { _P; #max_fields_len @ #( #variants_kind_src => #variants_shape, ) * } ) ,
1117
+ quote ! (
1101
1118
match _r[ #max_fields_len] . unwrap( ) . kind {
1102
1119
#( #variants_kind_src => #variants_expr, ) *
1103
1120
_ => unreachable!( ) ,
1104
1121
}
1105
- }
1122
+ ) ,
1106
1123
)
1107
1124
}
1108
1125
RustAdt :: Struct ( fields) => {
1109
- let fields_len = fields. len ( ) ;
1110
1126
let fields_ident = fields. keys ( ) . map ( |& name| Src :: ident ( & cx[ name] ) ) ;
1111
1127
let fields_expr = fields. values ( ) . enumerate ( ) . map ( field_handle_expr) ;
1112
1128
let marker_field = if fields. is_empty ( ) {
1113
1129
Some ( quote ! ( _marker: { let _ = forest; PhantomData } , ) )
1114
1130
} else {
1115
1131
None
1116
1132
} ;
1117
- quote ! (
1118
- fn from_forest (
1119
- forest : & ' a gll :: grammer :: forest :: ParseForest < ' i , _G , I > ,
1120
- _r : [ Option < Node < ' i , _G>> ; #fields_len ] ,
1121
- ) -> Self {
1133
+
1134
+ (
1135
+ fields . len ( ) ,
1136
+ rule . generate_traverse_shape ( cx , rules , fields ) ,
1137
+ quote ! (
1122
1138
#ident {
1123
1139
#( #fields_ident: #fields_expr) , *
1124
1140
#marker_field
1125
1141
}
1126
- }
1142
+ ) ,
1127
1143
)
1128
1144
}
1129
1145
} ;
1130
1146
1131
- quote ! ( impl <' a, ' i, I : gll:: grammer:: input:: Input > #ident<' a, ' i, I > {
1132
- #method
1133
- } )
1134
- }
1135
-
1136
- fn impl_rule_one_and_all < Pat > (
1137
- name : IStr ,
1138
- rule : RuleWithFields ,
1139
- rust_adt : & RustAdt ,
1140
- cx : & Context < Pat > ,
1141
- rules : & mut RuleMap < ' _ > ,
1142
- ) -> Src
1143
- where
1144
- Pat : RustInputPat ,
1145
- {
1146
- let ident = Src :: ident ( & cx[ name] ) ;
1147
- let ( total_fields, shape) = match rust_adt {
1148
- RustAdt :: Enum ( variants) => {
1149
- let max_fields_len = variants
1150
- . values ( )
1151
- . map ( |( _, variant) | match variant {
1152
- RustVariant :: Newtype ( _) => 0 ,
1153
- RustVariant :: StructLike ( v_fields) => v_fields. len ( ) ,
1154
- } )
1155
- . max ( )
1156
- . unwrap_or ( 0 ) ;
1157
- // HACK(eddyb) only collected to a `Vec` to avoid `rules` borrow conflicts.
1158
- let variants_kind = variants
1159
- . values ( )
1160
- . map ( |( v_rule, _) | v_rule. rule . node_kind ( cx, rules) )
1161
- . collect :: < Vec < _ > > ( ) ;
1162
- let variants_kind_src = variants_kind
1163
- . iter ( )
1164
- . map ( |kind| kind. to_src ( ) )
1165
- . collect :: < Vec < _ > > ( ) ;
1166
- let variants_shape = variants
1167
- . values ( )
1168
- . map ( |( v_rule, variant) | match variant {
1169
- RustVariant :: Newtype ( _) => quote ! ( _) ,
1170
- RustVariant :: StructLike ( v_fields) => {
1171
- v_rule. generate_traverse_shape ( cx, rules, v_fields)
1172
- }
1173
- } )
1174
- . collect :: < Vec < _ > > ( ) ;
1175
-
1176
- (
1177
- max_fields_len + 1 ,
1178
- quote ! ( { _P; #max_fields_len @ #( #variants_kind_src => #variants_shape, ) * } ) ,
1179
- )
1180
- }
1181
- RustAdt :: Struct ( fields) => (
1182
- fields. len ( ) ,
1183
- rule. generate_traverse_shape ( cx, rules, fields) ,
1184
- ) ,
1185
- } ;
1186
-
1187
- quote ! (
1188
- impl <' a, ' i, I : gll:: grammer:: input:: Input > #ident<' a, ' i, I > {
1189
- const SHAPE : traverse:: ty!( #shape) = traverse:: new!( #shape) ;
1190
- }
1191
-
1192
- impl <' a, ' i, I > Handle <' a, ' i, I , #ident<' a, ' i, I >>
1147
+ quote ! ( impl <' a, ' i, I >
1148
+ traverse:: FromShape <& ' a gll:: grammer:: forest:: ParseForest <' i, _G, I >, Node <' i, _G>>
1149
+ for #ident<' a, ' i, I >
1193
1150
where I : gll:: grammer:: input:: Input ,
1194
1151
{
1195
- pub fn one( self ) -> Result <#ident<' a, ' i, I >, Ambiguity <Self >> {
1196
- let forest = self . forest;
1197
- let node = forest. unpack_alias( self . node) ;
1198
-
1199
- let mut r = [ None ; #total_fields] ;
1200
- #ident:: <I >:: SHAPE
1201
- . one( forest, node, & mut r)
1202
- . map_err( |gll:: grammer:: forest:: MoreThanOne | Ambiguity ( self ) ) ?;
1152
+ type Shape = traverse:: ty!( #shape) ;
1153
+ type Fields = [ Option <Node <' i, _G>>; #total_fields] ;
1203
1154
1204
- Ok ( #ident:: from_forest( forest, r) )
1205
- }
1155
+ const SHAPE : Self :: Shape = traverse:: new!( #shape) ;
1206
1156
1207
- pub fn all( self ) -> :: std:: iter:: Map <
1208
- cursor:: IntoIter <
1209
- <traverse:: ty!( #shape) as traverse:: Shape <' a, ' i, _G>>:: All ,
1210
- [ Option <Node <' i, _G>>; #total_fields] ,
1211
- [ Option <Node <' i, _G>>] ,
1212
- >,
1213
- impl FnMut ( [ Option <Node <' i, _G>>; #total_fields] ) -> #ident<' a, ' i, I >,
1214
- > {
1215
- let forest = self . forest;
1216
- let node = forest. unpack_alias( self . node) ;
1217
-
1218
- #ident:: <I >:: SHAPE
1219
- . all( forest, node)
1220
- . into_iter( )
1221
- . map( move |r| #ident:: from_forest( forest, r) )
1157
+ fn from_shape(
1158
+ forest: & ' a gll:: grammer:: forest:: ParseForest <' i, _G, I >,
1159
+ _r: Self :: Fields ,
1160
+ ) -> Self {
1161
+ #from_shape
1222
1162
}
1223
- }
1224
- )
1225
- }
1226
-
1227
- fn rule_debug_impls < Pat > ( cx : & Context < Pat > , name : IStr , rust_adt : & RustAdt ) -> Src {
1228
- rule_debug_impl ( cx, name, rust_adt) + rule_handle_debug_impl ( cx, name, rust_adt)
1163
+ } )
1229
1164
}
1230
1165
1231
1166
fn rule_debug_impl < Pat > ( cx : & Context < Pat > , name : IStr , rust_adt : & RustAdt ) -> Src {
@@ -1306,44 +1241,6 @@ fn rule_debug_impl<Pat>(cx: &Context<Pat>, name: IStr, rust_adt: &RustAdt) -> Sr
1306
1241
} )
1307
1242
}
1308
1243
1309
- fn rule_handle_debug_impl < Pat > ( cx : & Context < Pat > , name : IStr , rust_adt : & RustAdt ) -> Src {
1310
- let ident = Src :: ident ( & cx[ name] ) ;
1311
- let is_opaque = match rust_adt {
1312
- RustAdt :: Struct ( fields) => fields. is_empty ( ) ,
1313
- _ => false ,
1314
- } ;
1315
- let body = if is_opaque {
1316
- quote ! ( )
1317
- } else {
1318
- quote ! (
1319
- write!( f, " => " ) ?;
1320
- let mut first = true ;
1321
- for x in self . all( ) {
1322
- if !first {
1323
- write!( f, " | " ) ?;
1324
- }
1325
- first = false ;
1326
- fmt:: Debug :: fmt( & x, f) ?;
1327
- }
1328
- )
1329
- } ;
1330
- quote ! (
1331
- impl <' a, ' i, I : gll:: grammer:: input:: Input > fmt:: Debug for Handle <' a, ' i, I , #ident<' a, ' i, I >> {
1332
- fn fmt( & self , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
1333
- write!( f, "{:?}" , self . source_info( ) ) ?;
1334
- #body
1335
- Ok ( ( ) )
1336
- }
1337
- }
1338
-
1339
- impl <I : gll:: grammer:: input:: Input > fmt:: Debug for OwnedHandle <I , #ident<' _, ' _, I >> {
1340
- fn fmt( & self , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
1341
- self . with( |handle| handle. fmt( f) )
1342
- }
1343
- }
1344
- )
1345
- }
1346
-
1347
1244
fn define_parse_fn < Pat > (
1348
1245
cx : & Context < Pat > ,
1349
1246
rules : & mut RuleMap < ' _ > ,
0 commit comments