aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorivan770 <[email protected]>2021-03-11 16:14:41 +0000
committerivan770 <[email protected]>2021-03-14 16:53:37 +0000
commit71a97a2d8c30fc4061a545f1e2db10e3559eae36 (patch)
tree1aa0a643c44d1068b915614e374b0ce71deeade4
parentaf8440b84851febd805b6b774bfb326cbdb7175e (diff)
Provide regions in file structure
-rw-r--r--crates/ide/src/file_structure.rs53
-rw-r--r--crates/ide/src/syntax_highlighting/tags.rs1
-rw-r--r--crates/ide_completion/src/item.rs1
-rw-r--r--crates/ide_db/src/lib.rs1
-rw-r--r--crates/rust-analyzer/src/to_proto.rs3
5 files changed, 55 insertions, 4 deletions
diff --git a/crates/ide/src/file_structure.rs b/crates/ide/src/file_structure.rs
index 26793bdb4..713c76957 100644
--- a/crates/ide/src/file_structure.rs
+++ b/crates/ide/src/file_structure.rs
@@ -1,7 +1,8 @@
1use ide_db::SymbolKind; 1use ide_db::SymbolKind;
2use syntax::{ 2use syntax::{
3 ast::{self, AttrsOwner, GenericParamsOwner, NameOwner}, 3 ast::{self, AttrsOwner, GenericParamsOwner, NameOwner},
4 match_ast, AstNode, SourceFile, SyntaxNode, TextRange, WalkEvent, 4 match_ast, AstNode, AstToken, NodeOrToken, SourceFile, SyntaxNode, SyntaxToken, TextRange,
5 WalkEvent,
5}; 6};
6 7
7#[derive(Debug, Clone)] 8#[derive(Debug, Clone)]
@@ -32,20 +33,32 @@ pub(crate) fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
32 let mut res = Vec::new(); 33 let mut res = Vec::new();
33 let mut stack = Vec::new(); 34 let mut stack = Vec::new();
34 35
35 for event in file.syntax().preorder() { 36 for event in file.syntax().preorder_with_tokens() {
36 match event { 37 match event {
37 WalkEvent::Enter(node) => { 38 WalkEvent::Enter(NodeOrToken::Node(node)) => {
38 if let Some(mut symbol) = structure_node(&node) { 39 if let Some(mut symbol) = structure_node(&node) {
39 symbol.parent = stack.last().copied(); 40 symbol.parent = stack.last().copied();
40 stack.push(res.len()); 41 stack.push(res.len());
41 res.push(symbol); 42 res.push(symbol);
42 } 43 }
43 } 44 }
44 WalkEvent::Leave(node) => { 45 WalkEvent::Leave(NodeOrToken::Node(node)) => {
45 if structure_node(&node).is_some() { 46 if structure_node(&node).is_some() {
46 stack.pop().unwrap(); 47 stack.pop().unwrap();
47 } 48 }
48 } 49 }
50 WalkEvent::Enter(NodeOrToken::Token(token)) => {
51 if let Some(mut symbol) = structure_token(token) {
52 symbol.parent = stack.last().copied();
53 stack.push(res.len());
54 res.push(symbol);
55 }
56 }
57 WalkEvent::Leave(NodeOrToken::Token(token)) => {
58 if structure_token(token).is_some() {
59 stack.pop().unwrap();
60 }
61 }
49 } 62 }
50 } 63 }
51 res 64 res
@@ -159,6 +172,26 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
159 } 172 }
160} 173}
161 174
175fn structure_token(token: SyntaxToken) -> Option<StructureNode> {
176 if let Some(comment) = ast::Comment::cast(token) {
177 let text = comment.text().trim();
178
179 if let Some(region_name) = text.strip_prefix("// region:").map(|text| text.trim()) {
180 return Some(StructureNode {
181 parent: None,
182 label: region_name.to_string(),
183 navigation_range: comment.syntax().text_range(),
184 node_range: comment.syntax().text_range(),
185 kind: SymbolKind::Region,
186 detail: None,
187 deprecated: false,
188 });
189 }
190 }
191
192 None
193}
194
162#[cfg(test)] 195#[cfg(test)]
163mod tests { 196mod tests {
164 use expect_test::{expect, Expect}; 197 use expect_test::{expect, Expect};
@@ -217,6 +250,9 @@ fn obsolete() {}
217 250
218#[deprecated(note = "for awhile")] 251#[deprecated(note = "for awhile")]
219fn very_obsolete() {} 252fn very_obsolete() {}
253
254// region: Some region name
255// endregion
220"#, 256"#,
221 expect![[r#" 257 expect![[r#"
222 [ 258 [
@@ -421,6 +457,15 @@ fn very_obsolete() {}
421 ), 457 ),
422 deprecated: true, 458 deprecated: true,
423 }, 459 },
460 StructureNode {
461 parent: None,
462 label: "Some region name",
463 navigation_range: 501..528,
464 node_range: 501..528,
465 kind: Region,
466 detail: None,
467 deprecated: false,
468 },
424 ] 469 ]
425 "#]], 470 "#]],
426 ); 471 );
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs
index 3c02fdb11..c7e74aed8 100644
--- a/crates/ide/src/syntax_highlighting/tags.rs
+++ b/crates/ide/src/syntax_highlighting/tags.rs
@@ -107,6 +107,7 @@ impl HlTag {
107 SymbolKind::ValueParam => "value_param", 107 SymbolKind::ValueParam => "value_param",
108 SymbolKind::SelfParam => "self_keyword", 108 SymbolKind::SelfParam => "self_keyword",
109 SymbolKind::Impl => "self_type", 109 SymbolKind::Impl => "self_type",
110 SymbolKind::Region => "region",
110 }, 111 },
111 HlTag::Attribute => "attribute", 112 HlTag::Attribute => "attribute",
112 HlTag::BoolLiteral => "bool_literal", 113 HlTag::BoolLiteral => "bool_literal",
diff --git a/crates/ide_completion/src/item.rs b/crates/ide_completion/src/item.rs
index 9a4b5217a..7b553ea7a 100644
--- a/crates/ide_completion/src/item.rs
+++ b/crates/ide_completion/src/item.rs
@@ -225,6 +225,7 @@ impl CompletionItemKind {
225 SymbolKind::Local => "lc", 225 SymbolKind::Local => "lc",
226 SymbolKind::Macro => "ma", 226 SymbolKind::Macro => "ma",
227 SymbolKind::Module => "md", 227 SymbolKind::Module => "md",
228 SymbolKind::Region => "rn",
228 SymbolKind::SelfParam => "sp", 229 SymbolKind::SelfParam => "sp",
229 SymbolKind::Static => "sc", 230 SymbolKind::Static => "sc",
230 SymbolKind::Struct => "st", 231 SymbolKind::Struct => "st",
diff --git a/crates/ide_db/src/lib.rs b/crates/ide_db/src/lib.rs
index 88ee4a87d..d478841e2 100644
--- a/crates/ide_db/src/lib.rs
+++ b/crates/ide_db/src/lib.rs
@@ -148,6 +148,7 @@ pub enum SymbolKind {
148 Local, 148 Local,
149 Macro, 149 Macro,
150 Module, 150 Module,
151 Region,
151 SelfParam, 152 SelfParam,
152 Static, 153 Static,
153 Struct, 154 Struct,
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index d415ed4d3..e88818eb0 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -60,6 +60,7 @@ pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind {
60 | SymbolKind::ValueParam 60 | SymbolKind::ValueParam
61 | SymbolKind::Label => lsp_types::SymbolKind::Variable, 61 | SymbolKind::Label => lsp_types::SymbolKind::Variable,
62 SymbolKind::Union => lsp_types::SymbolKind::Struct, 62 SymbolKind::Union => lsp_types::SymbolKind::Struct,
63 SymbolKind::Region => lsp_types::SymbolKind::Namespace,
63 } 64 }
64} 65}
65 66
@@ -117,6 +118,7 @@ pub(crate) fn completion_item_kind(
117 SymbolKind::Local => lsp_types::CompletionItemKind::Variable, 118 SymbolKind::Local => lsp_types::CompletionItemKind::Variable,
118 SymbolKind::Macro => lsp_types::CompletionItemKind::Method, 119 SymbolKind::Macro => lsp_types::CompletionItemKind::Method,
119 SymbolKind::Module => lsp_types::CompletionItemKind::Module, 120 SymbolKind::Module => lsp_types::CompletionItemKind::Module,
121 SymbolKind::Region => lsp_types::CompletionItemKind::Keyword,
120 SymbolKind::SelfParam => lsp_types::CompletionItemKind::Value, 122 SymbolKind::SelfParam => lsp_types::CompletionItemKind::Value,
121 SymbolKind::Static => lsp_types::CompletionItemKind::Value, 123 SymbolKind::Static => lsp_types::CompletionItemKind::Value,
122 SymbolKind::Struct => lsp_types::CompletionItemKind::Struct, 124 SymbolKind::Struct => lsp_types::CompletionItemKind::Struct,
@@ -428,6 +430,7 @@ fn semantic_token_type_and_modifiers(
428 SymbolKind::TypeAlias => semantic_tokens::TYPE_ALIAS, 430 SymbolKind::TypeAlias => semantic_tokens::TYPE_ALIAS,
429 SymbolKind::Trait => lsp_types::SemanticTokenType::INTERFACE, 431 SymbolKind::Trait => lsp_types::SemanticTokenType::INTERFACE,
430 SymbolKind::Macro => lsp_types::SemanticTokenType::MACRO, 432 SymbolKind::Macro => lsp_types::SemanticTokenType::MACRO,
433 SymbolKind::Region => lsp_types::SemanticTokenType::NAMESPACE,
431 }, 434 },
432 HlTag::BuiltinType => semantic_tokens::BUILTIN_TYPE, 435 HlTag::BuiltinType => semantic_tokens::BUILTIN_TYPE,
433 HlTag::None => semantic_tokens::GENERIC, 436 HlTag::None => semantic_tokens::GENERIC,