Fill in DocumentSymbol::detail

This commit is contained in:
Hrvoje Ban 2019-01-24 18:21:17 +01:00
parent abb9bfe44d
commit 4eff8ddb8b
5 changed files with 179 additions and 59 deletions

View File

@ -1,5 +1,5 @@
--- ---
created: "2019-01-22T14:45:01.959724300+00:00" created: "2019-01-24T18:04:00.090162+00:00"
creator: insta@0.4.0 creator: insta@0.4.0
expression: structure expression: structure
source: "crates\\ra_ide_api_light\\src\\structure.rs" source: "crates\\ra_ide_api_light\\src\\structure.rs"
@ -10,7 +10,8 @@ source: "crates\\ra_ide_api_light\\src\\structure.rs"
label: "Foo", label: "Foo",
navigation_range: [8; 11), navigation_range: [8; 11),
node_range: [1; 26), node_range: [1; 26),
kind: STRUCT_DEF kind: STRUCT_DEF,
detail: None
}, },
StructureNode { StructureNode {
parent: Some( parent: Some(
@ -19,64 +20,107 @@ source: "crates\\ra_ide_api_light\\src\\structure.rs"
label: "x", label: "x",
navigation_range: [18; 19), navigation_range: [18; 19),
node_range: [18; 24), node_range: [18; 24),
kind: NAMED_FIELD_DEF kind: NAMED_FIELD_DEF,
detail: Some(
"i32"
)
}, },
StructureNode { StructureNode {
parent: None, parent: None,
label: "m", label: "m",
navigation_range: [32; 33), navigation_range: [32; 33),
node_range: [28; 53), node_range: [28; 158),
kind: MODULE kind: MODULE,
detail: None
}, },
StructureNode { StructureNode {
parent: Some( parent: Some(
2 2
), ),
label: "bar", label: "bar1",
navigation_range: [43; 46), navigation_range: [43; 47),
node_range: [40; 51), node_range: [40; 52),
kind: FN_DEF kind: FN_DEF,
detail: Some(
"fn()"
)
},
StructureNode {
parent: Some(
2
),
label: "bar2",
navigation_range: [60; 64),
node_range: [57; 81),
kind: FN_DEF,
detail: Some(
"fn<T>(t: T) -> T"
)
},
StructureNode {
parent: Some(
2
),
label: "bar3",
navigation_range: [89; 93),
node_range: [86; 156),
kind: FN_DEF,
detail: Some(
"fn<A, B>(a: A, b: B) -> Vec< u32 >"
)
}, },
StructureNode { StructureNode {
parent: None, parent: None,
label: "E", label: "E",
navigation_range: [60; 61), navigation_range: [165; 166),
node_range: [55; 75), node_range: [160; 180),
kind: ENUM_DEF kind: ENUM_DEF,
detail: None
}, },
StructureNode { StructureNode {
parent: None, parent: None,
label: "T", label: "T",
navigation_range: [81; 82), navigation_range: [186; 187),
node_range: [76; 88), node_range: [181; 193),
kind: TYPE_DEF kind: TYPE_DEF,
detail: Some(
"()"
)
}, },
StructureNode { StructureNode {
parent: None, parent: None,
label: "S", label: "S",
navigation_range: [96; 97), navigation_range: [201; 202),
node_range: [89; 108), node_range: [194; 213),
kind: STATIC_DEF kind: STATIC_DEF,
detail: Some(
"i32"
)
}, },
StructureNode { StructureNode {
parent: None, parent: None,
label: "C", label: "C",
navigation_range: [115; 116), navigation_range: [220; 221),
node_range: [109; 127), node_range: [214; 232),
kind: CONST_DEF kind: CONST_DEF,
detail: Some(
"i32"
)
}, },
StructureNode { StructureNode {
parent: None, parent: None,
label: "impl E", label: "impl E",
navigation_range: [134; 135), navigation_range: [239; 240),
node_range: [129; 138), node_range: [234; 243),
kind: IMPL_BLOCK kind: IMPL_BLOCK,
detail: None
}, },
StructureNode { StructureNode {
parent: None, parent: None,
label: "impl fmt::Debug for E", label: "impl fmt::Debug for E",
navigation_range: [160; 161), navigation_range: [265; 266),
node_range: [140; 164), node_range: [245; 269),
kind: IMPL_BLOCK kind: IMPL_BLOCK,
detail: None
} }
] ]

View File

