mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 05:15:04 +00:00
Added basic support for completing fn
for trait impl.
This commit is contained in:
parent
2fb8a46122
commit
e3cda83f90
3 changed files with 116 additions and 0 deletions
|
@ -15,6 +15,7 @@ mod complete_path;
|
||||||
mod complete_scope;
|
mod complete_scope;
|
||||||
mod complete_postfix;
|
mod complete_postfix;
|
||||||
mod complete_macro_in_item_position;
|
mod complete_macro_in_item_position;
|
||||||
|
mod complete_impl_fn;
|
||||||
|
|
||||||
use ra_db::SourceDatabase;
|
use ra_db::SourceDatabase;
|
||||||
|
|
||||||
|
@ -73,5 +74,7 @@ pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Opti
|
||||||
complete_pattern::complete_pattern(&mut acc, &ctx);
|
complete_pattern::complete_pattern(&mut acc, &ctx);
|
||||||
complete_postfix::complete_postfix(&mut acc, &ctx);
|
complete_postfix::complete_postfix(&mut acc, &ctx);
|
||||||
complete_macro_in_item_position::complete_macro_in_item_position(&mut acc, &ctx);
|
complete_macro_in_item_position::complete_macro_in_item_position(&mut acc, &ctx);
|
||||||
|
complete_impl_fn::complete_impl_fn(&mut acc, &ctx);
|
||||||
|
|
||||||
Some(acc)
|
Some(acc)
|
||||||
}
|
}
|
||||||
|
|
80
crates/ra_ide/src/completion/complete_impl_fn.rs
Normal file
80
crates/ra_ide/src/completion/complete_impl_fn.rs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
|
||||||
|
use crate::completion::{CompletionContext, Completions};
|
||||||
|
|
||||||
|
use hir::{ self, db::HirDatabase, HasSource };
|
||||||
|
|
||||||
|
use ra_syntax::{ ast, ast::AstNode };
|
||||||
|
|
||||||
|
pub(crate) fn complete_impl_fn(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
|
let impl_trait = ast::ItemList::cast(ctx.token.parent())
|
||||||
|
.and_then(|item_list| item_list.syntax().parent())
|
||||||
|
.and_then(|item_list_parent| ast::ImplBlock::cast(item_list_parent))
|
||||||
|
.and_then(|impl_block| resolve_target_trait(ctx.db, &ctx.analyzer, &impl_block));
|
||||||
|
|
||||||
|
if let Some(x) = &impl_trait {
|
||||||
|
for trait_item in x.0.items(ctx.db) {
|
||||||
|
match trait_item {
|
||||||
|
hir::AssocItem::Function(f) => acc.add_function_impl(ctx, f),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve_target_trait(
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
analyzer: &hir::SourceAnalyzer,
|
||||||
|
impl_block: &ast::ImplBlock
|
||||||
|
) -> Option<(hir::Trait, ast::TraitDef)> {
|
||||||
|
let ast_path = impl_block
|
||||||
|
.target_trait()
|
||||||
|
.map(|it| it.syntax().clone())
|
||||||
|
.and_then(ast::PathType::cast)?
|
||||||
|
.path()?;
|
||||||
|
|
||||||
|
match analyzer.resolve_path(db, &ast_path) {
|
||||||
|
Some(hir::PathResolution::Def(hir::ModuleDef::Trait(def))) => {
|
||||||
|
Some((def, def.source(db).value))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::completion::{do_completion, CompletionItem, CompletionKind};
|
||||||
|
use insta::assert_debug_snapshot;
|
||||||
|
|
||||||
|
fn complete(code: &str) -> Vec<CompletionItem> {
|
||||||
|
do_completion(code, CompletionKind::Reference)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn single_function() {
|
||||||
|
let completions = complete(
|
||||||
|
r"
|
||||||
|
trait Test {
|
||||||
|
fn foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct T1;
|
||||||
|
|
||||||
|
impl Test for T1 {
|
||||||
|
<|>
|
||||||
|
}
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_debug_snapshot!(completions, @r###"
|
||||||
|
[
|
||||||
|
CompletionItem {
|
||||||
|
label: "fn foo()",
|
||||||
|
source_range: [138; 138),
|
||||||
|
delete: [138; 138),
|
||||||
|
insert: "fn foo() { $0 }",
|
||||||
|
kind: Function,
|
||||||
|
lookup: "foo",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
}
|
|
@ -129,6 +129,39 @@ impl Completions {
|
||||||
self.add_function_with_name(ctx, None, func)
|
self.add_function_with_name(ctx, None, func)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn add_function_impl(&mut self, ctx: &CompletionContext, func: hir::Function) {
|
||||||
|
use crate::display::FunctionSignature;
|
||||||
|
|
||||||
|
let display = FunctionSignature::from_hir(ctx.db, func.clone());
|
||||||
|
|
||||||
|
let func_name = func.name(ctx.db);
|
||||||
|
|
||||||
|
let mut builder = CompletionItem::new(
|
||||||
|
CompletionKind::Reference,
|
||||||
|
ctx.source_range(),
|
||||||
|
format!("fn {}()", func_name.to_string()))
|
||||||
|
.set_documentation(func.docs(ctx.db));
|
||||||
|
|
||||||
|
let completion_kind = if func.has_self_param(ctx.db) {
|
||||||
|
CompletionItemKind::Method
|
||||||
|
} else {
|
||||||
|
CompletionItemKind::Function
|
||||||
|
};
|
||||||
|
|
||||||
|
let snippet = {
|
||||||
|
let mut s = format!("{}", display);
|
||||||
|
s.push_str(" { $0 }");
|
||||||
|
s
|
||||||
|
};
|
||||||
|
|
||||||
|
builder = builder
|
||||||
|
.insert_text(snippet)
|
||||||
|
.kind(completion_kind)
|
||||||
|
.lookup_by(func_name.to_string());
|
||||||
|
|
||||||
|
self.add(builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
fn guess_macro_braces(&self, macro_name: &str, docs: &str) -> &'static str {
|
fn guess_macro_braces(&self, macro_name: &str, docs: &str) -> &'static str {
|
||||||
let mut votes = [0, 0, 0];
|
let mut votes = [0, 0, 0];
|
||||||
for (idx, s) in docs.match_indices(¯o_name) {
|
for (idx, s) in docs.match_indices(¯o_name) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue