@@ -52,7 +52,7 @@ pub(crate) fn determine_prev_sibling(name_like: &ast::NameLike) -> Option<Immedi
52
52
let res = match_ast ! {
53
53
match prev_sibling {
54
54
ast:: ExprStmt ( it) => {
55
- let node = it. expr( ) ?. syntax( ) . clone( ) ;
55
+ let node = it. expr( ) . filter ( |_| it . semicolon_token ( ) . is_none ( ) ) ?. syntax( ) . clone( ) ;
56
56
match_ast! {
57
57
match node {
58
58
ast:: IfExpr ( _it) => ImmediatePrevSibling :: IfExpr ,
@@ -149,59 +149,6 @@ fn maximize_name_ref(name_like: &ast::NameLike) -> Option<SyntaxNode> {
149
149
Some ( node)
150
150
}
151
151
152
- #[ cfg( test) ]
153
- fn check_location ( code : & str , loc : ImmediateLocation ) {
154
- check_pattern_is_applicable ( code, |e| {
155
- let name = & e. parent ( ) . and_then ( ast:: NameLike :: cast) . expect ( "Expected a namelike" ) ;
156
- assert_eq ! ( determine_location( name) , Some ( loc) ) ;
157
- true
158
- } ) ;
159
- }
160
-
161
- #[ test]
162
- fn test_has_trait_parent ( ) {
163
- check_location ( r"trait A { f$0 }" , ImmediateLocation :: Trait ) ;
164
- }
165
-
166
- #[ test]
167
- fn test_has_use_parent ( ) {
168
- check_location ( r"use f$0" , ImmediateLocation :: Use ) ;
169
- }
170
-
171
- #[ test]
172
- fn test_has_impl_parent ( ) {
173
- check_location ( r"impl A { f$0 }" , ImmediateLocation :: Impl ) ;
174
- }
175
- #[ test]
176
- fn test_has_field_list_parent ( ) {
177
- check_location ( r"struct Foo { f$0 }" , ImmediateLocation :: RecordField ) ;
178
- check_location ( r"struct Foo { f$0 pub f: i32}" , ImmediateLocation :: RecordField ) ;
179
- }
180
-
181
- #[ test]
182
- fn test_has_block_expr_parent ( ) {
183
- check_location ( r"fn my_fn() { let a = 2; f$0 }" , ImmediateLocation :: BlockExpr ) ;
184
- }
185
-
186
- #[ test]
187
- fn test_has_ident_pat_parent ( ) {
188
- check_location ( r"fn my_fn(m$0) {}" , ImmediateLocation :: IdentPat ) ;
189
- check_location ( r"fn my_fn() { let m$0 }" , ImmediateLocation :: IdentPat ) ;
190
- check_location ( r"fn my_fn(&m$0) {}" , ImmediateLocation :: IdentPat ) ;
191
- check_location ( r"fn my_fn() { let &m$0 }" , ImmediateLocation :: IdentPat ) ;
192
- }
193
-
194
- #[ test]
195
- fn test_has_ref_expr_parent ( ) {
196
- check_location ( r"fn my_fn() { let x = &m$0 foo; }" , ImmediateLocation :: RefExpr ) ;
197
- }
198
-
199
- #[ test]
200
- fn test_has_item_list_or_source_file_parent ( ) {
201
- check_location ( r"i$0" , ImmediateLocation :: ItemList ) ;
202
- check_location ( r"mod foo { f$0 }" , ImmediateLocation :: ItemList ) ;
203
- }
204
-
205
152
pub ( crate ) fn inside_impl_trait_block ( element : SyntaxElement ) -> bool {
206
153
// Here we search `impl` keyword up through the all ancestors, unlike in `has_impl_parent`,
207
154
// where we only check the first parent with different text range.
@@ -251,36 +198,6 @@ fn test_for_is_prev2() {
251
198
check_pattern_is_applicable ( r"for i i$0" , for_is_prev2) ;
252
199
}
253
200
254
- #[ cfg( test) ]
255
- fn check_prev_sibling ( code : & str , sibling : impl Into < Option < ImmediatePrevSibling > > ) {
256
- check_pattern_is_applicable ( code, |e| {
257
- let name = & e. parent ( ) . and_then ( ast:: NameLike :: cast) . expect ( "Expected a namelike" ) ;
258
- assert_eq ! ( determine_prev_sibling( name) , sibling. into( ) ) ;
259
- true
260
- } ) ;
261
- }
262
-
263
- #[ test]
264
- fn test_has_impl_as_prev_sibling ( ) {
265
- check_prev_sibling ( r"impl A w$0 " , ImmediatePrevSibling :: ImplDefType ) ;
266
- check_prev_sibling ( r"impl A w$0 {}" , ImmediatePrevSibling :: ImplDefType ) ;
267
- check_prev_sibling ( r"impl A for A w$0 " , ImmediatePrevSibling :: ImplDefType ) ;
268
- check_prev_sibling ( r"impl A for A w$0 {}" , ImmediatePrevSibling :: ImplDefType ) ;
269
- check_prev_sibling ( r"impl A for w$0 {}" , None ) ;
270
- check_prev_sibling ( r"impl A for w$0" , None ) ;
271
- }
272
-
273
- #[ test]
274
- fn test_has_trait_as_prev_sibling ( ) {
275
- check_prev_sibling ( r"trait A w$0 " , ImmediatePrevSibling :: TraitDefName ) ;
276
- check_prev_sibling ( r"trait A w$0 {}" , ImmediatePrevSibling :: TraitDefName ) ;
277
- }
278
-
279
- #[ test]
280
- fn test_has_if_expr_as_prev_sibling ( ) {
281
- check_prev_sibling ( r"fn foo() { if true {} w$0" , ImmediatePrevSibling :: IfExpr ) ;
282
- }
283
-
284
201
pub ( crate ) fn is_in_loop_body ( element : SyntaxElement ) -> bool {
285
202
element
286
203
. ancestors ( )
@@ -329,3 +246,111 @@ fn previous_sibling_or_ancestor_sibling(element: SyntaxElement) -> Option<Syntax
329
246
non_trivia_sibling ( NodeOrToken :: Node ( prev_sibling_node) , Direction :: Prev )
330
247
}
331
248
}
249
+
250
+ #[ cfg( test) ]
251
+ mod tests {
252
+ use super :: * ;
253
+
254
+ fn check_location ( code : & str , loc : impl Into < Option < ImmediateLocation > > ) {
255
+ check_pattern_is_applicable ( code, |e| {
256
+ let name = & e. parent ( ) . and_then ( ast:: NameLike :: cast) . expect ( "Expected a namelike" ) ;
257
+ assert_eq ! ( determine_location( name) , loc. into( ) ) ;
258
+ true
259
+ } ) ;
260
+ }
261
+
262
+ fn check_prev_sibling ( code : & str , sibling : impl Into < Option < ImmediatePrevSibling > > ) {
263
+ check_pattern_is_applicable ( code, |e| {
264
+ let name = & e. parent ( ) . and_then ( ast:: NameLike :: cast) . expect ( "Expected a namelike" ) ;
265
+ assert_eq ! ( determine_prev_sibling( name) , sibling. into( ) ) ;
266
+ true
267
+ } ) ;
268
+ }
269
+
270
+ #[ test]
271
+ fn test_trait_loc ( ) {
272
+ check_location ( r"trait A { f$0 }" , ImmediateLocation :: Trait ) ;
273
+ check_location ( r"trait A { #[attr] f$0 }" , ImmediateLocation :: Trait ) ;
274
+ check_location ( r"trait A { f$0 fn f() {} }" , ImmediateLocation :: Trait ) ;
275
+ check_location ( r"trait A { fn f() {} f$0 }" , ImmediateLocation :: Trait ) ;
276
+ check_location ( r"trait A$0 {}" , None ) ;
277
+ check_location ( r"trait A { fn f$0 }" , None ) ;
278
+ }
279
+
280
+ #[ test]
281
+ fn test_impl_loc ( ) {
282
+ check_location ( r"impl A { f$0 }" , ImmediateLocation :: Impl ) ;
283
+ check_location ( r"impl A { #[attr] f$0 }" , ImmediateLocation :: Impl ) ;
284
+ check_location ( r"impl A { f$0 fn f() {} }" , ImmediateLocation :: Impl ) ;
285
+ check_location ( r"impl A { fn f() {} f$0 }" , ImmediateLocation :: Impl ) ;
286
+ check_location ( r"impl A$0 {}" , None ) ;
287
+ check_location ( r"impl A { fn f$0 }" , None ) ;
288
+ }
289
+
290
+ #[ test]
291
+ fn test_use_loc ( ) {
292
+ check_location ( r"use f$0" , ImmediateLocation :: Use ) ;
293
+ check_location ( r"use f$0;" , ImmediateLocation :: Use ) ;
294
+ check_location ( r"use f::{f$0}" , None ) ;
295
+ check_location ( r"use {f$0}" , None ) ;
296
+ }
297
+
298
+ #[ test]
299
+ fn test_record_field_loc ( ) {
300
+ check_location ( r"struct Foo { f$0 }" , ImmediateLocation :: RecordField ) ;
301
+ check_location ( r"struct Foo { f$0 pub f: i32}" , ImmediateLocation :: RecordField ) ;
302
+ check_location ( r"struct Foo { pub f: i32, f$0 }" , ImmediateLocation :: RecordField ) ;
303
+ }
304
+
305
+ #[ test]
306
+ fn test_block_expr_loc ( ) {
307
+ check_location ( r"fn my_fn() { let a = 2; f$0 }" , ImmediateLocation :: BlockExpr ) ;
308
+ check_location ( r"fn my_fn() { f$0 f }" , ImmediateLocation :: BlockExpr ) ;
309
+ }
310
+
311
+ #[ test]
312
+ fn test_ident_pat_loc ( ) {
313
+ check_location ( r"fn my_fn(m$0) {}" , ImmediateLocation :: IdentPat ) ;
314
+ check_location ( r"fn my_fn() { let m$0 }" , ImmediateLocation :: IdentPat ) ;
315
+ check_location ( r"fn my_fn(&m$0) {}" , ImmediateLocation :: IdentPat ) ;
316
+ check_location ( r"fn my_fn() { let &m$0 }" , ImmediateLocation :: IdentPat ) ;
317
+ }
318
+
319
+ #[ test]
320
+ fn test_ref_expr_loc ( ) {
321
+ check_location ( r"fn my_fn() { let x = &m$0 foo; }" , ImmediateLocation :: RefExpr ) ;
322
+ }
323
+
324
+ #[ test]
325
+ fn test_item_list_loc ( ) {
326
+ check_location ( r"i$0" , ImmediateLocation :: ItemList ) ;
327
+ check_location ( r"#[attr] i$0" , ImmediateLocation :: ItemList ) ;
328
+ check_location ( r"fn f() {} i$0" , ImmediateLocation :: ItemList ) ;
329
+ check_location ( r"mod foo { f$0 }" , ImmediateLocation :: ItemList ) ;
330
+ check_location ( r"mod foo { #[attr] f$0 }" , ImmediateLocation :: ItemList ) ;
331
+ check_location ( r"mod foo { fn f() {} f$0 }" , ImmediateLocation :: ItemList ) ;
332
+ check_location ( r"mod foo$0 {}" , None ) ;
333
+ }
334
+
335
+ #[ test]
336
+ fn test_impl_prev_sibling ( ) {
337
+ check_prev_sibling ( r"impl A w$0 " , ImmediatePrevSibling :: ImplDefType ) ;
338
+ check_prev_sibling ( r"impl A w$0 {}" , ImmediatePrevSibling :: ImplDefType ) ;
339
+ check_prev_sibling ( r"impl A for A w$0 " , ImmediatePrevSibling :: ImplDefType ) ;
340
+ check_prev_sibling ( r"impl A for A w$0 {}" , ImmediatePrevSibling :: ImplDefType ) ;
341
+ check_prev_sibling ( r"impl A for w$0 {}" , None ) ;
342
+ check_prev_sibling ( r"impl A for w$0" , None ) ;
343
+ }
344
+
345
+ #[ test]
346
+ fn test_trait_prev_sibling ( ) {
347
+ check_prev_sibling ( r"trait A w$0 " , ImmediatePrevSibling :: TraitDefName ) ;
348
+ check_prev_sibling ( r"trait A w$0 {}" , ImmediatePrevSibling :: TraitDefName ) ;
349
+ }
350
+
351
+ #[ test]
352
+ fn test_if_expr_prev_sibling ( ) {
353
+ check_prev_sibling ( r"fn foo() { if true {} w$0" , ImmediatePrevSibling :: IfExpr ) ;
354
+ check_prev_sibling ( r"fn foo() { if true {}; w$0" , None ) ;
355
+ }
356
+ }
0 commit comments