aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide_api_light/src/snapshots/tests__file_structure.snap98
-rw-r--r--crates/ra_ide_api_light/src/structure.rs69
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs2
-rw-r--r--crates/ra_syntax/src/ast/generated.rs18
-rw-r--r--crates/ra_syntax/src/grammar.ron51
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---
2created: "2019-01-22T14:45:01.959724300+00:00" 2created: "2019-01-24T18:04:00.090162+00:00"
3creator: [email protected] 3creator: [email protected]
4expression: structure 4expression: structure
5source: "crates\\ra_ide_api_light\\src\\structure.rs" 5source: "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
3use ra_syntax::{ 3use 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
18pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> { 19pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
@@ -40,6 +41,22 @@ pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
40 41
41fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { 42fn 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
100mod m { 149mod 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
104enum E { X, Y(i32) } 159enum 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 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 {}
526impl ast::TypeParamsOwner for ConstDef {} 526impl ast::TypeParamsOwner for ConstDef {}
527impl ast::AttrsOwner for ConstDef {} 527impl ast::AttrsOwner for ConstDef {}
528impl ast::DocCommentsOwner for ConstDef {} 528impl ast::DocCommentsOwner for ConstDef {}
529impl ConstDef {} 529impl ConstDef {
530 pub fn type_ref(&self) -> Option<&TypeRef> {
531 super::child_opt(self)
532 }
533}
530 534
531// ContinueExpr 535// ContinueExpr
532#[derive(Debug, PartialEq, Eq, Hash)] 536#[derive(Debug, PartialEq, Eq, Hash)]
@@ -3015,7 +3019,11 @@ impl ast::NameOwner for StaticDef {}
3015impl ast::TypeParamsOwner for StaticDef {} 3019impl ast::TypeParamsOwner for StaticDef {}
3016impl ast::AttrsOwner for StaticDef {} 3020impl ast::AttrsOwner for StaticDef {}
3017impl ast::DocCommentsOwner for StaticDef {} 3021impl ast::DocCommentsOwner for StaticDef {}
3018impl StaticDef {} 3022impl StaticDef {
3023 pub fn type_ref(&self) -> Option<&TypeRef> {
3024 super::child_opt(self)
3025 }
3026}
3019 3027
3020// Stmt 3028// Stmt
3021#[derive(Debug, PartialEq, Eq, Hash)] 3029#[derive(Debug, PartialEq, Eq, Hash)]
@@ -3491,7 +3499,11 @@ impl ast::NameOwner for TypeDef {}
3491impl ast::TypeParamsOwner for TypeDef {} 3499impl ast::TypeParamsOwner for TypeDef {}
3492impl ast::AttrsOwner for TypeDef {} 3500impl ast::AttrsOwner for TypeDef {}
3493impl ast::DocCommentsOwner for TypeDef {} 3501impl ast::DocCommentsOwner for TypeDef {}
3494impl TypeDef {} 3502impl TypeDef {
3503 pub fn type_ref(&self) -> Option<&TypeRef> {
3504 super::child_opt(self)
3505 }
3506}
3495 3507
3496// TypeParam 3508// TypeParam
3497#[derive(Debug, PartialEq, Eq, Hash)] 3509#[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(
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"]),