aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_db/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-02-18 17:35:10 +0000
committerAleksey Kladov <[email protected]>2020-02-26 11:55:50 +0000
commitc3a4c4429de83450654795534e64e878a774a088 (patch)
tree12d89798f61b276f8bd640db07276a7d4e92b1c2 /crates/ra_ide_db/src
parent04deae3dba7c9b7054f7a1d64e4b93a05aecc132 (diff)
Refactor primary IDE API
This introduces the new type -- Semantics. Semantics maps SyntaxNodes to various semantic info, such as type, name resolution or macro expansions. To do so, Semantics maintains a HashMap which maps every node it saw to the file from which the node originated. This is enough to get all the necessary hir bits just from syntax.
Diffstat (limited to 'crates/ra_ide_db/src')
-rw-r--r--crates/ra_ide_db/src/defs.rs50
-rw-r--r--crates/ra_ide_db/src/imports_locator.rs26
2 files changed, 27 insertions, 49 deletions
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs
index 04c214624..e10e72f71 100644
--- a/crates/ra_ide_db/src/defs.rs
+++ b/crates/ra_ide_db/src/defs.rs
@@ -6,8 +6,8 @@
6// FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). 6// FIXME: this badly needs rename/rewrite (matklad, 2020-02-06).
7 7
8use hir::{ 8use hir::{
9 Adt, FieldSource, HasSource, ImplBlock, InFile, Local, MacroDef, Module, ModuleDef, 9 Adt, FieldSource, HasSource, ImplBlock, Local, MacroDef, Module, ModuleDef, Semantics,
10 SourceBinder, StructField, TypeParam, 10 StructField, TypeParam,
11}; 11};
12use ra_prof::profile; 12use ra_prof::profile;
13use ra_syntax::{ 13use ra_syntax::{
@@ -68,78 +68,62 @@ impl NameDefinition {
68 } 68 }
69} 69}
70 70
71pub fn classify_name( 71pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameDefinition> {
72 sb: &mut SourceBinder<RootDatabase>,
73 name: InFile<&ast::Name>,
74) -> Option<NameDefinition> {
75 let _p = profile("classify_name"); 72 let _p = profile("classify_name");
76 let parent = name.value.syntax().parent()?; 73 let parent = name.syntax().parent()?;
77 74
78 match_ast! { 75 match_ast! {
79 match parent { 76 match parent {
80 ast::BindPat(it) => { 77 ast::BindPat(it) => {
81 let src = name.with_value(it); 78 let local = sema.to_def(&it)?;
82 let local = sb.to_def(src)?;
83 Some(NameDefinition::Local(local)) 79 Some(NameDefinition::Local(local))
84 }, 80 },
85 ast::RecordFieldDef(it) => { 81 ast::RecordFieldDef(it) => {
86 let src = name.with_value(it); 82 let field: hir::StructField = sema.to_def(&it)?;
87 let field: hir::StructField = sb.to_def(src)?;
88 Some(from_struct_field(field)) 83 Some(from_struct_field(field))
89 }, 84 },
90 ast::Module(it) => { 85 ast::Module(it) => {
91 let def = sb.to_def(name.with_value(it))?; 86 let def = sema.to_def(&it)?;
92 Some(from_module_def(def.into())) 87 Some(from_module_def(def.into()))
93 }, 88 },
94 ast::StructDef(it) => { 89 ast::StructDef(it) => {
95 let src = name.with_value(it); 90 let def: hir::Struct = sema.to_def(&it)?;
96 let def: hir::Struct = sb.to_def(src)?;
97 Some(from_module_def(def.into())) 91 Some(from_module_def(def.into()))
98 }, 92 },
99 ast::EnumDef(it) => { 93 ast::EnumDef(it) => {
100 let src = name.with_value(it); 94 let def: hir::Enum = sema.to_def(&it)?;
101 let def: hir::Enum = sb.to_def(src)?;
102 Some(from_module_def(def.into())) 95 Some(from_module_def(def.into()))
103 }, 96 },
104 ast::TraitDef(it) => { 97 ast::TraitDef(it) => {
105 let src = name.with_value(it); 98 let def: hir::Trait = sema.to_def(&it)?;
106 let def: hir::Trait = sb.to_def(src)?;
107 Some(from_module_def(def.into())) 99 Some(from_module_def(def.into()))
108 }, 100 },
109 ast::StaticDef(it) => { 101 ast::StaticDef(it) => {
110 let src = name.with_value(it); 102 let def: hir::Static = sema.to_def(&it)?;
111 let def: hir::Static = sb.to_def(src)?;
112 Some(from_module_def(def.into())) 103 Some(from_module_def(def.into()))
113 }, 104 },
114 ast::EnumVariant(it) => { 105 ast::EnumVariant(it) => {
115 let src = name.with_value(it); 106 let def: hir::EnumVariant = sema.to_def(&it)?;
116 let def: hir::EnumVariant = sb.to_def(src)?;
117 Some(from_module_def(def.into())) 107 Some(from_module_def(def.into()))
118 }, 108 },
119 ast::FnDef(it) => { 109 ast::FnDef(it) => {
120 let src = name.with_value(it); 110 let def: hir::Function = sema.to_def(&it)?;
121 let def: hir::Function = sb.to_def(src)?;
122 Some(from_module_def(def.into())) 111 Some(from_module_def(def.into()))
123 }, 112 },
124 ast::ConstDef(it) => { 113 ast::ConstDef(it) => {
125 let src = name.with_value(it); 114 let def: hir::Const = sema.to_def(&it)?;
126 let def: hir::Const = sb.to_def(src)?;
127 Some(from_module_def(def.into())) 115 Some(from_module_def(def.into()))
128 }, 116 },
129 ast::TypeAliasDef(it) => { 117 ast::TypeAliasDef(it) => {
130 let src = name.with_value(it); 118 let def: hir::TypeAlias = sema.to_def(&it)?;
131 let def: hir::TypeAlias = sb.to_def(src)?;
132 Some(from_module_def(def.into())) 119 Some(from_module_def(def.into()))
133 }, 120 },
134 ast::MacroCall(it) => { 121 ast::MacroCall(it) => {
135 let src = name.with_value(it); 122 let def = sema.to_def(&it)?;
136 let def = sb.to_def(src.clone())?;
137
138 Some(NameDefinition::Macro(def)) 123 Some(NameDefinition::Macro(def))
139 }, 124 },
140 ast::TypeParam(it) => { 125 ast::TypeParam(it) => {
141 let src = name.with_value(it); 126 let def = sema.to_def(&it)?;
142 let def = sb.to_def(src)?;
143 Some(NameDefinition::TypeParam(def)) 127 Some(NameDefinition::TypeParam(def))
144 }, 128 },
145 _ => None, 129 _ => None,
diff --git a/crates/ra_ide_db/src/imports_locator.rs b/crates/ra_ide_db/src/imports_locator.rs
index b8dd358a9..e590d2a5c 100644
--- a/crates/ra_ide_db/src/imports_locator.rs
+++ b/crates/ra_ide_db/src/imports_locator.rs
@@ -1,7 +1,7 @@
1//! This module contains an import search funcionality that is provided to the ra_assists module. 1//! This module contains an import search funcionality that is provided to the ra_assists module.
2//! Later, this should be moved away to a separate crate that is accessible from the ra_assists module. 2//! Later, this should be moved away to a separate crate that is accessible from the ra_assists module.
3 3
4use hir::{db::HirDatabase, ModuleDef, SourceBinder}; 4use hir::{ModuleDef, Semantics};
5use ra_prof::profile; 5use ra_prof::profile;
6use ra_syntax::{ast, AstNode, SyntaxKind::NAME}; 6use ra_syntax::{ast, AstNode, SyntaxKind::NAME};
7 7
@@ -12,17 +12,17 @@ use crate::{
12}; 12};
13 13
14pub struct ImportsLocator<'a> { 14pub struct ImportsLocator<'a> {
15 source_binder: SourceBinder<'a, RootDatabase>, 15 sema: Semantics<'a, RootDatabase>,
16} 16}
17 17
18impl<'a> ImportsLocator<'a> { 18impl<'a> ImportsLocator<'a> {
19 pub fn new(db: &'a RootDatabase) -> Self { 19 pub fn new(db: &'a RootDatabase) -> Self {
20 Self { source_binder: SourceBinder::new(db) } 20 Self { sema: Semantics::new(db) }
21 } 21 }
22 22
23 pub fn find_imports(&mut self, name_to_import: &str) -> Vec<ModuleDef> { 23 pub fn find_imports(&mut self, name_to_import: &str) -> Vec<ModuleDef> {
24 let _p = profile("search_for_imports"); 24 let _p = profile("search_for_imports");
25 let db = self.source_binder.db; 25 let db = self.sema.db;
26 26
27 let project_results = { 27 let project_results = {
28 let mut query = Query::new(name_to_import.to_string()); 28 let mut query = Query::new(name_to_import.to_string());
@@ -41,7 +41,7 @@ impl<'a> ImportsLocator<'a> {
41 project_results 41 project_results
42 .into_iter() 42 .into_iter()
43 .chain(lib_results.into_iter()) 43 .chain(lib_results.into_iter())
44 .filter_map(|import_candidate| self.get_name_definition(db, &import_candidate)) 44 .filter_map(|import_candidate| self.get_name_definition(&import_candidate))
45 .filter_map(|name_definition_to_import| match name_definition_to_import { 45 .filter_map(|name_definition_to_import| match name_definition_to_import {
46 NameDefinition::ModuleDef(module_def) => Some(module_def), 46 NameDefinition::ModuleDef(module_def) => Some(module_def),
47 _ => None, 47 _ => None,
@@ -49,22 +49,16 @@ impl<'a> ImportsLocator<'a> {
49 .collect() 49 .collect()
50 } 50 }
51 51
52 fn get_name_definition( 52 fn get_name_definition(&mut self, import_candidate: &FileSymbol) -> Option<NameDefinition> {
53 &mut self,
54 db: &impl HirDatabase,
55 import_candidate: &FileSymbol,
56 ) -> Option<NameDefinition> {
57 let _p = profile("get_name_definition"); 53 let _p = profile("get_name_definition");
58 let file_id = import_candidate.file_id.into(); 54 let file_id = import_candidate.file_id;
59 let candidate_node = import_candidate.ptr.to_node(&db.parse_or_expand(file_id)?); 55
56 let candidate_node = import_candidate.ptr.to_node(self.sema.parse(file_id).syntax());
60 let candidate_name_node = if candidate_node.kind() != NAME { 57 let candidate_name_node = if candidate_node.kind() != NAME {
61 candidate_node.children().find(|it| it.kind() == NAME)? 58 candidate_node.children().find(|it| it.kind() == NAME)?
62 } else { 59 } else {
63 candidate_node 60 candidate_node
64 }; 61 };
65 classify_name( 62 classify_name(&self.sema, &ast::Name::cast(candidate_name_node)?)
66 &mut self.source_binder,
67 hir::InFile { file_id, value: &ast::Name::cast(candidate_name_node)? },
68 )
69 } 63 }
70} 64}