Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/render.rs')
| -rw-r--r-- | crates/ide-completion/src/render.rs | 159 |
1 files changed, 98 insertions, 61 deletions
diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index 643f34b22e..c29a50dd63 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -17,9 +17,13 @@ use ide_db::{ use syntax::{AstNode, SmolStr, SyntaxKind, TextRange}; use crate::{ - context::{PathCompletionCtx, PathKind}, + context::{PathCompletionCtx, PathKind, PatternContext}, item::{Builder, CompletionRelevanceTypeMatch}, - render::{function::render_fn, literal::render_variant_lit, macro_::render_macro}, + render::{ + function::render_fn, + literal::render_variant_lit, + macro_::{render_macro, render_macro_pat}, + }, CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance, }; /// Interface for data and methods required for items rendering. @@ -153,21 +157,29 @@ pub(crate) fn render_tuple_field( item.build() } +pub(crate) fn render_type_inference(ty_string: String, ctx: &CompletionContext) -> CompletionItem { + let mut builder = + CompletionItem::new(CompletionItemKind::InferredType, ctx.source_range(), ty_string); + builder.set_relevance(CompletionRelevance { is_definite: true, ..Default::default() }); + builder.build() +} + pub(crate) fn render_path_resolution( ctx: RenderContext<'_>, path_ctx: &PathCompletionCtx, local_name: hir::Name, resolution: ScopeDef, ) -> Builder { - render_resolution_(ctx, path_ctx, local_name, None, resolution) + render_resolution_path(ctx, path_ctx, local_name, None, resolution) } -pub(crate) fn render_resolution_simple( +pub(crate) fn render_pattern_resolution( ctx: RenderContext<'_>, + pattern_ctx: &PatternContext, local_name: hir::Name, resolution: ScopeDef, ) -> Builder { - render_resolution_simple_(ctx, None, local_name, None, resolution) + render_resolution_pat(ctx, pattern_ctx, local_name, None, resolution) } pub(crate) fn render_resolution_with_import( @@ -176,23 +188,56 @@ pub(crate) fn render_resolution_with_import( import_edit: LocatedImport, ) -> Option<Builder> { let resolution = ScopeDef::from(import_edit.original_item); - let local_name = match resolution { + let local_name = scope_def_to_name(resolution, &ctx, &import_edit)?; + + Some(render_resolution_path(ctx, path_ctx, local_name, Some(import_edit), resolution)) +} + +pub(crate) fn render_resolution_with_import_pat( + ctx: RenderContext<'_>, + pattern_ctx: &PatternContext, + import_edit: LocatedImport, +) -> Option<Builder> { + let resolution = ScopeDef::from(import_edit.original_item); + let local_name = scope_def_to_name(resolution, &ctx, &import_edit)?; + Some(render_resolution_pat(ctx, pattern_ctx, local_name, Some(import_edit), resolution)) +} + +fn scope_def_to_name( + resolution: ScopeDef, + ctx: &RenderContext, + import_edit: &LocatedImport, +) -> Option<hir::Name> { + Some(match resolution { ScopeDef::ModuleDef(hir::ModuleDef::Function(f)) => f.name(ctx.completion.db), ScopeDef::ModuleDef(hir::ModuleDef::Const(c)) => c.name(ctx.completion.db)?, ScopeDef::ModuleDef(hir::ModuleDef::TypeAlias(t)) => t.name(ctx.completion.db), _ => item_name(ctx.db(), import_edit.original_item)?, - }; - Some(render_resolution_(ctx, path_ctx, local_name, Some(import_edit), resolution)) + }) } -pub(crate) fn render_type_inference(ty_string: String, ctx: &CompletionContext) -> CompletionItem { - let mut builder = - CompletionItem::new(CompletionItemKind::InferredType, ctx.source_range(), ty_string); - builder.set_relevance(CompletionRelevance { is_definite: true, ..Default::default() }); - builder.build() +fn render_resolution_pat( + ctx: RenderContext<'_>, + pattern_ctx: &PatternContext, + local_name: hir::Name, + import_to_add: Option<LocatedImport>, + resolution: ScopeDef, +) -> Builder { + let _p = profile::span("render_resolution"); + use hir::ModuleDef::*; + + match resolution { + ScopeDef::ModuleDef(Macro(mac)) => { + let ctx = ctx.import_to_add(import_to_add); + return render_macro_pat(ctx, pattern_ctx, local_name, mac); + } + _ => (), + } + + render_resolution_simple_(ctx, local_name, import_to_add, resolution) } -fn render_resolution_( +fn render_resolution_path( ctx: RenderContext<'_>, path_ctx: &PathCompletionCtx, local_name: hir::Name, @@ -221,22 +266,14 @@ fn render_resolution_( } _ => (), } - render_resolution_simple_type(ctx, path_ctx, local_name, import_to_add, resolution) -} -fn render_resolution_simple_type( - ctx: RenderContext<'_>, - path_ctx: &PathCompletionCtx, - local_name: hir::Name, - import_to_add: Option<LocatedImport>, - resolution: ScopeDef, -) -> Builder { + let completion = ctx.completion; let cap = ctx.snippet_cap(); - let db = ctx.completion.db; - let config = ctx.completion.config; + let db = completion.db; + let config = completion.config; + let name = local_name.to_smol_str(); - let mut item = - render_resolution_simple_(ctx, Some(path_ctx), local_name, import_to_add, resolution); + let mut item = render_resolution_simple_(ctx, local_name, import_to_add, resolution); // Add `<>` for generic types let type_path_no_ty_args = matches!( path_ctx, @@ -251,6 +288,7 @@ fn render_resolution_simple_type( } _ => false, }; + if has_non_default_type_params { cov_mark::hit!(inserts_angle_brackets_for_generics); item.lookup_by(name.clone()) @@ -260,22 +298,52 @@ fn render_resolution_simple_type( } } } + if let ScopeDef::Local(local) = resolution { + let ty = local.ty(db); + if !ty.is_unknown() { + item.detail(ty.display(db).to_string()); + } + + item.set_relevance(CompletionRelevance { + type_match: compute_type_match(completion, &ty), + exact_name_match: compute_exact_name_match(completion, &name), + is_local: true, + ..CompletionRelevance::default() + }); + + if let Some(ref_match) = compute_ref_match(completion, &ty) { + item.ref_match(ref_match, path_ctx.path.syntax().text_range().start()); + } + }; item } fn render_resolution_simple_( ctx: RenderContext<'_>, - path_ctx: Option<&PathCompletionCtx>, local_name: hir::Name, import_to_add: Option<LocatedImport>, resolution: ScopeDef, ) -> Builder { let _p = profile::span("render_resolution"); - use hir::ModuleDef::*; let db = ctx.db(); let ctx = ctx.import_to_add(import_to_add); - let kind = match resolution { + let kind = res_to_kind(resolution); + + let mut item = CompletionItem::new(kind, ctx.source_range(), local_name.to_smol_str()); + item.set_relevance(ctx.completion_relevance()) + .set_documentation(scope_def_docs(db, resolution)) + .set_deprecated(scope_def_is_deprecated(&ctx, resolution)); + + if let Some(import_to_add) = ctx.import_to_add { + item.add_import(import_to_add); + } + item +} + +fn res_to_kind(resolution: ScopeDef) -> CompletionItemKind { + use hir::ModuleDef::*; + match resolution { ScopeDef::Unknown => CompletionItemKind::UnresolvedReference, ScopeDef::ModuleDef(Function(_)) => CompletionItemKind::SymbolKind(SymbolKind::Function), ScopeDef::ModuleDef(Variant(_)) => CompletionItemKind::SymbolKind(SymbolKind::Variant), @@ -301,38 +369,7 @@ fn render_resolution_simple_( ScopeDef::AdtSelfType(..) | ScopeDef::ImplSelfType(..) => { CompletionItemKind::SymbolKind(SymbolKind::SelfParam) } - }; - - let local_name = local_name.to_smol_str(); - let mut item = CompletionItem::new(kind, ctx.source_range(), local_name.clone()); - item.set_relevance(ctx.completion_relevance()); - if let ScopeDef::Local(local) = resolution { - let ty = local.ty(db); - if !ty.is_unknown() { - item.detail(ty.display(db).to_string()); - } - - item.set_relevance(CompletionRelevance { - type_match: compute_type_match(ctx.completion, &ty), - exact_name_match: compute_exact_name_match(ctx.completion, &local_name), - is_local: true, - ..CompletionRelevance::default() - }); - - if let Some(path_ctx) = path_ctx { - if let Some(ref_match) = compute_ref_match(ctx.completion, &ty) { - item.ref_match(ref_match, path_ctx.path.syntax().text_range().start()); - } - } - }; - - item.set_documentation(scope_def_docs(db, resolution)) - .set_deprecated(scope_def_is_deprecated(&ctx, resolution)); - - if let Some(import_to_add) = ctx.import_to_add { - item.add_import(import_to_add); } - item } fn scope_def_docs(db: &RootDatabase, resolution: ScopeDef) -> Option<hir::Documentation> { |