This commit is contained in:
Lukas Wirth 2021-06-16 15:46:58 +02:00
parent 1c034c084d
commit 66b701ed3e
3 changed files with 34 additions and 66 deletions

View file

@ -131,9 +131,6 @@ impl Completions {
func: hir::Function, func: hir::Function,
local_name: Option<hir::Name>, local_name: Option<hir::Name>,
) { ) {
if ctx.expects_type() {
return;
}
self.add_opt(render_fn(RenderContext::new(ctx), None, local_name, func)); self.add_opt(render_fn(RenderContext::new(ctx), None, local_name, func));
} }
@ -175,9 +172,6 @@ impl Completions {
} }
pub(crate) fn add_const(&mut self, ctx: &CompletionContext, constant: hir::Const) { pub(crate) fn add_const(&mut self, ctx: &CompletionContext, constant: hir::Const) {
if ctx.expects_type() {
return;
}
self.add_opt(render_const(RenderContext::new(ctx), constant)); self.add_opt(render_const(RenderContext::new(ctx), constant));
} }
@ -209,32 +203,30 @@ impl Completions {
variant: hir::Variant, variant: hir::Variant,
local_name: Option<hir::Name>, local_name: Option<hir::Name>,
) { ) {
if ctx.expects_type() {
return;
}
let item = render_variant(RenderContext::new(ctx), None, local_name, variant, None); let item = render_variant(RenderContext::new(ctx), None, local_name, variant, None);
self.add(item); self.add(item);
} }
} }
/// Calls the callback for each variant of the provided enum with the path to the variant.
fn complete_enum_variants( fn complete_enum_variants(
acc: &mut Completions, acc: &mut Completions,
ctx: &CompletionContext, ctx: &CompletionContext,
enum_data: hir::Enum, enum_: hir::Enum,
cb: impl Fn(&mut Completions, &CompletionContext, hir::Variant, hir::ModPath), cb: impl Fn(&mut Completions, &CompletionContext, hir::Variant, hir::ModPath),
) { ) {
let variants = enum_data.variants(ctx.db); let variants = enum_.variants(ctx.db);
let module = if let Some(module) = ctx.scope.module() { let module = if let Some(module) = ctx.scope.module() {
// Compute path from the completion site if available. // Compute path from the completion site if available.
module module
} else { } else {
// Otherwise fall back to the enum's definition site. // Otherwise fall back to the enum's definition site.
enum_data.module(ctx.db) enum_.module(ctx.db)
}; };
if let Some(impl_) = ctx.impl_def.as_ref().and_then(|impl_| ctx.sema.to_def(impl_)) { if let Some(impl_) = ctx.impl_def.as_ref().and_then(|impl_| ctx.sema.to_def(impl_)) {
if impl_.self_ty(ctx.db).as_adt() == Some(hir::Adt::Enum(enum_data)) { if impl_.self_ty(ctx.db).as_adt() == Some(hir::Adt::Enum(enum_)) {
for &variant in &variants { for &variant in &variants {
let self_path = hir::ModPath::from_segments( let self_path = hir::ModPath::from_segments(
hir::PathKind::Plain, hir::PathKind::Plain,

View file

@ -23,50 +23,6 @@ use crate::{
render::{enum_variant::render_variant, function::render_fn, macro_::render_macro}, render::{enum_variant::render_variant, function::render_fn, macro_::render_macro},
CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, CompletionRelevance, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, CompletionRelevance,
}; };
pub(crate) fn render_field(
ctx: RenderContext<'_>,
receiver: Option<hir::Name>,
field: hir::Field,
ty: &hir::Type,
) -> CompletionItem {
render_field_(ctx, receiver, field, ty)
}
pub(crate) fn render_tuple_field(
ctx: RenderContext<'_>,
receiver: Option<hir::Name>,
field: usize,
ty: &hir::Type,
) -> CompletionItem {
render_tuple_field_(ctx, receiver, field, ty)
}
pub(crate) fn render_resolution(
ctx: RenderContext<'_>,
local_name: hir::Name,
resolution: &hir::ScopeDef,
) -> Option<CompletionItem> {
render_resolution_(ctx, local_name, None, resolution)
}
pub(crate) fn render_resolution_with_import(
ctx: RenderContext<'_>,
import_edit: ImportEdit,
) -> Option<CompletionItem> {
let resolution = hir::ScopeDef::from(import_edit.import.original_item);
let local_name = match resolution {
hir::ScopeDef::ModuleDef(hir::ModuleDef::Function(f)) => f.name(ctx.completion.db),
hir::ScopeDef::ModuleDef(hir::ModuleDef::Const(c)) => c.name(ctx.completion.db)?,
hir::ScopeDef::ModuleDef(hir::ModuleDef::TypeAlias(t)) => t.name(ctx.completion.db),
_ => item_name(ctx.db(), import_edit.import.original_item)?,
};
render_resolution_(ctx, local_name, Some(import_edit), &resolution).map(|mut item| {
item.completion_kind = CompletionKind::Magic;
item
})
}
/// Interface for data and methods required for items rendering. /// Interface for data and methods required for items rendering.
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct RenderContext<'a> { pub(crate) struct RenderContext<'a> {
@ -119,7 +75,7 @@ impl<'a> RenderContext<'a> {
} }
} }
fn render_field_( pub(crate) fn render_field(
ctx: RenderContext<'_>, ctx: RenderContext<'_>,
receiver: Option<hir::Name>, receiver: Option<hir::Name>,
field: hir::Field, field: hir::Field,
@ -132,7 +88,6 @@ fn render_field_(
ctx.source_range(), ctx.source_range(),
receiver.map_or_else(|| name.clone(), |receiver| format!("{}.{}", receiver, name)), receiver.map_or_else(|| name.clone(), |receiver| format!("{}.{}", receiver, name)),
); );
item.set_relevance(CompletionRelevance { item.set_relevance(CompletionRelevance {
type_match: compute_type_match(ctx.completion, ty), type_match: compute_type_match(ctx.completion, ty),
exact_name_match: compute_exact_name_match(ctx.completion, &name), exact_name_match: compute_exact_name_match(ctx.completion, &name),
@ -143,17 +98,15 @@ fn render_field_(
.set_documentation(field.docs(ctx.db())) .set_documentation(field.docs(ctx.db()))
.set_deprecated(is_deprecated) .set_deprecated(is_deprecated)
.lookup_by(name); .lookup_by(name);
if let Some(_ref_match) = compute_ref_match(ctx.completion, ty) { if let Some(_ref_match) = compute_ref_match(ctx.completion, ty) {
// FIXME // FIXME
// For now we don't properly calculate the edits for ref match // For now we don't properly calculate the edits for ref match
// completions on struct fields, so we've disabled them. See #8058. // completions on struct fields, so we've disabled them. See #8058.
} }
item.build() item.build()
} }
fn render_tuple_field_( pub(crate) fn render_tuple_field(
ctx: RenderContext<'_>, ctx: RenderContext<'_>,
receiver: Option<hir::Name>, receiver: Option<hir::Name>,
field: usize, field: usize,
@ -164,14 +117,37 @@ fn render_tuple_field_(
ctx.source_range(), ctx.source_range(),
receiver.map_or_else(|| field.to_string(), |receiver| format!("{}.{}", receiver, field)), receiver.map_or_else(|| field.to_string(), |receiver| format!("{}.{}", receiver, field)),
); );
item.kind(SymbolKind::Field) item.kind(SymbolKind::Field)
.detail(ty.display(ctx.db()).to_string()) .detail(ty.display(ctx.db()).to_string())
.lookup_by(field.to_string()); .lookup_by(field.to_string());
item.build() item.build()
} }
pub(crate) fn render_resolution(
ctx: RenderContext<'_>,
local_name: hir::Name,
resolution: &hir::ScopeDef,
) -> Option<CompletionItem> {
render_resolution_(ctx, local_name, None, resolution)
}
pub(crate) fn render_resolution_with_import(
ctx: RenderContext<'_>,
import_edit: ImportEdit,
) -> Option<CompletionItem> {
let resolution = hir::ScopeDef::from(import_edit.import.original_item);
let local_name = match resolution {
hir::ScopeDef::ModuleDef(hir::ModuleDef::Function(f)) => f.name(ctx.completion.db),
hir::ScopeDef::ModuleDef(hir::ModuleDef::Const(c)) => c.name(ctx.completion.db)?,
hir::ScopeDef::ModuleDef(hir::ModuleDef::TypeAlias(t)) => t.name(ctx.completion.db),
_ => item_name(ctx.db(), import_edit.import.original_item)?,
};
render_resolution_(ctx, local_name, Some(import_edit), &resolution).map(|mut item| {
item.completion_kind = CompletionKind::Magic;
item
})
}
fn render_resolution_( fn render_resolution_(
ctx: RenderContext<'_>, ctx: RenderContext<'_>,
local_name: hir::Name, local_name: hir::Name,

View file

@ -180,7 +180,7 @@ fn main() { frobnicate!(); }
/// ``` /// ```
macro_rules! vec { () => {} } macro_rules! vec { () => {} }
fn fn main() { v$0 } fn main() { v$0 }
"#, "#,
r#" r#"
/// Creates a [`Vec`] containing the arguments. /// Creates a [`Vec`] containing the arguments.
@ -193,7 +193,7 @@ fn fn main() { v$0 }
/// ``` /// ```
macro_rules! vec { () => {} } macro_rules! vec { () => {} }
fn fn main() { vec![$0] } fn main() { vec![$0] }
"#, "#,
); );