@@ -23,7 +23,15 @@ impl GenericParamsOwnerEdit for ast::Fn {
23
23
match self . generic_param_list ( ) {
24
24
Some ( it) => it,
25
25
None => {
26
- let position = Position :: after ( self . name ( ) . unwrap ( ) . syntax ) ;
26
+ let position = if let Some ( name) = self . name ( ) {
27
+ Position :: after ( name. syntax )
28
+ } else if let Some ( fn_token) = self . fn_token ( ) {
29
+ Position :: after ( fn_token)
30
+ } else if let Some ( param_list) = self . param_list ( ) {
31
+ Position :: before ( param_list. syntax )
32
+ } else {
33
+ Position :: last_child_of ( self . syntax ( ) )
34
+ } ;
27
35
create_generic_param_list ( position)
28
36
}
29
37
}
@@ -49,7 +57,11 @@ impl GenericParamsOwnerEdit for ast::Impl {
49
57
match self . generic_param_list ( ) {
50
58
Some ( it) => it,
51
59
None => {
52
- let position = Position :: after ( self . impl_token ( ) . unwrap ( ) ) ;
60
+ let position = if let Some ( imp_token) = self . impl_token ( ) {
61
+ Position :: after ( imp_token)
62
+ } else {
63
+ Position :: last_child_of ( self . syntax ( ) )
64
+ } ;
53
65
create_generic_param_list ( position)
54
66
}
55
67
}
@@ -70,7 +82,19 @@ impl GenericParamsOwnerEdit for ast::Impl {
70
82
71
83
impl GenericParamsOwnerEdit for ast:: Trait {
72
84
fn get_or_create_generic_param_list ( & self ) -> ast:: GenericParamList {
73
- todo ! ( )
85
+ match self . generic_param_list ( ) {
86
+ Some ( it) => it,
87
+ None => {
88
+ let position = if let Some ( name) = self . name ( ) {
89
+ Position :: after ( name. syntax )
90
+ } else if let Some ( trait_token) = self . trait_token ( ) {
91
+ Position :: after ( trait_token)
92
+ } else {
93
+ Position :: last_child_of ( self . syntax ( ) )
94
+ } ;
95
+ create_generic_param_list ( position)
96
+ }
97
+ }
74
98
}
75
99
76
100
fn get_or_create_where_clause ( & self ) -> WhereClause {
@@ -88,7 +112,19 @@ impl GenericParamsOwnerEdit for ast::Trait {
88
112
89
113
impl GenericParamsOwnerEdit for ast:: Struct {
90
114
fn get_or_create_generic_param_list ( & self ) -> ast:: GenericParamList {
91
- todo ! ( )
115
+ match self . generic_param_list ( ) {
116
+ Some ( it) => it,
117
+ None => {
118
+ let position = if let Some ( name) = self . name ( ) {
119
+ Position :: after ( name. syntax )
120
+ } else if let Some ( struct_token) = self . struct_token ( ) {
121
+ Position :: after ( struct_token)
122
+ } else {
123
+ Position :: last_child_of ( self . syntax ( ) )
124
+ } ;
125
+ create_generic_param_list ( position)
126
+ }
127
+ }
92
128
}
93
129
94
130
fn get_or_create_where_clause ( & self ) -> WhereClause {
@@ -114,7 +150,19 @@ impl GenericParamsOwnerEdit for ast::Struct {
114
150
115
151
impl GenericParamsOwnerEdit for ast:: Enum {
116
152
fn get_or_create_generic_param_list ( & self ) -> ast:: GenericParamList {
117
- todo ! ( )
153
+ match self . generic_param_list ( ) {
154
+ Some ( it) => it,
155
+ None => {
156
+ let position = if let Some ( name) = self . name ( ) {
157
+ Position :: after ( name. syntax )
158
+ } else if let Some ( enum_token) = self . enum_token ( ) {
159
+ Position :: after ( enum_token)
160
+ } else {
161
+ Position :: last_child_of ( self . syntax ( ) )
162
+ } ;
163
+ create_generic_param_list ( position)
164
+ }
165
+ }
118
166
}
119
167
120
168
fn get_or_create_where_clause ( & self ) -> WhereClause {
@@ -228,3 +276,44 @@ impl ast::Use {
228
276
ted:: remove ( self . syntax ( ) )
229
277
}
230
278
}
279
+
280
+ #[ cfg( test) ]
281
+ mod tests {
282
+ use std:: fmt;
283
+
284
+ use crate :: SourceFile ;
285
+
286
+ use super :: * ;
287
+
288
+ fn ast_mut_from_text < N : AstNode > ( text : & str ) -> N {
289
+ let parse = SourceFile :: parse ( text) ;
290
+ parse. tree ( ) . syntax ( ) . descendants ( ) . find_map ( N :: cast) . unwrap ( ) . clone_for_update ( )
291
+ }
292
+
293
+ #[ test]
294
+ fn test_create_generic_param_list ( ) {
295
+ fn check_create_gpl < N : GenericParamsOwnerEdit + fmt:: Display > ( before : & str , after : & str ) {
296
+ let gpl_owner = ast_mut_from_text :: < N > ( before) ;
297
+ gpl_owner. get_or_create_generic_param_list ( ) ;
298
+ assert_eq ! ( gpl_owner. to_string( ) , after) ;
299
+ }
300
+
301
+ check_create_gpl :: < ast:: Fn > ( "fn foo" , "fn foo<>" ) ;
302
+ check_create_gpl :: < ast:: Fn > ( "fn foo() {}" , "fn foo<>() {}" ) ;
303
+
304
+ check_create_gpl :: < ast:: Impl > ( "impl" , "impl<>" ) ;
305
+ check_create_gpl :: < ast:: Impl > ( "impl Struct {}" , "impl<> Struct {}" ) ;
306
+ check_create_gpl :: < ast:: Impl > ( "impl Trait for Struct {}" , "impl<> Trait for Struct {}" ) ;
307
+
308
+ check_create_gpl :: < ast:: Trait > ( "trait Trait<>" , "trait Trait<>" ) ;
309
+ check_create_gpl :: < ast:: Trait > ( "trait Trait<> {}" , "trait Trait<> {}" ) ;
310
+
311
+ check_create_gpl :: < ast:: Struct > ( "struct A" , "struct A<>" ) ;
312
+ check_create_gpl :: < ast:: Struct > ( "struct A;" , "struct A<>;" ) ;
313
+ check_create_gpl :: < ast:: Struct > ( "struct A();" , "struct A<>();" ) ;
314
+ check_create_gpl :: < ast:: Struct > ( "struct A {}" , "struct A<> {}" ) ;
315
+
316
+ check_create_gpl :: < ast:: Enum > ( "enum E" , "enum E<>" ) ;
317
+ check_create_gpl :: < ast:: Enum > ( "enum E {" , "enum E<> {" ) ;
318
+ }
319
+ }
0 commit comments