From aca022f1d49a6d945f3ef4f8c781d7337120b68d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 17 Dec 2019 15:38:28 +0100 Subject: Refactor PathKind --- crates/ra_assists/src/assists/add_import.rs | 10 +++++++-- crates/ra_hir_def/src/nameres/collector.rs | 2 +- crates/ra_hir_def/src/nameres/path_resolution.rs | 26 +++++++++++++++++------- crates/ra_hir_def/src/path.rs | 5 ++--- crates/ra_hir_def/src/path/lower.rs | 4 ++-- crates/ra_hir_def/src/path/lower/lower_use.rs | 4 ++-- 6 files changed, 34 insertions(+), 17 deletions(-) diff --git a/crates/ra_assists/src/assists/add_import.rs b/crates/ra_assists/src/assists/add_import.rs index f81b4184a..ceffee9b8 100644 --- a/crates/ra_assists/src/assists/add_import.rs +++ b/crates/ra_assists/src/assists/add_import.rs @@ -582,8 +582,14 @@ fn collect_hir_path_segments(path: &hir::Path) -> Option> { hir::PathKind::Abs => ps.push("".into()), hir::PathKind::Crate => ps.push("crate".into()), hir::PathKind::Plain => {} - hir::PathKind::Self_ => ps.push("self".into()), - hir::PathKind::Super => ps.push("super".into()), + hir::PathKind::Super(0) => ps.push("self".into()), + hir::PathKind::Super(lvl) => { + let mut chain = "super".to_string(); + for _ in 0..*lvl { + chain += "::super"; + } + ps.push(chain.into()); + } hir::PathKind::Type(_) | hir::PathKind::DollarCrate(_) => return None, } ps.extend(path.segments().iter().map(|it| it.name.to_string().into())); diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 912a073ea..8bbf7ffa2 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -890,7 +890,7 @@ where // We rewrite simple path `macro_name` to `self::macro_name` to force resolve in module scope only. let mut path = mac.path.clone(); if path.is_ident() { - path.kind = PathKind::Self_; + path.kind = PathKind::Super(0); } self.def_collector.unexpanded_macros.push(MacroDirective { diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index 4a249e7e7..a3bfc1542 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs @@ -10,6 +10,8 @@ //! //! `ReachedFixedPoint` signals about this. +use std::iter::successors; + use hir_expand::name::Name; use ra_db::Edition; use test_utils::tested_by; @@ -97,9 +99,6 @@ impl CrateDefMap { PathKind::Crate => { PerNs::types(ModuleId { krate: self.krate, local_id: self.root }.into()) } - PathKind::Self_ => { - PerNs::types(ModuleId { krate: self.krate, local_id: original_module }.into()) - } // plain import or absolute path in 2015: crate-relative with // fallback to extern prelude (with the simplification in // rust-lang/rust#57745) @@ -123,9 +122,22 @@ impl CrateDefMap { log::debug!("resolving {:?} in module", segment); self.resolve_name_in_module(db, original_module, &segment, prefer_module(idx)) } - PathKind::Super => { - if let Some(p) = self.modules[original_module].parent { - PerNs::types(ModuleId { krate: self.krate, local_id: p }.into()) + // PathKind::Self_ => { + // PerNs::types(ModuleId { krate: self.krate, local_id: original_module }.into()) + // } + // PathKind::Super => { + // if let Some(p) = self.modules[original_module].parent { + // PerNs::types(ModuleId { krate: self.krate, local_id: p }.into()) + // } else { + // log::debug!("super path in root module"); + // return ResolvePathResult::empty(ReachedFixedPoint::Yes); + // } + // } + PathKind::Super(lvl) => { + let m = successors(Some(original_module), |m| self.modules[*m].parent) + .nth(lvl as usize); + if let Some(local_id) = m { + PerNs::types(ModuleId { krate: self.krate, local_id }.into()) } else { log::debug!("super path in root module"); return ResolvePathResult::empty(ReachedFixedPoint::Yes); @@ -170,7 +182,7 @@ impl CrateDefMap { if module.krate != self.krate { let path = ModPath { segments: path.segments[i..].to_vec(), - kind: PathKind::Self_, + kind: PathKind::Super(0), }; log::debug!("resolving {:?} in other crate", path); let defp_map = db.crate_def_map(module.krate); diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 20d6d98ea..3b26e8337 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -56,7 +56,7 @@ impl ModPath { } pub fn is_self(&self) -> bool { - self.kind == PathKind::Self_ && self.segments.is_empty() + self.kind == PathKind::Super(0) && self.segments.is_empty() } /// If this path is a single identifier, like `foo`, return its name. @@ -100,8 +100,7 @@ pub enum GenericArg { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum PathKind { Plain, - Self_, - Super, + Super(u8), Crate, // Absolute path Abs, diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs index a2e995198..c71b52d89 100644 --- a/crates/ra_hir_def/src/path/lower.rs +++ b/crates/ra_hir_def/src/path/lower.rs @@ -95,11 +95,11 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option break; } ast::PathSegmentKind::SelfKw => { - kind = PathKind::Self_; + kind = PathKind::Super(0); break; } ast::PathSegmentKind::SuperKw => { - kind = PathKind::Super; + kind = PathKind::Super(1); break; } } diff --git a/crates/ra_hir_def/src/path/lower/lower_use.rs b/crates/ra_hir_def/src/path/lower/lower_use.rs index ea3fdb56c..062c02063 100644 --- a/crates/ra_hir_def/src/path/lower/lower_use.rs +++ b/crates/ra_hir_def/src/path/lower/lower_use.rs @@ -95,13 +95,13 @@ fn convert_path(prefix: Option, path: ast::Path, hygiene: &Hygiene) -> if prefix.is_some() { return None; } - ModPath::from_simple_segments(PathKind::Self_, iter::empty()) + ModPath::from_simple_segments(PathKind::Super(0), iter::empty()) } ast::PathSegmentKind::SuperKw => { if prefix.is_some() { return None; } - ModPath::from_simple_segments(PathKind::Super, iter::empty()) + ModPath::from_simple_segments(PathKind::Super(1), iter::empty()) } ast::PathSegmentKind::Type { .. } => { // not allowed in imports -- cgit v1.2.3