mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-27 14:24:08 +00:00
Merge #320
320: completion uses hir scopes r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
82e3ab02af
@ -10,32 +10,34 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) ->
|
|||||||
if !ctx.is_trivial_path {
|
if !ctx.is_trivial_path {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
let module = match &ctx.module {
|
||||||
|
Some(it) => it,
|
||||||
|
None => return Ok(()),
|
||||||
|
};
|
||||||
if let Some(fn_def) = ctx.enclosing_fn {
|
if let Some(fn_def) = ctx.enclosing_fn {
|
||||||
let scopes = hir::FnScopes::new(fn_def);
|
let function = hir::source_binder::function_from_module(ctx.db, module, fn_def);
|
||||||
|
let scopes = function.scopes(ctx.db);
|
||||||
complete_fn(acc, &scopes, ctx.offset);
|
complete_fn(acc, &scopes, ctx.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(module) = &ctx.module {
|
let module_scope = module.scope(ctx.db)?;
|
||||||
let module_scope = module.scope(ctx.db)?;
|
module_scope
|
||||||
module_scope
|
.entries()
|
||||||
.entries()
|
.filter(|(_name, res)| {
|
||||||
.filter(|(_name, res)| {
|
// Don't expose this item
|
||||||
// Don't expose this item
|
match res.import {
|
||||||
match res.import {
|
None => true,
|
||||||
None => true,
|
Some(import) => {
|
||||||
Some(import) => {
|
let range = import.range(ctx.db, module.source().file_id());
|
||||||
let range = import.range(ctx.db, module.source().file_id());
|
!range.is_subrange(&ctx.leaf.range())
|
||||||
!range.is_subrange(&ctx.leaf.range())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.for_each(|(name, res)| {
|
})
|
||||||
CompletionItem::new(CompletionKind::Reference, name.to_string())
|
.for_each(|(name, res)| {
|
||||||
.from_resolution(ctx.db, res)
|
CompletionItem::new(CompletionKind::Reference, name.to_string())
|
||||||
.add_to(acc)
|
.from_resolution(ctx.db, res)
|
||||||
});
|
.add_to(acc)
|
||||||
}
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ impl AnalysisImpl {
|
|||||||
position.file_id,
|
position.file_id,
|
||||||
name_ref.syntax(),
|
name_ref.syntax(),
|
||||||
)? {
|
)? {
|
||||||
let scope = fn_descr.scope(&*self.db);
|
let scope = fn_descr.scopes(&*self.db);
|
||||||
// First try to resolve the symbol locally
|
// First try to resolve the symbol locally
|
||||||
if let Some(entry) = scope.resolve_local_name(name_ref) {
|
if let Some(entry) = scope.resolve_local_name(name_ref) {
|
||||||
rr.add_resolution(
|
rr.add_resolution(
|
||||||
@ -294,7 +294,7 @@ impl AnalysisImpl {
|
|||||||
let mut ret = vec![(position.file_id, binding.syntax().range())];
|
let mut ret = vec![(position.file_id, binding.syntax().range())];
|
||||||
ret.extend(
|
ret.extend(
|
||||||
descr
|
descr
|
||||||
.scope(&*self.db)
|
.scopes(&*self.db)
|
||||||
.find_all_refs(binding)
|
.find_all_refs(binding)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|ref_desc| (position.file_id, ref_desc.range)),
|
.map(|ref_desc| (position.file_id, ref_desc.range)),
|
||||||
@ -322,7 +322,7 @@ impl AnalysisImpl {
|
|||||||
position.file_id,
|
position.file_id,
|
||||||
name_ref.syntax(),
|
name_ref.syntax(),
|
||||||
)?);
|
)?);
|
||||||
let scope = descr.scope(db);
|
let scope = descr.scopes(db);
|
||||||
let resolved = ctry!(scope.resolve_local_name(name_ref));
|
let resolved = ctry!(scope.resolve_local_name(name_ref));
|
||||||
let resolved = resolved.ptr().resolve(source_file);
|
let resolved = resolved.ptr().resolve(source_file);
|
||||||
let binding = ctry!(find_node_at_offset::<ast::BindPat>(
|
let binding = ctry!(find_node_at_offset::<ast::BindPat>(
|
||||||
|
@ -27,7 +27,7 @@ impl Function {
|
|||||||
Function { fn_id }
|
Function { fn_id }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scope(&self, db: &impl HirDatabase) -> Arc<FnScopes> {
|
pub fn scopes(&self, db: &impl HirDatabase) -> Arc<FnScopes> {
|
||||||
db.fn_scopes(self.fn_id)
|
db.fn_scopes(self.fn_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ pub struct ScopeData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FnScopes {
|
impl FnScopes {
|
||||||
pub fn new(fn_def: ast::FnDef) -> FnScopes {
|
pub(crate) fn new(fn_def: ast::FnDef) -> FnScopes {
|
||||||
let mut scopes = FnScopes {
|
let mut scopes = FnScopes {
|
||||||
self_param: fn_def
|
self_param: fn_def
|
||||||
.param_list()
|
.param_list()
|
||||||
|
@ -74,6 +74,16 @@ pub fn function_from_source(
|
|||||||
fn_def: ast::FnDef,
|
fn_def: ast::FnDef,
|
||||||
) -> Cancelable<Option<Function>> {
|
) -> Cancelable<Option<Function>> {
|
||||||
let module = ctry!(module_from_child_node(db, file_id, fn_def.syntax())?);
|
let module = ctry!(module_from_child_node(db, file_id, fn_def.syntax())?);
|
||||||
|
let res = function_from_module(db, &module, fn_def);
|
||||||
|
Ok(Some(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn function_from_module(
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
module: &Module,
|
||||||
|
fn_def: ast::FnDef,
|
||||||
|
) -> Function {
|
||||||
|
let file_id = module.source().file_id();
|
||||||
let file_items = db.file_items(file_id);
|
let file_items = db.file_items(file_id);
|
||||||
let item_id = file_items.id_of(file_id, fn_def.syntax());
|
let item_id = file_items.id_of(file_id, fn_def.syntax());
|
||||||
let source_item_id = SourceItemId {
|
let source_item_id = SourceItemId {
|
||||||
@ -86,7 +96,7 @@ pub fn function_from_source(
|
|||||||
module_id: module.module_id,
|
module_id: module.module_id,
|
||||||
source_item_id,
|
source_item_id,
|
||||||
};
|
};
|
||||||
Ok(Some(Function::new(def_loc.id(db))))
|
Function::new(def_loc.id(db))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn function_from_child_node(
|
pub fn function_from_child_node(
|
||||||
|
Loading…
Reference in New Issue
Block a user