diff options
Diffstat (limited to 'crates/ra_ide_db/src')
-rw-r--r-- | crates/ra_ide_db/src/defs.rs | 134 | ||||
-rw-r--r-- | crates/ra_ide_db/src/imports_locator.rs | 8 |
2 files changed, 62 insertions, 80 deletions
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs index 030f44f86..04c214624 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 | ||
8 | use hir::{ | 8 | use hir::{ |
9 | Adt, HasSource, ImplBlock, InFile, Local, MacroDef, Module, ModuleDef, SourceBinder, | 9 | Adt, FieldSource, HasSource, ImplBlock, InFile, Local, MacroDef, Module, ModuleDef, |
10 | StructField, TypeParam, VariantDef, | 10 | SourceBinder, StructField, TypeParam, |
11 | }; | 11 | }; |
12 | use ra_prof::profile; | 12 | use ra_prof::profile; |
13 | use ra_syntax::{ | 13 | use ra_syntax::{ |
@@ -18,7 +18,7 @@ use ra_syntax::{ | |||
18 | use crate::RootDatabase; | 18 | use crate::RootDatabase; |
19 | 19 | ||
20 | #[derive(Debug, PartialEq, Eq)] | 20 | #[derive(Debug, PartialEq, Eq)] |
21 | pub enum NameKind { | 21 | pub enum NameDefinition { |
22 | Macro(MacroDef), | 22 | Macro(MacroDef), |
23 | StructField(StructField), | 23 | StructField(StructField), |
24 | ModuleDef(ModuleDef), | 24 | ModuleDef(ModuleDef), |
@@ -27,13 +27,45 @@ pub enum NameKind { | |||
27 | TypeParam(TypeParam), | 27 | TypeParam(TypeParam), |
28 | } | 28 | } |
29 | 29 | ||
30 | #[derive(PartialEq, Eq)] | 30 | impl NameDefinition { |
31 | pub struct NameDefinition { | 31 | pub fn module(&self, db: &RootDatabase) -> Option<Module> { |
32 | pub visibility: Option<ast::Visibility>, | 32 | match self { |
33 | /// FIXME: this doesn't really make sense. For example, builtin types don't | 33 | NameDefinition::Macro(it) => it.module(db), |
34 | /// really have a module. | 34 | NameDefinition::StructField(it) => Some(it.parent_def(db).module(db)), |
35 | pub container: Module, | 35 | NameDefinition::ModuleDef(it) => it.module(db), |
36 | pub kind: NameKind, | 36 | NameDefinition::SelfType(it) => Some(it.module(db)), |
37 | NameDefinition::Local(it) => Some(it.module(db)), | ||
38 | NameDefinition::TypeParam(it) => Some(it.module(db)), | ||
39 | } | ||
40 | } | ||
41 | |||
42 | pub fn visibility(&self, db: &RootDatabase) -> Option<ast::Visibility> { | ||
43 | match self { | ||
44 | NameDefinition::Macro(_) => None, | ||
45 | NameDefinition::StructField(sf) => match sf.source(db).value { | ||
46 | FieldSource::Named(it) => it.visibility(), | ||
47 | FieldSource::Pos(it) => it.visibility(), | ||
48 | }, | ||
49 | NameDefinition::ModuleDef(def) => match def { | ||
50 | ModuleDef::Module(it) => it.declaration_source(db)?.value.visibility(), | ||
51 | ModuleDef::Function(it) => it.source(db).value.visibility(), | ||
52 | ModuleDef::Adt(adt) => match adt { | ||
53 | Adt::Struct(it) => it.source(db).value.visibility(), | ||
54 | Adt::Union(it) => it.source(db).value.visibility(), | ||
55 | Adt::Enum(it) => it.source(db).value.visibility(), | ||
56 | }, | ||
57 | ModuleDef::Const(it) => it.source(db).value.visibility(), | ||
58 | ModuleDef::Static(it) => it.source(db).value.visibility(), | ||
59 | ModuleDef::Trait(it) => it.source(db).value.visibility(), | ||
60 | ModuleDef::TypeAlias(it) => it.source(db).value.visibility(), | ||
61 | ModuleDef::EnumVariant(_) => None, | ||
62 | ModuleDef::BuiltinType(_) => None, | ||
63 | }, | ||
64 | NameDefinition::SelfType(_) => None, | ||
65 | NameDefinition::Local(_) => None, | ||
66 | NameDefinition::TypeParam(_) => None, | ||
67 | } | ||
68 | } | ||
37 | } | 69 | } |
38 | 70 | ||
39 | pub fn classify_name( | 71 | pub fn classify_name( |
@@ -48,125 +80,77 @@ pub fn classify_name( | |||
48 | ast::BindPat(it) => { | 80 | ast::BindPat(it) => { |
49 | let src = name.with_value(it); | 81 | let src = name.with_value(it); |
50 | let local = sb.to_def(src)?; | 82 | let local = sb.to_def(src)?; |
51 | Some(NameDefinition { | 83 | Some(NameDefinition::Local(local)) |
52 | visibility: None, | ||
53 | container: local.module(sb.db), | ||
54 | kind: NameKind::Local(local), | ||
55 | }) | ||
56 | }, | 84 | }, |
57 | ast::RecordFieldDef(it) => { | 85 | ast::RecordFieldDef(it) => { |
58 | let src = name.with_value(it); | 86 | let src = name.with_value(it); |
59 | let field: hir::StructField = sb.to_def(src)?; | 87 | let field: hir::StructField = sb.to_def(src)?; |
60 | Some(from_struct_field(sb.db, field)) | 88 | Some(from_struct_field(field)) |
61 | }, | 89 | }, |
62 | ast::Module(it) => { | 90 | ast::Module(it) => { |
63 | let def = sb.to_def(name.with_value(it))?; | 91 | let def = sb.to_def(name.with_value(it))?; |
64 | Some(from_module_def(sb.db, def.into(), None)) | 92 | Some(from_module_def(def.into())) |
65 | }, | 93 | }, |
66 | ast::StructDef(it) => { | 94 | ast::StructDef(it) => { |
67 | let src = name.with_value(it); | 95 | let src = name.with_value(it); |
68 | let def: hir::Struct = sb.to_def(src)?; | 96 | let def: hir::Struct = sb.to_def(src)?; |
69 | Some(from_module_def(sb.db, def.into(), None)) | 97 | Some(from_module_def(def.into())) |
70 | }, | 98 | }, |
71 | ast::EnumDef(it) => { | 99 | ast::EnumDef(it) => { |
72 | let src = name.with_value(it); | 100 | let src = name.with_value(it); |
73 | let def: hir::Enum = sb.to_def(src)?; | 101 | let def: hir::Enum = sb.to_def(src)?; |
74 | Some(from_module_def(sb.db, def.into(), None)) | 102 | Some(from_module_def(def.into())) |
75 | }, | 103 | }, |
76 | ast::TraitDef(it) => { | 104 | ast::TraitDef(it) => { |
77 | let src = name.with_value(it); | 105 | let src = name.with_value(it); |
78 | let def: hir::Trait = sb.to_def(src)?; | 106 | let def: hir::Trait = sb.to_def(src)?; |
79 | Some(from_module_def(sb.db, def.into(), None)) | 107 | Some(from_module_def(def.into())) |
80 | }, | 108 | }, |
81 | ast::StaticDef(it) => { | 109 | ast::StaticDef(it) => { |
82 | let src = name.with_value(it); | 110 | let src = name.with_value(it); |
83 | let def: hir::Static = sb.to_def(src)?; | 111 | let def: hir::Static = sb.to_def(src)?; |
84 | Some(from_module_def(sb.db, def.into(), None)) | 112 | Some(from_module_def(def.into())) |
85 | }, | 113 | }, |
86 | ast::EnumVariant(it) => { | 114 | ast::EnumVariant(it) => { |
87 | let src = name.with_value(it); | 115 | let src = name.with_value(it); |
88 | let def: hir::EnumVariant = sb.to_def(src)?; | 116 | let def: hir::EnumVariant = sb.to_def(src)?; |
89 | Some(from_module_def(sb.db, def.into(), None)) | 117 | Some(from_module_def(def.into())) |
90 | }, | 118 | }, |
91 | ast::FnDef(it) => { | 119 | ast::FnDef(it) => { |
92 | let src = name.with_value(it); | 120 | let src = name.with_value(it); |
93 | let def: hir::Function = sb.to_def(src)?; | 121 | let def: hir::Function = sb.to_def(src)?; |
94 | Some(from_module_def(sb.db, def.into(), None)) | 122 | Some(from_module_def(def.into())) |
95 | }, | 123 | }, |
96 | ast::ConstDef(it) => { | 124 | ast::ConstDef(it) => { |
97 | let src = name.with_value(it); | 125 | let src = name.with_value(it); |
98 | let def: hir::Const = sb.to_def(src)?; | 126 | let def: hir::Const = sb.to_def(src)?; |
99 | Some(from_module_def(sb.db, def.into(), None)) | 127 | Some(from_module_def(def.into())) |
100 | }, | 128 | }, |
101 | ast::TypeAliasDef(it) => { | 129 | ast::TypeAliasDef(it) => { |
102 | let src = name.with_value(it); | 130 | let src = name.with_value(it); |
103 | let def: hir::TypeAlias = sb.to_def(src)?; | 131 | let def: hir::TypeAlias = sb.to_def(src)?; |
104 | Some(from_module_def(sb.db, def.into(), None)) | 132 | Some(from_module_def(def.into())) |
105 | }, | 133 | }, |
106 | ast::MacroCall(it) => { | 134 | ast::MacroCall(it) => { |
107 | let src = name.with_value(it); | 135 | let src = name.with_value(it); |
108 | let def = sb.to_def(src.clone())?; | 136 | let def = sb.to_def(src.clone())?; |
109 | 137 | ||
110 | let module = sb.to_module_def(src.file_id.original_file(sb.db))?; | 138 | Some(NameDefinition::Macro(def)) |
111 | |||
112 | Some(NameDefinition { | ||
113 | visibility: None, | ||
114 | container: module, | ||
115 | kind: NameKind::Macro(def), | ||
116 | }) | ||
117 | }, | 139 | }, |
118 | ast::TypeParam(it) => { | 140 | ast::TypeParam(it) => { |
119 | let src = name.with_value(it); | 141 | let src = name.with_value(it); |
120 | let def = sb.to_def(src)?; | 142 | let def = sb.to_def(src)?; |
121 | Some(NameDefinition { | 143 | Some(NameDefinition::TypeParam(def)) |
122 | visibility: None, | ||
123 | container: def.module(sb.db), | ||
124 | kind: NameKind::TypeParam(def), | ||
125 | }) | ||
126 | }, | 144 | }, |
127 | _ => None, | 145 | _ => None, |
128 | } | 146 | } |
129 | } | 147 | } |
130 | } | 148 | } |
131 | 149 | ||
132 | pub fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDefinition { | 150 | pub fn from_struct_field(field: StructField) -> NameDefinition { |
133 | let kind = NameKind::StructField(field); | 151 | NameDefinition::StructField(field) |
134 | let parent = field.parent_def(db); | ||
135 | let container = parent.module(db); | ||
136 | let visibility = match parent { | ||
137 | VariantDef::Struct(s) => s.source(db).value.visibility(), | ||
138 | VariantDef::Union(e) => e.source(db).value.visibility(), | ||
139 | VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(), | ||
140 | }; | ||
141 | NameDefinition { kind, container, visibility } | ||
142 | } | 152 | } |
143 | 153 | ||
144 | pub fn from_module_def( | 154 | pub fn from_module_def(def: ModuleDef) -> NameDefinition { |
145 | db: &RootDatabase, | 155 | NameDefinition::ModuleDef(def) |
146 | def: ModuleDef, | ||
147 | module: Option<Module>, | ||
148 | ) -> NameDefinition { | ||
149 | let kind = NameKind::ModuleDef(def); | ||
150 | let (container, visibility) = match def { | ||
151 | ModuleDef::Module(it) => { | ||
152 | let container = it.parent(db).or_else(|| Some(it)).unwrap(); | ||
153 | let visibility = it.declaration_source(db).and_then(|s| s.value.visibility()); | ||
154 | (container, visibility) | ||
155 | } | ||
156 | ModuleDef::EnumVariant(it) => { | ||
157 | let container = it.module(db); | ||
158 | let visibility = it.source(db).value.parent_enum().visibility(); | ||
159 | (container, visibility) | ||
160 | } | ||
161 | ModuleDef::Function(it) => (it.module(db), it.source(db).value.visibility()), | ||
162 | ModuleDef::Const(it) => (it.module(db), it.source(db).value.visibility()), | ||
163 | ModuleDef::Static(it) => (it.module(db), it.source(db).value.visibility()), | ||
164 | ModuleDef::Trait(it) => (it.module(db), it.source(db).value.visibility()), | ||
165 | ModuleDef::TypeAlias(it) => (it.module(db), it.source(db).value.visibility()), | ||
166 | ModuleDef::Adt(Adt::Struct(it)) => (it.module(db), it.source(db).value.visibility()), | ||
167 | ModuleDef::Adt(Adt::Union(it)) => (it.module(db), it.source(db).value.visibility()), | ||
168 | ModuleDef::Adt(Adt::Enum(it)) => (it.module(db), it.source(db).value.visibility()), | ||
169 | ModuleDef::BuiltinType(..) => (module.unwrap(), None), | ||
170 | }; | ||
171 | NameDefinition { kind, container, visibility } | ||
172 | } | 156 | } |
diff --git a/crates/ra_ide_db/src/imports_locator.rs b/crates/ra_ide_db/src/imports_locator.rs index 86383bcd0..b8dd358a9 100644 --- a/crates/ra_ide_db/src/imports_locator.rs +++ b/crates/ra_ide_db/src/imports_locator.rs | |||
@@ -6,8 +6,7 @@ use ra_prof::profile; | |||
6 | use ra_syntax::{ast, AstNode, SyntaxKind::NAME}; | 6 | use ra_syntax::{ast, AstNode, SyntaxKind::NAME}; |
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | defs::classify_name, | 9 | defs::{classify_name, NameDefinition}, |
10 | defs::NameKind, | ||
11 | symbol_index::{self, FileSymbol, Query}, | 10 | symbol_index::{self, FileSymbol, Query}, |
12 | RootDatabase, | 11 | RootDatabase, |
13 | }; | 12 | }; |
@@ -44,7 +43,7 @@ impl<'a> ImportsLocator<'a> { | |||
44 | .chain(lib_results.into_iter()) | 43 | .chain(lib_results.into_iter()) |
45 | .filter_map(|import_candidate| self.get_name_definition(db, &import_candidate)) | 44 | .filter_map(|import_candidate| self.get_name_definition(db, &import_candidate)) |
46 | .filter_map(|name_definition_to_import| match name_definition_to_import { | 45 | .filter_map(|name_definition_to_import| match name_definition_to_import { |
47 | NameKind::ModuleDef(module_def) => Some(module_def), | 46 | NameDefinition::ModuleDef(module_def) => Some(module_def), |
48 | _ => None, | 47 | _ => None, |
49 | }) | 48 | }) |
50 | .collect() | 49 | .collect() |
@@ -54,7 +53,7 @@ impl<'a> ImportsLocator<'a> { | |||
54 | &mut self, | 53 | &mut self, |
55 | db: &impl HirDatabase, | 54 | db: &impl HirDatabase, |
56 | import_candidate: &FileSymbol, | 55 | import_candidate: &FileSymbol, |
57 | ) -> Option<NameKind> { | 56 | ) -> Option<NameDefinition> { |
58 | let _p = profile("get_name_definition"); | 57 | let _p = profile("get_name_definition"); |
59 | let file_id = import_candidate.file_id.into(); | 58 | let file_id = import_candidate.file_id.into(); |
60 | let candidate_node = import_candidate.ptr.to_node(&db.parse_or_expand(file_id)?); | 59 | let candidate_node = import_candidate.ptr.to_node(&db.parse_or_expand(file_id)?); |
@@ -67,6 +66,5 @@ impl<'a> ImportsLocator<'a> { | |||
67 | &mut self.source_binder, | 66 | &mut self.source_binder, |
68 | hir::InFile { file_id, value: &ast::Name::cast(candidate_name_node)? }, | 67 | hir::InFile { file_id, value: &ast::Name::cast(candidate_name_node)? }, |
69 | ) | 68 | ) |
70 | .map(|it| it.kind) | ||
71 | } | 69 | } |
72 | } | 70 | } |