@ -2,7 +2,7 @@ use crate::TextRange;
use ra_syntax::{ use ra_syntax::{
algo::visit::{visitor, Visitor}, algo::visit::{visitor, Visitor},
ast::{self, NameOwner}, ast::{self, NameOwner, TypeParamsOwner},
AstNode, SourceFile, SyntaxKind, SyntaxNode, WalkEvent, AstNode, SourceFile, SyntaxKind, SyntaxNode, WalkEvent,
}; };
@ -13,6 +13,7 @@ pub struct StructureNode {
pub navigation_range: TextRange, pub navigation_range: TextRange,
pub node_range: TextRange, pub node_range: TextRange,
pub kind: SyntaxKind, pub kind: SyntaxKind,
pub detail: Option<String>,
} }
pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> { pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
@ -40,6 +41,22 @@ pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
fn decl<N: NameOwner>(node: &N) -> Option<StructureNode> { fn decl<N: NameOwner>(node: &N) -> Option<StructureNode> {
decl_with_detail(node, None)
}
fn decl_with_type_ref<N: NameOwner>(
node: &N,
type_ref: Option<&ast::TypeRef>,
) -> Option<StructureNode> {
let detail = type_ref.map(|type_ref| {
let mut detail = String::new();
collapse_ws(type_ref.syntax(), &mut detail);
detail
});
decl_with_detail(node, detail)
}
fn decl_with_detail<N: NameOwner>(node: &N, detail: Option<String>) -> Option<StructureNode> {
let name = node.name()?; let name = node.name()?;
Some(StructureNode { Some(StructureNode {
parent: None, parent: None,
@ -47,19 +64,50 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
navigation_range: name.syntax().range(), navigation_range: name.syntax().range(),
node_range: node.syntax().range(), node_range: node.syntax().range(),
kind: node.syntax().kind(), kind: node.syntax().kind(),
detail,
}) })
} }
fn collapse_ws(node: &SyntaxNode, output: &mut String) {
let mut can_insert_ws = false;
for line in node.text().chunks().flat_map(|chunk| chunk.lines()) {
let line = line.trim();
if line.is_empty() {
if can_insert_ws {
output.push_str(" ");
can_insert_ws = false;
}
} else {
output.push_str(line);
can_insert_ws = true;
}
}
}
visitor() visitor()
.visit(decl::<ast::FnDef>) .visit(|fn_def: &ast::FnDef| {
let mut detail = String::from("fn");
if let Some(type_param_list) = fn_def.type_param_list() {
collapse_ws(type_param_list.syntax(), &mut detail);
}
if let Some(param_list) = fn_def.param_list() {
collapse_ws(param_list.syntax(), &mut detail);
}
if let Some(ret_type) = fn_def.ret_type() {
detail.push_str(" ");
collapse_ws(ret_type.syntax(), &mut detail);
}
decl_with_detail(fn_def, Some(detail))
})
.visit(decl::<ast::StructDef>) .visit(decl::<ast::StructDef>)
.visit(decl::<ast::NamedFieldDef>) .visit(|nfd: &ast::NamedFieldDef| decl_with_type_ref(nfd, nfd.type_ref()))
.visit(decl::<ast::EnumDef>) .visit(decl::<ast::EnumDef>)
.visit(decl::<ast::TraitDef>) .visit(decl::<ast::TraitDef>)
.visit(decl::<ast::Module>) .visit(decl::<ast::Module>)
.visit(decl::<ast::TypeDef>) .visit(|td: &ast::TypeDef| decl_with_type_ref(td, td.type_ref()))
.visit(decl::<ast::ConstDef>) .visit(|cd: &ast::ConstDef| decl_with_type_ref(cd, cd.type_ref()))
.visit(decl::<ast::StaticDef>) .visit(|sd: &ast::StaticDef| decl_with_type_ref(sd, sd.type_ref()))
.visit(|im: &ast::ImplBlock| { .visit(|im: &ast::ImplBlock| {
let target_type = im.target_type()?; let target_type = im.target_type()?;
let target_trait = im.target_trait(); let target_trait = im.target_trait();
@ -78,6 +126,7 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
navigation_range: target_type.syntax().range(), navigation_range: target_type.syntax().range(),
node_range: im.syntax().range(), node_range: im.syntax().range(),
kind: im.syntax().kind(), kind: im.syntax().kind(),
detail: None,
}; };
Some(node) Some(node)
}) })
@ -98,7 +147,13 @@ struct Foo {
} }
mod m { mod m {
fn bar() {} fn bar1() {}
fn bar2<T>(t: T) -> T {}
fn bar3<A,
B>(a: A,
b: B) -> Vec<
u32
> {}
} }
enum E { X, Y(i32) } enum E { X, Y(i32) }

View File

@ -136,7 +136,7 @@ pub fn handle_document_symbol(
for symbol in world.analysis().file_structure(file_id) { for symbol in world.analysis().file_structure(file_id) {
let doc_symbol = DocumentSymbol { let doc_symbol = DocumentSymbol {
name: symbol.label, name: symbol.label,
detail: Some("".to_string()), detail: symbol.detail,
kind: symbol.kind.conv(), kind: symbol.kind.conv(),
deprecated: None, deprecated: None,
range: symbol.node_range.conv_with(&line_index), range: symbol.node_range.conv_with(&line_index),

View File

@ -526,7 +526,11 @@ impl ast::NameOwner for ConstDef {}
impl ast::TypeParamsOwner for ConstDef {} impl ast::TypeParamsOwner for ConstDef {}
impl ast::AttrsOwner for ConstDef {} impl ast::AttrsOwner for ConstDef {}
impl ast::DocCommentsOwner for ConstDef {} impl ast::DocCommentsOwner for ConstDef {}
impl ConstDef {} impl ConstDef {
pub fn type_ref(&self) -> Option<&TypeRef> {
super::child_opt(self)
}
}
// ContinueExpr // ContinueExpr
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
@ -3015,7 +3019,11 @@ impl ast::NameOwner for StaticDef {}
impl ast::TypeParamsOwner for StaticDef {} impl ast::TypeParamsOwner for StaticDef {}
impl ast::AttrsOwner for StaticDef {} impl ast::AttrsOwner for StaticDef {}
impl ast::DocCommentsOwner for StaticDef {} impl ast::DocCommentsOwner for StaticDef {}
impl StaticDef {} impl StaticDef {
pub fn type_ref(&self) -> Option<&TypeRef> {
super::child_opt(self)
}
}
// Stmt // Stmt
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
@ -3491,7 +3499,11 @@ impl ast::NameOwner for TypeDef {}
impl ast::TypeParamsOwner for TypeDef {} impl ast::TypeParamsOwner for TypeDef {}
impl ast::AttrsOwner for TypeDef {} impl ast::AttrsOwner for TypeDef {}
impl ast::DocCommentsOwner for TypeDef {} impl ast::DocCommentsOwner for TypeDef {}
impl TypeDef {} impl TypeDef {
pub fn type_ref(&self) -> Option<&TypeRef> {
super::child_opt(self)
}
}
// TypeParam // TypeParam
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]

View File

@ -289,27 +289,36 @@ Grammar(
collections: [["impl_items", "ImplItem"]], collections: [["impl_items", "ImplItem"]],
traits: [ "FnDefOwner", "ModuleItemOwner" ], traits: [ "FnDefOwner", "ModuleItemOwner" ],
), ),
"ConstDef": ( traits: [ "ConstDef": (
traits: [
"VisibilityOwner", "VisibilityOwner",
"NameOwner", "NameOwner",
"TypeParamsOwner", "TypeParamsOwner",
"AttrsOwner", "AttrsOwner",
"DocCommentsOwner" "DocCommentsOwner"
] ), ],
"StaticDef": ( traits: [ options: ["TypeRef"]
),
"StaticDef": (
traits: [
"VisibilityOwner", "VisibilityOwner",
"NameOwner", "NameOwner",
"TypeParamsOwner", "TypeParamsOwner",
"AttrsOwner", "AttrsOwner",
"DocCommentsOwner" "DocCommentsOwner"
] ), ],
"TypeDef": ( traits: [ options: ["TypeRef"]
),
"TypeDef": (
traits: [
"VisibilityOwner", "VisibilityOwner",
"NameOwner", "NameOwner",
"TypeParamsOwner", "TypeParamsOwner",
"AttrsOwner", "AttrsOwner",
"DocCommentsOwner" "DocCommentsOwner"
] ), ],
options: ["TypeRef"]
),
"ImplBlock": (options: ["ItemList"]), "ImplBlock": (options: ["ItemList"]),
"ParenType": (options: ["TypeRef"]), "ParenType": (options: ["TypeRef"]),