From 4eff8ddb8b8352d432d87198d43c674696ca9344 Mon Sep 17 00:00:00 2001 From: Hrvoje Ban Date: Thu, 24 Jan 2019 18:21:17 +0100 Subject: Fill in DocumentSymbol::detail --- .../src/snapshots/tests__file_structure.snap | 98 ++++++++++++++++------ crates/ra_ide_api_light/src/structure.rs | 69 +++++++++++++-- crates/ra_lsp_server/src/main_loop/handlers.rs | 2 +- crates/ra_syntax/src/ast/generated.rs | 18 +++- crates/ra_syntax/src/grammar.ron | 51 ++++++----- 5 files changed, 179 insertions(+), 59 deletions(-) diff --git a/crates/ra_ide_api_light/src/snapshots/tests__file_structure.snap b/crates/ra_ide_api_light/src/snapshots/tests__file_structure.snap index 4661ea2c4..b96398950 100644 --- a/crates/ra_ide_api_light/src/snapshots/tests__file_structure.snap +++ b/crates/ra_ide_api_light/src/snapshots/tests__file_structure.snap @@ -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 expression: structure source: "crates\\ra_ide_api_light\\src\\structure.rs" @@ -10,7 +10,8 @@ source: "crates\\ra_ide_api_light\\src\\structure.rs" label: "Foo", navigation_range: [8; 11), node_range: [1; 26), - kind: STRUCT_DEF + kind: STRUCT_DEF, + detail: None }, StructureNode { parent: Some( @@ -19,64 +20,107 @@ source: "crates\\ra_ide_api_light\\src\\structure.rs" label: "x", navigation_range: [18; 19), node_range: [18; 24), - kind: NAMED_FIELD_DEF + kind: NAMED_FIELD_DEF, + detail: Some( + "i32" + ) }, StructureNode { parent: None, label: "m", navigation_range: [32; 33), - node_range: [28; 53), - kind: MODULE + node_range: [28; 158), + kind: MODULE, + detail: None }, StructureNode { parent: Some( 2 ), - label: "bar", - navigation_range: [43; 46), - node_range: [40; 51), - kind: FN_DEF + label: "bar1", + navigation_range: [43; 47), + node_range: [40; 52), + 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" + ) + }, + StructureNode { + parent: Some( + 2 + ), + label: "bar3", + navigation_range: [89; 93), + node_range: [86; 156), + kind: FN_DEF, + detail: Some( + "fn(a: A, b: B) -> Vec< u32 >" + ) }, StructureNode { parent: None, label: "E", - navigation_range: [60; 61), - node_range: [55; 75), - kind: ENUM_DEF + navigation_range: [165; 166), + node_range: [160; 180), + kind: ENUM_DEF, + detail: None }, StructureNode { parent: None, label: "T", - navigation_range: [81; 82), - node_range: [76; 88), - kind: TYPE_DEF + navigation_range: [186; 187), + node_range: [181; 193), + kind: TYPE_DEF, + detail: Some( + "()" + ) }, StructureNode { parent: None, label: "S", - navigation_range: [96; 97), - node_range: [89; 108), - kind: STATIC_DEF + navigation_range: [201; 202), + node_range: [194; 213), + kind: STATIC_DEF, + detail: Some( + "i32" + ) }, StructureNode { parent: None, label: "C", - navigation_range: [115; 116), - node_range: [109; 127), - kind: CONST_DEF + navigation_range: [220; 221), + node_range: [214; 232), + kind: CONST_DEF, + detail: Some( + "i32" + ) }, StructureNode { parent: None, label: "impl E", - navigation_range: [134; 135), - node_range: [129; 138), - kind: IMPL_BLOCK + navigation_range: [239; 240), + node_range: [234; 243), + kind: IMPL_BLOCK, + detail: None }, StructureNode { parent: None, label: "impl fmt::Debug for E", - navigation_range: [160; 161), - node_range: [140; 164), - kind: IMPL_BLOCK + navigation_range: [265; 266), + node_range: [245; 269), + kind: IMPL_BLOCK, + detail: None } ] diff --git a/crates/ra_ide_api_light/src/structure.rs b/crates/ra_ide_api_light/src/structure.rs index 3c6f39e16..e3713c217 100644 --- a/crates/ra_ide_api_light/src/structure.rs +++ b/crates/ra_ide_api_light/src/structure.rs @@ -2,7 +2,7 @@ use crate::TextRange; use ra_syntax::{ algo::visit::{visitor, Visitor}, - ast::{self, NameOwner}, + ast::{self, NameOwner, TypeParamsOwner}, AstNode, SourceFile, SyntaxKind, SyntaxNode, WalkEvent, }; @@ -13,6 +13,7 @@ pub struct StructureNode { pub navigation_range: TextRange, pub node_range: TextRange, pub kind: SyntaxKind, + pub detail: Option, } pub fn file_structure(file: &SourceFile) -> Vec { @@ -40,6 +41,22 @@ pub fn file_structure(file: &SourceFile) -> Vec { fn structure_node(node: &SyntaxNode) -> Option { fn decl(node: &N) -> Option { + decl_with_detail(node, None) + } + + fn decl_with_type_ref( + node: &N, + type_ref: Option<&ast::TypeRef>, + ) -> Option { + 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(node: &N, detail: Option) -> Option { let name = node.name()?; Some(StructureNode { parent: None, @@ -47,19 +64,50 @@ fn structure_node(node: &SyntaxNode) -> Option { navigation_range: name.syntax().range(), node_range: node.syntax().range(), 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() - .visit(decl::) + .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::) - .visit(decl::) + .visit(|nfd: &ast::NamedFieldDef| decl_with_type_ref(nfd, nfd.type_ref())) .visit(decl::) .visit(decl::) .visit(decl::) - .visit(decl::) - .visit(decl::) - .visit(decl::) + .visit(|td: &ast::TypeDef| decl_with_type_ref(td, td.type_ref())) + .visit(|cd: &ast::ConstDef| decl_with_type_ref(cd, cd.type_ref())) + .visit(|sd: &ast::StaticDef| decl_with_type_ref(sd, sd.type_ref())) .visit(|im: &ast::ImplBlock| { let target_type = im.target_type()?; let target_trait = im.target_trait(); @@ -78,6 +126,7 @@ fn structure_node(node: &SyntaxNode) -> Option { navigation_range: target_type.syntax().range(), node_range: im.syntax().range(), kind: im.syntax().kind(), + detail: None, }; Some(node) }) @@ -98,7 +147,13 @@ struct Foo { } mod m { - fn bar() {} + fn bar1() {} + fn bar2(t: T) -> T {} + fn bar3(a: A, + b: B) -> Vec< + u32 + > {} } enum E { X, Y(i32) } diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index d84f762f4..c0fe0216d 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -136,7 +136,7 @@ pub fn handle_document_symbol( for symbol in world.analysis().file_structure(file_id) { let doc_symbol = DocumentSymbol { name: symbol.label, - detail: Some("".to_string()), + detail: symbol.detail, kind: symbol.kind.conv(), deprecated: None, range: symbol.node_range.conv_with(&line_index), diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index ac6c8a835..be16511df 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -526,7 +526,11 @@ impl ast::NameOwner for ConstDef {} impl ast::TypeParamsOwner for ConstDef {} impl ast::AttrsOwner for ConstDef {} impl ast::DocCommentsOwner for ConstDef {} -impl ConstDef {} +impl ConstDef { + pub fn type_ref(&self) -> Option<&TypeRef> { + super::child_opt(self) + } +} // ContinueExpr #[derive(Debug, PartialEq, Eq, Hash)] @@ -3015,7 +3019,11 @@ impl ast::NameOwner for StaticDef {} impl ast::TypeParamsOwner for StaticDef {} impl ast::AttrsOwner for StaticDef {} impl ast::DocCommentsOwner for StaticDef {} -impl StaticDef {} +impl StaticDef { + pub fn type_ref(&self) -> Option<&TypeRef> { + super::child_opt(self) + } +} // Stmt #[derive(Debug, PartialEq, Eq, Hash)] @@ -3491,7 +3499,11 @@ impl ast::NameOwner for TypeDef {} impl ast::TypeParamsOwner for TypeDef {} impl ast::AttrsOwner for TypeDef {} impl ast::DocCommentsOwner for TypeDef {} -impl TypeDef {} +impl TypeDef { + pub fn type_ref(&self) -> Option<&TypeRef> { + super::child_opt(self) + } +} // TypeParam #[derive(Debug, PartialEq, Eq, Hash)] diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index c5297e46d..9a6f990b6 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -289,27 +289,36 @@ Grammar( collections: [["impl_items", "ImplItem"]], traits: [ "FnDefOwner", "ModuleItemOwner" ], ), - "ConstDef": ( traits: [ - "VisibilityOwner", - "NameOwner", - "TypeParamsOwner", - "AttrsOwner", - "DocCommentsOwner" - ] ), - "StaticDef": ( traits: [ - "VisibilityOwner", - "NameOwner", - "TypeParamsOwner", - "AttrsOwner", - "DocCommentsOwner" - ] ), - "TypeDef": ( traits: [ - "VisibilityOwner", - "NameOwner", - "TypeParamsOwner", - "AttrsOwner", - "DocCommentsOwner" - ] ), + "ConstDef": ( + traits: [ + "VisibilityOwner", + "NameOwner", + "TypeParamsOwner", + "AttrsOwner", + "DocCommentsOwner" + ], + options: ["TypeRef"] + ), + "StaticDef": ( + traits: [ + "VisibilityOwner", + "NameOwner", + "TypeParamsOwner", + "AttrsOwner", + "DocCommentsOwner" + ], + options: ["TypeRef"] + ), + "TypeDef": ( + traits: [ + "VisibilityOwner", + "NameOwner", + "TypeParamsOwner", + "AttrsOwner", + "DocCommentsOwner" + ], + options: ["TypeRef"] + ), "ImplBlock": (options: ["ItemList"]), "ParenType": (options: ["TypeRef"]), -- cgit v1.2.3