Change SourceAnalyzer method resoltion API

This commit is contained in:
Florian Diebold 2019-11-01 20:01:21 +01:00
parent b29092ade3
commit 8952380884
4 changed files with 44 additions and 36 deletions

View file

@ -76,8 +76,7 @@ pub use crate::{
resolve::ScopeDef, resolve::ScopeDef,
source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
ty::{ ty::{
display::HirDisplay, method_resolution::LookupMode, ApplicationTy, CallableDef, Substs, display::HirDisplay, ApplicationTy, CallableDef, Substs, TraitRef, Ty, TypeCtor, TypeWalk,
TraitRef, Ty, TypeCtor, TypeWalk,
}, },
}; };

View file

@ -327,7 +327,30 @@ impl SourceAnalyzer {
db: &impl HirDatabase, db: &impl HirDatabase,
ty: Ty, ty: Ty,
name: Option<&Name>, name: Option<&Name>,
mode: method_resolution::LookupMode, mut callback: impl FnMut(&Ty, Function) -> Option<T>,
) -> Option<T> {
// There should be no inference vars in types passed here
// FIXME check that?
// FIXME replace Unknown by bound vars here
let canonical = crate::ty::Canonical { value: ty, num_vars: 0 };
method_resolution::iterate_method_candidates(
&canonical,
db,
&self.resolver,
name,
method_resolution::LookupMode::MethodCall,
|ty, it| match it {
AssocItem::Function(f) => callback(ty, f),
_ => None,
},
)
}
pub fn iterate_path_candidates<T>(
&self,
db: &impl HirDatabase,
ty: Ty,
name: Option<&Name>,
callback: impl FnMut(&Ty, AssocItem) -> Option<T>, callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
) -> Option<T> { ) -> Option<T> {
// There should be no inference vars in types passed here // There should be no inference vars in types passed here
@ -339,7 +362,7 @@ impl SourceAnalyzer {
db, db,
&self.resolver, &self.resolver,
name, name,
mode, method_resolution::LookupMode::Path,
callback, callback,
) )
} }

View file

@ -58,21 +58,13 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty)
fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) {
let mut seen_methods = FxHashSet::default(); let mut seen_methods = FxHashSet::default();
ctx.analyzer.iterate_method_candidates( ctx.analyzer.iterate_method_candidates(ctx.db, receiver, None, |_ty, func| {
ctx.db,
receiver,
None,
hir::LookupMode::MethodCall,
|_ty, item| {
if let hir::AssocItem::Function(func) = item {
let data = func.data(ctx.db); let data = func.data(ctx.db);
if data.has_self_param() && seen_methods.insert(data.name().clone()) { if data.has_self_param() && seen_methods.insert(data.name().clone()) {
acc.add_function(ctx, func); acc.add_function(ctx, func);
} }
}
None::<()> None::<()>
}, });
);
} }
#[cfg(test)] #[cfg(test)]

View file

@ -50,12 +50,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db), hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db),
_ => unreachable!(), _ => unreachable!(),
}; };
ctx.analyzer.iterate_method_candidates( ctx.analyzer.iterate_path_candidates(ctx.db, ty.clone(), None, |_ty, item| {
ctx.db,
ty.clone(),
None,
hir::LookupMode::Path,
|_ty, item| {
match item { match item {
hir::AssocItem::Function(func) => { hir::AssocItem::Function(func) => {
let data = func.data(ctx.db); let data = func.data(ctx.db);
@ -67,8 +62,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty), hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
} }
None::<()> None::<()>
}, });
);
// Iterate assoc types separately // Iterate assoc types separately
// FIXME: complete T::AssocType // FIXME: complete T::AssocType
let krate = ctx.module.map(|m| m.krate()); let krate = ctx.module.map(|m| m.krate());