Skip to content

Commit 9a53f10

Browse files
committed
Implement yield point highlighting
1 parent 14b66bb commit 9a53f10

File tree

2 files changed

+125
-11
lines changed

2 files changed

+125
-11
lines changed

Diff for: crates/ide/src/highlight_references.rs renamed to crates/ide/src/highlight_related.rs

+122-8
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ use ide_db::{
77
RootDatabase,
88
};
99
use syntax::{
10-
AstNode,
10+
ast, match_ast, AstNode,
1111
SyntaxKind::{ASYNC_KW, AWAIT_KW, QUESTION, RETURN_KW, THIN_ARROW},
12-
SyntaxNode, TextRange,
12+
SyntaxNode, SyntaxToken, TextRange, WalkEvent,
1313
};
1414

1515
use crate::{display::TryToNav, references, NavigationTarget};
@@ -36,17 +36,59 @@ pub(crate) fn highlight_related(
3636
})?;
3737

3838
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),
4141
_ => highlight_references(sema, &syntax, position),
4242
}
4343
}
4444

45-
fn highlight_exit_points() -> Option<Vec<DocumentHighlight>> {
45+
fn highlight_exit_points(_token: SyntaxToken) -> Option<Vec<DocumentHighlight>> {
4646
None
4747
}
4848

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+
}
5092
None
5193
}
5294

@@ -135,7 +177,6 @@ struct Foo;
135177
fn test_hl_self_in_crate_root() {
136178
check(
137179
r#"
138-
//- /lib.rs
139180
use self$0;
140181
"#,
141182
);
@@ -157,13 +198,86 @@ use self$0;
157198
fn test_hl_local() {
158199
check(
159200
r#"
160-
//- /lib.rs
161201
fn foo() {
162202
let mut bar = 3;
163203
// ^^^ write
164204
bar$0;
165205
// ^^^ read
166206
}
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+
}
167281
"#,
168282
);
169283
}

Diff for: crates/ide/src/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ mod display;
2525
mod annotations;
2626
mod call_hierarchy;
2727
mod doc_links;
28-
mod highlight_references;
28+
mod highlight_related;
2929
mod expand_macro;
3030
mod extend_selection;
3131
mod file_structure;
@@ -76,7 +76,7 @@ pub use crate::{
7676
expand_macro::ExpandedMacro,
7777
file_structure::{StructureNode, StructureNodeKind},
7878
folding_ranges::{Fold, FoldKind},
79-
highlight_references::DocumentHighlight,
79+
highlight_related::DocumentHighlight,
8080
hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult},
8181
inlay_hints::{InlayHint, InlayHintsConfig, InlayKind},
8282
markup::Markup,
@@ -490,7 +490,7 @@ impl Analysis {
490490
&self,
491491
position: FilePosition,
492492
) -> Cancellable<Option<Vec<DocumentHighlight>>> {
493-
self.with_db(|db| highlight_references::highlight_related(&Semantics::new(db), position))
493+
self.with_db(|db| highlight_related::highlight_related(&Semantics::new(db), position))
494494
}
495495

496496
/// Computes syntax highlighting for the given file range.

0 commit comments

Comments
 (0)