diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/debug.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir/src/ids.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/mod_resolution.rs | 60 |
4 files changed, 37 insertions, 55 deletions
diff --git a/crates/ra_hir/src/debug.rs b/crates/ra_hir/src/debug.rs index 87f3180c3..48b69000b 100644 --- a/crates/ra_hir/src/debug.rs +++ b/crates/ra_hir/src/debug.rs | |||
@@ -22,7 +22,7 @@ use std::fmt; | |||
22 | 22 | ||
23 | use ra_db::{CrateId, FileId}; | 23 | use ra_db::{CrateId, FileId}; |
24 | 24 | ||
25 | use crate::{db::HirDatabase, Crate, Module, Name}; | 25 | use crate::{db::HirDatabase, Crate, HirFileId, Module, Name}; |
26 | 26 | ||
27 | impl Crate { | 27 | impl Crate { |
28 | pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ { | 28 | pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ { |
@@ -36,6 +36,12 @@ impl Module { | |||
36 | } | 36 | } |
37 | } | 37 | } |
38 | 38 | ||
39 | impl HirFileId { | ||
40 | pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ { | ||
41 | debug_fn(move |fmt| db.debug_hir_file_id(self, fmt)) | ||
42 | } | ||
43 | } | ||
44 | |||
39 | pub trait HirDebugHelper: HirDatabase { | 45 | pub trait HirDebugHelper: HirDatabase { |
40 | fn crate_name(&self, _krate: CrateId) -> Option<String> { | 46 | fn crate_name(&self, _krate: CrateId) -> Option<String> { |
41 | None | 47 | None |
@@ -48,6 +54,7 @@ pub trait HirDebugHelper: HirDatabase { | |||
48 | pub trait HirDebugDatabase { | 54 | pub trait HirDebugDatabase { |
49 | fn debug_crate(&self, krate: Crate, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; | 55 | fn debug_crate(&self, krate: Crate, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; |
50 | fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; | 56 | fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; |
57 | fn debug_hir_file_id(&self, file_id: HirFileId, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; | ||
51 | } | 58 | } |
52 | 59 | ||
53 | impl<DB: HirDebugHelper> HirDebugDatabase for DB { | 60 | impl<DB: HirDebugHelper> HirDebugDatabase for DB { |
@@ -62,12 +69,19 @@ impl<DB: HirDebugHelper> HirDebugDatabase for DB { | |||
62 | 69 | ||
63 | fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { | 70 | fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
64 | let file_id = module.definition_source(self).file_id.original_file(self); | 71 | let file_id = module.definition_source(self).file_id.original_file(self); |
65 | let path = self.file_path(file_id); | 72 | let path = self.file_path(file_id).unwrap_or_else(|| "N/A".to_string()); |
66 | fmt.debug_struct("Module") | 73 | fmt.debug_struct("Module") |
67 | .field("name", &module.name(self).unwrap_or_else(Name::missing)) | 74 | .field("name", &module.name(self).unwrap_or_else(Name::missing)) |
68 | .field("path", &path.unwrap_or_else(|| "N/A".to_string())) | 75 | .field("path", &path) |
69 | .finish() | 76 | .finish() |
70 | } | 77 | } |
78 | |||
79 | fn debug_hir_file_id(&self, file_id: HirFileId, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
80 | let original = file_id.original_file(self); | ||
81 | let path = self.file_path(original).unwrap_or_else(|| "N/A".to_string()); | ||
82 | let is_macro = file_id != original.into(); | ||
83 | fmt.debug_struct("HirFileId").field("path", &path).field("macro", &is_macro).finish() | ||
84 | } | ||
71 | } | 85 | } |
72 | 86 | ||
73 | fn debug_fn(f: impl Fn(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Debug { | 87 | fn debug_fn(f: impl Fn(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Debug { |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index a3b65cc79..85b022744 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -50,16 +50,6 @@ impl HirFileId { | |||
50 | } | 50 | } |
51 | } | 51 | } |
52 | 52 | ||
53 | /// XXX: this is a temporary function, which should go away when we implement the | ||
54 | /// nameresolution+macro expansion combo. Prefer using `original_file` if | ||
55 | /// possible. | ||
56 | pub fn as_original_file(self) -> FileId { | ||
57 | match self.0 { | ||
58 | HirFileIdRepr::File(file_id) => file_id, | ||
59 | HirFileIdRepr::Macro(_r) => panic!("macro generated file: {:?}", self), | ||
60 | } | ||
61 | } | ||
62 | |||
63 | /// Get the crate which the macro lives in, if it is a macro file. | 53 | /// Get the crate which the macro lives in, if it is a macro file. |
64 | pub(crate) fn macro_crate(self, db: &impl AstDatabase) -> Option<Crate> { | 54 | pub(crate) fn macro_crate(self, db: &impl AstDatabase) -> Option<Crate> { |
65 | match self.0 { | 55 | match self.0 { |
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index aa5885f04..b5fe16bfa 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -584,7 +584,7 @@ where | |||
584 | // out of line module, resolve, parse and recurse | 584 | // out of line module, resolve, parse and recurse |
585 | raw::ModuleData::Declaration { name, ast_id } => { | 585 | raw::ModuleData::Declaration { name, ast_id } => { |
586 | let ast_id = ast_id.with_file_id(self.file_id); | 586 | let ast_id = ast_id.with_file_id(self.file_id); |
587 | match self.mod_dir.resolve_submodule( | 587 | match self.mod_dir.resolve_declaration( |
588 | self.def_collector.db, | 588 | self.def_collector.db, |
589 | self.file_id, | 589 | self.file_id, |
590 | name, | 590 | name, |
diff --git a/crates/ra_hir/src/nameres/mod_resolution.rs b/crates/ra_hir/src/nameres/mod_resolution.rs index f50f9abe6..e8b808514 100644 --- a/crates/ra_hir/src/nameres/mod_resolution.rs +++ b/crates/ra_hir/src/nameres/mod_resolution.rs | |||
@@ -1,9 +1,7 @@ | |||
1 | //! This module resolves `mod foo;` declaration to file. | 1 | //! This module resolves `mod foo;` declaration to file. |
2 | use std::borrow::Cow; | ||
3 | |||
4 | use ra_db::FileId; | 2 | use ra_db::FileId; |
5 | use ra_syntax::SmolStr; | 3 | use ra_syntax::SmolStr; |
6 | use relative_path::{RelativePath, RelativePathBuf}; | 4 | use relative_path::RelativePathBuf; |
7 | 5 | ||
8 | use crate::{db::DefDatabase, HirFileId, Name}; | 6 | use crate::{db::DefDatabase, HirFileId, Name}; |
9 | 7 | ||
@@ -28,23 +26,22 @@ impl ModDir { | |||
28 | attr_path: Option<&SmolStr>, | 26 | attr_path: Option<&SmolStr>, |
29 | ) -> ModDir { | 27 | ) -> ModDir { |
30 | let mut path = self.path.clone(); | 28 | let mut path = self.path.clone(); |
31 | match attr_path { | 29 | match attr_to_path(attr_path) { |
32 | None => path.push(&name.to_string()), | 30 | None => path.push(&name.to_string()), |
33 | Some(attr_path) => { | 31 | Some(attr_path) => { |
34 | if self.root_non_dir_owner { | 32 | if self.root_non_dir_owner { |
35 | path = path | 33 | // Workaround for relative path API: turn `lib.rs` into ``. |
36 | .parent() | 34 | if !path.pop() { |
37 | .map(|it| it.to_relative_path_buf()) | 35 | path = RelativePathBuf::default(); |
38 | .unwrap_or_else(RelativePathBuf::new); | 36 | } |
39 | } | 37 | } |
40 | let attr_path = &*normalize_attribute_path(attr_path); | 38 | path.push(attr_path); |
41 | path.push(RelativePath::new(attr_path)); | ||
42 | } | 39 | } |
43 | } | 40 | } |
44 | ModDir { path, root_non_dir_owner: false } | 41 | ModDir { path, root_non_dir_owner: false } |
45 | } | 42 | } |
46 | 43 | ||
47 | pub(super) fn resolve_submodule( | 44 | pub(super) fn resolve_declaration( |
48 | &self, | 45 | &self, |
49 | db: &impl DefDatabase, | 46 | db: &impl DefDatabase, |
50 | file_id: HirFileId, | 47 | file_id: HirFileId, |
@@ -53,32 +50,25 @@ impl ModDir { | |||
53 | ) -> Result<(FileId, ModDir), RelativePathBuf> { | 50 | ) -> Result<(FileId, ModDir), RelativePathBuf> { |
54 | let empty_path = RelativePathBuf::default(); | 51 | let empty_path = RelativePathBuf::default(); |
55 | let file_id = file_id.original_file(db); | 52 | let file_id = file_id.original_file(db); |
56 | let base_dir = { | ||
57 | let path = db.file_relative_path(file_id); | ||
58 | path.parent().unwrap_or(&empty_path).join(&self.path) | ||
59 | }; | ||
60 | 53 | ||
61 | let mut candidate_files = Vec::new(); | 54 | let mut candidate_files = Vec::new(); |
62 | match attr_path { | 55 | match attr_to_path(attr_path) { |
63 | Some(attr) => { | 56 | Some(attr_path) => { |
64 | let base = if self.root_non_dir_owner { | 57 | let base = if self.root_non_dir_owner { |
65 | base_dir.parent().unwrap_or(&empty_path) | 58 | self.path.parent().unwrap_or(&empty_path) |
66 | } else { | 59 | } else { |
67 | &base_dir | 60 | &self.path |
68 | }; | 61 | }; |
69 | candidate_files.push(base.join(&*normalize_attribute_path(attr))) | 62 | candidate_files.push(base.join(attr_path)) |
70 | } | 63 | } |
71 | None => { | 64 | None => { |
72 | candidate_files.push(base_dir.join(&format!("{}.rs", name))); | 65 | candidate_files.push(self.path.join(&format!("{}.rs", name))); |
73 | candidate_files.push(base_dir.join(&format!("{}/mod.rs", name))); | 66 | candidate_files.push(self.path.join(&format!("{}/mod.rs", name))); |
74 | } | 67 | } |
75 | }; | 68 | }; |
76 | 69 | ||
77 | let source_root_id = db.file_source_root(file_id); | ||
78 | let source_root = db.source_root(source_root_id); | ||
79 | for candidate in candidate_files.iter() { | 70 | for candidate in candidate_files.iter() { |
80 | let candidate = candidate.normalize(); | 71 | if let Some(file_id) = db.resolve_relative_path(file_id, candidate) { |
81 | if let Some(file_id) = source_root.file_by_relative_path(&candidate) { | ||
82 | let mut root_non_dir_owner = false; | 72 | let mut root_non_dir_owner = false; |
83 | let mut mod_path = RelativePathBuf::new(); | 73 | let mut mod_path = RelativePathBuf::new(); |
84 | if !(candidate.ends_with("mod.rs") || attr_path.is_some()) { | 74 | if !(candidate.ends_with("mod.rs") || attr_path.is_some()) { |
@@ -88,22 +78,10 @@ impl ModDir { | |||
88 | return Ok((file_id, ModDir { path: mod_path, root_non_dir_owner })); | 78 | return Ok((file_id, ModDir { path: mod_path, root_non_dir_owner })); |
89 | } | 79 | } |
90 | } | 80 | } |
91 | let suggestion = candidate_files.first().unwrap(); | 81 | Err(candidate_files.remove(0)) |
92 | Err(base_dir.join(suggestion)) | ||
93 | } | 82 | } |
94 | } | 83 | } |
95 | 84 | ||
96 | fn normalize_attribute_path(file_path: &str) -> Cow<str> { | 85 | fn attr_to_path(attr: Option<&SmolStr>) -> Option<RelativePathBuf> { |
97 | let current_dir = "./"; | 86 | attr.and_then(|it| RelativePathBuf::from_path(&it.replace("\\", "/")).ok()) |
98 | let windows_path_separator = r#"\"#; | ||
99 | let current_dir_normalize = if file_path.starts_with(current_dir) { | ||
100 | &file_path[current_dir.len()..] | ||
101 | } else { | ||
102 | file_path | ||
103 | }; | ||
104 | if current_dir_normalize.contains(windows_path_separator) { | ||
105 | Cow::Owned(current_dir_normalize.replace(windows_path_separator, "/")) | ||
106 | } else { | ||
107 | Cow::Borrowed(current_dir_normalize) | ||
108 | } | ||
109 | } | 87 | } |