Make ModPath
's representation private
This commit is contained in:
parent
36191543a6
commit
5d99ba1d9a
@ -151,8 +151,8 @@ fn insert_import(
|
||||
ctx.config.insert_use.prefix_kind,
|
||||
);
|
||||
if let Some(mut mod_path) = mod_path {
|
||||
mod_path.segments.pop();
|
||||
mod_path.segments.push(variant_hir_name.clone());
|
||||
mod_path.pop_segment();
|
||||
mod_path.push_segment(variant_hir_name.clone());
|
||||
let scope = ImportScope::find_insert_use_container(scope_node, &ctx.sema)?;
|
||||
*rewriter += insert_use(&scope, mod_path_to_ast(&mod_path), ctx.config.insert_use.merge);
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ fn compute_fuzzy_completion_order_key(
|
||||
user_input_lowercased: &str,
|
||||
) -> usize {
|
||||
mark::hit!(certain_fuzzy_order_test);
|
||||
let proposed_import_name = match proposed_mod_path.segments.last() {
|
||||
let proposed_import_name = match proposed_mod_path.segments().last() {
|
||||
Some(name) => name.to_string().to_lowercase(),
|
||||
None => return usize::MAX,
|
||||
};
|
||||
|
@ -63,7 +63,7 @@ fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &T
|
||||
if let Some(path) = module.find_use_path(ctx.db, ModuleDef::from(variant)) {
|
||||
// Variants with trivial paths are already added by the existing completion logic,
|
||||
// so we should avoid adding these twice
|
||||
if path.segments.len() > 1 {
|
||||
if path.segments().len() > 1 {
|
||||
acc.add_qualified_enum_variant(ctx, variant, path);
|
||||
}
|
||||
}
|
||||
|
@ -332,9 +332,9 @@ impl Builder {
|
||||
label = format!("{} ({})", label, import_to_add.import_path);
|
||||
} else {
|
||||
let mut import_path_without_last_segment = import_to_add.import_path.to_owned();
|
||||
let _ = import_path_without_last_segment.segments.pop();
|
||||
let _ = import_path_without_last_segment.pop_segment();
|
||||
|
||||
if !import_path_without_last_segment.segments.is_empty() {
|
||||
if !import_path_without_last_segment.segments().is_empty() {
|
||||
lookup = lookup.or_else(|| Some(label.clone()));
|
||||
insert_text = insert_text.or_else(|| Some(label.clone()));
|
||||
label = format!("{}::{}", import_path_without_last_segment, label);
|
||||
|
@ -57,7 +57,7 @@ pub(crate) fn render_resolution_with_import<'a>(
|
||||
ScopeDef::ModuleDef(ModuleDef::Function(f)) => f.name(ctx.completion.db).to_string(),
|
||||
ScopeDef::ModuleDef(ModuleDef::Const(c)) => c.name(ctx.completion.db)?.to_string(),
|
||||
ScopeDef::ModuleDef(ModuleDef::TypeAlias(t)) => t.name(ctx.completion.db).to_string(),
|
||||
_ => import_edit.import_path.segments.last()?.to_string(),
|
||||
_ => import_edit.import_path.segments().last()?.to_string(),
|
||||
};
|
||||
Render::new(ctx).render_resolution(local_name, Some(import_edit), resolution).map(|mut item| {
|
||||
item.completion_kind = CompletionKind::Magic;
|
||||
|
@ -45,8 +45,8 @@ impl<'a> EnumRender<'a> {
|
||||
let (qualified_name, short_qualified_name) = match &path {
|
||||
Some(path) => {
|
||||
let full = path.to_string();
|
||||
let short =
|
||||
path.segments[path.segments.len().saturating_sub(2)..].iter().join("::");
|
||||
let segments = path.segments();
|
||||
let short = segments[segments.len().saturating_sub(2)..].iter().join("::");
|
||||
(full, short)
|
||||
}
|
||||
None => (name.to_string(), name.to_string()),
|
||||
|
@ -36,13 +36,13 @@ const MAX_PATH_LEN: usize = 15;
|
||||
|
||||
impl ModPath {
|
||||
fn starts_with_std(&self) -> bool {
|
||||
self.segments.first() == Some(&known::std)
|
||||
self.segments().first() == Some(&known::std)
|
||||
}
|
||||
|
||||
// When std library is present, paths starting with `std::`
|
||||
// should be preferred over paths starting with `core::` and `alloc::`
|
||||
fn can_start_with_std(&self) -> bool {
|
||||
let first_segment = self.segments.first();
|
||||
let first_segment = self.segments().first();
|
||||
first_segment == Some(&known::alloc) || first_segment == Some(&known::core)
|
||||
}
|
||||
}
|
||||
@ -157,7 +157,7 @@ fn find_path_inner(
|
||||
if let Some(ModuleDefId::EnumVariantId(variant)) = item.as_module_def_id() {
|
||||
if let Some(mut path) = find_path(db, ItemInNs::Types(variant.parent.into()), from) {
|
||||
let data = db.enum_data(variant.parent);
|
||||
path.segments.push(data.variants[variant.local_id].name.clone());
|
||||
path.push_segment(data.variants[variant.local_id].name.clone());
|
||||
return Some(path);
|
||||
}
|
||||
// If this doesn't work, it seems we have no way of referring to the
|
||||
@ -186,7 +186,7 @@ fn find_path_inner(
|
||||
best_path_len - 1,
|
||||
prefixed,
|
||||
) {
|
||||
path.segments.push(name);
|
||||
path.push_segment(name);
|
||||
|
||||
let new_path = if let Some(best_path) = best_path {
|
||||
select_best_path(best_path, path, prefer_no_std)
|
||||
@ -215,7 +215,7 @@ fn find_path_inner(
|
||||
prefixed,
|
||||
)?;
|
||||
mark::hit!(partially_imported);
|
||||
path.segments.push(info.path.segments.last().unwrap().clone());
|
||||
path.push_segment(info.path.segments.last().unwrap().clone());
|
||||
Some(path)
|
||||
})
|
||||
});
|
||||
|
@ -240,7 +240,7 @@ impl ItemVisibilities {
|
||||
fn alloc(&mut self, vis: RawVisibility) -> RawVisibilityId {
|
||||
match &vis {
|
||||
RawVisibility::Public => RawVisibilityId::PUB,
|
||||
RawVisibility::Module(path) if path.segments.is_empty() => match &path.kind {
|
||||
RawVisibility::Module(path) if path.segments().is_empty() => match &path.kind {
|
||||
PathKind::Super(0) => RawVisibilityId::PRIV,
|
||||
PathKind::Crate => RawVisibilityId::PUB_CRATE,
|
||||
_ => RawVisibilityId(self.arena.alloc(vis).into_raw().into()),
|
||||
@ -251,10 +251,8 @@ impl ItemVisibilities {
|
||||
}
|
||||
|
||||
static VIS_PUB: RawVisibility = RawVisibility::Public;
|
||||
static VIS_PRIV: RawVisibility =
|
||||
RawVisibility::Module(ModPath { kind: PathKind::Super(0), segments: Vec::new() });
|
||||
static VIS_PUB_CRATE: RawVisibility =
|
||||
RawVisibility::Module(ModPath { kind: PathKind::Crate, segments: Vec::new() });
|
||||
static VIS_PRIV: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Super(0)));
|
||||
static VIS_PUB_CRATE: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Crate));
|
||||
|
||||
#[derive(Default, Debug, Eq, PartialEq)]
|
||||
struct GenericParamsStorage {
|
||||
|
@ -750,7 +750,8 @@ impl Ctx {
|
||||
|
||||
fn desugar_future_path(orig: TypeRef) -> Path {
|
||||
let path = path![core::future::Future];
|
||||
let mut generic_args: Vec<_> = std::iter::repeat(None).take(path.segments.len() - 1).collect();
|
||||
let mut generic_args: Vec<_> =
|
||||
std::iter::repeat(None).take(path.segments().len() - 1).collect();
|
||||
let mut last = GenericArgs::empty();
|
||||
let binding =
|
||||
AssociatedTypeBinding { name: name![Output], type_ref: Some(orig), bounds: Vec::new() };
|
||||
|
@ -662,7 +662,7 @@ impl AsMacroCall for AstIdWithPath<ast::Item> {
|
||||
def.as_lazy_macro(
|
||||
db.upcast(),
|
||||
krate,
|
||||
MacroCallKind::Attr(self.ast_id, self.path.segments.last()?.to_string()),
|
||||
MacroCallKind::Attr(self.ast_id, self.path.segments().last()?.to_string()),
|
||||
)
|
||||
.into(),
|
||||
)
|
||||
|
@ -655,7 +655,7 @@ impl DefCollector<'_> {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match import.path.segments.last() {
|
||||
match import.path.segments().last() {
|
||||
Some(last_segment) => {
|
||||
let name = match &import.alias {
|
||||
Some(ImportAlias::Alias(name)) => Some(name.clone()),
|
||||
@ -956,7 +956,7 @@ impl DefCollector<'_> {
|
||||
let item_tree = self.db.item_tree(import.file_id);
|
||||
let import_data = &item_tree[import.value];
|
||||
|
||||
match (import_data.path.segments.first(), &import_data.path.kind) {
|
||||
match (import_data.path.segments().first(), &import_data.path.kind) {
|
||||
(Some(krate), PathKind::Plain) | (Some(krate), PathKind::Abs) => {
|
||||
if diagnosed_extern_crates.contains(krate) {
|
||||
continue;
|
||||
|
@ -149,7 +149,7 @@ impl DefMap {
|
||||
path: &ModPath,
|
||||
shadow: BuiltinShadowMode,
|
||||
) -> ResolvePathResult {
|
||||
let mut segments = path.segments.iter().enumerate();
|
||||
let mut segments = path.segments().iter().enumerate();
|
||||
let mut curr_per_ns: PerNs = match path.kind {
|
||||
PathKind::DollarCrate(krate) => {
|
||||
if krate == self.krate {
|
||||
@ -190,7 +190,7 @@ impl DefMap {
|
||||
// BuiltinShadowMode wasn't Module, then we need to try
|
||||
// resolving it as a builtin.
|
||||
let prefer_module =
|
||||
if path.segments.len() == 1 { shadow } else { BuiltinShadowMode::Module };
|
||||
if path.segments().len() == 1 { shadow } else { BuiltinShadowMode::Module };
|
||||
|
||||
log::debug!("resolving {:?} in module", segment);
|
||||
self.resolve_name_in_module(db, original_module, &segment, prefer_module)
|
||||
@ -203,10 +203,10 @@ impl DefMap {
|
||||
None => match &self.block {
|
||||
Some(block) => {
|
||||
// Look up remaining path in parent `DefMap`
|
||||
let new_path = ModPath {
|
||||
kind: PathKind::Super(lvl - i),
|
||||
segments: path.segments.clone(),
|
||||
};
|
||||
let new_path = ModPath::from_segments(
|
||||
PathKind::Super(lvl - i),
|
||||
path.segments().to_vec(),
|
||||
);
|
||||
log::debug!("`super` path: {} -> {} in parent map", path, new_path);
|
||||
return block.parent.def_map(db).resolve_path_fp_with_macro(
|
||||
db,
|
||||
@ -258,10 +258,10 @@ impl DefMap {
|
||||
curr_per_ns = match curr {
|
||||
ModuleDefId::ModuleId(module) => {
|
||||
if module.krate != self.krate {
|
||||
let path = ModPath {
|
||||
segments: path.segments[i..].to_vec(),
|
||||
kind: PathKind::Super(0),
|
||||
};
|
||||
let path = ModPath::from_segments(
|
||||
PathKind::Super(0),
|
||||
path.segments()[i..].iter().cloned(),
|
||||
);
|
||||
log::debug!("resolving {:?} in other crate", path);
|
||||
let defp_map = module.def_map(db);
|
||||
let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow);
|
||||
|
@ -20,7 +20,7 @@ use crate::{
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct ModPath {
|
||||
pub kind: PathKind,
|
||||
pub segments: Vec<Name>,
|
||||
segments: Vec<Name>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
@ -53,6 +53,11 @@ impl ModPath {
|
||||
ModPath { kind, segments }
|
||||
}
|
||||
|
||||
/// Creates a `ModPath` from a `PathKind`, with no extra path segments.
|
||||
pub const fn from_kind(kind: PathKind) -> ModPath {
|
||||
ModPath { kind, segments: Vec::new() }
|
||||
}
|
||||
|
||||
/// Calls `cb` with all paths, represented by this use item.
|
||||
pub(crate) fn expand_use_item(
|
||||
item_src: InFile<ast::Use>,
|
||||
@ -64,6 +69,18 @@ impl ModPath {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn segments(&self) -> &[Name] {
|
||||
&self.segments
|
||||
}
|
||||
|
||||
pub fn push_segment(&mut self, segment: Name) {
|
||||
self.segments.push(segment);
|
||||
}
|
||||
|
||||
pub fn pop_segment(&mut self) -> Option<Name> {
|
||||
self.segments.pop()
|
||||
}
|
||||
|
||||
/// Returns the number of segments in the path (counting special segments like `$crate` and
|
||||
/// `super`).
|
||||
pub fn len(&self) -> usize {
|
||||
@ -78,7 +95,7 @@ impl ModPath {
|
||||
}
|
||||
|
||||
pub fn is_ident(&self) -> bool {
|
||||
self.kind == PathKind::Plain && self.segments.len() == 1
|
||||
self.as_ident().is_some()
|
||||
}
|
||||
|
||||
pub fn is_self(&self) -> bool {
|
||||
@ -87,10 +104,14 @@ impl ModPath {
|
||||
|
||||
/// If this path is a single identifier, like `foo`, return its name.
|
||||
pub fn as_ident(&self) -> Option<&Name> {
|
||||
if !self.is_ident() {
|
||||
if self.kind != PathKind::Plain {
|
||||
return None;
|
||||
}
|
||||
self.segments.first()
|
||||
|
||||
match &*self.segments {
|
||||
[name] => Some(name),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ impl Resolver {
|
||||
db: &dyn DefDatabase,
|
||||
path: &ModPath,
|
||||
) -> Option<(TypeNs, Option<usize>)> {
|
||||
let first_name = path.segments.first()?;
|
||||
let first_name = path.segments().first()?;
|
||||
let skip_to_mod = path.kind != PathKind::Plain;
|
||||
for scope in self.scopes.iter().rev() {
|
||||
match scope {
|
||||
@ -179,7 +179,7 @@ impl Resolver {
|
||||
|
||||
Scope::GenericParams { params, def } => {
|
||||
if let Some(local_id) = params.find_type_by_name(first_name) {
|
||||
let idx = if path.segments.len() == 1 { None } else { Some(1) };
|
||||
let idx = if path.segments().len() == 1 { None } else { Some(1) };
|
||||
return Some((
|
||||
TypeNs::GenericParam(TypeParamId { local_id, parent: *def }),
|
||||
idx,
|
||||
@ -188,13 +188,13 @@ impl Resolver {
|
||||
}
|
||||
Scope::ImplDefScope(impl_) => {
|
||||
if first_name == &name![Self] {
|
||||
let idx = if path.segments.len() == 1 { None } else { Some(1) };
|
||||
let idx = if path.segments().len() == 1 { None } else { Some(1) };
|
||||
return Some((TypeNs::SelfType(*impl_), idx));
|
||||
}
|
||||
}
|
||||
Scope::AdtScope(adt) => {
|
||||
if first_name == &name![Self] {
|
||||
let idx = if path.segments.len() == 1 { None } else { Some(1) };
|
||||
let idx = if path.segments().len() == 1 { None } else { Some(1) };
|
||||
return Some((TypeNs::AdtSelfType(*adt), idx));
|
||||
}
|
||||
}
|
||||
@ -270,9 +270,9 @@ impl Resolver {
|
||||
db: &dyn DefDatabase,
|
||||
path: &ModPath,
|
||||
) -> Option<ResolveValueResult> {
|
||||
let n_segments = path.segments.len();
|
||||
let n_segments = path.segments().len();
|
||||
let tmp = name![self];
|
||||
let first_name = if path.is_self() { &tmp } else { path.segments.first()? };
|
||||
let first_name = if path.is_self() { &tmp } else { path.segments().first()? };
|
||||
let skip_to_mod = path.kind != PathKind::Plain && !path.is_self();
|
||||
for scope in self.scopes.iter().rev() {
|
||||
match scope {
|
||||
|
@ -22,8 +22,7 @@ pub enum RawVisibility {
|
||||
|
||||
impl RawVisibility {
|
||||
pub(crate) const fn private() -> RawVisibility {
|
||||
let path = ModPath { kind: PathKind::Super(0), segments: Vec::new() };
|
||||
RawVisibility::Module(path)
|
||||
RawVisibility::Module(ModPath::from_kind(PathKind::Super(0)))
|
||||
}
|
||||
|
||||
pub(crate) fn from_ast(
|
||||
@ -59,15 +58,15 @@ impl RawVisibility {
|
||||
RawVisibility::Module(path)
|
||||
}
|
||||
ast::VisibilityKind::PubCrate => {
|
||||
let path = ModPath { kind: PathKind::Crate, segments: Vec::new() };
|
||||
let path = ModPath::from_kind(PathKind::Crate);
|
||||
RawVisibility::Module(path)
|
||||
}
|
||||
ast::VisibilityKind::PubSuper => {
|
||||
let path = ModPath { kind: PathKind::Super(1), segments: Vec::new() };
|
||||
let path = ModPath::from_kind(PathKind::Super(1));
|
||||
RawVisibility::Module(path)
|
||||
}
|
||||
ast::VisibilityKind::PubSelf => {
|
||||
let path = ModPath { kind: PathKind::Plain, segments: Vec::new() };
|
||||
let path = ModPath::from_kind(PathKind::Plain);
|
||||
RawVisibility::Module(path)
|
||||
}
|
||||
ast::VisibilityKind::Pub => RawVisibility::Public,
|
||||
|
@ -461,7 +461,7 @@ impl<'a> InferenceContext<'a> {
|
||||
(ty, variant)
|
||||
}
|
||||
Some(1) => {
|
||||
let segment = path.mod_path().segments.last().unwrap();
|
||||
let segment = path.mod_path().segments().last().unwrap();
|
||||
// this could be an enum variant or associated type
|
||||
if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
|
||||
let enum_data = self.db.enum_data(enum_id);
|
||||
|
@ -24,7 +24,7 @@ pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path {
|
||||
}
|
||||
|
||||
segments.extend(
|
||||
path.segments
|
||||
path.segments()
|
||||
.iter()
|
||||
.map(|segment| make::path_segment(make::name_ref(&segment.to_string()))),
|
||||
);
|
||||
|
@ -1729,7 +1729,7 @@ fn fill_resolve_data(
|
||||
) -> Option<()> {
|
||||
let import_edit = item.import_to_add()?;
|
||||
let full_import_path = import_edit.import_path.to_string();
|
||||
let imported_name = import_edit.import_path.segments.clone().pop()?.to_string();
|
||||
let imported_name = import_edit.import_path.segments().last()?.to_string();
|
||||
|
||||
*resolve_data = Some(
|
||||
to_value(CompletionResolveData {
|
||||
|
Loading…
x
Reference in New Issue
Block a user