Skip to content

Commit 1fffcff

Browse files
authored
Merge pull request #20080 from Veykril/push-vnrwqppplykm
Cleanup `folding_ranges` and support more things
2 parents e8388b0 + 40aeda9 commit 1fffcff

File tree

2 files changed

+60
-39
lines changed

2 files changed

+60
-39
lines changed

src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use ide_db::{FxHashSet, syntax_helpers::node_ext::vis_eq};
22
use syntax::{
33
Direction, NodeOrToken, SourceFile,
44
SyntaxKind::{self, *},
5-
TextRange, TextSize,
5+
SyntaxNode, TextRange, TextSize,
66
ast::{self, AstNode, AstToken},
77
match_ast,
88
};
@@ -16,16 +16,21 @@ const REGION_END: &str = "// endregion";
1616
pub enum FoldKind {
1717
Comment,
1818
Imports,
19-
Mods,
19+
Region,
2020
Block,
2121
ArgList,
22-
Region,
23-
Consts,
24-
Statics,
2522
Array,
2623
WhereClause,
2724
ReturnType,
2825
MatchArm,
26+
// region: item runs
27+
Modules,
28+
Consts,
29+
Statics,
30+
TypeAliases,
31+
TraitAliases,
32+
ExternCrates,
33+
// endregion: item runs
2934
}
3035

