diff options
author | Aleksey Kladov <[email protected]> | 2020-02-06 15:23:28 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-02-06 15:23:28 +0000 |
commit | 271017e6bf5b5f46464d09db7fc869c92998fc80 (patch) | |
tree | 76227de73a33f3dd51d74d6736cf425a8a89bb64 /crates/ra_ide_db | |
parent | f8dde21fe9ccceea0b3dea83d646a45a409a0e3f (diff) |
Move NameKind up
Diffstat (limited to 'crates/ra_ide_db')
-rw-r--r-- | crates/ra_ide_db/src/defs.rs | 194 | ||||
-rw-r--r-- | crates/ra_ide_db/src/lib.rs | 1 |
2 files changed, 195 insertions, 0 deletions
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs new file mode 100644 index 000000000..1c983fb60 --- /dev/null +++ b/crates/ra_ide_db/src/defs.rs | |||
@@ -0,0 +1,194 @@ | |||
1 | //! `NameDefinition` keeps information about the element we want to search references for. | ||
2 | //! The element is represented by `NameKind`. It's located inside some `container` and | ||
3 | //! has a `visibility`, which defines a search scope. | ||
4 | //! Note that the reference search is possible for not all of the classified items. | ||
5 | |||
6 | use hir::{ | ||
7 | Adt, AssocItem, HasSource, ImplBlock, InFile, Local, MacroDef, Module, ModuleDef, SourceBinder, | ||
8 | StructField, TypeParam, VariantDef, | ||
9 | }; | ||
10 | use ra_prof::profile; | ||
11 | use ra_syntax::{ | ||
12 | ast::{self, AstNode, VisibilityOwner}, | ||
13 | match_ast, | ||
14 | }; | ||
15 | |||
16 | use crate::RootDatabase; | ||
17 | |||
18 | #[derive(Debug, PartialEq, Eq)] | ||
19 | pub enum NameKind { | ||
20 | Macro(MacroDef), | ||
21 | Field(StructField), | ||
22 | AssocItem(AssocItem), | ||
23 | Def(ModuleDef), | ||
24 | SelfType(ImplBlock), | ||
25 | Local(Local), | ||
26 | TypeParam(TypeParam), | ||
27 | } | ||
28 | |||
29 | #[derive(PartialEq, Eq)] | ||
30 | pub struct NameDefinition { | ||
31 | pub visibility: Option<ast::Visibility>, | ||
32 | /// FIXME: this doesn't really make sense. For example, builtin types don't | ||
33 | /// really have a module. | ||
34 | pub container: Module, | ||
35 | pub kind: NameKind, | ||
36 | } | ||
37 | |||
38 | pub fn classify_name( | ||
39 | sb: &mut SourceBinder<RootDatabase>, | ||
40 | name: InFile<&ast::Name>, | ||
41 | ) -> Option<NameDefinition> { | ||
42 | let _p = profile("classify_name"); | ||
43 | let parent = name.value.syntax().parent()?; | ||
44 | |||
45 | match_ast! { | ||
46 | match parent { | ||
47 | ast::BindPat(it) => { | ||
48 | let src = name.with_value(it); | ||
49 | let local = sb.to_def(src)?; | ||
50 | Some(NameDefinition { | ||
51 | visibility: None, | ||
52 | container: local.module(sb.db), | ||
53 | kind: NameKind::Local(local), | ||
54 | }) | ||
55 | }, | ||
56 | ast::RecordFieldDef(it) => { | ||
57 | let src = name.with_value(it); | ||
58 | let field: hir::StructField = sb.to_def(src)?; | ||
59 | Some(from_struct_field(sb.db, field)) | ||
60 | }, | ||
61 | ast::Module(it) => { | ||
62 | let def = sb.to_def(name.with_value(it))?; | ||
63 | Some(from_module_def(sb.db, def.into(), None)) | ||
64 | }, | ||
65 | ast::StructDef(it) => { | ||
66 | let src = name.with_value(it); | ||
67 | let def: hir::Struct = sb.to_def(src)?; | ||
68 | Some(from_module_def(sb.db, def.into(), None)) | ||
69 | }, | ||
70 | ast::EnumDef(it) => { | ||
71 | let src = name.with_value(it); | ||
72 | let def: hir::Enum = sb.to_def(src)?; | ||
73 | Some(from_module_def(sb.db, def.into(), None)) | ||
74 | }, | ||
75 | ast::TraitDef(it) => { | ||
76 | let src = name.with_value(it); | ||
77 | let def: hir::Trait = sb.to_def(src)?; | ||
78 | Some(from_module_def(sb.db, def.into(), None)) | ||
79 | }, | ||
80 | ast::StaticDef(it) => { | ||
81 | let src = name.with_value(it); | ||
82 | let def: hir::Static = sb.to_def(src)?; | ||
83 | Some(from_module_def(sb.db, def.into(), None)) | ||
84 | }, | ||
85 | ast::EnumVariant(it) => { | ||
86 | let src = name.with_value(it); | ||
87 | let def: hir::EnumVariant = sb.to_def(src)?; | ||
88 | Some(from_module_def(sb.db, def.into(), None)) | ||
89 | }, | ||
90 | ast::FnDef(it) => { | ||
91 | let src = name.with_value(it); | ||
92 | let def: hir::Function = sb.to_def(src)?; | ||
93 | if parent.parent().and_then(ast::ItemList::cast).is_some() { | ||
94 | Some(from_assoc_item(sb.db, def.into())) | ||
95 | } else { | ||
96 | Some(from_module_def(sb.db, def.into(), None)) | ||
97 | } | ||
98 | }, | ||
99 | ast::ConstDef(it) => { | ||
100 | let src = name.with_value(it); | ||
101 | let def: hir::Const = sb.to_def(src)?; | ||
102 | if parent.parent().and_then(ast::ItemList::cast).is_some() { | ||
103 | Some(from_assoc_item(sb.db, def.into())) | ||
104 | } else { | ||
105 | Some(from_module_def(sb.db, def.into(), None)) | ||
106 | } | ||
107 | }, | ||
108 | ast::TypeAliasDef(it) => { | ||
109 | let src = name.with_value(it); | ||
110 | let def: hir::TypeAlias = sb.to_def(src)?; | ||
111 | if parent.parent().and_then(ast::ItemList::cast).is_some() { | ||
112 | Some(from_assoc_item(sb.db, def.into())) | ||
113 | } else { | ||
114 | Some(from_module_def(sb.db, def.into(), None)) | ||
115 | } | ||
116 | }, | ||
117 | ast::MacroCall(it) => { | ||
118 | let src = name.with_value(it); | ||
119 | let def = sb.to_def(src.clone())?; | ||
120 | |||
121 | let module = sb.to_module_def(src.file_id.original_file(sb.db))?; | ||
122 | |||
123 | Some(NameDefinition { | ||
124 | visibility: None, | ||
125 | container: module, | ||
126 | kind: NameKind::Macro(def), | ||
127 | }) | ||
128 | }, | ||
129 | ast::TypeParam(it) => { | ||
130 | let src = name.with_value(it); | ||
131 | let def = sb.to_def(src)?; | ||
132 | Some(NameDefinition { | ||
133 | visibility: None, | ||
134 | container: def.module(sb.db), | ||
135 | kind: NameKind::TypeParam(def), | ||
136 | }) | ||
137 | }, | ||
138 | _ => None, | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | |||
143 | pub fn from_assoc_item(db: &RootDatabase, item: AssocItem) -> NameDefinition { | ||
144 | let container = item.module(db); | ||
145 | let visibility = match item { | ||
146 | AssocItem::Function(f) => f.source(db).value.visibility(), | ||
147 | AssocItem::Const(c) => c.source(db).value.visibility(), | ||
148 | AssocItem::TypeAlias(a) => a.source(db).value.visibility(), | ||
149 | }; | ||
150 | let kind = NameKind::AssocItem(item); | ||
151 | NameDefinition { kind, container, visibility } | ||
152 | } | ||
153 | |||
154 | pub fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDefinition { | ||
155 | let kind = NameKind::Field(field); | ||
156 | let parent = field.parent_def(db); | ||
157 | let container = parent.module(db); | ||
158 | let visibility = match parent { | ||
159 | VariantDef::Struct(s) => s.source(db).value.visibility(), | ||
160 | VariantDef::Union(e) => e.source(db).value.visibility(), | ||
161 | VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(), | ||
162 | }; | ||
163 | NameDefinition { kind, container, visibility } | ||
164 | } | ||
165 | |||
166 | pub fn from_module_def( | ||
167 | db: &RootDatabase, | ||
168 | def: ModuleDef, | ||
169 | module: Option<Module>, | ||
170 | ) -> NameDefinition { | ||
171 | let kind = NameKind::Def(def); | ||
172 | let (container, visibility) = match def { | ||
173 | ModuleDef::Module(it) => { | ||
174 | let container = it.parent(db).or_else(|| Some(it)).unwrap(); | ||
175 | let visibility = it.declaration_source(db).and_then(|s| s.value.visibility()); | ||
176 | (container, visibility) | ||
177 | } | ||
178 | ModuleDef::EnumVariant(it) => { | ||
179 | let container = it.module(db); | ||
180 | let visibility = it.source(db).value.parent_enum().visibility(); | ||
181 | (container, visibility) | ||
182 | } | ||
183 | ModuleDef::Function(it) => (it.module(db), it.source(db).value.visibility()), | ||
184 | ModuleDef::Const(it) => (it.module(db), it.source(db).value.visibility()), | ||
185 | ModuleDef::Static(it) => (it.module(db), it.source(db).value.visibility()), | ||
186 | ModuleDef::Trait(it) => (it.module(db), it.source(db).value.visibility()), | ||
187 | ModuleDef::TypeAlias(it) => (it.module(db), it.source(db).value.visibility()), | ||
188 | ModuleDef::Adt(Adt::Struct(it)) => (it.module(db), it.source(db).value.visibility()), | ||
189 | ModuleDef::Adt(Adt::Union(it)) => (it.module(db), it.source(db).value.visibility()), | ||
190 | ModuleDef::Adt(Adt::Enum(it)) => (it.module(db), it.source(db).value.visibility()), | ||
191 | ModuleDef::BuiltinType(..) => (module.unwrap(), None), | ||
192 | }; | ||
193 | NameDefinition { kind, container, visibility } | ||
194 | } | ||
diff --git a/crates/ra_ide_db/src/lib.rs b/crates/ra_ide_db/src/lib.rs index e922d1e5f..0715dfc66 100644 --- a/crates/ra_ide_db/src/lib.rs +++ b/crates/ra_ide_db/src/lib.rs | |||
@@ -7,6 +7,7 @@ pub mod line_index_utils; | |||
7 | pub mod feature_flags; | 7 | pub mod feature_flags; |
8 | pub mod symbol_index; | 8 | pub mod symbol_index; |
9 | pub mod change; | 9 | pub mod change; |
10 | pub mod defs; | ||
10 | mod wasm_shims; | 11 | mod wasm_shims; |
11 | 12 | ||
12 | use std::sync::Arc; | 13 | use std::sync::Arc; |