mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 04:44:57 +00:00
Provide regions in file structure
This commit is contained in:
parent
af8440b848
commit
71a97a2d8c
5 changed files with 55 additions and 4 deletions
|
@ -1,7 +1,8 @@
|
||||||
use ide_db::SymbolKind;
|
use ide_db::SymbolKind;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, AttrsOwner, GenericParamsOwner, NameOwner},
|
ast::{self, AttrsOwner, GenericParamsOwner, NameOwner},
|
||||||
match_ast, AstNode, SourceFile, SyntaxNode, TextRange, WalkEvent,
|
match_ast, AstNode, AstToken, NodeOrToken, SourceFile, SyntaxNode, SyntaxToken, TextRange,
|
||||||
|
WalkEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -32,20 +33,32 @@ pub(crate) fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
|
||||||
let mut res = Vec::new();
|
let mut res = Vec::new();
|
||||||
let mut stack = Vec::new();
|
let mut stack = Vec::new();
|
||||||
|
|
||||||
for event in file.syntax().preorder() {
|
for event in file.syntax().preorder_with_tokens() {
|
||||||
match event {
|
match event {
|
||||||
WalkEvent::Enter(node) => {
|
WalkEvent::Enter(NodeOrToken::Node(node)) => {
|
||||||
if let Some(mut symbol) = structure_node(&node) {
|
if let Some(mut symbol) = structure_node(&node) {
|
||||||
symbol.parent = stack.last().copied();
|
symbol.parent = stack.last().copied();
|
||||||
stack.push(res.len());
|
stack.push(res.len());
|
||||||
res.push(symbol);
|
res.push(symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WalkEvent::Leave(node) => {
|
WalkEvent::Leave(NodeOrToken::Node(node)) => {
|
||||||
if structure_node(&node).is_some() {
|
if structure_node(&node).is_some() {
|
||||||
stack.pop().unwrap();
|
stack.pop().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
WalkEvent::Enter(NodeOrToken::Token(token)) => {
|
||||||
|
if let Some(mut symbol) = structure_token(token) {
|
||||||
|
symbol.parent = stack.last().copied();
|
||||||
|
stack.push(res.len());
|
||||||
|
res.push(symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WalkEvent::Leave(NodeOrToken::Token(token)) => {
|
||||||
|
if structure_token(token).is_some() {
|
||||||
|
stack.pop().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
|
@ -159,6 +172,26 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn structure_token(token: SyntaxToken) -> Option<StructureNode> {
|
||||||
|
if let Some(comment) = ast::Comment::cast(token) {
|
||||||
|
let text = comment.text().trim();
|
||||||
|
|
||||||
|
if let Some(region_name) = text.strip_prefix("// region:").map(|text| text.trim()) {
|
||||||
|
return Some(StructureNode {
|
||||||
|
parent: None,
|
||||||
|
label: region_name.to_string(),
|
||||||
|
navigation_range: comment.syntax().text_range(),
|
||||||
|
node_range: comment.syntax().text_range(),
|
||||||
|
kind: SymbolKind::Region,
|
||||||
|
detail: None,
|
||||||
|
deprecated: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use expect_test::{expect, Expect};
|
use expect_test::{expect, Expect};
|
||||||
|
@ -217,6 +250,9 @@ fn obsolete() {}
|
||||||
|
|
||||||
#[deprecated(note = "for awhile")]
|
#[deprecated(note = "for awhile")]
|
||||||
fn very_obsolete() {}
|
fn very_obsolete() {}
|
||||||
|
|
||||||
|
// region: Some region name
|
||||||
|
// endregion
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
[
|
[
|
||||||
|
@ -421,6 +457,15 @@ fn very_obsolete() {}
|
||||||
),
|
),
|
||||||
deprecated: true,
|
deprecated: true,
|
||||||
},
|
},
|
||||||
|
StructureNode {
|
||||||
|
parent: None,
|
||||||
|
label: "Some region name",
|
||||||
|
navigation_range: 501..528,
|
||||||
|
node_range: 501..528,
|
||||||
|
kind: Region,
|
||||||
|
detail: None,
|
||||||
|
deprecated: false,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
|
|
@ -107,6 +107,7 @@ impl HlTag {
|
||||||
SymbolKind::ValueParam => "value_param",
|
SymbolKind::ValueParam => "value_param",
|
||||||
SymbolKind::SelfParam => "self_keyword",
|
SymbolKind::SelfParam => "self_keyword",
|
||||||
SymbolKind::Impl => "self_type",
|
SymbolKind::Impl => "self_type",
|
||||||
|
SymbolKind::Region => "region",
|
||||||
},
|
},
|
||||||
HlTag::Attribute => "attribute",
|
HlTag::Attribute => "attribute",
|
||||||
HlTag::BoolLiteral => "bool_literal",
|
HlTag::BoolLiteral => "bool_literal",
|
||||||
|
|
|
@ -225,6 +225,7 @@ impl CompletionItemKind {
|
||||||
SymbolKind::Local => "lc",
|
SymbolKind::Local => "lc",
|
||||||
SymbolKind::Macro => "ma",
|
SymbolKind::Macro => "ma",
|
||||||
SymbolKind::Module => "md",
|
SymbolKind::Module => "md",
|
||||||
|
SymbolKind::Region => "rn",
|
||||||
SymbolKind::SelfParam => "sp",
|
SymbolKind::SelfParam => "sp",
|
||||||
SymbolKind::Static => "sc",
|
SymbolKind::Static => "sc",
|
||||||
SymbolKind::Struct => "st",
|
SymbolKind::Struct => "st",
|
||||||
|
|
|
@ -148,6 +148,7 @@ pub enum SymbolKind {
|
||||||
Local,
|
Local,
|
||||||
Macro,
|
Macro,
|
||||||
Module,
|
Module,
|
||||||
|
Region,
|
||||||
SelfParam,
|
SelfParam,
|
||||||
Static,
|
Static,
|
||||||
Struct,
|
Struct,
|
||||||
|
|
|
@ -60,6 +60,7 @@ pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind {
|
||||||
| SymbolKind::ValueParam
|
| SymbolKind::ValueParam
|
||||||
| SymbolKind::Label => lsp_types::SymbolKind::Variable,
|
| SymbolKind::Label => lsp_types::SymbolKind::Variable,
|
||||||
SymbolKind::Union => lsp_types::SymbolKind::Struct,
|
SymbolKind::Union => lsp_types::SymbolKind::Struct,
|
||||||
|
SymbolKind::Region => lsp_types::SymbolKind::Namespace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +118,7 @@ pub(crate) fn completion_item_kind(
|
||||||
SymbolKind::Local => lsp_types::CompletionItemKind::Variable,
|
SymbolKind::Local => lsp_types::CompletionItemKind::Variable,
|
||||||
SymbolKind::Macro => lsp_types::CompletionItemKind::Method,
|
SymbolKind::Macro => lsp_types::CompletionItemKind::Method,
|
||||||
SymbolKind::Module => lsp_types::CompletionItemKind::Module,
|
SymbolKind::Module => lsp_types::CompletionItemKind::Module,
|
||||||
|
SymbolKind::Region => lsp_types::CompletionItemKind::Keyword,
|
||||||
SymbolKind::SelfParam => lsp_types::CompletionItemKind::Value,
|
SymbolKind::SelfParam => lsp_types::CompletionItemKind::Value,
|
||||||
SymbolKind::Static => lsp_types::CompletionItemKind::Value,
|
SymbolKind::Static => lsp_types::CompletionItemKind::Value,
|
||||||
SymbolKind::Struct => lsp_types::CompletionItemKind::Struct,
|
SymbolKind::Struct => lsp_types::CompletionItemKind::Struct,
|
||||||
|
@ -428,6 +430,7 @@ fn semantic_token_type_and_modifiers(
|
||||||
SymbolKind::TypeAlias => semantic_tokens::TYPE_ALIAS,
|
SymbolKind::TypeAlias => semantic_tokens::TYPE_ALIAS,
|
||||||
SymbolKind::Trait => lsp_types::SemanticTokenType::INTERFACE,
|
SymbolKind::Trait => lsp_types::SemanticTokenType::INTERFACE,
|
||||||
SymbolKind::Macro => lsp_types::SemanticTokenType::MACRO,
|
SymbolKind::Macro => lsp_types::SemanticTokenType::MACRO,
|
||||||
|
SymbolKind::Region => lsp_types::SemanticTokenType::NAMESPACE,
|
||||||
},
|
},
|
||||||
HlTag::BuiltinType => semantic_tokens::BUILTIN_TYPE,
|
HlTag::BuiltinType => semantic_tokens::BUILTIN_TYPE,
|
||||||
HlTag::None => semantic_tokens::GENERIC,
|
HlTag::None => semantic_tokens::GENERIC,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue