mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
Merge #1973
1973: add <> for type aliases as well r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
afc871199d
2 changed files with 85 additions and 57 deletions
|
@ -71,7 +71,7 @@ pub use self::{
|
||||||
either::Either,
|
either::Either,
|
||||||
expr::ExprScopes,
|
expr::ExprScopes,
|
||||||
from_source::FromSource,
|
from_source::FromSource,
|
||||||
generics::{GenericParam, GenericParams, HasGenericParams},
|
generics::{GenericDef, GenericParam, GenericParams, HasGenericParams},
|
||||||
ids::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile},
|
ids::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile},
|
||||||
impl_block::ImplBlock,
|
impl_block::ImplBlock,
|
||||||
name::Name,
|
name::Name,
|
||||||
|
|
|
@ -44,48 +44,56 @@ impl Completions {
|
||||||
) {
|
) {
|
||||||
use hir::ModuleDef::*;
|
use hir::ModuleDef::*;
|
||||||
|
|
||||||
let mut completion_kind = CompletionKind::Reference;
|
let completion_kind = match resolution {
|
||||||
let (kind, docs) = match resolution {
|
ScopeDef::ModuleDef(BuiltinType(..)) => CompletionKind::BuiltinType,
|
||||||
ScopeDef::ModuleDef(Module(it)) => (CompletionItemKind::Module, it.docs(ctx.db)),
|
_ => CompletionKind::Reference,
|
||||||
|
};
|
||||||
|
|
||||||
|
let kind = match resolution {
|
||||||
|
ScopeDef::ModuleDef(Module(..)) => CompletionItemKind::Module,
|
||||||
ScopeDef::ModuleDef(Function(func)) => {
|
ScopeDef::ModuleDef(Function(func)) => {
|
||||||
return self.add_function_with_name(ctx, Some(local_name), *func);
|
return self.add_function_with_name(ctx, Some(local_name), *func);
|
||||||
}
|
}
|
||||||
ScopeDef::ModuleDef(Adt(adt)) => {
|
ScopeDef::ModuleDef(Adt(hir::Adt::Struct(_))) => CompletionItemKind::Struct,
|
||||||
return self.add_adt_with_name(ctx, local_name, *adt);
|
// FIXME: add CompletionItemKind::Union
|
||||||
}
|
ScopeDef::ModuleDef(Adt(hir::Adt::Union(_))) => CompletionItemKind::Struct,
|
||||||
ScopeDef::ModuleDef(EnumVariant(it)) => {
|
ScopeDef::ModuleDef(Adt(hir::Adt::Enum(_))) => CompletionItemKind::Enum,
|
||||||
(CompletionItemKind::EnumVariant, it.docs(ctx.db))
|
|
||||||
}
|
ScopeDef::ModuleDef(EnumVariant(..)) => CompletionItemKind::EnumVariant,
|
||||||
ScopeDef::ModuleDef(Const(it)) => (CompletionItemKind::Const, it.docs(ctx.db)),
|
ScopeDef::ModuleDef(Const(..)) => CompletionItemKind::Const,
|
||||||
ScopeDef::ModuleDef(Static(it)) => (CompletionItemKind::Static, it.docs(ctx.db)),
|
ScopeDef::ModuleDef(Static(..)) => CompletionItemKind::Static,
|
||||||
ScopeDef::ModuleDef(Trait(it)) => (CompletionItemKind::Trait, it.docs(ctx.db)),
|
ScopeDef::ModuleDef(Trait(..)) => CompletionItemKind::Trait,
|
||||||
ScopeDef::ModuleDef(TypeAlias(it)) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)),
|
ScopeDef::ModuleDef(TypeAlias(..)) => CompletionItemKind::TypeAlias,
|
||||||
ScopeDef::ModuleDef(BuiltinType(..)) => {
|
ScopeDef::ModuleDef(BuiltinType(..)) => CompletionItemKind::BuiltinType,
|
||||||
completion_kind = CompletionKind::BuiltinType;
|
ScopeDef::GenericParam(..) => CompletionItemKind::TypeParam,
|
||||||
(CompletionItemKind::BuiltinType, None)
|
ScopeDef::LocalBinding(..) => CompletionItemKind::Binding,
|
||||||
}
|
// (does this need its own kind?)
|
||||||
ScopeDef::GenericParam(..) => (CompletionItemKind::TypeParam, None),
|
ScopeDef::AdtSelfType(..) | ScopeDef::ImplSelfType(..) => CompletionItemKind::TypeParam,
|
||||||
ScopeDef::LocalBinding(..) => (CompletionItemKind::Binding, None),
|
|
||||||
ScopeDef::AdtSelfType(..) | ScopeDef::ImplSelfType(..) => (
|
|
||||||
CompletionItemKind::TypeParam, // (does this need its own kind?)
|
|
||||||
None,
|
|
||||||
),
|
|
||||||
ScopeDef::MacroDef(mac) => {
|
ScopeDef::MacroDef(mac) => {
|
||||||
self.add_macro(ctx, Some(local_name), *mac);
|
return self.add_macro(ctx, Some(local_name), *mac);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
ScopeDef::Unknown => {
|
ScopeDef::Unknown => {
|
||||||
self.add(CompletionItem::new(
|
return self.add(CompletionItem::new(
|
||||||
CompletionKind::Reference,
|
CompletionKind::Reference,
|
||||||
ctx.source_range(),
|
ctx.source_range(),
|
||||||
local_name,
|
local_name,
|
||||||
));
|
));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let docs = match resolution {
|
||||||
|
ScopeDef::ModuleDef(Module(it)) => it.docs(ctx.db),
|
||||||
|
ScopeDef::ModuleDef(Adt(it)) => it.docs(ctx.db),
|
||||||
|
ScopeDef::ModuleDef(EnumVariant(it)) => it.docs(ctx.db),
|
||||||
|
ScopeDef::ModuleDef(Const(it)) => it.docs(ctx.db),
|
||||||
|
ScopeDef::ModuleDef(Static(it)) => it.docs(ctx.db),
|
||||||
|
ScopeDef::ModuleDef(Trait(it)) => it.docs(ctx.db),
|
||||||
|
ScopeDef::ModuleDef(TypeAlias(it)) => it.docs(ctx.db),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
let mut completion_item =
|
let mut completion_item =
|
||||||
CompletionItem::new(completion_kind, ctx.source_range(), local_name);
|
CompletionItem::new(completion_kind, ctx.source_range(), local_name.clone());
|
||||||
if let ScopeDef::LocalBinding(pat_id) = resolution {
|
if let ScopeDef::LocalBinding(pat_id) = resolution {
|
||||||
let ty = ctx
|
let ty = ctx
|
||||||
.analyzer
|
.analyzer
|
||||||
|
@ -94,6 +102,25 @@ impl Completions {
|
||||||
.map(|t| t.display(ctx.db).to_string());
|
.map(|t| t.display(ctx.db).to_string());
|
||||||
completion_item = completion_item.set_detail(ty);
|
completion_item = completion_item.set_detail(ty);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// If not an import, add parenthesis automatically.
|
||||||
|
if ctx.is_path_type
|
||||||
|
&& !ctx.has_type_args
|
||||||
|
&& ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis")
|
||||||
|
{
|
||||||
|
let generic_def: Option<hir::GenericDef> = match resolution {
|
||||||
|
ScopeDef::ModuleDef(Adt(it)) => Some((*it).into()),
|
||||||
|
ScopeDef::ModuleDef(TypeAlias(it)) => Some((*it).into()),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
if let Some(def) = generic_def {
|
||||||
|
if has_non_default_type_params(def, ctx.db) {
|
||||||
|
tested_by!(inserts_angle_brackets_for_generics);
|
||||||
|
completion_item = completion_item.insert_snippet(format!("{}<$0>", local_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
completion_item.kind(kind).set_documentation(docs).add_to(self)
|
completion_item.kind(kind).set_documentation(docs).add_to(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,32 +196,6 @@ impl Completions {
|
||||||
self.add(builder)
|
self.add(builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_adt_with_name(&mut self, ctx: &CompletionContext, name: String, adt: hir::Adt) {
|
|
||||||
let mut builder =
|
|
||||||
CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.clone());
|
|
||||||
|
|
||||||
let kind = match adt {
|
|
||||||
hir::Adt::Struct(_) => CompletionItemKind::Struct,
|
|
||||||
// FIXME: add CompletionItemKind::Union
|
|
||||||
hir::Adt::Union(_) => CompletionItemKind::Struct,
|
|
||||||
hir::Adt::Enum(_) => CompletionItemKind::Enum,
|
|
||||||
};
|
|
||||||
let docs = adt.docs(ctx.db);
|
|
||||||
|
|
||||||
// If not an import, add parenthesis automatically.
|
|
||||||
if ctx.is_path_type
|
|
||||||
&& !ctx.has_type_args
|
|
||||||
&& ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis")
|
|
||||||
{
|
|
||||||
if has_non_default_type_params(adt, ctx.db) {
|
|
||||||
tested_by!(inserts_angle_brackets_for_generics);
|
|
||||||
builder = builder.insert_snippet(format!("{}<$0>", name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.kind(kind).set_documentation(docs).add_to(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn add_const(&mut self, ctx: &CompletionContext, constant: hir::Const) {
|
pub(crate) fn add_const(&mut self, ctx: &CompletionContext, constant: hir::Const) {
|
||||||
let ast_node = constant.source(ctx.db).ast;
|
let ast_node = constant.source(ctx.db).ast;
|
||||||
let name = match ast_node.name() {
|
let name = match ast_node.name() {
|
||||||
|
@ -243,8 +244,8 @@ impl Completions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_non_default_type_params(adt: hir::Adt, db: &db::RootDatabase) -> bool {
|
fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool {
|
||||||
let subst = db.generic_defaults(adt.into());
|
let subst = db.generic_defaults(def);
|
||||||
subst.iter().any(|ty| ty == &Ty::Unknown)
|
subst.iter().any(|ty| ty == &Ty::Unknown)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,6 +447,33 @@ mod tests {
|
||||||
]
|
]
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
|
assert_debug_snapshot!(
|
||||||
|
do_reference_completion(
|
||||||
|
r"
|
||||||
|
type Vec<T> = (T,);
|
||||||
|
fn foo(xs: Ve<|>)
|
||||||
|
"
|
||||||
|
),
|
||||||
|
@r###"
|
||||||
|
[
|
||||||
|
CompletionItem {
|
||||||
|
label: "Vec",
|
||||||
|
source_range: [64; 66),
|
||||||
|
delete: [64; 66),
|
||||||
|
insert: "Vec<$0>",
|
||||||
|
kind: TypeAlias,
|
||||||
|
},
|
||||||
|
CompletionItem {
|
||||||
|
label: "foo",
|
||||||
|
source_range: [64; 66),
|
||||||
|
delete: [64; 66),
|
||||||
|
insert: "foo($0)",
|
||||||
|
kind: Function,
|
||||||
|
detail: "fn foo(xs: Ve)",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
"###
|
||||||
|
);
|
||||||
assert_debug_snapshot!(
|
assert_debug_snapshot!(
|
||||||
do_reference_completion(
|
do_reference_completion(
|
||||||
r"
|
r"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue