mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Use the new Resolver API in completion
This commit is contained in:
parent
6b076f1931
commit
33ff7b56ff
@ -72,11 +72,23 @@ impl Body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// needs arbitrary_self_types to be a method... or maybe move to the def?
|
// needs arbitrary_self_types to be a method... or maybe move to the def?
|
||||||
#[allow(dead_code)]
|
pub fn resolver_for_expr(
|
||||||
pub fn resolver_for_expr(body: Arc<Body>, db: &impl HirDatabase, expr_id: ExprId) -> Resolver {
|
body: Arc<Body>,
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
expr_id: ExprId,
|
||||||
|
) -> Resolver<'static> {
|
||||||
|
let scopes = db.expr_scopes(body.owner);
|
||||||
|
resolver_for_scope(body, db, scopes.scope_for(expr_id))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resolver_for_scope(
|
||||||
|
body: Arc<Body>,
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
scope_id: Option<scope::ScopeId>,
|
||||||
|
) -> Resolver<'static> {
|
||||||
let mut r = body.owner.resolver(db);
|
let mut r = body.owner.resolver(db);
|
||||||
let scopes = db.expr_scopes(body.owner);
|
let scopes = db.expr_scopes(body.owner);
|
||||||
let scope_chain = scopes.scope_chain_for(expr_id).collect::<Vec<_>>();
|
let scope_chain = scopes.scope_chain_for(scope_id).collect::<Vec<_>>();
|
||||||
for scope in scope_chain.into_iter().rev() {
|
for scope in scope_chain.into_iter().rev() {
|
||||||
r = r.push_expr_scope(Arc::clone(&scopes), scope);
|
r = r.push_expr_scope(Arc::clone(&scopes), scope);
|
||||||
}
|
}
|
||||||
|
@ -62,25 +62,11 @@ impl ExprScopes {
|
|||||||
&self.scopes[scope].entries
|
&self.scopes[scope].entries
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scope_chain_for<'a>(&'a self, expr: ExprId) -> impl Iterator<Item = ScopeId> + 'a {
|
pub fn scope_chain_for<'a>(
|
||||||
generate(self.scope_for(expr), move |&scope| {
|
|
||||||
self.scopes[scope].parent
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resolve_local_name<'a>(
|
|
||||||
&'a self,
|
&'a self,
|
||||||
context_expr: ExprId,
|
scope: Option<ScopeId>,
|
||||||
name: Name,
|
) -> impl Iterator<Item = ScopeId> + 'a {
|
||||||
) -> Option<&'a ScopeEntry> {
|
generate(scope, move |&scope| self.scopes[scope].parent)
|
||||||
// TODO replace by Resolver::resolve_name
|
|
||||||
let mut shadowed = FxHashSet::default();
|
|
||||||
let ret = self
|
|
||||||
.scope_chain_for(context_expr)
|
|
||||||
.flat_map(|scope| self.entries(scope).iter())
|
|
||||||
.filter(|entry| shadowed.insert(entry.name()))
|
|
||||||
.find(|entry| entry.name() == &name);
|
|
||||||
ret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn root_scope(&mut self) -> ScopeId {
|
fn root_scope(&mut self) -> ScopeId {
|
||||||
@ -123,7 +109,7 @@ impl ExprScopes {
|
|||||||
self.scope_for.insert(node, scope);
|
self.scope_for.insert(node, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scope_for(&self, expr: ExprId) -> Option<ScopeId> {
|
pub fn scope_for(&self, expr: ExprId) -> Option<ScopeId> {
|
||||||
self.scope_for.get(&expr).map(|&scope| scope)
|
self.scope_for.get(&expr).map(|&scope| scope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,18 +137,14 @@ impl ScopeEntryWithSyntax {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ScopesWithSyntaxMapping {
|
impl ScopesWithSyntaxMapping {
|
||||||
pub fn scope_chain<'a>(&'a self, node: &SyntaxNode) -> impl Iterator<Item = ScopeId> + 'a {
|
fn scope_chain<'a>(&'a self, node: &SyntaxNode) -> impl Iterator<Item = ScopeId> + 'a {
|
||||||
generate(self.scope_for(node), move |&scope| {
|
generate(self.scope_for(node), move |&scope| {
|
||||||
self.scopes.scopes[scope].parent
|
self.scopes.scopes[scope].parent
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scope_chain_for_offset<'a>(
|
pub fn scope_for_offset<'a>(&'a self, offset: TextUnit) -> Option<ScopeId> {
|
||||||
&'a self,
|
self.scopes
|
||||||
offset: TextUnit,
|
|
||||||
) -> impl Iterator<Item = ScopeId> + 'a {
|
|
||||||
let scope = self
|
|
||||||
.scopes
|
|
||||||
.scope_for
|
.scope_for
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(id, scope)| Some((self.syntax_mapping.expr_syntax(*id)?, scope)))
|
.filter_map(|(id, scope)| Some((self.syntax_mapping.expr_syntax(*id)?, scope)))
|
||||||
@ -173,9 +155,7 @@ impl ScopesWithSyntaxMapping {
|
|||||||
ptr.range().len(),
|
ptr.range().len(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|(ptr, scope)| self.adjust(ptr, *scope, offset));
|
.map(|(ptr, scope)| self.adjust(ptr, *scope, offset))
|
||||||
|
|
||||||
generate(scope, move |&scope| self.scopes.scopes[scope].parent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: during completion, cursor might be outside of any particular
|
// XXX: during completion, cursor might be outside of any particular
|
||||||
|
@ -81,6 +81,15 @@ pub struct PerNs<T> {
|
|||||||
pub values: Option<T>,
|
pub values: Option<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Default for PerNs<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
PerNs {
|
||||||
|
types: None,
|
||||||
|
values: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> PerNs<T> {
|
impl<T> PerNs<T> {
|
||||||
pub fn none() -> PerNs<T> {
|
pub fn none() -> PerNs<T> {
|
||||||
PerNs {
|
PerNs {
|
||||||
|
@ -89,8 +89,20 @@ impl Resolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_names(&self) -> FxHashMap<Name, Resolution> {
|
pub fn all_names(&self) -> FxHashMap<Name, PerNs<Resolution>> {
|
||||||
unimplemented!()
|
let mut names = FxHashMap::default();
|
||||||
|
for scope in &self.scopes {
|
||||||
|
scope.collect_names(&mut |name, res| {
|
||||||
|
let current: &mut PerNs<Resolution> = names.entry(name).or_default();
|
||||||
|
if current.types.is_none() {
|
||||||
|
current.types = res.types;
|
||||||
|
}
|
||||||
|
if current.values.is_none() {
|
||||||
|
current.values = res.values;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
names
|
||||||
}
|
}
|
||||||
|
|
||||||
fn module(&self) -> Option<(&ItemMap, Module)> {
|
fn module(&self) -> Option<(&ItemMap, Module)> {
|
||||||
@ -175,4 +187,45 @@ impl Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collect_names(&self, f: &mut FnMut(Name, PerNs<Resolution>)) {
|
||||||
|
match self {
|
||||||
|
Scope::ModuleScope(m) => {
|
||||||
|
m.item_map[m.module.module_id]
|
||||||
|
.entries()
|
||||||
|
.for_each(|(name, res)| {
|
||||||
|
f(name.clone(), res.def.map(|def| Resolution::Def { def }));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Scope::ModuleScopeRef(m) => {
|
||||||
|
m.item_map[m.module.module_id]
|
||||||
|
.entries()
|
||||||
|
.for_each(|(name, res)| {
|
||||||
|
f(name.clone(), res.def.map(|def| Resolution::Def { def }));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Scope::GenericParams(gp) => {
|
||||||
|
for param in &gp.params {
|
||||||
|
f(
|
||||||
|
param.name.clone(),
|
||||||
|
PerNs::types(Resolution::GenericParam { idx: param.idx }),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Scope::ImplBlockScope(i) => {
|
||||||
|
f(
|
||||||
|
Name::self_type(),
|
||||||
|
PerNs::types(Resolution::SelfType(i.clone())),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Scope::ExprScope(e) => {
|
||||||
|
e.expr_scopes.entries(e.scope_id).iter().for_each(|e| {
|
||||||
|
f(
|
||||||
|
e.name().clone(),
|
||||||
|
PerNs::values(Resolution::LocalBinding { pat: e.pat() }),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,14 @@ use ra_db::{FileId, FilePosition};
|
|||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
SmolStr, TextRange, SyntaxNode,
|
SmolStr, TextRange, SyntaxNode,
|
||||||
ast::{self, AstNode, NameOwner},
|
ast::{self, AstNode, NameOwner},
|
||||||
algo::find_node_at_offset,
|
algo::{find_node_at_offset, find_leaf_at_offset},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
HirDatabase, Function, ModuleDef, Struct, Enum,
|
HirDatabase, Function, ModuleDef, Struct, Enum,
|
||||||
AsName, Module, HirFileId, Crate, Trait, Resolver,
|
AsName, Module, HirFileId, Crate, Trait, Resolver,
|
||||||
ids::{LocationCtx, SourceFileItemId},
|
ids::{LocationCtx, SourceFileItemId},
|
||||||
|
expr
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Locates the module by `FileId`. Picks topmost module in the file.
|
/// Locates the module by `FileId`. Picks topmost module in the file.
|
||||||
@ -202,7 +203,29 @@ pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, Te
|
|||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> Resolver<'static> {
|
||||||
pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> Resolver {
|
let file = db.parse(position.file_id);
|
||||||
unimplemented!()
|
find_leaf_at_offset(file.syntax(), position.offset)
|
||||||
|
.find_map(|node| {
|
||||||
|
node.ancestors().find_map(|node| {
|
||||||
|
if ast::Expr::cast(node).is_some() || ast::Block::cast(node).is_some() {
|
||||||
|
if let Some(func) = function_from_child_node(db, position.file_id, node) {
|
||||||
|
let scopes = func.scopes(db);
|
||||||
|
let scope = scopes.scope_for_offset(position.offset);
|
||||||
|
Some(expr::resolver_for_scope(func.body(db), db, scope))
|
||||||
|
} else {
|
||||||
|
// TODO const/static/array length
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else if let Some(module) = ast::Module::cast(node) {
|
||||||
|
Some(module_from_declaration(db, position.file_id, module)?.resolver(db))
|
||||||
|
} else if let Some(_) = ast::SourceFile::cast(node) {
|
||||||
|
Some(module_from_source(db, position.file_id.into(), None)?.resolver(db))
|
||||||
|
} else {
|
||||||
|
// TODO add missing cases
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,13 @@ use crate::{
|
|||||||
use hir::Docs;
|
use hir::Docs;
|
||||||
|
|
||||||
pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
|
pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
let (path, module) = match (&ctx.path_prefix, &ctx.module) {
|
let path = match &ctx.path_prefix {
|
||||||
(Some(path), Some(module)) => (path.clone(), module),
|
Some(path) => path.clone(),
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
let def_id = match module.resolve_path(ctx.db, &path).take_types() {
|
let def = match ctx.resolver.resolve_path(ctx.db, &path).take_types() {
|
||||||
Some(it) => it,
|
Some(Resolution::Def { def }) => def,
|
||||||
None => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
match def_id {
|
match def_id {
|
||||||
hir::ModuleDef::Module(module) => {
|
hir::ModuleDef::Module(module) => {
|
||||||
@ -24,7 +24,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
|
|||||||
ctx.source_range(),
|
ctx.source_range(),
|
||||||
name.to_string(),
|
name.to_string(),
|
||||||
)
|
)
|
||||||
.from_resolution(ctx, res)
|
.from_resolution(ctx, &res.def.map(|def| hir::Resolution::Def { def }))
|
||||||
.add_to(acc);
|
.add_to(acc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,61 +1,32 @@
|
|||||||
use rustc_hash::FxHashSet;
|
use crate::completion::{CompletionItem, Completions, CompletionKind, CompletionContext};
|
||||||
use ra_syntax::ast::AstNode;
|
|
||||||
use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext};
|
|
||||||
|
|
||||||
pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
|
pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
if !ctx.is_trivial_path {
|
if !ctx.is_trivial_path {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let module = match &ctx.module {
|
let names = ctx.resolver.all_names();
|
||||||
Some(it) => it,
|
|
||||||
None => return,
|
|
||||||
};
|
|
||||||
if let Some(function) = &ctx.function {
|
|
||||||
let scopes = function.scopes(ctx.db);
|
|
||||||
complete_fn(acc, &scopes, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
let module_scope = module.scope(ctx.db);
|
// let module_scope = module.scope(ctx.db);
|
||||||
module_scope
|
names
|
||||||
.entries()
|
.into_iter()
|
||||||
.filter(|(_name, res)| {
|
// FIXME check tests
|
||||||
// For cases like `use self::foo<|>` don't suggest foo itself.
|
// .filter(|(_name, res)| {
|
||||||
match res.import {
|
// // For cases like `use self::foo<|>` don't suggest foo itself.
|
||||||
None => true,
|
// match res.import {
|
||||||
Some(import) => {
|
// None => true,
|
||||||
let source = module.import_source(ctx.db, import);
|
// Some(import) => {
|
||||||
!source.syntax().range().is_subrange(&ctx.leaf.range())
|
// let source = module.import_source(ctx.db, import);
|
||||||
}
|
// !source.syntax().range().is_subrange(&ctx.leaf.range())
|
||||||
}
|
// }
|
||||||
})
|
// }
|
||||||
|
// })
|
||||||
.for_each(|(name, res)| {
|
.for_each(|(name, res)| {
|
||||||
CompletionItem::new(
|
CompletionItem::new(
|
||||||
CompletionKind::Reference,
|
CompletionKind::Reference,
|
||||||
ctx.source_range(),
|
ctx.source_range(),
|
||||||
name.to_string(),
|
name.to_string(),
|
||||||
)
|
)
|
||||||
.from_resolution(ctx, res)
|
.from_resolution(ctx, &res)
|
||||||
.add_to(acc)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn complete_fn(
|
|
||||||
acc: &mut Completions,
|
|
||||||
scopes: &hir::ScopesWithSyntaxMapping,
|
|
||||||
ctx: &CompletionContext,
|
|
||||||
) {
|
|
||||||
let mut shadowed = FxHashSet::default();
|
|
||||||
scopes
|
|
||||||
.scope_chain_for_offset(ctx.offset)
|
|
||||||
.flat_map(|scope| scopes.scopes.entries(scope).iter())
|
|
||||||
.filter(|entry| shadowed.insert(entry.name()))
|
|
||||||
.for_each(|entry| {
|
|
||||||
CompletionItem::new(
|
|
||||||
CompletionKind::Reference,
|
|
||||||
ctx.source_range(),
|
|
||||||
entry.name().to_string(),
|
|
||||||
)
|
|
||||||
.kind(CompletionItemKind::Binding)
|
|
||||||
.add_to(acc)
|
.add_to(acc)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use ra_syntax::{
|
|||||||
algo::{find_leaf_at_offset, find_covering_node, find_node_at_offset},
|
algo::{find_leaf_at_offset, find_covering_node, find_node_at_offset},
|
||||||
SyntaxKind::*,
|
SyntaxKind::*,
|
||||||
};
|
};
|
||||||
use hir::source_binder;
|
use hir::{source_binder, Resolver};
|
||||||
|
|
||||||
use crate::{db, FilePosition};
|
use crate::{db, FilePosition};
|
||||||
|
|
||||||
@ -16,6 +16,7 @@ pub(crate) struct CompletionContext<'a> {
|
|||||||
pub(super) db: &'a db::RootDatabase,
|
pub(super) db: &'a db::RootDatabase,
|
||||||
pub(super) offset: TextUnit,
|
pub(super) offset: TextUnit,
|
||||||
pub(super) leaf: &'a SyntaxNode,
|
pub(super) leaf: &'a SyntaxNode,
|
||||||
|
pub(super) resolver: Resolver<'static>,
|
||||||
pub(super) module: Option<hir::Module>,
|
pub(super) module: Option<hir::Module>,
|
||||||
pub(super) function: Option<hir::Function>,
|
pub(super) function: Option<hir::Function>,
|
||||||
pub(super) function_syntax: Option<&'a ast::FnDef>,
|
pub(super) function_syntax: Option<&'a ast::FnDef>,
|
||||||
@ -42,12 +43,14 @@ impl<'a> CompletionContext<'a> {
|
|||||||
original_file: &'a SourceFile,
|
original_file: &'a SourceFile,
|
||||||
position: FilePosition,
|
position: FilePosition,
|
||||||
) -> Option<CompletionContext<'a>> {
|
) -> Option<CompletionContext<'a>> {
|
||||||
|
let resolver = source_binder::resolver_for_position(db, position);
|
||||||
let module = source_binder::module_from_position(db, position);
|
let module = source_binder::module_from_position(db, position);
|
||||||
let leaf = find_leaf_at_offset(original_file.syntax(), position.offset).left_biased()?;
|
let leaf = find_leaf_at_offset(original_file.syntax(), position.offset).left_biased()?;
|
||||||
let mut ctx = CompletionContext {
|
let mut ctx = CompletionContext {
|
||||||
db,
|
db,
|
||||||
leaf,
|
leaf,
|
||||||
offset: position.offset,
|
offset: position.offset,
|
||||||
|
resolver,
|
||||||
module,
|
module,
|
||||||
function: None,
|
function: None,
|
||||||
function_syntax: None,
|
function_syntax: None,
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use hir::{Docs, Documentation};
|
use hir::{Docs, Documentation, PerNs, Resolution};
|
||||||
use ra_syntax::TextRange;
|
use ra_syntax::{
|
||||||
|
TextRange,
|
||||||
|
};
|
||||||
use ra_text_edit::TextEdit;
|
use ra_text_edit::TextEdit;
|
||||||
use test_utils::tested_by;
|
use test_utils::tested_by;
|
||||||
|
|
||||||
@ -48,6 +50,7 @@ pub enum CompletionItemKind {
|
|||||||
Trait,
|
Trait,
|
||||||
TypeAlias,
|
TypeAlias,
|
||||||
Method,
|
Method,
|
||||||
|
TypeParam,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
@ -207,23 +210,38 @@ impl Builder {
|
|||||||
pub(super) fn from_resolution(
|
pub(super) fn from_resolution(
|
||||||
mut self,
|
mut self,
|
||||||
ctx: &CompletionContext,
|
ctx: &CompletionContext,
|
||||||
resolution: &hir::Resolution,
|
resolution: &PerNs<Resolution>,
|
||||||
) -> Builder {
|
) -> Builder {
|
||||||
let def = resolution.def.take_types().or(resolution.def.take_values());
|
use hir::ModuleDef::*;
|
||||||
|
|
||||||
|
let def = resolution
|
||||||
|
.as_ref()
|
||||||
|
.take_types()
|
||||||
|
.or(resolution.as_ref().take_values());
|
||||||
let def = match def {
|
let def = match def {
|
||||||
None => return self,
|
None => return self,
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
};
|
};
|
||||||
let (kind, docs) = match def {
|
let (kind, docs) = match def {
|
||||||
hir::ModuleDef::Module(it) => (CompletionItemKind::Module, it.docs(ctx.db)),
|
Resolution::Def { def: Module(it) } => (CompletionItemKind::Module, it.docs(ctx.db)),
|
||||||
hir::ModuleDef::Function(func) => return self.from_function(ctx, func),
|
Resolution::Def {
|
||||||
hir::ModuleDef::Struct(it) => (CompletionItemKind::Struct, it.docs(ctx.db)),
|
def: Function(func),
|
||||||
hir::ModuleDef::Enum(it) => (CompletionItemKind::Enum, it.docs(ctx.db)),
|
} => return self.from_function(ctx, *func),
|
||||||
hir::ModuleDef::EnumVariant(it) => (CompletionItemKind::EnumVariant, it.docs(ctx.db)),
|
Resolution::Def { def: Struct(it) } => (CompletionItemKind::Struct, it.docs(ctx.db)),
|
||||||
hir::ModuleDef::Const(it) => (CompletionItemKind::Const, it.docs(ctx.db)),
|
Resolution::Def { def: Enum(it) } => (CompletionItemKind::Enum, it.docs(ctx.db)),
|
||||||
hir::ModuleDef::Static(it) => (CompletionItemKind::Static, it.docs(ctx.db)),
|
Resolution::Def {
|
||||||
hir::ModuleDef::Trait(it) => (CompletionItemKind::Trait, it.docs(ctx.db)),
|
def: EnumVariant(it),
|
||||||
hir::ModuleDef::Type(it) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)),
|
} => (CompletionItemKind::EnumVariant, it.docs(ctx.db)),
|
||||||
|
Resolution::Def { def: Const(it) } => (CompletionItemKind::Const, it.docs(ctx.db)),
|
||||||
|
Resolution::Def { def: Static(it) } => (CompletionItemKind::Static, it.docs(ctx.db)),
|
||||||
|
Resolution::Def { def: Trait(it) } => (CompletionItemKind::Trait, it.docs(ctx.db)),
|
||||||
|
Resolution::Def { def: Type(it) } => (CompletionItemKind::TypeAlias, it.docs(ctx.db)),
|
||||||
|
Resolution::GenericParam { .. } => (CompletionItemKind::TypeParam, None),
|
||||||
|
Resolution::LocalBinding { .. } => (CompletionItemKind::Binding, None),
|
||||||
|
Resolution::SelfType { .. } => (
|
||||||
|
CompletionItemKind::TypeParam, // (does this need its own kind?)
|
||||||
|
None,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
self.kind = Some(kind);
|
self.kind = Some(kind);
|
||||||
self.documentation = docs;
|
self.documentation = docs;
|
||||||
|
@ -1,10 +1,24 @@
|
|||||||
---
|
---
|
||||||
created: "2019-01-23T05:27:32.422259+00:00"
|
created: "2019-01-27T20:17:10.051725945+00:00"
|
||||||
creator: insta@0.4.0
|
creator: insta@0.5.2
|
||||||
expression: kind_completions
|
expression: kind_completions
|
||||||
source: crates/ra_ide_api/src/completion/completion_item.rs
|
source: crates/ra_ide_api/src/completion/completion_item.rs
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
CompletionItem {
|
||||||
|
completion_kind: Reference,
|
||||||
|
label: "Self",
|
||||||
|
kind: Some(
|
||||||
|
TypeParam
|
||||||
|
),
|
||||||
|
detail: None,
|
||||||
|
documentation: None,
|
||||||
|
lookup: None,
|
||||||
|
insert_text: None,
|
||||||
|
insert_text_format: PlainText,
|
||||||
|
source_range: [25; 25),
|
||||||
|
text_edit: None
|
||||||
|
},
|
||||||
CompletionItem {
|
CompletionItem {
|
||||||
completion_kind: Reference,
|
completion_kind: Reference,
|
||||||
label: "self",
|
label: "self",
|
||||||
|
@ -70,6 +70,7 @@ impl Conv for CompletionItemKind {
|
|||||||
CompletionItemKind::Const => Constant,
|
CompletionItemKind::Const => Constant,
|
||||||
CompletionItemKind::Static => Value,
|
CompletionItemKind::Static => Value,
|
||||||
CompletionItemKind::Method => Method,
|
CompletionItemKind::Method => Method,
|
||||||
|
CompletionItemKind::TypeParam => TypeParameter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user