@@ -7,9 +7,9 @@ use ide_db::{
7
7
RootDatabase ,
8
8
} ;
9
9
use syntax:: {
10
- AstNode ,
10
+ ast , match_ast , AstNode ,
11
11
SyntaxKind :: { ASYNC_KW , AWAIT_KW , QUESTION , RETURN_KW , THIN_ARROW } ,
12
- SyntaxNode , TextRange ,
12
+ SyntaxNode , SyntaxToken , TextRange , WalkEvent ,
13
13
} ;
14
14
15
15
use crate :: { display:: TryToNav , references, NavigationTarget } ;
@@ -36,17 +36,59 @@ pub(crate) fn highlight_related(
36
36
} ) ?;
37
37
38
38
match token. kind ( ) {
39
- QUESTION | RETURN_KW | THIN_ARROW => highlight_exit_points ( ) ,
40
- AWAIT_KW | ASYNC_KW => highlight_yield_points ( ) ,
39
+ QUESTION | RETURN_KW | THIN_ARROW => highlight_exit_points ( token ) ,
40
+ AWAIT_KW | ASYNC_KW => highlight_yield_points ( token ) ,
41
41
_ => highlight_references ( sema, & syntax, position) ,
42
42
}
43
43
}
44
44
45
- fn highlight_exit_points ( ) -> Option < Vec < DocumentHighlight > > {
45
+ fn highlight_exit_points ( _token : SyntaxToken ) -> Option < Vec < DocumentHighlight > > {
46
46
None
47
47
}
48
48
49
- fn highlight_yield_points ( ) -> Option < Vec < DocumentHighlight > > {
49
+ fn highlight_yield_points ( token : SyntaxToken ) -> Option < Vec < DocumentHighlight > > {
50
+ fn hl (
51
+ async_token : Option < SyntaxToken > ,
52
+ body : Option < ast:: BlockExpr > ,
53
+ ) -> Option < Vec < DocumentHighlight > > {
54
+ let mut highlights = Vec :: new ( ) ;
55
+ highlights. push ( DocumentHighlight { access : None , range : async_token?. text_range ( ) } ) ;
56
+ if let Some ( body) = body {
57
+ let mut preorder = body. syntax ( ) . preorder ( ) ;
58
+ while let Some ( event) = preorder. next ( ) {
59
+ let node = match event {
60
+ WalkEvent :: Enter ( node) => node,
61
+ WalkEvent :: Leave ( _) => continue ,
62
+ } ;
63
+ match_ast ! {
64
+ match node {
65
+ ast:: AwaitExpr ( expr) => if let Some ( token) = expr. await_token( ) {
66
+ highlights. push( DocumentHighlight {
67
+ access: None ,
68
+ range: token. text_range( ) ,
69
+ } ) ;
70
+ } ,
71
+ ast:: EffectExpr ( __) => preorder. skip_subtree( ) ,
72
+ ast:: ClosureExpr ( __) => preorder. skip_subtree( ) ,
73
+ ast:: Item ( __) => preorder. skip_subtree( ) ,
74
+ ast:: Path ( __) => preorder. skip_subtree( ) ,
75
+ _ => ( ) ,
76
+ }
77
+ }
78
+ }
79
+ }
80
+ Some ( highlights)
81
+ }
82
+ for anc in token. ancestors ( ) {
83
+ return match_ast ! {
84
+ match anc {
85
+ ast:: Fn ( fn_) => hl( fn_. async_token( ) , fn_. body( ) ) ,
86
+ ast:: EffectExpr ( effect) => hl( effect. async_token( ) , effect. block_expr( ) ) ,
87
+ ast:: ClosureExpr ( __) => None ,
88
+ _ => continue ,
89
+ }
90
+ } ;
91
+ }
50
92
None
51
93
}
52
94
@@ -135,7 +177,6 @@ struct Foo;
135
177
fn test_hl_self_in_crate_root ( ) {
136
178
check (
137
179
r#"
138
- //- /lib.rs
139
180
use self$0;
140
181
"# ,
141
182
) ;
@@ -157,13 +198,86 @@ use self$0;
157
198
fn test_hl_local ( ) {
158
199
check (
159
200
r#"
160
- //- /lib.rs
161
201
fn foo() {
162
202
let mut bar = 3;
163
203
// ^^^ write
164
204
bar$0;
165
205
// ^^^ read
166
206
}
207
+ "# ,
208
+ ) ;
209
+ }
210
+
211
+ #[ test]
212
+ fn test_hl_yield_points ( ) {
213
+ check (
214
+ r#"
215
+ pub async fn foo() {
216
+ // ^^^^^
217
+ let x = foo()
218
+ .await$0
219
+ // ^^^^^
220
+ .await;
221
+ // ^^^^^
222
+ || { 0.await };
223
+ (async { 0.await }).await
224
+ // ^^^^^
225
+ }
226
+ "# ,
227
+ ) ;
228
+ }
229
+
230
+ #[ test]
231
+ fn test_hl_yield_points2 ( ) {
232
+ check (
233
+ r#"
234
+ pub async$0 fn foo() {
235
+ // ^^^^^
236
+ let x = foo()
237
+ .await
238
+ // ^^^^^
239
+ .await;
240
+ // ^^^^^
241
+ || { 0.await };
242
+ (async { 0.await }).await
243
+ // ^^^^^
244
+ }
245
+ "# ,
246
+ ) ;
247
+ }
248
+
249
+ #[ test]
250
+ fn test_hl_yield_nested_fn ( ) {
251
+ check (
252
+ r#"
253
+ async fn foo() {
254
+ async fn foo2() {
255
+ // ^^^^^
256
+ async fn foo3() {
257
+ 0.await
258
+ }
259
+ 0.await$0
260
+ // ^^^^^
261
+ }
262
+ 0.await
263
+ }
264
+ "# ,
265
+ ) ;
266
+ }
267
+
268
+ #[ test]
269
+ fn test_hl_yield_nested_async_blocks ( ) {
270
+ check (
271
+ r#"
272
+ async fn foo() {
273
+ (async {
274
+ // ^^^^^
275
+ (async {
276
+ 0.await
277
+ }).await$0 }
278
+ // ^^^^^
279
+ ).await;
280
+ }
167
281
"# ,
168
282
) ;
169
283
}
0 commit comments