diff options
author | Aleksey Kladov <[email protected]> | 2018-12-27 17:07:21 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-12-27 17:07:21 +0000 |
commit | d963042ca9da93be8d5922ce46ea26dc6a79c929 (patch) | |
tree | 76f7bfc934dda4e9dfc956fc86fe73379d86a332 | |
parent | 3b820bcca3a66660d0c5960f2a5c8f765095333e (diff) |
introduce hir::Name
-rw-r--r-- | crates/ra_db/src/lib.rs | 2 | ||||
-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 | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/name.rs | 56 | ||||
-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/ty.rs | 10 |
11 files changed, 121 insertions, 51 deletions
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 1f7c9187b..3028db17c 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -14,7 +14,7 @@ pub use crate::{ | |||
14 | cancelation::{Canceled, Cancelable}, | 14 | cancelation::{Canceled, Cancelable}, |
15 | syntax_ptr::LocalSyntaxPtr, | 15 | syntax_ptr::LocalSyntaxPtr, |
16 | input::{ | 16 | input::{ |
17 | FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, | 17 | FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, |
18 | FileTextQuery, FileSourceRootQuery, SourceRootQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery, | 18 | FileTextQuery, FileSourceRootQuery, SourceRootQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery, |
19 | FileRelativePathQuery | 19 | FileRelativePathQuery |
20 | }, | 20 | }, |
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..bf43cd0ae 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, | ||
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..165ac81c8 100644 --- a/crates/ra_hir/src/module/nameres/tests.rs +++ b/crates/ra_hir/src/module/nameres/tests.rs | |||
@@ -9,6 +9,7 @@ use crate::{ | |||
9 | self as hir, | 9 | self as hir, |
10 | db::HirDatabase, | 10 | db::HirDatabase, |
11 | mock::MockDatabase, | 11 | mock::MockDatabase, |
12 | Name, | ||
12 | }; | 13 | }; |
13 | 14 | ||
14 | fn item_map(fixture: &str) -> (Arc<hir::ItemMap>, hir::ModuleId) { | 15 | fn item_map(fixture: &str) -> (Arc<hir::ItemMap>, hir::ModuleId) { |
@@ -38,7 +39,7 @@ fn item_map_smoke_test() { | |||
38 | pub struct Baz; | 39 | pub struct Baz; |
39 | ", | 40 | ", |
40 | ); | 41 | ); |
41 | let name = SmolStr::from("Baz"); | 42 | let name = Name::new(SmolStr::from("Baz")); |
42 | let resolution = &item_map.per_module[&module_id].items[&name]; | 43 | let resolution = &item_map.per_module[&module_id].items[&name]; |
43 | assert!(resolution.def_id.take_types().is_some()); | 44 | assert!(resolution.def_id.take_types().is_some()); |
44 | } | 45 | } |
@@ -57,7 +58,7 @@ fn test_self() { | |||
57 | pub struct Baz; | 58 | pub struct Baz; |
58 | ", | 59 | ", |
59 | ); | 60 | ); |
60 | let name = SmolStr::from("Baz"); | 61 | let name = Name::new(SmolStr::from("Baz")); |
61 | let resolution = &item_map.per_module[&module_id].items[&name]; | 62 | let resolution = &item_map.per_module[&module_id].items[&name]; |
62 | assert!(resolution.def_id.take_types().is_some()); | 63 | assert!(resolution.def_id.take_types().is_some()); |
63 | } | 64 | } |
@@ -90,7 +91,7 @@ fn item_map_across_crates() { | |||
90 | let module_id = module.module_id; | 91 | let module_id = module.module_id; |
91 | let item_map = db.item_map(source_root).unwrap(); | 92 | let item_map = db.item_map(source_root).unwrap(); |
92 | 93 | ||
93 | let name = SmolStr::from("Baz"); | 94 | let name = Name::new(SmolStr::from("Baz")); |
94 | let resolution = &item_map.per_module[&module_id].items[&name]; | 95 | let resolution = &item_map.per_module[&module_id].items[&name]; |
95 | assert!(resolution.def_id.take_types().is_some()); | 96 | assert!(resolution.def_id.take_types().is_some()); |
96 | } | 97 | } |
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs new file mode 100644 index 000000000..7f42c9f04 --- /dev/null +++ b/crates/ra_hir/src/name.rs | |||
@@ -0,0 +1,56 @@ | |||
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(Debug, 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 Name { | ||
20 | // TODO: get rid of this? | ||
21 | pub(crate) fn as_str(&self) -> &str { | ||
22 | self.text.as_str() | ||
23 | } | ||
24 | |||
25 | #[cfg(not(test))] | ||
26 | fn new(text: SmolStr) -> Name { | ||
27 | Name { text } | ||
28 | } | ||
29 | |||
30 | #[cfg(test)] | ||
31 | pub(crate) fn new(text: SmolStr) -> Name { | ||
32 | Name { text } | ||
33 | } | ||
34 | } | ||
35 | |||
36 | pub(crate) trait AsName { | ||
37 | fn as_name(&self) -> Name; | ||
38 | } | ||
39 | |||
40 | impl AsName for ast::NameRef<'_> { | ||
41 | fn as_name(&self) -> Name { | ||
42 | Name::new(self.text()) | ||
43 | } | ||
44 | } | ||
45 | |||
46 | impl AsName for ast::Name<'_> { | ||
47 | fn as_name(&self) -> Name { | ||
48 | Name::new(self.text()) | ||
49 | } | ||
50 | } | ||
51 | |||
52 | impl AsName for ra_db::Dependency { | ||
53 | fn as_name(&self) -> Name { | ||
54 | Name::new(self.name.clone()) | ||
55 | } | ||
56 | } | ||
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/ty.rs b/crates/ra_hir/src/ty.rs index 67b523c2c..dc3323b1a 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -179,13 +179,13 @@ 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 | let name = name.as_str(); // :-( |
184 | if let Some(int_ty) = primitive::IntTy::from_string(&name) { | 184 | if let Some(int_ty) = primitive::IntTy::from_string(name) { |
185 | return Ok(Ty::Int(int_ty)); | 185 | return Ok(Ty::Int(int_ty)); |
186 | } else if let Some(uint_ty) = primitive::UintTy::from_string(&name) { | 186 | } else if let Some(uint_ty) = primitive::UintTy::from_string(name) { |
187 | return Ok(Ty::Uint(uint_ty)); | 187 | return Ok(Ty::Uint(uint_ty)); |
188 | } else if let Some(float_ty) = primitive::FloatTy::from_string(&name) { | 188 | } else if let Some(float_ty) = primitive::FloatTy::from_string(name) { |
189 | return Ok(Ty::Float(float_ty)); | 189 | return Ok(Ty::Float(float_ty)); |
190 | } | 190 | } |
191 | } | 191 | } |