diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-25 07:13:16 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-25 07:13:16 +0000 |
commit | 675943712ce92e0ce04e85e6952f50bcbf1ee611 (patch) | |
tree | 20e611b63e26157457855db38d4fd866e6d3e7cd | |
parent | 1d4b421aad0bbcd26d88e65b28dbbb4efb51d155 (diff) | |
parent | 4eff8ddb8b8352d432d87198d43c674696ca9344 (diff) |
Merge #630
630: Fill in DocumentSymbol::detail r=matklad a=hban
Closes: #516
I just pulled type text from the syntax node and "formatted" is bit. VS Code can't really handle multi-line symbol detail (it's will crop it when rendering), so that formatting will just collapse all white-space to singe space. It isn't pretty, but maybe there's a better way.
Issue also mentions "need to be done for `NavigationTarget` to `SymbolInformation`", but `SymbolInformation` doesn't have detail field on it?
Co-authored-by: Hrvoje Ban <[email protected]>
-rw-r--r-- | crates/ra_ide_api_light/src/snapshots/tests__file_structure.snap | 98 | ||||
-rw-r--r-- | crates/ra_ide_api_light/src/structure.rs | 69 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 18 | ||||
-rw-r--r-- | 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 @@ | |||
1 | --- | 1 | --- |
2 | created: "2019-01-22T14:45:01.959724300+00:00" | 2 | created: "2019-01-24T18:04:00.090162+00:00" |
3 | creator: [email protected] | 3 | creator: [email protected] |
4 | expression: structure | 4 | expression: structure |
5 | source: "crates\\ra_ide_api_light\\src\\structure.rs" | 5 | source: "crates\\ra_ide_api_light\\src\\structure.rs" |
@@ -10,7 +10,8 @@ source: "crates\\ra_ide_api_light\\src\\structure.rs" | |||
10 | label: "Foo", | 10 | label: "Foo", |
11 | navigation_range: [8; 11), | 11 | navigation_range: [8; 11), |
12 | node_range: [1; 26), | 12 | node_range: [1; 26), |
13 | kind: STRUCT_DEF | 13 | kind: STRUCT_DEF, |
14 | detail: None | ||
14 | }, | 15 | }, |
15 | StructureNode { | 16 | StructureNode { |
16 | parent: Some( | 17 | parent: Some( |
@@ -19,64 +20,107 @@ source: "crates\\ra_ide_api_light\\src\\structure.rs" | |||
19 | label: "x", | 20 | label: "x", |
20 | navigation_range: [18; 19), | 21 | navigation_range: [18; 19), |
21 | node_range: [18; 24), | 22 | node_range: [18; 24), |
22 | kind: NAMED_FIELD_DEF | 23 | kind: NAMED_FIELD_DEF, |
24 | detail: Some( | ||
25 | "i32" | ||
26 | ) | ||
23 | }, | 27 | }, |
24 | StructureNode { | 28 | StructureNode { |
25 | parent: None, | 29 | parent: None, |
26 | label: "m", | 30 | label: "m", |
27 | navigation_range: [32; 33), | 31 | navigation_range: [32; 33), |
28 | node_range: [28; 53), | 32 | node_range: [28; 158), |
29 | kind: MODULE | 33 | kind: MODULE, |
34 | detail: None | ||
30 | }, | 35 | }, |
31 | StructureNode { | 36 | StructureNode { |
32 | parent: Some( | 37 | parent: Some( |
33 | 2 | 38 | 2 |
34 | ), | 39 | ), |
35 | label: "bar", | 40 | label: "bar1", |
36 | navigation_range: [43; 46), | 41 | navigation_range: [43; 47), |
37 | node_range: [40; 51), | 42 | node_range: [40; 52), |
38 | kind: FN_DEF | 43 | kind: FN_DEF, |
44 | detail: Some( | ||
45 | "fn()" | ||
46 | ) | ||
47 | }, | ||
48 | StructureNode { | ||
49 | parent: Some( | ||
50 | 2 | ||
51 | ), | ||
52 | label: "bar2", | ||
53 | navigation_range: [60; 64), | ||
54 | node_range: [57; 81), | ||
55 | kind: FN_DEF, | ||
56 | detail: Some( | ||
57 | "fn<T>(t: T) -> T" | ||
58 | ) | ||
59 | }, | ||
60 | StructureNode { | ||
61 | parent: Some( | ||
62 | 2 | ||
63 | ), | ||
64 | label: "bar3", | ||
65 | navigation_range: [89; 93), | ||
66 | node_range: [86; 156), | ||
67 | kind: FN_DEF, | ||
68 | detail: Some( | ||
69 | "fn<A, B>(a: A, b: B) -> Vec< u32 >" | ||
70 | ) | ||
39 | }, | 71 | }, |
40 | StructureNode { | 72 | StructureNode { |
41 | parent: None, | 73 | parent: None, |
42 | label: "E", | 74 | label: "E", |
43 | navigation_range: [60; 61), | 75 | navigation_range: [165; 166), |
44 | node_range: [55; 75), | 76 | node_range: [160; 180), |
45 | kind: ENUM_DEF | 77 | kind: ENUM_DEF, |
78 | detail: None | ||
46 | }, | 79 | }, |
47 | StructureNode { | 80 | StructureNode { |
48 | parent: None, | 81 | parent: None, |
49 | label: "T", | 82 | label: "T", |
50 | navigation_range: [81; 82), | 83 | navigation_range: [186; 187), |
51 | node_range: [76; 88), | 84 | node_range: [181; 193), |
52 | kind: TYPE_DEF | 85 | kind: TYPE_DEF, |
86 | detail: Some( | ||
87 | "()" | ||
88 | ) | ||
53 | }, | 89 | }, |
54 | StructureNode { | 90 | StructureNode { |
55 | parent: None, | 91 | parent: None, |
56 | label: "S", | 92 | label: "S", |
57 | navigation_range: [96; 97), | 93 | navigation_range: [201; 202), |
58 | node_range: [89; 108), | 94 | node_range: [194; 213), |
59 | kind: STATIC_DEF | 95 | kind: STATIC_DEF, |
96 | detail: Some( | ||
97 | "i32" | ||
98 | ) | ||
60 | }, | 99 | }, |
61 | StructureNode { | 100 | StructureNode { |
62 | parent: None, | 101 | parent: None, |
63 | label: "C", | 102 | label: "C", |
64 | navigation_range: [115; 116), | 103 | navigation_range: [220; 221), |
65 | node_range: [109; 127), | 104 | node_range: [214; 232), |
66 | kind: CONST_DEF | 105 | kind: CONST_DEF, |
106 | detail: Some( | ||
107 | "i32" | ||
108 | ) | ||
67 | }, | 109 | }, |
68 | StructureNode { | 110 | StructureNode { |
69 | parent: None, | 111 | parent: None, |
70 | label: "impl E", | 112 | label: "impl E", |
71 | navigation_range: [134; 135), | 113 | navigation_range: [239; 240), |
72 | node_range: [129; 138), | 114 | node_range: [234; 243), |
73 | kind: IMPL_BLOCK | 115 | kind: IMPL_BLOCK, |
116 | detail: None | ||
74 | }, | 117 | }, |
75 | StructureNode { | 118 | StructureNode { |
76 | parent: None, | 119 | parent: None, |
77 | label: "impl fmt::Debug for E", | 120 | label: "impl fmt::Debug for E", |
78 | navigation_range: [160; 161), | 121 | navigation_range: [265; 266), |
79 | node_range: [140; 164), | 122 | node_range: [245; 269), |
80 | kind: IMPL_BLOCK | 123 | kind: IMPL_BLOCK, |
124 | detail: None | ||
81 | } | 125 | } |
82 | ] | 126 | ] |
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; | |||
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | algo::visit::{visitor, Visitor}, | 4 | algo::visit::{visitor, Visitor}, |
5 | ast::{self, NameOwner}, | 5 | ast::{self, NameOwner, TypeParamsOwner}, |
6 | AstNode, SourceFile, SyntaxKind, SyntaxNode, WalkEvent, | 6 | AstNode, SourceFile, SyntaxKind, SyntaxNode, WalkEvent, |
7 | }; | 7 | }; |
8 | 8 | ||
@@ -13,6 +13,7 @@ pub struct StructureNode { | |||
13 | pub navigation_range: TextRange, | 13 | pub navigation_range: TextRange, |
14 | pub node_range: TextRange, | 14 | pub node_range: TextRange, |
15 | pub kind: SyntaxKind, | 15 | pub kind: SyntaxKind, |
16 | pub detail: Option<String>, | ||
16 | } | 17 | } |
17 | 18 | ||
18 | pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> { | 19 | pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> { |
@@ -40,6 +41,22 @@ pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> { | |||
40 | 41 | ||
41 | fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { | 42 | fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { |
42 | fn decl<N: NameOwner>(node: &N) -> Option<StructureNode> { | 43 | fn decl<N: NameOwner>(node: &N) -> Option<StructureNode> { |
44 | decl_with_detail(node, None) | ||
45 | } | ||
46 | |||
47 | fn decl_with_type_ref<N: NameOwner>( | ||
48 | node: &N, | ||
49 | type_ref: Option<&ast::TypeRef>, | ||
50 | ) -> Option<StructureNode> { | ||
51 | let detail = type_ref.map(|type_ref| { | ||
52 | let mut detail = String::new(); | ||
53 | collapse_ws(type_ref.syntax(), &mut detail); | ||
54 | detail | ||
55 | }); | ||
56 | decl_with_detail(node, detail) | ||
57 | } | ||
58 | |||
59 | fn decl_with_detail<N: NameOwner>(node: &N, detail: Option<String>) -> Option<StructureNode> { | ||
43 | let name = node.name()?; | 60 | let name = node.name()?; |
44 | Some(StructureNode { | 61 | Some(StructureNode { |
45 | parent: None, | 62 | parent: None, |
@@ -47,19 +64,50 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { | |||
47 | navigation_range: name.syntax().range(), | 64 | navigation_range: name.syntax().range(), |
48 | node_range: node.syntax().range(), | 65 | node_range: node.syntax().range(), |
49 | kind: node.syntax().kind(), | 66 | kind: node.syntax().kind(), |
67 | detail, | ||
50 | }) | 68 | }) |
51 | } | 69 | } |
52 | 70 | ||
71 | fn collapse_ws(node: &SyntaxNode, output: &mut String) { | ||
72 | let mut can_insert_ws = false; | ||
73 | for line in node.text().chunks().flat_map(|chunk| chunk.lines()) { | ||
74 | let line = line.trim(); | ||
75 | if line.is_empty() { | ||
76 | if can_insert_ws { | ||
77 | output.push_str(" "); | ||
78 | can_insert_ws = false; | ||
79 | } | ||
80 | } else { | ||
81 | output.push_str(line); | ||
82 | can_insert_ws = true; | ||
83 | } | ||
84 | } | ||
85 | } | ||
86 | |||
53 | visitor() | 87 | visitor() |
54 | .visit(decl::<ast::FnDef>) | 88 | .visit(|fn_def: &ast::FnDef| { |
89 | let mut detail = String::from("fn"); | ||
90 | if let Some(type_param_list) = fn_def.type_param_list() { | ||
91 | collapse_ws(type_param_list.syntax(), &mut detail); | ||
92 | } | ||
93 | if let Some(param_list) = fn_def.param_list() { | ||
94 | collapse_ws(param_list.syntax(), &mut detail); | ||
95 | } | ||
96 | if let Some(ret_type) = fn_def.ret_type() { | ||
97 | detail.push_str(" "); | ||
98 | collapse_ws(ret_type.syntax(), &mut detail); | ||
99 | } | ||
100 | |||
101 | decl_with_detail(fn_def, Some(detail)) | ||
102 | }) | ||
55 | .visit(decl::<ast::StructDef>) | 103 | .visit(decl::<ast::StructDef>) |
56 | .visit(decl::<ast::NamedFieldDef>) | 104 | .visit(|nfd: &ast::NamedFieldDef| decl_with_type_ref(nfd, nfd.type_ref())) |
57 | .visit(decl::<ast::EnumDef>) | 105 | .visit(decl::<ast::EnumDef>) |
58 | .visit(decl::<ast::TraitDef>) | 106 | .visit(decl::<ast::TraitDef>) |
59 | .visit(decl::<ast::Module>) | 107 | .visit(decl::<ast::Module>) |
60 | .visit(decl::<ast::TypeDef>) | 108 | .visit(|td: &ast::TypeDef| decl_with_type_ref(td, td.type_ref())) |
61 | .visit(decl::<ast::ConstDef>) | 109 | .visit(|cd: &ast::ConstDef| decl_with_type_ref(cd, cd.type_ref())) |
62 | .visit(decl::<ast::StaticDef>) | 110 | .visit(|sd: &ast::StaticDef| decl_with_type_ref(sd, sd.type_ref())) |
63 | .visit(|im: &ast::ImplBlock| { | 111 | .visit(|im: &ast::ImplBlock| { |
64 | let target_type = im.target_type()?; | 112 | let target_type = im.target_type()?; |
65 | let target_trait = im.target_trait(); | 113 | let target_trait = im.target_trait(); |
@@ -78,6 +126,7 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { | |||
78 | navigation_range: target_type.syntax().range(), | 126 | navigation_range: target_type.syntax().range(), |
79 | node_range: im.syntax().range(), | 127 | node_range: im.syntax().range(), |
80 | kind: im.syntax().kind(), | 128 | kind: im.syntax().kind(), |
129 | detail: None, | ||
81 | }; | 130 | }; |
82 | Some(node) | 131 | Some(node) |
83 | }) | 132 | }) |
@@ -98,7 +147,13 @@ struct Foo { | |||
98 | } | 147 | } |
99 | 148 | ||
100 | mod m { | 149 | mod m { |
101 | fn bar() {} | 150 | fn bar1() {} |
151 | fn bar2<T>(t: T) -> T {} | ||
152 | fn bar3<A, | ||
153 | B>(a: A, | ||
154 | b: B) -> Vec< | ||
155 | u32 | ||
156 | > {} | ||
102 | } | 157 | } |
103 | 158 | ||
104 | enum E { X, Y(i32) } | 159 | 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( | |||
136 | for symbol in world.analysis().file_structure(file_id) { | 136 | for symbol in world.analysis().file_structure(file_id) { |
137 | let doc_symbol = DocumentSymbol { | 137 | let doc_symbol = DocumentSymbol { |
138 | name: symbol.label, | 138 | name: symbol.label, |
139 | detail: Some("".to_string()), | 139 | detail: symbol.detail, |
140 | kind: symbol.kind.conv(), | 140 | kind: symbol.kind.conv(), |
141 | deprecated: None, | 141 | deprecated: None, |
142 | range: symbol.node_range.conv_with(&line_index), | 142 | 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 bb223e0dc..7da19d782 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -598,7 +598,11 @@ impl ast::NameOwner for ConstDef {} | |||
598 | impl ast::TypeParamsOwner for ConstDef {} | 598 | impl ast::TypeParamsOwner for ConstDef {} |
599 | impl ast::AttrsOwner for ConstDef {} | 599 | impl ast::AttrsOwner for ConstDef {} |
600 | impl ast::DocCommentsOwner for ConstDef {} | 600 | impl ast::DocCommentsOwner for ConstDef {} |
601 | impl ConstDef {} | 601 | impl ConstDef { |
602 | pub fn type_ref(&self) -> Option<&TypeRef> { | ||
603 | super::child_opt(self) | ||
604 | } | ||
605 | } | ||
602 | 606 | ||
603 | // ContinueExpr | 607 | // ContinueExpr |
604 | #[derive(Debug, PartialEq, Eq, Hash)] | 608 | #[derive(Debug, PartialEq, Eq, Hash)] |
@@ -3407,7 +3411,11 @@ impl ast::NameOwner for StaticDef {} | |||
3407 | impl ast::TypeParamsOwner for StaticDef {} | 3411 | impl ast::TypeParamsOwner for StaticDef {} |
3408 | impl ast::AttrsOwner for StaticDef {} | 3412 | impl ast::AttrsOwner for StaticDef {} |
3409 | impl ast::DocCommentsOwner for StaticDef {} | 3413 | impl ast::DocCommentsOwner for StaticDef {} |
3410 | impl StaticDef {} | 3414 | impl StaticDef { |
3415 | pub fn type_ref(&self) -> Option<&TypeRef> { | ||
3416 | super::child_opt(self) | ||
3417 | } | ||
3418 | } | ||
3411 | 3419 | ||
3412 | // Stmt | 3420 | // Stmt |
3413 | #[derive(Debug, PartialEq, Eq, Hash)] | 3421 | #[derive(Debug, PartialEq, Eq, Hash)] |
@@ -3948,7 +3956,11 @@ impl ast::NameOwner for TypeDef {} | |||
3948 | impl ast::TypeParamsOwner for TypeDef {} | 3956 | impl ast::TypeParamsOwner for TypeDef {} |
3949 | impl ast::AttrsOwner for TypeDef {} | 3957 | impl ast::AttrsOwner for TypeDef {} |
3950 | impl ast::DocCommentsOwner for TypeDef {} | 3958 | impl ast::DocCommentsOwner for TypeDef {} |
3951 | impl TypeDef {} | 3959 | impl TypeDef { |
3960 | pub fn type_ref(&self) -> Option<&TypeRef> { | ||
3961 | super::child_opt(self) | ||
3962 | } | ||
3963 | } | ||
3952 | 3964 | ||
3953 | // TypeParam | 3965 | // TypeParam |
3954 | #[derive(Debug, PartialEq, Eq, Hash)] | 3966 | #[derive(Debug, PartialEq, Eq, Hash)] |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index dedefea59..cb5d6cde8 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -289,27 +289,36 @@ Grammar( | |||
289 | collections: [["impl_items", "ImplItem"]], | 289 | collections: [["impl_items", "ImplItem"]], |
290 | traits: [ "FnDefOwner", "ModuleItemOwner" ], | 290 | traits: [ "FnDefOwner", "ModuleItemOwner" ], |
291 | ), | 291 | ), |
292 | "ConstDef": ( traits: [ | 292 | "ConstDef": ( |
293 | "VisibilityOwner", | 293 | traits: [ |
294 | "NameOwner", | 294 | "VisibilityOwner", |
295 | "TypeParamsOwner", | 295 | "NameOwner", |
296 | "AttrsOwner", | 296 | "TypeParamsOwner", |
297 | "DocCommentsOwner" | 297 | "AttrsOwner", |
298 | ] ), | 298 | "DocCommentsOwner" |
299 | "StaticDef": ( traits: [ | 299 | ], |
300 | "VisibilityOwner", | 300 | options: ["TypeRef"] |
301 | "NameOwner", | 301 | ), |
302 | "TypeParamsOwner", | 302 | "StaticDef": ( |
303 | "AttrsOwner", | 303 | traits: [ |
304 | "DocCommentsOwner" | 304 | "VisibilityOwner", |
305 | ] ), | 305 | "NameOwner", |
306 | "TypeDef": ( traits: [ | 306 | "TypeParamsOwner", |
307 | "VisibilityOwner", | 307 | "AttrsOwner", |
308 | "NameOwner", | 308 | "DocCommentsOwner" |
309 | "TypeParamsOwner", | 309 | ], |
310 | "AttrsOwner", | 310 | options: ["TypeRef"] |
311 | "DocCommentsOwner" | 311 | ), |
312 | ] ), | 312 | "TypeDef": ( |
313 | traits: [ | ||
314 | "VisibilityOwner", | ||
315 | "NameOwner", | ||
316 | "TypeParamsOwner", | ||
317 | "AttrsOwner", | ||
318 | "DocCommentsOwner" | ||
319 | ], | ||
320 | options: ["TypeRef"] | ||
321 | ), | ||
313 | "ImplBlock": (options: ["ItemList"]), | 322 | "ImplBlock": (options: ["ItemList"]), |
314 | 323 | ||
315 | "ParenType": (options: ["TypeRef"]), | 324 | "ParenType": (options: ["TypeRef"]), |