mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-24 12:03:31 +00:00
Less lifetines: derive SemanticsScope in place
This commit is contained in:
parent
db61d4ea13
commit
dccbb38d2e
7 changed files with 49 additions and 50 deletions
|
@ -774,7 +774,7 @@ fn find_root(node: &SyntaxNode) -> SyntaxNode {
|
|||
///
|
||||
/// Note that if you are wondering "what does this specific existing name mean?",
|
||||
/// you'd better use the `resolve_` family of methods.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug)]
|
||||
pub struct SemanticsScope<'a> {
|
||||
pub db: &'a dyn HirDatabase,
|
||||
file_id: HirFileId,
|
||||
|
|
|
@ -112,9 +112,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
|
|||
Some(())
|
||||
}
|
||||
|
||||
pub(super) fn find_importable_node<'a>(
|
||||
ctx: &'a AssistContext,
|
||||
) -> Option<(ImportAssets<'a>, SyntaxNode)> {
|
||||
pub(super) fn find_importable_node(ctx: &AssistContext) -> Option<(ImportAssets, SyntaxNode)> {
|
||||
if let Some(path_under_caret) = ctx.find_node_at_offset_with_descend::<ast::Path>() {
|
||||
ImportAssets::for_exact_path(&path_under_caret, &ctx.sema)
|
||||
.zip(Some(path_under_caret.syntax().clone()))
|
||||
|
|
|
@ -65,23 +65,20 @@ pub(crate) fn replace_derive_with_manual_impl(
|
|||
let current_module = ctx.sema.scope(annotated_name.syntax()).module()?;
|
||||
let current_crate = current_module.krate();
|
||||
|
||||
let found_traits = items_locator::with_for_exact_name(
|
||||
&ctx.sema,
|
||||
current_crate,
|
||||
trait_token.text().to_string(),
|
||||
)
|
||||
.into_iter()
|
||||
.filter_map(|item| match ModuleDef::from(item.as_module_def_id()?) {
|
||||
ModuleDef::Trait(trait_) => Some(trait_),
|
||||
_ => None,
|
||||
})
|
||||
.flat_map(|trait_| {
|
||||
current_module
|
||||
.find_use_path(ctx.sema.db, hir::ModuleDef::Trait(trait_))
|
||||
.as_ref()
|
||||
.map(mod_path_to_ast)
|
||||
.zip(Some(trait_))
|
||||
});
|
||||
let found_traits =
|
||||
items_locator::with_exact_name(&ctx.sema, current_crate, trait_token.text().to_string())
|
||||
.into_iter()
|
||||
.filter_map(|item| match ModuleDef::from(item.as_module_def_id()?) {
|
||||
ModuleDef::Trait(trait_) => Some(trait_),
|
||||
_ => None,
|
||||
})
|
||||
.flat_map(|trait_| {
|
||||
current_module
|
||||
.find_use_path(ctx.sema.db, hir::ModuleDef::Trait(trait_))
|
||||
.as_ref()
|
||||
.map(mod_path_to_ast)
|
||||
.zip(Some(trait_))
|
||||
});
|
||||
|
||||
let mut no_traits_found = true;
|
||||
for (trait_path, trait_) in found_traits.inspect(|_| no_traits_found = false) {
|
||||
|
|
|
@ -169,23 +169,28 @@ pub(crate) fn position_for_import<'a>(
|
|||
})
|
||||
}
|
||||
|
||||
fn import_assets<'a>(ctx: &'a CompletionContext, fuzzy_name: String) -> Option<ImportAssets<'a>> {
|
||||
fn import_assets(ctx: &CompletionContext, fuzzy_name: String) -> Option<ImportAssets> {
|
||||
let current_module = ctx.scope.module()?;
|
||||
if let Some(dot_receiver) = &ctx.dot_receiver {
|
||||
ImportAssets::for_fuzzy_method_call(
|
||||
current_module,
|
||||
ctx.sema.type_of_expr(dot_receiver)?,
|
||||
fuzzy_name,
|
||||
ctx.scope.clone(),
|
||||
dot_receiver.syntax().clone(),
|
||||
)
|
||||
} else {
|
||||
let fuzzy_name_length = fuzzy_name.len();
|
||||
let approximate_node = match current_module.definition_source(ctx.db).value {
|
||||
hir::ModuleSource::SourceFile(s) => s.syntax().clone(),
|
||||
hir::ModuleSource::Module(m) => m.syntax().clone(),
|
||||
hir::ModuleSource::BlockExpr(b) => b.syntax().clone(),
|
||||
};
|
||||
let assets_for_path = ImportAssets::for_fuzzy_path(
|
||||
current_module,
|
||||
ctx.path_qual.clone(),
|
||||
fuzzy_name,
|
||||
&ctx.sema,
|
||||
ctx.scope.clone(),
|
||||
approximate_node,
|
||||
)?;
|
||||
|
||||
if matches!(assets_for_path.import_candidate(), ImportCandidate::Path(_))
|
||||
|
|
|
@ -150,7 +150,7 @@ pub fn resolve_completion_edits(
|
|||
let current_crate = current_module.krate();
|
||||
|
||||
let (import_path, item_to_import) =
|
||||
items_locator::with_for_exact_name(&ctx.sema, current_crate, imported_name)
|
||||
items_locator::with_exact_name(&ctx.sema, current_crate, imported_name)
|
||||
.into_iter()
|
||||
.filter_map(|candidate| {
|
||||
current_module
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
//! Look up accessible paths for items.
|
||||
use hir::{
|
||||
AsAssocItem, AssocItem, AssocItemContainer, Crate, ItemInNs, MacroDef, ModPath, Module,
|
||||
ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, SemanticsScope, Type,
|
||||
ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, Type,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use rustc_hash::FxHashSet;
|
||||
use syntax::{ast, AstNode};
|
||||
use syntax::{ast, AstNode, SyntaxNode};
|
||||
|
||||
use crate::{
|
||||
items_locator::{self, AssocItemSearch, DEFAULT_QUERY_SEARCH_LIMIT},
|
||||
|
@ -62,38 +62,37 @@ impl NameToImport {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ImportAssets<'a> {
|
||||
pub struct ImportAssets {
|
||||
import_candidate: ImportCandidate,
|
||||
candidate_node: SyntaxNode,
|
||||
module_with_candidate: Module,
|
||||
scope: SemanticsScope<'a>,
|
||||
}
|
||||
|
||||
impl<'a> ImportAssets<'a> {
|
||||
impl ImportAssets {
|
||||
pub fn for_method_call(
|
||||
method_call: &ast::MethodCallExpr,
|
||||
sema: &'a Semantics<RootDatabase>,
|
||||
sema: &Semantics<RootDatabase>,
|
||||
) -> Option<Self> {
|
||||
let scope = sema.scope(method_call.syntax());
|
||||
let candidate_node = method_call.syntax().clone();
|
||||
Some(Self {
|
||||
import_candidate: ImportCandidate::for_method_call(sema, method_call)?,
|
||||
module_with_candidate: scope.module()?,
|
||||
scope,
|
||||
module_with_candidate: sema.scope(&candidate_node).module()?,
|
||||
candidate_node,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn for_exact_path(
|
||||
fully_qualified_path: &ast::Path,
|
||||
sema: &'a Semantics<RootDatabase>,
|
||||
sema: &Semantics<RootDatabase>,
|
||||
) -> Option<Self> {
|
||||
let syntax_under_caret = fully_qualified_path.syntax();
|
||||
if syntax_under_caret.ancestors().find_map(ast::Use::cast).is_some() {
|
||||
let candidate_node = fully_qualified_path.syntax().clone();
|
||||
if candidate_node.ancestors().find_map(ast::Use::cast).is_some() {
|
||||
return None;
|
||||
}
|
||||
let scope = sema.scope(syntax_under_caret);
|
||||
Some(Self {
|
||||
import_candidate: ImportCandidate::for_regular_path(sema, fully_qualified_path)?,
|
||||
module_with_candidate: scope.module()?,
|
||||
scope,
|
||||
module_with_candidate: sema.scope(&candidate_node).module()?,
|
||||
candidate_node,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -102,12 +101,12 @@ impl<'a> ImportAssets<'a> {
|
|||
qualifier: Option<ast::Path>,
|
||||
fuzzy_name: String,
|
||||
sema: &Semantics<RootDatabase>,
|
||||
scope: SemanticsScope<'a>,
|
||||
candidate_node: SyntaxNode,
|
||||
) -> Option<Self> {
|
||||
Some(Self {
|
||||
import_candidate: ImportCandidate::for_fuzzy_path(qualifier, fuzzy_name, sema)?,
|
||||
module_with_candidate,
|
||||
scope,
|
||||
candidate_node,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -115,7 +114,7 @@ impl<'a> ImportAssets<'a> {
|
|||
module_with_method_call: Module,
|
||||
receiver_ty: Type,
|
||||
fuzzy_method_name: String,
|
||||
scope: SemanticsScope<'a>,
|
||||
candidate_node: SyntaxNode,
|
||||
) -> Option<Self> {
|
||||
Some(Self {
|
||||
import_candidate: ImportCandidate::TraitMethod(TraitImportCandidate {
|
||||
|
@ -123,7 +122,7 @@ impl<'a> ImportAssets<'a> {
|
|||
name: NameToImport::Fuzzy(fuzzy_method_name),
|
||||
}),
|
||||
module_with_candidate: module_with_method_call,
|
||||
scope,
|
||||
candidate_node,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +155,7 @@ impl LocatedImport {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ImportAssets<'a> {
|
||||
impl ImportAssets {
|
||||
pub fn import_candidate(&self) -> &ImportCandidate {
|
||||
&self.import_candidate
|
||||
}
|
||||
|
@ -182,7 +181,7 @@ impl<'a> ImportAssets<'a> {
|
|||
prefixed: Option<PrefixKind>,
|
||||
) -> Vec<LocatedImport> {
|
||||
let items_with_candidate_name = match self.name_to_import() {
|
||||
NameToImport::Exact(exact_name) => items_locator::with_for_exact_name(
|
||||
NameToImport::Exact(exact_name) => items_locator::with_exact_name(
|
||||
sema,
|
||||
self.module_with_candidate.krate(),
|
||||
exact_name.clone(),
|
||||
|
@ -209,7 +208,7 @@ impl<'a> ImportAssets<'a> {
|
|||
}
|
||||
};
|
||||
|
||||
let scope_definitions = self.scope_definitions();
|
||||
let scope_definitions = self.scope_definitions(sema);
|
||||
self.applicable_defs(sema.db, prefixed, items_with_candidate_name)
|
||||
.into_iter()
|
||||
.filter(|import| import.import_path.len() > 1)
|
||||
|
@ -218,9 +217,9 @@ impl<'a> ImportAssets<'a> {
|
|||
.collect()
|
||||
}
|
||||
|
||||
fn scope_definitions(&self) -> FxHashSet<ScopeDef> {
|
||||
fn scope_definitions(&self, sema: &Semantics<RootDatabase>) -> FxHashSet<ScopeDef> {
|
||||
let mut scope_definitions = FxHashSet::default();
|
||||
self.scope.process_all_names(&mut |_, scope_def| {
|
||||
sema.scope(&self.candidate_node).process_all_names(&mut |_, scope_def| {
|
||||
scope_definitions.insert(scope_def);
|
||||
});
|
||||
scope_definitions
|
||||
|
|
|
@ -17,7 +17,7 @@ use rustc_hash::FxHashSet;
|
|||
|
||||
pub(crate) const DEFAULT_QUERY_SEARCH_LIMIT: usize = 40;
|
||||
|
||||
pub fn with_for_exact_name(
|
||||
pub fn with_exact_name(
|
||||
sema: &Semantics<'_, RootDatabase>,
|
||||
krate: Crate,
|
||||
exact_name: String,
|
||||
|
|
Loading…
Reference in a new issue