mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 07:44:10 +00:00
Simplify
This commit is contained in:
parent
301711ee71
commit
fbc1d2a514
@ -1327,14 +1327,14 @@ impl<'a> SemanticsScope<'a> {
|
|||||||
resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
|
resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
|
||||||
resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
|
resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
|
||||||
resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(id.into()),
|
resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(id.into()),
|
||||||
resolver::ScopeDef::Local(pat_id) => {
|
resolver::ScopeDef::Local(pat_id) => match self.resolver.body_owner() {
|
||||||
let parent = self.resolver.body_owner().unwrap();
|
Some(parent) => ScopeDef::Local(Local { parent, pat_id }),
|
||||||
ScopeDef::Local(Local { parent, pat_id })
|
None => continue,
|
||||||
}
|
},
|
||||||
resolver::ScopeDef::Label(label_id) => {
|
resolver::ScopeDef::Label(label_id) => match self.resolver.body_owner() {
|
||||||
let parent = self.resolver.body_owner().unwrap();
|
Some(parent) => ScopeDef::Label(Label { parent, label_id }),
|
||||||
ScopeDef::Label(Label { parent, label_id })
|
None => continue,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
f(name.clone(), def)
|
f(name.clone(), def)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! Name resolution façade.
|
//! Name resolution façade.
|
||||||
use std::sync::Arc;
|
use std::{hash::BuildHasherDefault, sync::Arc};
|
||||||
|
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use hir_expand::name::{name, Name};
|
use hir_expand::name::{name, Name};
|
||||||
@ -352,7 +352,7 @@ impl Resolver {
|
|||||||
/// Returns a set of names available in the current scope.
|
/// Returns a set of names available in the current scope.
|
||||||
///
|
///
|
||||||
/// Note that this is a somewhat fuzzy concept -- internally, the compiler
|
/// Note that this is a somewhat fuzzy concept -- internally, the compiler
|
||||||
/// doesn't necessary follow a strict scoping discipline. Rathe, it just
|
/// doesn't necessary follow a strict scoping discipline. Rather, it just
|
||||||
/// tells for each ident what it resolves to.
|
/// tells for each ident what it resolves to.
|
||||||
///
|
///
|
||||||
/// A good example is something like `str::from_utf8`. From scopes point of
|
/// A good example is something like `str::from_utf8`. From scopes point of
|
||||||
@ -387,10 +387,13 @@ impl Resolver {
|
|||||||
/// The result is ordered *roughly* from the innermost scope to the
|
/// The result is ordered *roughly* from the innermost scope to the
|
||||||
/// outermost: when the name is introduced in two namespaces in two scopes,
|
/// outermost: when the name is introduced in two namespaces in two scopes,
|
||||||
/// we use the position of the first scope.
|
/// we use the position of the first scope.
|
||||||
pub fn names_in_scope(&self, db: &dyn DefDatabase) -> IndexMap<Name, SmallVec<[ScopeDef; 1]>> {
|
pub fn names_in_scope(
|
||||||
|
&self,
|
||||||
|
db: &dyn DefDatabase,
|
||||||
|
) -> FxIndexMap<Name, SmallVec<[ScopeDef; 1]>> {
|
||||||
let mut res = ScopeNames::default();
|
let mut res = ScopeNames::default();
|
||||||
for scope in self.scopes() {
|
for scope in self.scopes() {
|
||||||
scope.process_names(db, &mut res);
|
scope.process_names(&mut res, db);
|
||||||
}
|
}
|
||||||
res.map
|
res.map
|
||||||
}
|
}
|
||||||
@ -475,7 +478,7 @@ impl Resolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum ScopeDef {
|
pub enum ScopeDef {
|
||||||
ModuleDef(ModuleDefId),
|
ModuleDef(ModuleDefId),
|
||||||
Unknown,
|
Unknown,
|
||||||
@ -487,7 +490,7 @@ pub enum ScopeDef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Scope {
|
impl Scope {
|
||||||
fn process_names(&self, db: &dyn DefDatabase, acc: &mut ScopeNames) {
|
fn process_names(&self, acc: &mut ScopeNames, db: &dyn DefDatabase) {
|
||||||
match self {
|
match self {
|
||||||
Scope::ModuleScope(m) => {
|
Scope::ModuleScope(m) => {
|
||||||
// FIXME: should we provide `self` here?
|
// FIXME: should we provide `self` here?
|
||||||
@ -700,9 +703,10 @@ fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> {
|
|||||||
Some(res)
|
Some(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<rustc_hash::FxHasher>>;
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct ScopeNames {
|
struct ScopeNames {
|
||||||
map: IndexMap<Name, SmallVec<[ScopeDef; 1]>>,
|
map: FxIndexMap<Name, SmallVec<[ScopeDef; 1]>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScopeNames {
|
impl ScopeNames {
|
||||||
|
@ -30,7 +30,7 @@ pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext)
|
|||||||
let param_lifetime = param_lifetime.as_ref().map(ast::Lifetime::text);
|
let param_lifetime = param_lifetime.as_ref().map(ast::Lifetime::text);
|
||||||
let param_lifetime = param_lifetime.as_ref().map(TokenText::as_str);
|
let param_lifetime = param_lifetime.as_ref().map(TokenText::as_str);
|
||||||
|
|
||||||
ctx.scope.process_all_names(&mut |name, res| {
|
ctx.process_all_names_raw(&mut |name, res| {
|
||||||
if matches!(
|
if matches!(
|
||||||
res,
|
res,
|
||||||
ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_))
|
ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_))
|
||||||
@ -49,7 +49,7 @@ pub(crate) fn complete_label(acc: &mut Completions, ctx: &CompletionContext) {
|
|||||||
if !matches!(ctx.lifetime_ctx, Some(LifetimeContext::LabelRef)) {
|
if !matches!(ctx.lifetime_ctx, Some(LifetimeContext::LabelRef)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ctx.scope.process_all_names(&mut |name, res| {
|
ctx.process_all_names_raw(&mut |name, res| {
|
||||||
if let ScopeDef::Label(_) = res {
|
if let ScopeDef::Label(_) = res {
|
||||||
acc.add_label(ctx, name);
|
acc.add_label(ctx, name);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use ide_db::{
|
|||||||
famous_defs::FamousDefs,
|
famous_defs::FamousDefs,
|
||||||
RootDatabase,
|
RootDatabase,
|
||||||
};
|
};
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
algo::{find_node_at_offset, non_trivia_sibling},
|
algo::{find_node_at_offset, non_trivia_sibling},
|
||||||
ast::{self, AttrKind, HasName, NameOrNameRef},
|
ast::{self, AttrKind, HasName, NameOrNameRef},
|
||||||
@ -146,7 +146,7 @@ pub(crate) struct CompletionContext<'a> {
|
|||||||
|
|
||||||
pub(super) existing_derives: FxHashSet<hir::Macro>,
|
pub(super) existing_derives: FxHashSet<hir::Macro>,
|
||||||
|
|
||||||
pub(super) locals: Vec<(Name, Local)>,
|
pub(super) locals: FxHashMap<Name, Local>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompletionContext<'a> {
|
impl<'a> CompletionContext<'a> {
|
||||||
@ -293,6 +293,10 @@ impl<'a> CompletionContext<'a> {
|
|||||||
self.path_context.as_ref().and_then(|it| it.kind)
|
self.path_context.as_ref().and_then(|it| it.kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn is_immediately_after_macro_bang(&self) -> bool {
|
||||||
|
self.token.kind() == BANG && self.token.parent().map_or(false, |it| it.kind() == MACRO_CALL)
|
||||||
|
}
|
||||||
|
|
||||||
/// Checks if an item is visible and not `doc(hidden)` at the completion site.
|
/// Checks if an item is visible and not `doc(hidden)` at the completion site.
|
||||||
pub(crate) fn is_visible<I>(&self, item: &I) -> Visible
|
pub(crate) fn is_visible<I>(&self, item: &I) -> Visible
|
||||||
where
|
where
|
||||||
@ -318,11 +322,6 @@ impl<'a> CompletionContext<'a> {
|
|||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_immediately_after_macro_bang(&self) -> bool {
|
|
||||||
self.token.kind() == BANG && self.token.parent().map_or(false, |it| it.kind() == MACRO_CALL)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether the given trait is an operator trait or not.
|
/// Whether the given trait is an operator trait or not.
|
||||||
pub(crate) fn is_ops_trait(&self, trait_: hir::Trait) -> bool {
|
pub(crate) fn is_ops_trait(&self, trait_: hir::Trait) -> bool {
|
||||||
match trait_.attrs(self.db).lang() {
|
match trait_.attrs(self.db).lang() {
|
||||||
@ -340,7 +339,12 @@ impl<'a> CompletionContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
f(name, def);
|
f(name, def);
|
||||||
})
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn process_all_names_raw(&self, f: &mut dyn FnMut(Name, ScopeDef)) {
|
||||||
|
let _p = profile::span("CompletionContext::process_all_names_raw");
|
||||||
|
self.scope.process_all_names(&mut |name, def| f(name, def));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_visible_impl(
|
fn is_visible_impl(
|
||||||
@ -372,16 +376,11 @@ impl<'a> CompletionContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_doc_hidden(&self, attrs: &hir::Attrs, defining_crate: hir::Crate) -> bool {
|
fn is_doc_hidden(&self, attrs: &hir::Attrs, defining_crate: hir::Crate) -> bool {
|
||||||
let krate = match self.krate {
|
match self.krate {
|
||||||
Some(it) => it,
|
|
||||||
None => return true,
|
|
||||||
};
|
|
||||||
if krate != defining_crate && attrs.has_doc_hidden() {
|
|
||||||
// `doc(hidden)` items are only completed within the defining crate.
|
// `doc(hidden)` items are only completed within the defining crate.
|
||||||
return true;
|
Some(krate) => krate != defining_crate && attrs.has_doc_hidden(),
|
||||||
|
None => true,
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,10 +412,10 @@ impl<'a> CompletionContext<'a> {
|
|||||||
let scope = sema.scope_at_offset(&token.parent()?, offset);
|
let scope = sema.scope_at_offset(&token.parent()?, offset);
|
||||||
let krate = scope.krate();
|
let krate = scope.krate();
|
||||||
let module = scope.module();
|
let module = scope.module();
|
||||||
let mut locals = vec![];
|
let mut locals = FxHashMap::default();
|
||||||
scope.process_all_names(&mut |name, scope| {
|
scope.process_all_names(&mut |name, scope| {
|
||||||
if let ScopeDef::Local(local) = scope {
|
if let ScopeDef::Local(local) = scope {
|
||||||
locals.push((name, local));
|
locals.insert(name, local);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user