diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/function/scope.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir/src/krate.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir/src/module.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir/src/module/imp.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir/src/module/nameres.rs | 25 | ||||
-rw-r--r-- | crates/ra_hir/src/module/nameres/tests.rs | 66 | ||||
-rw-r--r-- | crates/ra_hir/src/name.rs | 97 | ||||
-rw-r--r-- | crates/ra_hir/src/path.rs | 18 | ||||
-rw-r--r-- | crates/ra_hir/src/query_definitions.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 23 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/primitive.rs | 42 |
13 files changed, 269 insertions, 91 deletions
diff --git a/crates/ra_hir/src/function/scope.rs b/crates/ra_hir/src/function/scope.rs index a1a580979..3e4cfad0c 100644 --- a/crates/ra_hir/src/function/scope.rs +++ b/crates/ra_hir/src/function/scope.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use rustc_hash::{FxHashMap, FxHashSet}; | 1 | use rustc_hash::{FxHashMap, FxHashSet}; |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | AstNode, SmolStr, SyntaxNodeRef, TextUnit, TextRange, | 4 | AstNode, SyntaxNodeRef, TextUnit, TextRange, |
5 | algo::generate, | 5 | algo::generate, |
6 | ast::{self, ArgListOwner, LoopBodyOwner, NameOwner}, | 6 | ast::{self, ArgListOwner, LoopBodyOwner, NameOwner}, |
7 | }; | 7 | }; |
@@ -9,6 +9,7 @@ use ra_db::LocalSyntaxPtr; | |||
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | arena::{Arena, Id}, | 11 | arena::{Arena, Id}, |
12 | Name, AsName, | ||
12 | }; | 13 | }; |
13 | 14 | ||
14 | pub(crate) type ScopeId = Id<ScopeData>; | 15 | pub(crate) type ScopeId = Id<ScopeData>; |
@@ -22,7 +23,7 @@ pub struct FnScopes { | |||
22 | 23 | ||
23 | #[derive(Debug, PartialEq, Eq)] | 24 | #[derive(Debug, PartialEq, Eq)] |
24 | pub struct ScopeEntry { | 25 | pub struct ScopeEntry { |
25 | name: SmolStr, | 26 | name: Name, |
26 | ptr: LocalSyntaxPtr, | 27 | ptr: LocalSyntaxPtr, |
27 | } | 28 | } |
28 | 29 | ||
@@ -101,11 +102,12 @@ impl FnScopes { | |||
101 | 102 | ||
102 | pub fn resolve_local_name<'a>(&'a self, name_ref: ast::NameRef) -> Option<&'a ScopeEntry> { | 103 | pub fn resolve_local_name<'a>(&'a self, name_ref: ast::NameRef) -> Option<&'a ScopeEntry> { |
103 | let mut shadowed = FxHashSet::default(); | 104 | let mut shadowed = FxHashSet::default(); |
105 | let name = name_ref.as_name(); | ||
104 | let ret = self | 106 | let ret = self |
105 | .scope_chain(name_ref.syntax()) | 107 | .scope_chain(name_ref.syntax()) |
106 | .flat_map(|scope| self.entries(scope).iter()) | 108 | .flat_map(|scope| self.entries(scope).iter()) |
107 | .filter(|entry| shadowed.insert(entry.name())) | 109 | .filter(|entry| shadowed.insert(entry.name())) |
108 | .filter(|entry| entry.name() == &name_ref.text()) | 110 | .filter(|entry| entry.name() == &name) |
109 | .nth(0); | 111 | .nth(0); |
110 | ret | 112 | ret |
111 | } | 113 | } |
@@ -170,14 +172,14 @@ impl FnScopes { | |||
170 | 172 | ||
171 | impl ScopeEntry { | 173 | impl ScopeEntry { |
172 | fn new(pat: ast::BindPat) -> Option<ScopeEntry> { | 174 | fn new(pat: ast::BindPat) -> Option<ScopeEntry> { |
173 | let name = pat.name()?; | 175 | let name = pat.name()?.as_name(); |
174 | let res = ScopeEntry { | 176 | let res = ScopeEntry { |
175 | name: name.text(), | 177 | name, |
176 | ptr: LocalSyntaxPtr::new(pat.syntax()), | 178 | ptr: LocalSyntaxPtr::new(pat.syntax()), |
177 | }; | 179 | }; |
178 | Some(res) | 180 | Some(res) |
179 | } | 181 | } |
180 | pub fn name(&self) -> &SmolStr { | 182 | pub fn name(&self) -> &Name { |
181 | &self.name | 183 | &self.name |
182 | } | 184 | } |
183 | pub fn ptr(&self) -> LocalSyntaxPtr { | 185 | pub fn ptr(&self) -> LocalSyntaxPtr { |
@@ -334,7 +336,7 @@ pub struct ReferenceDescriptor { | |||
334 | mod tests { | 336 | mod tests { |
335 | use ra_editor::find_node_at_offset; | 337 | use ra_editor::find_node_at_offset; |
336 | use ra_syntax::SourceFileNode; | 338 | use ra_syntax::SourceFileNode; |
337 | use test_utils::extract_offset; | 339 | use test_utils::{extract_offset, assert_eq_text}; |
338 | 340 | ||
339 | use super::*; | 341 | use super::*; |
340 | 342 | ||
@@ -355,9 +357,11 @@ mod tests { | |||
355 | let actual = scopes | 357 | let actual = scopes |
356 | .scope_chain(marker.syntax()) | 358 | .scope_chain(marker.syntax()) |
357 | .flat_map(|scope| scopes.entries(scope)) | 359 | .flat_map(|scope| scopes.entries(scope)) |
358 | .map(|it| it.name()) | 360 | .map(|it| it.name().to_string()) |
359 | .collect::<Vec<_>>(); | 361 | .collect::<Vec<_>>() |
360 | assert_eq!(actual.as_slice(), expected); | 362 | .join("\n"); |
363 | let expected = expected.join("\n"); | ||
364 | assert_eq_text!(&actual, &expected); | ||
361 | } | 365 | } |
362 | 366 | ||
363 | #[test] | 367 | #[test] |
diff --git a/crates/ra_hir/src/krate.rs b/crates/ra_hir/src/krate.rs index 1196dcef1..89b1e639e 100644 --- a/crates/ra_hir/src/krate.rs +++ b/crates/ra_hir/src/krate.rs | |||
@@ -1,7 +1,6 @@ | |||
1 | use ra_syntax::SmolStr; | ||
2 | pub use ra_db::CrateId; | 1 | pub use ra_db::CrateId; |
3 | 2 | ||
4 | use crate::{HirDatabase, Module, Cancelable}; | 3 | use crate::{HirDatabase, Module, Cancelable, Name, AsName}; |
5 | 4 | ||
6 | /// hir::Crate describes a single crate. It's the main inteface with which | 5 | /// hir::Crate describes a single crate. It's the main inteface with which |
7 | /// crate's dependencies interact. Mostly, it should be just a proxy for the | 6 | /// crate's dependencies interact. Mostly, it should be just a proxy for the |
@@ -14,7 +13,7 @@ pub struct Crate { | |||
14 | #[derive(Debug)] | 13 | #[derive(Debug)] |
15 | pub struct CrateDependency { | 14 | pub struct CrateDependency { |
16 | pub krate: Crate, | 15 | pub krate: Crate, |
17 | pub name: SmolStr, | 16 | pub name: Name, |
18 | } | 17 | } |
19 | 18 | ||
20 | impl Crate { | 19 | impl Crate { |
@@ -27,7 +26,7 @@ impl Crate { | |||
27 | .dependencies(self.crate_id) | 26 | .dependencies(self.crate_id) |
28 | .map(|dep| { | 27 | .map(|dep| { |
29 | let krate = Crate::new(dep.crate_id()); | 28 | let krate = Crate::new(dep.crate_id()); |
30 | let name = dep.name.clone(); | 29 | let name = dep.as_name(); |
31 | CrateDependency { krate, name } | 30 | CrateDependency { krate, name } |
32 | }) | 31 | }) |
33 | .collect() | 32 | .collect() |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index f1cc0ccd0..5bbb09c01 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -22,6 +22,7 @@ mod path; | |||
22 | mod arena; | 22 | mod arena; |
23 | pub mod source_binder; | 23 | pub mod source_binder; |
24 | 24 | ||
25 | mod name; | ||
25 | mod krate; | 26 | mod krate; |
26 | mod module; | 27 | mod module; |
27 | mod function; | 28 | mod function; |
@@ -37,10 +38,12 @@ use ra_db::{LocationIntener, SourceRootId, FileId, Cancelable}; | |||
37 | use crate::{ | 38 | use crate::{ |
38 | db::HirDatabase, | 39 | db::HirDatabase, |
39 | arena::{Arena, Id}, | 40 | arena::{Arena, Id}, |
41 | name::{AsName, KnownName}, | ||
40 | }; | 42 | }; |
41 | 43 | ||
42 | pub use self::{ | 44 | pub use self::{ |
43 | path::{Path, PathKind}, | 45 | path::{Path, PathKind}, |
46 | name::Name, | ||
44 | krate::Crate, | 47 | krate::Crate, |
45 | module::{Module, ModuleId, Problem, nameres::{ItemMap, PerNs, Namespace}, ModuleScope, Resolution}, | 48 | module::{Module, ModuleId, Problem, nameres::{ItemMap, PerNs, Namespace}, ModuleScope, Resolution}, |
46 | function::{Function, FnScopes}, | 49 | function::{Function, FnScopes}, |
diff --git a/crates/ra_hir/src/module.rs b/crates/ra_hir/src/module.rs index b9d36f01f..43413acb8 100644 --- a/crates/ra_hir/src/module.rs +++ b/crates/ra_hir/src/module.rs | |||
@@ -7,13 +7,14 @@ use log; | |||
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
8 | algo::generate, | 8 | algo::generate, |
9 | ast::{self, AstNode, NameOwner}, | 9 | ast::{self, AstNode, NameOwner}, |
10 | SmolStr, SyntaxNode, | 10 | SyntaxNode, |
11 | }; | 11 | }; |
12 | use ra_db::{SourceRootId, FileId, Cancelable}; | 12 | use ra_db::{SourceRootId, FileId, Cancelable}; |
13 | use relative_path::RelativePathBuf; | 13 | use relative_path::RelativePathBuf; |
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | DefKind, DefLoc, DefId, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, Crate, | 16 | DefKind, DefLoc, DefId, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, Crate, |
17 | Name, | ||
17 | arena::{Arena, Id}, | 18 | arena::{Arena, Id}, |
18 | }; | 19 | }; |
19 | 20 | ||
@@ -84,7 +85,7 @@ impl Module { | |||
84 | } | 85 | } |
85 | 86 | ||
86 | /// `name` is `None` for the crate's root module | 87 | /// `name` is `None` for the crate's root module |
87 | pub fn name(&self) -> Option<SmolStr> { | 88 | pub fn name(&self) -> Option<&Name> { |
88 | let link = self.module_id.parent_link(&self.tree)?; | 89 | let link = self.module_id.parent_link(&self.tree)?; |
89 | Some(link.name(&self.tree)) | 90 | Some(link.name(&self.tree)) |
90 | } | 91 | } |
@@ -100,7 +101,7 @@ impl Module { | |||
100 | } | 101 | } |
101 | 102 | ||
102 | /// Finds a child module with the specified name. | 103 | /// Finds a child module with the specified name. |
103 | pub fn child(&self, name: &str) -> Option<Module> { | 104 | pub fn child(&self, name: &Name) -> Option<Module> { |
104 | let child_id = self.module_id.child(&self.tree, name)?; | 105 | let child_id = self.module_id.child(&self.tree, name)?; |
105 | Some(Module { | 106 | Some(Module { |
106 | module_id: child_id, | 107 | module_id: child_id, |
@@ -230,15 +231,15 @@ impl ModuleId { | |||
230 | .last() | 231 | .last() |
231 | .unwrap() | 232 | .unwrap() |
232 | } | 233 | } |
233 | fn child(self, tree: &ModuleTree, name: &str) -> Option<ModuleId> { | 234 | fn child(self, tree: &ModuleTree, name: &Name) -> Option<ModuleId> { |
234 | let link = tree.mods[self] | 235 | let link = tree.mods[self] |
235 | .children | 236 | .children |
236 | .iter() | 237 | .iter() |
237 | .map(|&it| &tree.links[it]) | 238 | .map(|&it| &tree.links[it]) |
238 | .find(|it| it.name == name)?; | 239 | .find(|it| it.name == *name)?; |
239 | Some(*link.points_to.first()?) | 240 | Some(*link.points_to.first()?) |
240 | } | 241 | } |
241 | fn children<'a>(self, tree: &'a ModuleTree) -> impl Iterator<Item = (SmolStr, ModuleId)> + 'a { | 242 | fn children<'a>(self, tree: &'a ModuleTree) -> impl Iterator<Item = (Name, ModuleId)> + 'a { |
242 | tree.mods[self].children.iter().filter_map(move |&it| { | 243 | tree.mods[self].children.iter().filter_map(move |&it| { |
243 | let link = &tree.links[it]; | 244 | let link = &tree.links[it]; |
244 | let module = *link.points_to.first()?; | 245 | let module = *link.points_to.first()?; |
@@ -263,8 +264,8 @@ impl LinkId { | |||
263 | fn owner(self, tree: &ModuleTree) -> ModuleId { | 264 | fn owner(self, tree: &ModuleTree) -> ModuleId { |
264 | tree.links[self].owner | 265 | tree.links[self].owner |
265 | } | 266 | } |
266 | fn name(self, tree: &ModuleTree) -> SmolStr { | 267 | fn name(self, tree: &ModuleTree) -> &Name { |
267 | tree.links[self].name.clone() | 268 | &tree.links[self].name |
268 | } | 269 | } |
269 | fn bind_source<'a>(self, tree: &ModuleTree, db: &impl HirDatabase) -> ast::ModuleNode { | 270 | fn bind_source<'a>(self, tree: &ModuleTree, db: &impl HirDatabase) -> ast::ModuleNode { |
270 | let owner = self.owner(tree); | 271 | let owner = self.owner(tree); |
@@ -328,7 +329,7 @@ impl ModuleSource { | |||
328 | #[derive(Hash, Debug, PartialEq, Eq)] | 329 | #[derive(Hash, Debug, PartialEq, Eq)] |
329 | struct LinkData { | 330 | struct LinkData { |
330 | owner: ModuleId, | 331 | owner: ModuleId, |
331 | name: SmolStr, | 332 | name: Name, |
332 | points_to: Vec<ModuleId>, | 333 | points_to: Vec<ModuleId>, |
333 | problem: Option<Problem>, | 334 | problem: Option<Problem>, |
334 | } | 335 | } |
diff --git a/crates/ra_hir/src/module/imp.rs b/crates/ra_hir/src/module/imp.rs index 748fdb64e..eded85a63 100644 --- a/crates/ra_hir/src/module/imp.rs +++ b/crates/ra_hir/src/module/imp.rs | |||
@@ -1,16 +1,13 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::ast::{self, NameOwner}; |
4 | ast::{self, NameOwner}, | ||
5 | SmolStr, | ||
6 | }; | ||
7 | use relative_path::RelativePathBuf; | 4 | use relative_path::RelativePathBuf; |
8 | use rustc_hash::{FxHashMap, FxHashSet}; | 5 | use rustc_hash::{FxHashMap, FxHashSet}; |
9 | use arrayvec::ArrayVec; | 6 | use arrayvec::ArrayVec; |
10 | use ra_db::{SourceRoot, SourceRootId, Cancelable, FileId}; | 7 | use ra_db::{SourceRoot, SourceRootId, Cancelable, FileId}; |
11 | 8 | ||
12 | use crate::{ | 9 | use crate::{ |
13 | HirDatabase, | 10 | HirDatabase, Name, AsName, |
14 | }; | 11 | }; |
15 | 12 | ||
16 | use super::{ | 13 | use super::{ |
@@ -20,12 +17,12 @@ use super::{ | |||
20 | 17 | ||
21 | #[derive(Clone, Hash, PartialEq, Eq, Debug)] | 18 | #[derive(Clone, Hash, PartialEq, Eq, Debug)] |
22 | pub enum Submodule { | 19 | pub enum Submodule { |
23 | Declaration(SmolStr), | 20 | Declaration(Name), |
24 | Definition(SmolStr, ModuleSource), | 21 | Definition(Name, ModuleSource), |
25 | } | 22 | } |
26 | 23 | ||
27 | impl Submodule { | 24 | impl Submodule { |
28 | fn name(&self) -> &SmolStr { | 25 | fn name(&self) -> &Name { |
29 | match self { | 26 | match self { |
30 | Submodule::Declaration(name) => name, | 27 | Submodule::Declaration(name) => name, |
31 | Submodule::Definition(name, _) => name, | 28 | Submodule::Definition(name, _) => name, |
@@ -35,14 +32,14 @@ impl Submodule { | |||
35 | 32 | ||
36 | pub(crate) fn modules<'a>( | 33 | pub(crate) fn modules<'a>( |
37 | root: impl ast::ModuleItemOwner<'a>, | 34 | root: impl ast::ModuleItemOwner<'a>, |
38 | ) -> impl Iterator<Item = (SmolStr, ast::Module<'a>)> { | 35 | ) -> impl Iterator<Item = (Name, ast::Module<'a>)> { |
39 | root.items() | 36 | root.items() |
40 | .filter_map(|item| match item { | 37 | .filter_map(|item| match item { |
41 | ast::ModuleItem::Module(m) => Some(m), | 38 | ast::ModuleItem::Module(m) => Some(m), |
42 | _ => None, | 39 | _ => None, |
43 | }) | 40 | }) |
44 | .filter_map(|module| { | 41 | .filter_map(|module| { |
45 | let name = module.name()?.text(); | 42 | let name = module.name()?.as_name(); |
46 | Some((name, module)) | 43 | Some((name, module)) |
47 | }) | 44 | }) |
48 | } | 45 | } |
@@ -155,7 +152,7 @@ fn build_subtree( | |||
155 | fn resolve_submodule( | 152 | fn resolve_submodule( |
156 | db: &impl HirDatabase, | 153 | db: &impl HirDatabase, |
157 | source: ModuleSource, | 154 | source: ModuleSource, |
158 | name: &SmolStr, | 155 | name: &Name, |
159 | ) -> (Vec<FileId>, Option<Problem>) { | 156 | ) -> (Vec<FileId>, Option<Problem>) { |
160 | // FIXME: handle submodules of inline modules properly | 157 | // FIXME: handle submodules of inline modules properly |
161 | let file_id = source.file_id(); | 158 | let file_id = source.file_id(); |
diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs index 98cd225dd..68eb02a98 100644 --- a/crates/ra_hir/src/module/nameres.rs +++ b/crates/ra_hir/src/module/nameres.rs | |||
@@ -14,14 +14,12 @@ | |||
14 | //! modifications (that is, typing inside a function shold not change IMIs), | 14 | //! modifications (that is, typing inside a function shold not change IMIs), |
15 | //! such that the results of name resolution can be preserved unless the module | 15 | //! such that the results of name resolution can be preserved unless the module |
16 | //! structure itself is modified. | 16 | //! structure itself is modified. |
17 | use std::{ | 17 | use std::sync::Arc; |
18 | sync::Arc, | ||
19 | }; | ||
20 | 18 | ||
21 | use rustc_hash::FxHashMap; | 19 | use rustc_hash::FxHashMap; |
22 | use ra_syntax::{ | 20 | use ra_syntax::{ |
23 | TextRange, | 21 | TextRange, |
24 | SmolStr, SyntaxKind::{self, *}, | 22 | SyntaxKind::{self, *}, |
25 | ast::{self, AstNode} | 23 | ast::{self, AstNode} |
26 | }; | 24 | }; |
27 | use ra_db::SourceRootId; | 25 | use ra_db::SourceRootId; |
@@ -32,6 +30,7 @@ use crate::{ | |||
32 | SourceItemId, SourceFileItemId, SourceFileItems, | 30 | SourceItemId, SourceFileItemId, SourceFileItems, |
33 | Path, PathKind, | 31 | Path, PathKind, |
34 | HirDatabase, Crate, | 32 | HirDatabase, Crate, |
33 | Name, AsName, | ||
35 | module::{Module, ModuleId, ModuleTree}, | 34 | module::{Module, ModuleId, ModuleTree}, |
36 | }; | 35 | }; |
37 | 36 | ||
@@ -45,14 +44,14 @@ pub struct ItemMap { | |||
45 | 44 | ||
46 | #[derive(Debug, Default, PartialEq, Eq, Clone)] | 45 | #[derive(Debug, Default, PartialEq, Eq, Clone)] |
47 | pub struct ModuleScope { | 46 | pub struct ModuleScope { |
48 | items: FxHashMap<SmolStr, Resolution>, | 47 | items: FxHashMap<Name, Resolution>, |
49 | } | 48 | } |
50 | 49 | ||
51 | impl ModuleScope { | 50 | impl ModuleScope { |
52 | pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a SmolStr, &'a Resolution)> + 'a { | 51 | pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, &'a Resolution)> + 'a { |
53 | self.items.iter() | 52 | self.items.iter() |
54 | } | 53 | } |
55 | pub fn get(&self, name: &SmolStr) -> Option<&Resolution> { | 54 | pub fn get(&self, name: &Name) -> Option<&Resolution> { |
56 | self.items.get(name) | 55 | self.items.get(name) |
57 | } | 56 | } |
58 | } | 57 | } |
@@ -72,7 +71,7 @@ pub struct InputModuleItems { | |||
72 | #[derive(Debug, PartialEq, Eq)] | 71 | #[derive(Debug, PartialEq, Eq)] |
73 | struct ModuleItem { | 72 | struct ModuleItem { |
74 | id: SourceFileItemId, | 73 | id: SourceFileItemId, |
75 | name: SmolStr, | 74 | name: Name, |
76 | kind: SyntaxKind, | 75 | kind: SyntaxKind, |
77 | vis: Vis, | 76 | vis: Vis, |
78 | } | 77 | } |
@@ -260,7 +259,7 @@ impl InputModuleItems { | |||
260 | 259 | ||
261 | impl ModuleItem { | 260 | impl ModuleItem { |
262 | fn new<'a>(file_items: &SourceFileItems, item: impl ast::NameOwner<'a>) -> Option<ModuleItem> { | 261 | fn new<'a>(file_items: &SourceFileItems, item: impl ast::NameOwner<'a>) -> Option<ModuleItem> { |
263 | let name = item.name()?.text(); | 262 | let name = item.name()?.as_name(); |
264 | let kind = item.syntax().kind(); | 263 | let kind = item.syntax().kind(); |
265 | let vis = Vis::Other; | 264 | let vis = Vis::Other; |
266 | let id = file_items.id_of_unchecked(item.syntax()); | 265 | let id = file_items.id_of_unchecked(item.syntax()); |
@@ -328,7 +327,11 @@ where | |||
328 | for dep in krate.dependencies(self.db) { | 327 | for dep in krate.dependencies(self.db) { |
329 | if let Some(module) = dep.krate.root_module(self.db)? { | 328 | if let Some(module) = dep.krate.root_module(self.db)? { |
330 | let def_id = module.def_id(self.db); | 329 | let def_id = module.def_id(self.db); |
331 | self.add_module_item(&mut module_items, dep.name, PerNs::types(def_id)); | 330 | self.add_module_item( |
331 | &mut module_items, | ||
332 | dep.name.clone(), | ||
333 | PerNs::types(def_id), | ||
334 | ); | ||
332 | } | 335 | } |
333 | } | 336 | } |
334 | }; | 337 | }; |
@@ -389,7 +392,7 @@ where | |||
389 | Ok(()) | 392 | Ok(()) |
390 | } | 393 | } |
391 | 394 | ||
392 | fn add_module_item(&self, module_items: &mut ModuleScope, name: SmolStr, def_id: PerNs<DefId>) { | 395 | fn add_module_item(&self, module_items: &mut ModuleScope, name: Name, def_id: PerNs<DefId>) { |
393 | let resolution = Resolution { | 396 | let resolution = Resolution { |
394 | def_id, | 397 | def_id, |
395 | import: None, | 398 | import: None, |
diff --git a/crates/ra_hir/src/module/nameres/tests.rs b/crates/ra_hir/src/module/nameres/tests.rs index 03ea5c1d6..ca20f064f 100644 --- a/crates/ra_hir/src/module/nameres/tests.rs +++ b/crates/ra_hir/src/module/nameres/tests.rs | |||
@@ -2,8 +2,8 @@ use std::sync::Arc; | |||
2 | 2 | ||
3 | use salsa::Database; | 3 | use salsa::Database; |
4 | use ra_db::{FilesDatabase, CrateGraph}; | 4 | use ra_db::{FilesDatabase, CrateGraph}; |
5 | use ra_syntax::SmolStr; | ||
6 | use relative_path::RelativePath; | 5 | use relative_path::RelativePath; |
6 | use test_utils::assert_eq_text; | ||
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | self as hir, | 9 | self as hir, |
@@ -21,6 +21,35 @@ fn item_map(fixture: &str) -> (Arc<hir::ItemMap>, hir::ModuleId) { | |||
21 | (db.item_map(source_root).unwrap(), module_id) | 21 | (db.item_map(source_root).unwrap(), module_id) |
22 | } | 22 | } |
23 | 23 | ||
24 | fn check_module_item_map(map: &hir::ItemMap, module_id: hir::ModuleId, expected: &str) { | ||
25 | let mut lines = map.per_module[&module_id] | ||
26 | .items | ||
27 | .iter() | ||
28 | .map(|(name, res)| format!("{}: {}", name, dump_resolution(res))) | ||
29 | .collect::<Vec<_>>(); | ||
30 | lines.sort(); | ||
31 | let actual = lines.join("\n"); | ||
32 | let expected = expected | ||
33 | .trim() | ||
34 | .lines() | ||
35 | .map(|it| it.trim()) | ||
36 | .collect::<Vec<_>>() | ||
37 | .join("\n"); | ||
38 | assert_eq_text!(&actual, &expected); | ||
39 | |||
40 | fn dump_resolution(resolution: &hir::Resolution) -> &'static str { | ||
41 | match ( | ||
42 | resolution.def_id.types.is_some(), | ||
43 | resolution.def_id.values.is_some(), | ||
44 | ) { | ||
45 | (true, true) => "t v", | ||
46 | (true, false) => "t", | ||
47 | (false, true) => "v", | ||
48 | (false, false) => "_", | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | |||
24 | #[test] | 53 | #[test] |
25 | fn item_map_smoke_test() { | 54 | fn item_map_smoke_test() { |
26 | let (item_map, module_id) = item_map( | 55 | let (item_map, module_id) = item_map( |
@@ -38,13 +67,18 @@ fn item_map_smoke_test() { | |||
38 | pub struct Baz; | 67 | pub struct Baz; |
39 | ", | 68 | ", |
40 | ); | 69 | ); |
41 | let name = SmolStr::from("Baz"); | 70 | check_module_item_map( |
42 | let resolution = &item_map.per_module[&module_id].items[&name]; | 71 | &item_map, |
43 | assert!(resolution.def_id.take_types().is_some()); | 72 | module_id, |
73 | " | ||
74 | Baz: t v | ||
75 | foo: t | ||
76 | ", | ||
77 | ); | ||
44 | } | 78 | } |
45 | 79 | ||
46 | #[test] | 80 | #[test] |
47 | fn test_self() { | 81 | fn item_map_using_self() { |
48 | let (item_map, module_id) = item_map( | 82 | let (item_map, module_id) = item_map( |
49 | " | 83 | " |
50 | //- /lib.rs | 84 | //- /lib.rs |
@@ -57,9 +91,14 @@ fn test_self() { | |||
57 | pub struct Baz; | 91 | pub struct Baz; |
58 | ", | 92 | ", |
59 | ); | 93 | ); |
60 | let name = SmolStr::from("Baz"); | 94 | check_module_item_map( |
61 | let resolution = &item_map.per_module[&module_id].items[&name]; | 95 | &item_map, |
62 | assert!(resolution.def_id.take_types().is_some()); | 96 | module_id, |
97 | " | ||
98 | Baz: t v | ||
99 | foo: t | ||
100 | ", | ||
101 | ); | ||
63 | } | 102 | } |
64 | 103 | ||
65 | #[test] | 104 | #[test] |
@@ -90,9 +129,14 @@ fn item_map_across_crates() { | |||
90 | let module_id = module.module_id; | 129 | let module_id = module.module_id; |
91 | let item_map = db.item_map(source_root).unwrap(); | 130 | let item_map = db.item_map(source_root).unwrap(); |
92 | 131 | ||
93 | let name = SmolStr::from("Baz"); | 132 | check_module_item_map( |
94 | let resolution = &item_map.per_module[&module_id].items[&name]; | 133 | &item_map, |
95 | assert!(resolution.def_id.take_types().is_some()); | 134 | module_id, |
135 | " | ||
136 | Baz: t v | ||
137 | test_crate: t | ||
138 | ", | ||
139 | ); | ||
96 | } | 140 | } |
97 | 141 | ||
98 | #[test] | 142 | #[test] |
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs new file mode 100644 index 000000000..e4fc141a6 --- /dev/null +++ b/crates/ra_hir/src/name.rs | |||
@@ -0,0 +1,97 @@ | |||
1 | use std::fmt; | ||
2 | |||
3 | use ra_syntax::{ast, SmolStr}; | ||
4 | |||
5 | /// `Name` is a wrapper around string, which is used in hir for both references | ||
6 | /// and declarations. In theory, names should also carry hygene info, but we are | ||
7 | /// not there yet! | ||
8 | #[derive(Clone, PartialEq, Eq, Hash)] | ||
9 | pub struct Name { | ||
10 | text: SmolStr, | ||
11 | } | ||
12 | |||
13 | impl fmt::Display for Name { | ||
14 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
15 | fmt::Display::fmt(&self.text, f) | ||
16 | } | ||
17 | } | ||
18 | |||
19 | impl fmt::Debug for Name { | ||
20 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
21 | fmt::Debug::fmt(&self.text, f) | ||
22 | } | ||
23 | } | ||
24 | |||
25 | impl Name { | ||
26 | pub(crate) fn as_known_name(&self) -> Option<KnownName> { | ||
27 | let name = match self.text.as_str() { | ||
28 | "isize" => KnownName::Isize, | ||
29 | "i8" => KnownName::I8, | ||
30 | "i16" => KnownName::I16, | ||
31 | "i32" => KnownName::I32, | ||
32 | "i64" => KnownName::I64, | ||
33 | "i128" => KnownName::I128, | ||
34 | "usize" => KnownName::Usize, | ||
35 | "u8" => KnownName::U8, | ||
36 | "u16" => KnownName::U16, | ||
37 | "u32" => KnownName::U32, | ||
38 | "u64" => KnownName::U64, | ||
39 | "u128" => KnownName::U128, | ||
40 | "f32" => KnownName::F32, | ||
41 | "f64" => KnownName::F64, | ||
42 | _ => return None, | ||
43 | }; | ||
44 | Some(name) | ||
45 | } | ||
46 | |||
47 | fn new(text: SmolStr) -> Name { | ||
48 | Name { text } | ||
49 | } | ||
50 | } | ||
51 | |||
52 | pub(crate) trait AsName { | ||
53 | fn as_name(&self) -> Name; | ||
54 | } | ||
55 | |||
56 | impl AsName for ast::NameRef<'_> { | ||
57 | fn as_name(&self) -> Name { | ||
58 | Name::new(self.text()) | ||
59 | } | ||
60 | } | ||
61 | |||
62 | impl AsName for ast::Name<'_> { | ||
63 | fn as_name(&self) -> Name { | ||
64 | Name::new(self.text()) | ||
65 | } | ||
66 | } | ||
67 | |||
68 | impl AsName for ra_db::Dependency { | ||
69 | fn as_name(&self) -> Name { | ||
70 | Name::new(self.name.clone()) | ||
71 | } | ||
72 | } | ||
73 | |||
74 | // Ideally, should be replaced with | ||
75 | // ``` | ||
76 | // const ISIZE: Name = Name::new("isize") | ||
77 | // ``` | ||
78 | // but const-fn is not that powerful yet. | ||
79 | #[derive(Debug)] | ||
80 | pub(crate) enum KnownName { | ||
81 | Isize, | ||
82 | I8, | ||
83 | I16, | ||
84 | I32, | ||
85 | I64, | ||
86 | I128, | ||
87 | |||
88 | Usize, | ||
89 | U8, | ||
90 | U16, | ||
91 | U32, | ||
92 | U64, | ||
93 | U128, | ||
94 | |||
95 | F32, | ||
96 | F64, | ||
97 | } | ||
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs index 0b260072c..93f7203fe 100644 --- a/crates/ra_hir/src/path.rs +++ b/crates/ra_hir/src/path.rs | |||
@@ -1,9 +1,11 @@ | |||
1 | use ra_syntax::{SmolStr, ast, AstNode, TextRange}; | 1 | use ra_syntax::{ast, AstNode, TextRange}; |
2 | |||
3 | use crate::{Name, AsName}; | ||
2 | 4 | ||
3 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 5 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
4 | pub struct Path { | 6 | pub struct Path { |
5 | pub kind: PathKind, | 7 | pub kind: PathKind, |
6 | pub segments: Vec<SmolStr>, | 8 | pub segments: Vec<Name>, |
7 | } | 9 | } |
8 | 10 | ||
9 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 11 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -29,7 +31,7 @@ impl Path { | |||
29 | loop { | 31 | loop { |
30 | let segment = path.segment()?; | 32 | let segment = path.segment()?; |
31 | match segment.kind()? { | 33 | match segment.kind()? { |
32 | ast::PathSegmentKind::Name(name) => segments.push(name.text()), | 34 | ast::PathSegmentKind::Name(name) => segments.push(name.as_name()), |
33 | ast::PathSegmentKind::CrateKw => { | 35 | ast::PathSegmentKind::CrateKw => { |
34 | kind = PathKind::Crate; | 36 | kind = PathKind::Crate; |
35 | break; | 37 | break; |
@@ -67,6 +69,14 @@ impl Path { | |||
67 | pub fn is_ident(&self) -> bool { | 69 | pub fn is_ident(&self) -> bool { |
68 | self.kind == PathKind::Plain && self.segments.len() == 1 | 70 | self.kind == PathKind::Plain && self.segments.len() == 1 |
69 | } | 71 | } |
72 | |||
73 | /// If this path is a single identifier, like `foo`, return its name. | ||
74 | pub fn as_ident(&self) -> Option<&Name> { | ||
75 | if self.kind != PathKind::Plain || self.segments.len() > 1 { | ||
76 | return None; | ||
77 | } | ||
78 | self.segments.first() | ||
79 | } | ||
70 | } | 80 | } |
71 | 81 | ||
72 | fn expand_use_tree( | 82 | fn expand_use_tree( |
@@ -130,7 +140,7 @@ fn convert_path(prefix: Option<Path>, path: ast::Path) -> Option<Path> { | |||
130 | kind: PathKind::Plain, | 140 | kind: PathKind::Plain, |
131 | segments: Vec::with_capacity(1), | 141 | segments: Vec::with_capacity(1), |
132 | }); | 142 | }); |
133 | res.segments.push(name.text()); | 143 | res.segments.push(name.as_name()); |
134 | res | 144 | res |
135 | } | 145 | } |
136 | ast::PathSegmentKind::CrateKw => { | 146 | ast::PathSegmentKind::CrateKw => { |
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs index 4a7958a12..e6241342a 100644 --- a/crates/ra_hir/src/query_definitions.rs +++ b/crates/ra_hir/src/query_definitions.rs | |||
@@ -11,7 +11,7 @@ use ra_syntax::{ | |||
11 | use ra_db::{SourceRootId, FileId, Cancelable,}; | 11 | use ra_db::{SourceRootId, FileId, Cancelable,}; |
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | SourceFileItems, SourceItemId, DefKind, Function, DefId, | 14 | SourceFileItems, SourceItemId, DefKind, Function, DefId, Name, AsName, |
15 | db::HirDatabase, | 15 | db::HirDatabase, |
16 | function::{FnScopes, FnId}, | 16 | function::{FnScopes, FnId}, |
17 | module::{ | 17 | module::{ |
@@ -130,14 +130,14 @@ pub(crate) fn submodules( | |||
130 | 130 | ||
131 | pub(crate) fn modules<'a>( | 131 | pub(crate) fn modules<'a>( |
132 | root: impl ast::ModuleItemOwner<'a>, | 132 | root: impl ast::ModuleItemOwner<'a>, |
133 | ) -> impl Iterator<Item = (SmolStr, ast::Module<'a>)> { | 133 | ) -> impl Iterator<Item = (Name, ast::Module<'a>)> { |
134 | root.items() | 134 | root.items() |
135 | .filter_map(|item| match item { | 135 | .filter_map(|item| match item { |
136 | ast::ModuleItem::Module(m) => Some(m), | 136 | ast::ModuleItem::Module(m) => Some(m), |
137 | _ => None, | 137 | _ => None, |
138 | }) | 138 | }) |
139 | .filter_map(|module| { | 139 | .filter_map(|module| { |
140 | let name = module.name()?.text(); | 140 | let name = module.name()?.as_name(); |
141 | Some((name, module)) | 141 | Some((name, module)) |
142 | }) | 142 | }) |
143 | } | 143 | } |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index a0165aef2..a0d1daf71 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -8,14 +8,14 @@ | |||
8 | use ra_db::{FileId, FilePosition, Cancelable}; | 8 | use ra_db::{FileId, FilePosition, Cancelable}; |
9 | use ra_editor::find_node_at_offset; | 9 | use ra_editor::find_node_at_offset; |
10 | use ra_syntax::{ | 10 | use ra_syntax::{ |
11 | ast::{self, AstNode}, | 11 | ast::{self, AstNode, NameOwner}, |
12 | SyntaxNodeRef, | 12 | SyntaxNodeRef, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | HirDatabase, Module, Function, SourceItemId, | 16 | HirDatabase, Module, Function, SourceItemId, |
17 | module::ModuleSource, | 17 | module::ModuleSource, |
18 | DefKind, DefLoc | 18 | DefKind, DefLoc, AsName, |
19 | }; | 19 | }; |
20 | 20 | ||
21 | /// Locates the module by `FileId`. Picks topmost module in the file. | 21 | /// Locates the module by `FileId`. Picks topmost module in the file. |
@@ -24,6 +24,25 @@ pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Cancelable | |||
24 | module_from_source(db, module_source) | 24 | module_from_source(db, module_source) |
25 | } | 25 | } |
26 | 26 | ||
27 | /// Locates the child module by `mod child;` declaration. | ||
28 | pub fn module_from_declaration( | ||
29 | db: &impl HirDatabase, | ||
30 | file_id: FileId, | ||
31 | decl: ast::Module, | ||
32 | ) -> Cancelable<Option<Module>> { | ||
33 | let parent_module = module_from_file_id(db, file_id)?; | ||
34 | let child_name = decl.name(); | ||
35 | match (parent_module, child_name) { | ||
36 | (Some(parent_module), Some(child_name)) => { | ||
37 | if let Some(child) = parent_module.child(&child_name.as_name()) { | ||
38 | return Ok(Some(child)); | ||
39 | } | ||
40 | } | ||
41 | _ => (), | ||
42 | } | ||
43 | Ok(None) | ||
44 | } | ||
45 | |||
27 | /// Locates the module by position in the source code. | 46 | /// Locates the module by position in the source code. |
28 | pub fn module_from_position( | 47 | pub fn module_from_position( |
29 | db: &impl HirDatabase, | 48 | db: &impl HirDatabase, |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 67b523c2c..ad097d1f1 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -95,7 +95,7 @@ pub enum Ty { | |||
95 | Tuple(Vec<Ty>), | 95 | Tuple(Vec<Ty>), |
96 | 96 | ||
97 | // The projection of an associated type. For example, | 97 | // The projection of an associated type. For example, |
98 | // `<T as Trait<..>>::N`. | 98 | // `<T as Trait<..>>::N`.pub |
99 | // Projection(ProjectionTy), | 99 | // Projection(ProjectionTy), |
100 | 100 | ||
101 | // Opaque (`impl Trait`) type found in a return type. | 101 | // Opaque (`impl Trait`) type found in a return type. |
@@ -179,13 +179,12 @@ impl Ty { | |||
179 | module: &Module, | 179 | module: &Module, |
180 | path: &Path, | 180 | path: &Path, |
181 | ) -> Cancelable<Self> { | 181 | ) -> Cancelable<Self> { |
182 | if path.is_ident() { | 182 | if let Some(name) = path.as_ident() { |
183 | let name = &path.segments[0]; | 183 | if let Some(int_ty) = primitive::IntTy::from_name(name) { |
184 | if let Some(int_ty) = primitive::IntTy::from_string(&name) { | ||
185 | return Ok(Ty::Int(int_ty)); | 184 | return Ok(Ty::Int(int_ty)); |
186 | } else if let Some(uint_ty) = primitive::UintTy::from_string(&name) { | 185 | } else if let Some(uint_ty) = primitive::UintTy::from_name(name) { |
187 | return Ok(Ty::Uint(uint_ty)); | 186 | return Ok(Ty::Uint(uint_ty)); |
188 | } else if let Some(float_ty) = primitive::FloatTy::from_string(&name) { | 187 | } else if let Some(float_ty) = primitive::FloatTy::from_name(name) { |
189 | return Ok(Ty::Float(float_ty)); | 188 | return Ok(Ty::Float(float_ty)); |
190 | } | 189 | } |
191 | } | 190 | } |
diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs index ad79b17e4..498d42d52 100644 --- a/crates/ra_hir/src/ty/primitive.rs +++ b/crates/ra_hir/src/ty/primitive.rs | |||
@@ -1,5 +1,7 @@ | |||
1 | use std::fmt; | 1 | use std::fmt; |
2 | 2 | ||
3 | use crate::{Name, KnownName}; | ||
4 | |||
3 | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] | 5 | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] |
4 | pub enum IntTy { | 6 | pub enum IntTy { |
5 | Isize, | 7 | Isize, |
@@ -34,14 +36,14 @@ impl IntTy { | |||
34 | } | 36 | } |
35 | } | 37 | } |
36 | 38 | ||
37 | pub fn from_string(s: &str) -> Option<IntTy> { | 39 | pub fn from_name(name: &Name) -> Option<IntTy> { |
38 | match s { | 40 | match name.as_known_name()? { |
39 | "isize" => Some(IntTy::Isize), | 41 | KnownName::Isize => Some(IntTy::Isize), |
40 | "i8" => Some(IntTy::I8), | 42 | KnownName::I8 => Some(IntTy::I8), |
41 | "i16" => Some(IntTy::I16), | 43 | KnownName::I16 => Some(IntTy::I16), |
42 | "i32" => Some(IntTy::I32), | 44 | KnownName::I32 => Some(IntTy::I32), |
43 | "i64" => Some(IntTy::I64), | 45 | KnownName::I64 => Some(IntTy::I64), |
44 | "i128" => Some(IntTy::I128), | 46 | KnownName::I128 => Some(IntTy::I128), |
45 | _ => None, | 47 | _ => None, |
46 | } | 48 | } |
47 | } | 49 | } |
@@ -69,14 +71,14 @@ impl UintTy { | |||
69 | } | 71 | } |
70 | } | 72 | } |
71 | 73 | ||
72 | pub fn from_string(s: &str) -> Option<UintTy> { | 74 | pub fn from_name(name: &Name) -> Option<UintTy> { |
73 | match s { | 75 | match name.as_known_name()? { |
74 | "usize" => Some(UintTy::Usize), | 76 | KnownName::Usize => Some(UintTy::Usize), |
75 | "u8" => Some(UintTy::U8), | 77 | KnownName::U8 => Some(UintTy::U8), |
76 | "u16" => Some(UintTy::U16), | 78 | KnownName::U16 => Some(UintTy::U16), |
77 | "u32" => Some(UintTy::U32), | 79 | KnownName::U32 => Some(UintTy::U32), |
78 | "u64" => Some(UintTy::U64), | 80 | KnownName::U64 => Some(UintTy::U64), |
79 | "u128" => Some(UintTy::U128), | 81 | KnownName::U128 => Some(UintTy::U128), |
80 | _ => None, | 82 | _ => None, |
81 | } | 83 | } |
82 | } | 84 | } |
@@ -120,10 +122,10 @@ impl FloatTy { | |||
120 | } | 122 | } |
121 | } | 123 | } |
122 | 124 | ||
123 | pub fn from_string(s: &str) -> Option<FloatTy> { | 125 | pub fn from_name(name: &Name) -> Option<FloatTy> { |
124 | match s { | 126 | match name.as_known_name()? { |
125 | "f32" => Some(FloatTy::F32), | 127 | KnownName::F32 => Some(FloatTy::F32), |
126 | "f64" => Some(FloatTy::F64), | 128 | KnownName::F64 => Some(FloatTy::F64), |
127 | _ => None, | 129 | _ => None, |
128 | } | 130 | } |
129 | } | 131 | } |