aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src')
-rw-r--r--crates/ra_ide_api/src/change.rs1
-rw-r--r--crates/ra_ide_api/src/completion/presentation.rs12
-rw-r--r--crates/ra_ide_api/src/db.rs11
-rw-r--r--crates/ra_ide_api/src/display/function_signature.rs9
-rw-r--r--crates/ra_ide_api/src/display/navigation_target.rs200
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs8
-rw-r--r--crates/ra_ide_api/src/hover.rs144
-rw-r--r--crates/ra_ide_api/src/lib.rs11
-rw-r--r--crates/ra_ide_api/src/references.rs6
9 files changed, 148 insertions, 254 deletions
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs
index 247dc0fee..ce03a0f95 100644
--- a/crates/ra_ide_api/src/change.rs
+++ b/crates/ra_ide_api/src/change.rs
@@ -225,7 +225,6 @@ impl RootDatabase {
225 let sweep = SweepStrategy::default().discard_values().sweep_all_revisions(); 225 let sweep = SweepStrategy::default().discard_values().sweep_all_revisions();
226 226
227 self.query(ra_db::ParseQuery).sweep(sweep); 227 self.query(ra_db::ParseQuery).sweep(sweep);
228
229 self.query(hir::db::ParseMacroQuery).sweep(sweep); 228 self.query(hir::db::ParseMacroQuery).sweep(sweep);
230 self.query(hir::db::MacroDefQuery).sweep(sweep); 229 self.query(hir::db::MacroDefQuery).sweep(sweep);
231 self.query(hir::db::MacroArgQuery).sweep(sweep); 230 self.query(hir::db::MacroArgQuery).sweep(sweep);
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs
index d405161d6..f4ff4404b 100644
--- a/crates/ra_ide_api/src/completion/presentation.rs
+++ b/crates/ra_ide_api/src/completion/presentation.rs
@@ -1,7 +1,7 @@
1//! This modules takes care of rendering various defenitions as completion items. 1//! This modules takes care of rendering various defenitions as completion items.
2use join_to_string::join; 2use join_to_string::join;
3use test_utils::tested_by; 3use test_utils::tested_by;
4use hir::{Docs, PerNs, Resolution, HirDisplay}; 4use hir::{Docs, PerNs, Resolution, HirDisplay, HasSource};
5use ra_syntax::ast::NameOwner; 5use ra_syntax::ast::NameOwner;
6 6
7use crate::completion::{ 7use crate::completion::{
@@ -100,7 +100,7 @@ impl Completions {
100 ) { 100 ) {
101 let sig = func.signature(ctx.db); 101 let sig = func.signature(ctx.db);
102 let name = name.unwrap_or_else(|| sig.name().to_string()); 102 let name = name.unwrap_or_else(|| sig.name().to_string());
103 let (_, ast_node) = func.source(ctx.db); 103 let ast_node = func.source(ctx.db).ast;
104 let detail = function_label(&ast_node); 104 let detail = function_label(&ast_node);
105 105
106 let mut builder = CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name) 106 let mut builder = CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name)
@@ -126,12 +126,11 @@ impl Completions {
126 } 126 }
127 127
128 pub(crate) fn add_const(&mut self, ctx: &CompletionContext, constant: hir::Const) { 128 pub(crate) fn add_const(&mut self, ctx: &CompletionContext, constant: hir::Const) {
129 let (_file_id, ast_node) = constant.source(ctx.db); 129 let ast_node = constant.source(ctx.db).ast;
130 let name = match ast_node.name() { 130 let name = match ast_node.name() {
131 Some(name) => name, 131 Some(name) => name,
132 _ => return, 132 _ => return,
133 }; 133 };
134 let (_, ast_node) = constant.source(ctx.db);
135 let detail = const_label(&ast_node); 134 let detail = const_label(&ast_node);
136 135
137 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.text().to_string()) 136 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.text().to_string())
@@ -142,13 +141,12 @@ impl Completions {
142 } 141 }
143 142
144 pub(crate) fn add_type_alias(&mut self, ctx: &CompletionContext, type_alias: hir::TypeAlias) { 143 pub(crate) fn add_type_alias(&mut self, ctx: &CompletionContext, type_alias: hir::TypeAlias) {
145 let (_file_id, type_def) = type_alias.source(ctx.db); 144 let type_def = type_alias.source(ctx.db).ast;
146 let name = match type_def.name() { 145 let name = match type_def.name() {
147 Some(name) => name, 146 Some(name) => name,
148 _ => return, 147 _ => return,
149 }; 148 };
150 let (_, ast_node) = type_alias.source(ctx.db); 149 let detail = type_label(&type_def);
151 let detail = type_label(&ast_node);
152 150
153 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.text().to_string()) 151 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.text().to_string())
154 .kind(CompletionItemKind::TypeAlias) 152 .kind(CompletionItemKind::TypeAlias)
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs
index d1a452ecb..b3f395502 100644
--- a/crates/ra_ide_api/src/db.rs
+++ b/crates/ra_ide_api/src/db.rs
@@ -5,7 +5,7 @@ use std::{
5 5
6use ra_db::{ 6use ra_db::{
7 CheckCanceled, FileId, Canceled, SourceDatabase, 7 CheckCanceled, FileId, Canceled, SourceDatabase,
8 salsa, 8 salsa::{self, Database},
9}; 9};
10 10
11use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}}; 11use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}};
@@ -41,6 +41,12 @@ impl salsa::Database for RootDatabase {
41 41
42impl Default for RootDatabase { 42impl Default for RootDatabase {
43 fn default() -> RootDatabase { 43 fn default() -> RootDatabase {
44 RootDatabase::new(None)
45 }
46}
47
48impl RootDatabase {
49 pub fn new(lru_capacity: Option<usize>) -> RootDatabase {
44 let mut db = RootDatabase { 50 let mut db = RootDatabase {
45 runtime: salsa::Runtime::default(), 51 runtime: salsa::Runtime::default(),
46 last_gc: time::Instant::now(), 52 last_gc: time::Instant::now(),
@@ -49,6 +55,9 @@ impl Default for RootDatabase {
49 db.set_crate_graph(Default::default()); 55 db.set_crate_graph(Default::default());
50 db.set_local_roots(Default::default()); 56 db.set_local_roots(Default::default());
51 db.set_library_roots(Default::default()); 57 db.set_library_roots(Default::default());
58 let lru_capacity = lru_capacity.unwrap_or(ra_db::DEFAULT_LRU_CAP);
59 db.query_mut(ra_db::ParseQuery).set_lru_capacity(lru_capacity);
60 db.query_mut(hir::db::ParseMacroQuery).set_lru_capacity(lru_capacity);
52 db 61 db
53 } 62 }
54} 63}
diff --git a/crates/ra_ide_api/src/display/function_signature.rs b/crates/ra_ide_api/src/display/function_signature.rs
index d09950bce..b0b0c7122 100644
--- a/crates/ra_ide_api/src/display/function_signature.rs
+++ b/crates/ra_ide_api/src/display/function_signature.rs
@@ -1,10 +1,11 @@
1use super::{where_predicates, generic_parameters};
2use crate::db;
3use std::fmt::{self, Display}; 1use std::fmt::{self, Display};
2
4use join_to_string::join; 3use join_to_string::join;
5use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner}; 4use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner};
6use std::convert::From; 5use std::convert::From;
7use hir::{Docs, Documentation}; 6use hir::{Docs, Documentation, HasSource};
7
8use crate::{db, display::{where_predicates, generic_parameters}};
8 9
9/// Contains information about a function signature 10/// Contains information about a function signature
10#[derive(Debug)] 11#[derive(Debug)]
@@ -33,7 +34,7 @@ impl FunctionSignature {
33 34
34 pub(crate) fn from_hir(db: &db::RootDatabase, function: hir::Function) -> Self { 35 pub(crate) fn from_hir(db: &db::RootDatabase, function: hir::Function) -> Self {
35 let doc = function.docs(db); 36 let doc = function.docs(db);
36 let (_, ast_node) = function.source(db); 37 let ast_node = function.source(db).ast;
37 FunctionSignature::from(&*ast_node).with_doc_opt(doc) 38 FunctionSignature::from(&*ast_node).with_doc_opt(doc)
38 } 39 }
39} 40}
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs
index cfd3f5478..823cdaaf3 100644
--- a/crates/ra_ide_api/src/display/navigation_target.rs
+++ b/crates/ra_ide_api/src/display/navigation_target.rs
@@ -1,11 +1,11 @@
1use ra_db::{FileId, SourceDatabase}; 1use ra_db::{FileId, SourceDatabase};
2use ra_syntax::{ 2use ra_syntax::{
3 SyntaxNode, AstNode, SmolStr, TextRange, AstPtr, 3 SyntaxNode, AstNode, SmolStr, TextRange, AstPtr, TreeArc,
4 SyntaxKind::{self, NAME}, 4 SyntaxKind::{self, NAME},
5 ast::{self, DocCommentsOwner}, 5 ast::{self, DocCommentsOwner},
6 algo::visit::{visitor, Visitor}, 6 algo::visit::{visitor, Visitor},
7}; 7};
8use hir::{ModuleSource, FieldSource, ImplItem}; 8use hir::{ModuleSource, FieldSource, ImplItem, HasSource};
9 9
10use crate::{FileSymbol, db::RootDatabase}; 10use crate::{FileSymbol, db::RootDatabase};
11use super::short_label::ShortLabel; 11use super::short_label::ShortLabel;
@@ -129,10 +129,10 @@ impl NavigationTarget {
129 } 129 }
130 130
131 pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget { 131 pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
132 let (file_id, source) = module.definition_source(db); 132 let src = module.definition_source(db);
133 let file_id = file_id.as_original_file(); 133 let file_id = src.file_id.as_original_file();
134 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); 134 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
135 match source { 135 match src.ast {
136 ModuleSource::SourceFile(node) => { 136 ModuleSource::SourceFile(node) => {
137 NavigationTarget::from_syntax(file_id, name, None, node.syntax(), None, None) 137 NavigationTarget::from_syntax(file_id, name, None, node.syntax(), None, None)
138 } 138 }
@@ -149,34 +149,24 @@ impl NavigationTarget {
149 149
150 pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget { 150 pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
151 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); 151 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
152 if let Some((file_id, source)) = module.declaration_source(db) { 152 if let Some(src) = module.declaration_source(db) {
153 let file_id = file_id.as_original_file(); 153 let file_id = src.file_id.as_original_file();
154 return NavigationTarget::from_syntax( 154 return NavigationTarget::from_syntax(
155 file_id, 155 file_id,
156 name, 156 name,
157 None, 157 None,
158 source.syntax(), 158 src.ast.syntax(),
159 source.doc_comment_text(), 159 src.ast.doc_comment_text(),
160 source.short_label(), 160 src.ast.short_label(),
161 ); 161 );
162 } 162 }
163 NavigationTarget::from_module(db, module) 163 NavigationTarget::from_module(db, module)
164 } 164 }
165 165
166 pub(crate) fn from_function(db: &RootDatabase, func: hir::Function) -> NavigationTarget {
167 let (file_id, fn_def) = func.source(db);
168 NavigationTarget::from_named(
169 file_id.original_file(db),
170 &*fn_def,
171 fn_def.doc_comment_text(),
172 fn_def.short_label(),
173 )
174 }
175
176 pub(crate) fn from_field(db: &RootDatabase, field: hir::StructField) -> NavigationTarget { 166 pub(crate) fn from_field(db: &RootDatabase, field: hir::StructField) -> NavigationTarget {
177 let (file_id, field) = field.source(db); 167 let src = field.source(db);
178 let file_id = file_id.original_file(db); 168 let file_id = src.file_id.original_file(db);
179 match field { 169 match src.ast {
180 FieldSource::Named(it) => { 170 FieldSource::Named(it) => {
181 NavigationTarget::from_named(file_id, &*it, it.doc_comment_text(), it.short_label()) 171 NavigationTarget::from_named(file_id, &*it, it.doc_comment_text(), it.short_label())
182 } 172 }
@@ -186,35 +176,25 @@ impl NavigationTarget {
186 } 176 }
187 } 177 }
188 178
179 pub(crate) fn from_def_source<A, D>(db: &RootDatabase, def: D) -> NavigationTarget
180 where
181 D: HasSource<Ast = TreeArc<A>>,
182 A: ast::DocCommentsOwner + ast::NameOwner + ShortLabel,
183 {
184 let src = def.source(db);
185 NavigationTarget::from_named(
186 src.file_id.original_file(db),
187 &*src.ast,
188 src.ast.doc_comment_text(),
189 src.ast.short_label(),
190 )
191 }
192
189 pub(crate) fn from_adt_def(db: &RootDatabase, adt_def: hir::AdtDef) -> NavigationTarget { 193 pub(crate) fn from_adt_def(db: &RootDatabase, adt_def: hir::AdtDef) -> NavigationTarget {
190 match adt_def { 194 match adt_def {
191 hir::AdtDef::Struct(s) => { 195 hir::AdtDef::Struct(it) => NavigationTarget::from_def_source(db, it),
192 let (file_id, node) = s.source(db); 196 hir::AdtDef::Union(it) => NavigationTarget::from_def_source(db, it),
193 NavigationTarget::from_named( 197 hir::AdtDef::Enum(it) => NavigationTarget::from_def_source(db, it),
194 file_id.original_file(db),
195 &*node,
196 node.doc_comment_text(),
197 node.short_label(),
198 )
199 }
200 hir::AdtDef::Union(s) => {
201 let (file_id, node) = s.source(db);
202 NavigationTarget::from_named(
203 file_id.original_file(db),
204 &*node,
205 node.doc_comment_text(),
206 node.short_label(),
207 )
208 }
209 hir::AdtDef::Enum(s) => {
210 let (file_id, node) = s.source(db);
211 NavigationTarget::from_named(
212 file_id.original_file(db),
213 &*node,
214 node.doc_comment_text(),
215 node.short_label(),
216 )
217 }
218 } 198 }
219 } 199 }
220 200
@@ -224,79 +204,15 @@ impl NavigationTarget {
224 ) -> Option<NavigationTarget> { 204 ) -> Option<NavigationTarget> {
225 let nav = match module_def { 205 let nav = match module_def {
226 hir::ModuleDef::Module(module) => NavigationTarget::from_module(db, module), 206 hir::ModuleDef::Module(module) => NavigationTarget::from_module(db, module),
227 hir::ModuleDef::Function(func) => NavigationTarget::from_function(db, func), 207 hir::ModuleDef::Function(func) => NavigationTarget::from_def_source(db, func),
228 hir::ModuleDef::Struct(s) => { 208 hir::ModuleDef::Struct(it) => NavigationTarget::from_adt_def(db, it.into()),
229 let (file_id, node) = s.source(db); 209 hir::ModuleDef::Enum(it) => NavigationTarget::from_adt_def(db, it.into()),
230 NavigationTarget::from_named( 210 hir::ModuleDef::Union(it) => NavigationTarget::from_adt_def(db, it.into()),
231 file_id.original_file(db), 211 hir::ModuleDef::Const(it) => NavigationTarget::from_def_source(db, it),
232 &*node, 212 hir::ModuleDef::Static(it) => NavigationTarget::from_def_source(db, it),
233 node.doc_comment_text(), 213 hir::ModuleDef::EnumVariant(it) => NavigationTarget::from_def_source(db, it),
234 node.short_label(), 214 hir::ModuleDef::Trait(it) => NavigationTarget::from_def_source(db, it),
235 ) 215 hir::ModuleDef::TypeAlias(it) => NavigationTarget::from_def_source(db, it),
236 }
237 hir::ModuleDef::Union(s) => {
238 let (file_id, node) = s.source(db);
239 NavigationTarget::from_named(
240 file_id.original_file(db),
241 &*node,
242 node.doc_comment_text(),
243 node.short_label(),
244 )
245 }
246 hir::ModuleDef::Const(s) => {
247 let (file_id, node) = s.source(db);
248 NavigationTarget::from_named(
249 file_id.original_file(db),
250 &*node,
251 node.doc_comment_text(),
252 node.short_label(),
253 )
254 }
255 hir::ModuleDef::Static(s) => {
256 let (file_id, node) = s.source(db);
257 NavigationTarget::from_named(
258 file_id.original_file(db),
259 &*node,
260 node.doc_comment_text(),
261 node.short_label(),
262 )
263 }
264 hir::ModuleDef::Enum(e) => {
265 let (file_id, node) = e.source(db);
266 NavigationTarget::from_named(
267 file_id.original_file(db),
268 &*node,
269 node.doc_comment_text(),
270 node.short_label(),
271 )
272 }
273 hir::ModuleDef::EnumVariant(var) => {
274 let (file_id, node) = var.source(db);
275 NavigationTarget::from_named(
276 file_id.original_file(db),
277 &*node,
278 node.doc_comment_text(),
279 node.short_label(),
280 )
281 }
282 hir::ModuleDef::Trait(e) => {
283 let (file_id, node) = e.source(db);
284 NavigationTarget::from_named(
285 file_id.original_file(db),
286 &*node,
287 node.doc_comment_text(),
288 node.short_label(),
289 )
290 }
291 hir::ModuleDef::TypeAlias(e) => {
292 let (file_id, node) = e.source(db);
293 NavigationTarget::from_named(
294 file_id.original_file(db),
295 &*node,
296 node.doc_comment_text(),
297 node.short_label(),
298 )
299 }
300 hir::ModuleDef::BuiltinType(..) => { 216 hir::ModuleDef::BuiltinType(..) => {
301 return None; 217 return None;
302 } 218 }
@@ -308,12 +224,12 @@ impl NavigationTarget {
308 db: &RootDatabase, 224 db: &RootDatabase,
309 impl_block: hir::ImplBlock, 225 impl_block: hir::ImplBlock,
310 ) -> NavigationTarget { 226 ) -> NavigationTarget {
311 let (file_id, node) = impl_block.source(db); 227 let src = impl_block.source(db);
312 NavigationTarget::from_syntax( 228 NavigationTarget::from_syntax(
313 file_id.as_original_file(), 229 src.file_id.as_original_file(),
314 "impl".into(), 230 "impl".into(),
315 None, 231 None,
316 node.syntax(), 232 src.ast.syntax(),
317 None, 233 None,
318 None, 234 None,
319 ) 235 )
@@ -321,35 +237,19 @@ impl NavigationTarget {
321 237
322 pub(crate) fn from_impl_item(db: &RootDatabase, impl_item: hir::ImplItem) -> NavigationTarget { 238 pub(crate) fn from_impl_item(db: &RootDatabase, impl_item: hir::ImplItem) -> NavigationTarget {
323 match impl_item { 239 match impl_item {
324 ImplItem::Method(f) => NavigationTarget::from_function(db, f), 240 ImplItem::Method(it) => NavigationTarget::from_def_source(db, it),
325 ImplItem::Const(c) => { 241 ImplItem::Const(it) => NavigationTarget::from_def_source(db, it),
326 let (file_id, node) = c.source(db); 242 ImplItem::TypeAlias(it) => NavigationTarget::from_def_source(db, it),
327 NavigationTarget::from_named(
328 file_id.original_file(db),
329 &*node,
330 node.doc_comment_text(),
331 node.short_label(),
332 )
333 }
334 ImplItem::TypeAlias(a) => {
335 let (file_id, node) = a.source(db);
336 NavigationTarget::from_named(
337 file_id.original_file(db),
338 &*node,
339 node.doc_comment_text(),
340 node.short_label(),
341 )
342 }
343 } 243 }
344 } 244 }
345 245
346 pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget { 246 pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget {
347 let (file_id, node) = macro_call.source(db); 247 let src = macro_call.source(db);
348 log::debug!("nav target {}", node.syntax().debug_dump()); 248 log::debug!("nav target {}", src.ast.syntax().debug_dump());
349 NavigationTarget::from_named( 249 NavigationTarget::from_named(
350 file_id.original_file(db), 250 src.file_id.original_file(db),
351 &*node, 251 &*src.ast,
352 node.doc_comment_text(), 252 src.ast.doc_comment_text(),
353 None, 253 None,
354 ) 254 )
355 } 255 }
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs
index 325a5a4f3..63ba6cf9d 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide_api/src/goto_definition.rs
@@ -59,10 +59,10 @@ pub(crate) fn reference_definition(
59 let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None); 59 let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None);
60 60
61 match classify_name_ref(db, &analyzer, name_ref) { 61 match classify_name_ref(db, &analyzer, name_ref) {
62 Some(Method(func)) => return Exact(NavigationTarget::from_function(db, func)),
63 Some(Macro(mac)) => return Exact(NavigationTarget::from_macro_def(db, mac)), 62 Some(Macro(mac)) => return Exact(NavigationTarget::from_macro_def(db, mac)),
64 Some(FieldAccess(field)) => return Exact(NavigationTarget::from_field(db, field)), 63 Some(FieldAccess(field)) => return Exact(NavigationTarget::from_field(db, field)),
65 Some(AssocItem(assoc)) => return Exact(NavigationTarget::from_impl_item(db, assoc)), 64 Some(AssocItem(assoc)) => return Exact(NavigationTarget::from_impl_item(db, assoc)),
65 Some(Method(func)) => return Exact(NavigationTarget::from_def_source(db, func)),
66 Some(Def(def)) => match NavigationTarget::from_def(db, def) { 66 Some(Def(def)) => match NavigationTarget::from_def(db, def) {
67 Some(nav) => return Exact(nav), 67 Some(nav) => return Exact(nav),
68 None => return Approximate(vec![]), 68 None => return Approximate(vec![]),
@@ -253,12 +253,12 @@ mod tests {
253 //- /foo/lib.rs 253 //- /foo/lib.rs
254 #[macro_export] 254 #[macro_export]
255 macro_rules! foo { 255 macro_rules! foo {
256 () => { 256 () => {
257 {} 257 {}
258 }; 258 };
259 } 259 }
260 ", 260 ",
261 "foo MACRO_CALL FileId(2) [0; 79) [29; 32)", 261 "foo MACRO_CALL FileId(2) [0; 66) [29; 32)",
262 ); 262 );
263 } 263 }
264 264
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs
index fbabeb194..df877c324 100644
--- a/crates/ra_ide_api/src/hover.rs
+++ b/crates/ra_ide_api/src/hover.rs
@@ -1,9 +1,10 @@
1use ra_db::SourceDatabase; 1use ra_db::SourceDatabase;
2use ra_syntax::{ 2use ra_syntax::{
3 AstNode, ast::{self, DocCommentsOwner}, 3 AstNode, TreeArc,
4 ast::{self, DocCommentsOwner},
4 algo::{find_covering_element, find_node_at_offset, ancestors_at_offset, visit::{visitor, Visitor}}, 5 algo::{find_covering_element, find_node_at_offset, ancestors_at_offset, visit::{visitor, Visitor}},
5}; 6};
6use hir::HirDisplay; 7use hir::{HirDisplay, HasSource};
7 8
8use crate::{ 9use crate::{
9 db::RootDatabase, 10 db::RootDatabase,
@@ -94,79 +95,41 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
94 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset) { 95 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset) {
95 let analyzer = hir::SourceAnalyzer::new(db, position.file_id, name_ref.syntax(), None); 96 let analyzer = hir::SourceAnalyzer::new(db, position.file_id, name_ref.syntax(), None);
96 97
98 let mut no_fallback = false;
99
97 match classify_name_ref(db, &analyzer, name_ref) { 100 match classify_name_ref(db, &analyzer, name_ref) {
98 Some(Method(it)) => { 101 Some(Method(it)) => res.extend(from_def_source(db, it)),
99 let it = it.source(db).1;
100 res.extend(hover_text(it.doc_comment_text(), it.short_label()));
101 }
102 Some(Macro(it)) => { 102 Some(Macro(it)) => {
103 let it = it.source(db).1; 103 let src = it.source(db);
104 res.extend(hover_text(it.doc_comment_text(), None)); 104 res.extend(hover_text(src.ast.doc_comment_text(), None));
105 } 105 }
106 Some(FieldAccess(it)) => { 106 Some(FieldAccess(it)) => {
107 let it = it.source(db).1; 107 let src = it.source(db);
108 if let hir::FieldSource::Named(it) = it { 108 if let hir::FieldSource::Named(it) = src.ast {
109 res.extend(hover_text(it.doc_comment_text(), it.short_label())); 109 res.extend(hover_text(it.doc_comment_text(), it.short_label()));
110 } 110 }
111 } 111 }
112 Some(AssocItem(it)) => match it { 112 Some(AssocItem(it)) => res.extend(match it {
113 hir::ImplItem::Method(it) => { 113 hir::ImplItem::Method(it) => from_def_source(db, it),
114 let it = it.source(db).1; 114 hir::ImplItem::Const(it) => from_def_source(db, it),
115 res.extend(hover_text(it.doc_comment_text(), it.short_label())) 115 hir::ImplItem::TypeAlias(it) => from_def_source(db, it),
116 } 116 }),
117 hir::ImplItem::Const(it) => {
118 let it = it.source(db).1;
119 res.extend(hover_text(it.doc_comment_text(), it.short_label()))
120 }
121 hir::ImplItem::TypeAlias(it) => {
122 let it = it.source(db).1;
123 res.extend(hover_text(it.doc_comment_text(), it.short_label()))
124 }
125 },
126 Some(Def(it)) => { 117 Some(Def(it)) => {
127 match it { 118 match it {
128 hir::ModuleDef::Module(it) => { 119 hir::ModuleDef::Module(it) => {
129 let it = it.definition_source(db).1; 120 if let hir::ModuleSource::Module(it) = it.definition_source(db).ast {
130 if let hir::ModuleSource::Module(it) = it {
131 res.extend(hover_text(it.doc_comment_text(), it.short_label())) 121 res.extend(hover_text(it.doc_comment_text(), it.short_label()))
132 } 122 }
133 } 123 }
134 hir::ModuleDef::Function(it) => { 124 hir::ModuleDef::Function(it) => res.extend(from_def_source(db, it)),
135 let it = it.source(db).1; 125 hir::ModuleDef::Struct(it) => res.extend(from_def_source(db, it)),
136 res.extend(hover_text(it.doc_comment_text(), it.short_label())) 126 hir::ModuleDef::Union(it) => res.extend(from_def_source(db, it)),
137 } 127 hir::ModuleDef::Enum(it) => res.extend(from_def_source(db, it)),
138 hir::ModuleDef::Struct(it) => { 128 hir::ModuleDef::EnumVariant(it) => res.extend(from_def_source(db, it)),
139 let it = it.source(db).1; 129 hir::ModuleDef::Const(it) => res.extend(from_def_source(db, it)),
140 res.extend(hover_text(it.doc_comment_text(), it.short_label())) 130 hir::ModuleDef::Static(it) => res.extend(from_def_source(db, it)),
141 } 131 hir::ModuleDef::Trait(it) => res.extend(from_def_source(db, it)),
142 hir::ModuleDef::Union(it) => { 132 hir::ModuleDef::TypeAlias(it) => res.extend(from_def_source(db, it)),
143 let it = it.source(db).1;
144 res.extend(hover_text(it.doc_comment_text(), it.short_label()))
145 }
146 hir::ModuleDef::Enum(it) => {
147 let it = it.source(db).1;
148 res.extend(hover_text(it.doc_comment_text(), it.short_label()))
149 }
150 hir::ModuleDef::EnumVariant(it) => {
151 let it = it.source(db).1;
152 res.extend(hover_text(it.doc_comment_text(), it.short_label()))
153 }
154 hir::ModuleDef::Const(it) => {
155 let it = it.source(db).1;
156 res.extend(hover_text(it.doc_comment_text(), it.short_label()))
157 }
158 hir::ModuleDef::Static(it) => {
159 let it = it.source(db).1;
160 res.extend(hover_text(it.doc_comment_text(), it.short_label()))
161 }
162 hir::ModuleDef::Trait(it) => {
163 let it = it.source(db).1;
164 res.extend(hover_text(it.doc_comment_text(), it.short_label()))
165 }
166 hir::ModuleDef::TypeAlias(it) => {
167 let it = it.source(db).1;
168 res.extend(hover_text(it.doc_comment_text(), it.short_label()))
169 }
170 hir::ModuleDef::BuiltinType(_) => { 133 hir::ModuleDef::BuiltinType(_) => {
171 // FIXME: hover for builtin Type ? 134 // FIXME: hover for builtin Type ?
172 } 135 }
@@ -174,27 +137,16 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
174 } 137 }
175 Some(SelfType(ty)) => { 138 Some(SelfType(ty)) => {
176 if let Some((adt_def, _)) = ty.as_adt() { 139 if let Some((adt_def, _)) = ty.as_adt() {
177 match adt_def { 140 res.extend(match adt_def {
178 hir::AdtDef::Struct(it) => { 141 hir::AdtDef::Struct(it) => from_def_source(db, it),
179 let it = it.source(db).1; 142 hir::AdtDef::Union(it) => from_def_source(db, it),
180 res.extend(hover_text(it.doc_comment_text(), it.short_label())) 143 hir::AdtDef::Enum(it) => from_def_source(db, it),
181 } 144 })
182 hir::AdtDef::Union(it) => {
183 let it = it.source(db).1;
184 res.extend(hover_text(it.doc_comment_text(), it.short_label()))
185 }
186 hir::AdtDef::Enum(it) => {
187 let it = it.source(db).1;
188 res.extend(hover_text(it.doc_comment_text(), it.short_label()))
189 }
190 }
191 } 145 }
192 } 146 }
193 Some(Pat(_)) => { 147 Some(Pat(_)) | Some(SelfParam(_)) => {
194 res.extend(None); 148 // Hover for these shows type names
195 } 149 no_fallback = true;
196 Some(SelfParam(_)) => {
197 res.extend(None);
198 } 150 }
199 Some(GenericParam(_)) => { 151 Some(GenericParam(_)) => {
200 // FIXME: Hover for generic param 152 // FIXME: Hover for generic param
@@ -202,7 +154,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
202 None => {} 154 None => {}
203 } 155 }
204 156
205 if res.is_empty() { 157 if res.is_empty() && !no_fallback {
206 // Fallback index based approach: 158 // Fallback index based approach:
207 let symbols = crate::symbol_index::index_resolve(db, name_ref); 159 let symbols = crate::symbol_index::index_resolve(db, name_ref);
208 for sym in symbols { 160 for sym in symbols {
@@ -270,7 +222,16 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
270 return None; 222 return None;
271 } 223 }
272 let res = RangeInfo::new(range, res); 224 let res = RangeInfo::new(range, res);
273 Some(res) 225 return Some(res);
226
227 fn from_def_source<A, D>(db: &RootDatabase, def: D) -> Option<String>
228 where
229 D: HasSource<Ast = TreeArc<A>>,
230 A: ast::DocCommentsOwner + ast::NameOwner + ShortLabel,
231 {
232 let src = def.source(db);
233 hover_text(src.ast.doc_comment_text(), src.ast.short_label())
234 }
274} 235}
275 236
276pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> { 237pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> {
@@ -714,4 +675,21 @@ fn func(foo: i32) { if true { <|>foo; }; }
714 assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing")); 675 assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing"));
715 assert_eq!(hover.info.is_exact(), true); 676 assert_eq!(hover.info.is_exact(), true);
716 } 677 }
678
679 #[test]
680 fn test_hover_shadowing_pat() {
681 let (analysis, position) = single_file_with_position(
682 "
683 fn x() {}
684
685 fn y() {
686 let x = 0i32;
687 x<|>;
688 }
689 ",
690 );
691 let hover = analysis.hover(position).unwrap().unwrap();
692 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32"));
693 assert_eq!(hover.info.is_exact(), true);
694 }
717} 695}
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index dbebf50a6..8741e736f 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -242,12 +242,21 @@ pub struct CallInfo {
242} 242}
243 243
244/// `AnalysisHost` stores the current state of the world. 244/// `AnalysisHost` stores the current state of the world.
245#[derive(Debug, Default)] 245#[derive(Debug)]
246pub struct AnalysisHost { 246pub struct AnalysisHost {
247 db: db::RootDatabase, 247 db: db::RootDatabase,
248} 248}
249 249
250impl Default for AnalysisHost {
251 fn default() -> AnalysisHost {
252 AnalysisHost::new(None)
253 }
254}
255
250impl AnalysisHost { 256impl AnalysisHost {
257 pub fn new(lru_capcity: Option<usize>) -> AnalysisHost {
258 AnalysisHost { db: db::RootDatabase::new(lru_capcity) }
259 }
251 /// Returns a snapshot of the current state, which you can query for 260 /// Returns a snapshot of the current state, which you can query for
252 /// semantic information. 261 /// semantic information.
253 pub fn analysis(&self) -> Analysis { 262 pub fn analysis(&self) -> Analysis {
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs
index a75042b76..12cdc6a6d 100644
--- a/crates/ra_ide_api/src/references.rs
+++ b/crates/ra_ide_api/src/references.rs
@@ -148,9 +148,9 @@ fn rename_mod(
148 let mut file_system_edits = Vec::new(); 148 let mut file_system_edits = Vec::new();
149 if let Some(module) = source_binder::module_from_declaration(db, position.file_id, &ast_module) 149 if let Some(module) = source_binder::module_from_declaration(db, position.file_id, &ast_module)
150 { 150 {
151 let (file_id, module_source) = module.definition_source(db); 151 let src = module.definition_source(db);
152 let file_id = file_id.as_original_file(); 152 let file_id = src.file_id.as_original_file();
153 match module_source { 153 match src.ast {
154 ModuleSource::SourceFile(..) => { 154 ModuleSource::SourceFile(..) => {
155 let mod_path: RelativePathBuf = db.file_relative_path(file_id); 155 let mod_path: RelativePathBuf = db.file_relative_path(file_id);
156 // mod is defined in path/to/dir/mod.rs 156 // mod is defined in path/to/dir/mod.rs