3136
#[derive(Debug)]
@@ -41,10 +46,7 @@ pub struct Fold {
4146
pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
4247
let mut res = vec![];
4348
let mut visited_comments = FxHashSet::default();
44-
let mut visited_imports = FxHashSet::default();
45-
let mut visited_mods = FxHashSet::default();
46-
let mut visited_consts = FxHashSet::default();
47-
let mut visited_statics = FxHashSet::default();
49+
let mut visited_nodes = FxHashSet::default();
4850

4951
// regions can be nested, here is a LIFO buffer
5052
let mut region_starts: Vec<TextSize> = vec![];
@@ -93,30 +95,40 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
9395
if module.item_list().is_none() {
9496
if let Some(range) = contiguous_range_for_item_group(
9597
module,
96-
&mut visited_mods,
98+
&mut visited_nodes,
9799
) {
98-
res.push(Fold { range, kind: FoldKind::Mods })
100+
res.push(Fold { range, kind: FoldKind::Modules })
99101
}
100102
}
101103
},
102104
ast::Use(use_) => {
103-
if let Some(range) = contiguous_range_for_item_group(use_, &mut visited_imports) {
105+
if let Some(range) = contiguous_range_for_item_group(use_, &mut visited_nodes) {
104106
res.push(Fold { range, kind: FoldKind::Imports })
105107
}
106108
},
107109
ast::Const(konst) => {
108-
if let Some(range) = contiguous_range_for_item_group(konst, &mut visited_consts) {
110+
if let Some(range) = contiguous_range_for_item_group(konst, &mut visited_nodes) {
109111
res.push(Fold { range, kind: FoldKind::Consts })
110112
}
111113
},
112114
ast::Static(statik) => {
113-
if let Some(range) = contiguous_range_for_item_group(statik, &mut visited_statics) {
115+
if let Some(range) = contiguous_range_for_item_group(statik, &mut visited_nodes) {
114116
res.push(Fold { range, kind: FoldKind::Statics })
115117
}
116118
},
117-
ast::WhereClause(where_clause) => {
118-
if let Some(range) = fold_range_for_where_clause(where_clause) {
119-
res.push(Fold { range, kind: FoldKind::WhereClause })
119+
ast::TypeAlias(alias) => {
120+
if let Some(range) = contiguous_range_for_item_group(alias, &mut visited_nodes) {
121+
res.push(Fold { range, kind: FoldKind::TypeAliases })
122+
}
123+
},
124+
ast::TraitAlias(alias) => {
125+
if let Some(range) = contiguous_range_for_item_group(alias, &mut visited_nodes) {
126+
res.push(Fold { range, kind: FoldKind::TraitAliases })
127+
}
128+
},
129+
ast::ExternCrate(extern_crate) => {
130+
if let Some(range) = contiguous_range_for_item_group(extern_crate, &mut visited_nodes) {
131+
res.push(Fold { range, kind: FoldKind::ExternCrates })
120132
}
121133
},
122134
ast::MatchArm(match_arm) => {
@@ -137,9 +149,10 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
137149
fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> {
138150
match kind {
139151
COMMENT => Some(FoldKind::Comment),
140-
ARG_LIST | PARAM_LIST => Some(FoldKind::ArgList),
152+
ARG_LIST | PARAM_LIST | GENERIC_ARG_LIST | GENERIC_PARAM_LIST => Some(FoldKind::ArgList),
141153
ARRAY_EXPR => Some(FoldKind::Array),
142154
RET_TYPE => Some(FoldKind::ReturnType),
155+
WHERE_CLAUSE => Some(FoldKind::WhereClause),
143156
ASSOC_ITEM_LIST
144157
| RECORD_FIELD_LIST
145158
| RECORD_PAT_FIELD_LIST
@@ -155,11 +168,14 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> {
155168
}
156169
}
157170

158-
fn contiguous_range_for_item_group<N>(first: N, visited: &mut FxHashSet<N>) -> Option<TextRange>
171+
fn contiguous_range_for_item_group<N>(
172+
first: N,
173+
visited: &mut FxHashSet<SyntaxNode>,
174+
) -> Option<TextRange>
159175
where
160176
N: ast::HasVisibility + Clone + Hash + Eq,
161177
{
162-
if !visited.insert(first.clone()) {
178+
if !visited.insert(first.syntax().clone()) {
163179
return None;
164180
}
165181

@@ -183,7 +199,7 @@ where
183199
if let Some(next) = N::cast(node) {
184200
let next_vis = next.visibility();
185201
if eq_visibility(next_vis.clone(), last_vis) {
186-
visited.insert(next.clone());
202+
visited.insert(next.syntax().clone());
187203
last_vis = next_vis;
188204
last = next;
189205
continue;
@@ -259,18 +275,6 @@ fn contiguous_range_for_comment(
259275
}
260276
}
261277

262-
fn fold_range_for_where_clause(where_clause: ast::WhereClause) -> Option<TextRange> {
263-
let first_where_pred = where_clause.predicates().next();
264-
let last_where_pred = where_clause.predicates().last();
265-
266-
if first_where_pred != last_where_pred {
267-
let start = where_clause.where_token()?.text_range().end();
268-
let end = where_clause.syntax().text_range().end();
269-
return Some(TextRange::new(start, end));
270-
}
271-
None
272-
}
273-
274278
fn fold_range_for_multiline_match_arm(match_arm: ast::MatchArm) -> Option<TextRange> {
275279
if fold_kind(match_arm.expr()?.syntax().kind()).is_some() {
276280
None
@@ -307,16 +311,19 @@ mod tests {
307311
let kind = match fold.kind {
308312
FoldKind::Comment => "comment",
309313
FoldKind::Imports => "imports",
310-
FoldKind::Mods => "mods",
314+
FoldKind::Modules => "mods",
311315
FoldKind::Block => "block",
312316
FoldKind::ArgList => "arglist",
313317
FoldKind::Region => "region",
314318
FoldKind::Consts => "consts",
315319
FoldKind::Statics => "statics",
320+
FoldKind::TypeAliases => "typealiases",
316321
FoldKind::Array => "array",
317322
FoldKind::WhereClause => "whereclause",
318323
FoldKind::ReturnType => "returntype",
319324
FoldKind::MatchArm => "matcharm",
325+
FoldKind::TraitAliases => "traitaliases",
326+
FoldKind::ExternCrates => "externcrates",
320327
};
321328
assert_eq!(kind, &attr.unwrap());
322329
}
@@ -594,19 +601,18 @@ static SECOND_STATIC: &str = "second";</fold>
594601

595602
#[test]
596603
fn fold_where_clause() {
597-
// fold multi-line and don't fold single line.
598604
check(
599605
r#"
600606
fn foo()
601-
where<fold whereclause>
607+
<fold whereclause>where
602608
A: Foo,
603609
B: Foo,
604610
C: Foo,
605611
D: Foo,</fold> {}
606612
607613
fn bar()
608-
where
609-
A: Bar, {}
614+
<fold whereclause>where
615+
A: Bar,</fold> {}
610616
"#,
611617
)
612618
}
@@ -621,6 +627,18 @@ fn foo()<fold returntype>-> (
621627
)</fold> { (true, true) }
622628
623629
fn bar() -> (bool, bool) { (true, true) }
630+
"#,
631+
)
632+
}
633+
634+
#[test]
635+
fn fold_generics() {
636+
check(
637+
r#"
638+
type Foo<T, U> = foo<fold arglist><
639+
T,
640+
U,
641+
></fold>;
624642
"#,
625643
)
626644
}

src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -900,14 +900,17 @@ pub(crate) fn folding_range(
900900
FoldKind::Comment => Some(lsp_types::FoldingRangeKind::Comment),
901901
FoldKind::Imports => Some(lsp_types::FoldingRangeKind::Imports),
902902
FoldKind::Region => Some(lsp_types::FoldingRangeKind::Region),
903-
FoldKind::Mods
903+
FoldKind::Modules
904904
| FoldKind::Block
905905
| FoldKind::ArgList
906906
| FoldKind::Consts
907907
| FoldKind::Statics
908+
| FoldKind::TypeAliases
908909
| FoldKind::WhereClause
909910
| FoldKind::ReturnType
910911
| FoldKind::Array
912+
| FoldKind::TraitAliases
913+
| FoldKind::ExternCrates
911914
| FoldKind::MatchArm => None,
912915
};
913916

0 commit comments

Comments
 (0)