aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/display/structure.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/display/structure.rs')
-rw-r--r--crates/ra_ide_api/src/display/structure.rs116
1 files changed, 59 insertions, 57 deletions
diff --git a/crates/ra_ide_api/src/display/structure.rs b/crates/ra_ide_api/src/display/structure.rs
index 8815df747..ddd8b7b20 100644
--- a/crates/ra_ide_api/src/display/structure.rs
+++ b/crates/ra_ide_api/src/display/structure.rs
@@ -3,9 +3,8 @@
3use crate::TextRange; 3use crate::TextRange;
4 4
5use ra_syntax::{ 5use ra_syntax::{
6 algo::visit::{visitor, Visitor},
7 ast::{self, AttrsOwner, NameOwner, TypeAscriptionOwner, TypeParamsOwner}, 6 ast::{self, AttrsOwner, NameOwner, TypeAscriptionOwner, TypeParamsOwner},
8 AstNode, SourceFile, SyntaxKind, SyntaxNode, WalkEvent, 7 match_ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, WalkEvent,
9}; 8};
10 9
11#[derive(Debug, Clone)] 10#[derive(Debug, Clone)]
@@ -101,63 +100,66 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
101 }) 100 })
102 } 101 }
103 102
104 visitor() 103 match_ast! {
105 .visit(|fn_def: ast::FnDef| { 104 match node {
106 let mut detail = String::from("fn"); 105 ast::FnDef(it) => {
107 if let Some(type_param_list) = fn_def.type_param_list() { 106 let mut detail = String::from("fn");
108 collapse_ws(type_param_list.syntax(), &mut detail); 107 if let Some(type_param_list) = it.type_param_list() {
109 } 108 collapse_ws(type_param_list.syntax(), &mut detail);
110 if let Some(param_list) = fn_def.param_list() { 109 }
111 collapse_ws(param_list.syntax(), &mut detail); 110 if let Some(param_list) = it.param_list() {
112 } 111 collapse_ws(param_list.syntax(), &mut detail);
113 if let Some(ret_type) = fn_def.ret_type() { 112 }
114 detail.push_str(" "); 113 if let Some(ret_type) = it.ret_type() {
115 collapse_ws(ret_type.syntax(), &mut detail); 114 detail.push_str(" ");
116 } 115 collapse_ws(ret_type.syntax(), &mut detail);
117
118 decl_with_detail(fn_def, Some(detail))
119 })
120 .visit(decl::<ast::StructDef>)
121 .visit(decl::<ast::EnumDef>)
122 .visit(decl::<ast::EnumVariant>)
123 .visit(decl::<ast::TraitDef>)
124 .visit(decl::<ast::Module>)
125 .visit(|td: ast::TypeAliasDef| {
126 let ty = td.type_ref();
127 decl_with_type_ref(td, ty)
128 })
129 .visit(decl_with_ascription::<ast::RecordFieldDef>)
130 .visit(decl_with_ascription::<ast::ConstDef>)
131 .visit(decl_with_ascription::<ast::StaticDef>)
132 .visit(|im: ast::ImplBlock| {
133 let target_type = im.target_type()?;
134 let target_trait = im.target_trait();
135 let label = match target_trait {
136 None => format!("impl {}", target_type.syntax().text()),
137 Some(t) => {
138 format!("impl {} for {}", t.syntax().text(), target_type.syntax().text(),)
139 } 116 }
140 };
141 117
142 let node = StructureNode { 118 decl_with_detail(it, Some(detail))
143 parent: None, 119 },
144 label, 120 ast::StructDef(it) => { decl(it) },
145 navigation_range: target_type.syntax().text_range(), 121 ast::EnumDef(it) => { decl(it) },
146 node_range: im.syntax().text_range(), 122 ast::EnumVariant(it) => { decl(it) },
147 kind: im.syntax().kind(), 123 ast::TraitDef(it) => { decl(it) },
148 detail: None, 124 ast::Module(it) => { decl(it) },
149 deprecated: false, 125 ast::TypeAliasDef(it) => {
150 }; 126 let ty = it.type_ref();
151 Some(node) 127 decl_with_type_ref(it, ty)
152 }) 128 },
153 .visit(|mc: ast::MacroCall| { 129 ast::RecordFieldDef(it) => { decl_with_ascription(it) },
154 let first_token = mc.syntax().first_token().unwrap(); 130 ast::ConstDef(it) => { decl_with_ascription(it) },
155 if first_token.text().as_str() != "macro_rules" { 131 ast::StaticDef(it) => { decl_with_ascription(it) },
156 return None; 132 ast::ImplBlock(it) => {
157 } 133 let target_type = it.target_type()?;
158 decl(mc) 134 let target_trait = it.target_trait();
159 }) 135 let label = match target_trait {
160 .accept(&node)? 136 None => format!("impl {}", target_type.syntax().text()),
137 Some(t) => {
138 format!("impl {} for {}", t.syntax().text(), target_type.syntax().text(),)
139 }
140 };
141
142 let node = StructureNode {
143 parent: None,
144 label,
145 navigation_range: target_type.syntax().text_range(),
146 node_range: it.syntax().text_range(),
147 kind: it.syntax().kind(),
148 detail: None,
149 deprecated: false,
150 };
151 Some(node)
152 },
153 ast::MacroCall(it) => {
154 let first_token = it.syntax().first_token().unwrap();
155 if first_token.text().as_str() != "macro_rules" {
156 return None;
157 }
158 decl(it)
159 },
160 _ => None,
161 }
162 }
161} 163}
162 164
163#[cfg(test)] 165#[cfg(test)]