Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/completions/flyimport.rs')
| -rw-r--r-- | crates/ide-completion/src/completions/flyimport.rs | 110 |
1 files changed, 75 insertions, 35 deletions
diff --git a/crates/ide-completion/src/completions/flyimport.rs b/crates/ide-completion/src/completions/flyimport.rs index 608a74dc15..129910465c 100644 --- a/crates/ide-completion/src/completions/flyimport.rs +++ b/crates/ide-completion/src/completions/flyimport.rs @@ -116,17 +116,17 @@ pub(crate) fn import_on_the_fly_path( if !ctx.config.enable_imports_on_the_fly { return None; } - let (kind, qualified) = match path_ctx { + let qualified = match path_ctx { PathCompletionCtx { kind: - kind @ (PathKind::Expr { .. } + PathKind::Expr { .. } | PathKind::Type { .. } | PathKind::Attr { .. } | PathKind::Derive { .. } - | PathKind::Pat { .. }), + | PathKind::Pat { .. }, qualified, .. - } => (Some(kind), qualified), + } => qualified, _ => return None, }; let potential_import_name = import_name(ctx); @@ -139,63 +139,70 @@ pub(crate) fn import_on_the_fly_path( import_on_the_fly( acc, ctx, - kind, + path_ctx, import_assets, qualifier.map(|it| it.syntax().clone()).or_else(|| ctx.original_token.parent())?, potential_import_name, ) } -pub(crate) fn import_on_the_fly_dot( +pub(crate) fn import_on_the_fly_pat( acc: &mut Completions, ctx: &CompletionContext, - dot_access: &DotAccess, + pat_ctx: &PatternContext, ) -> Option<()> { if !ctx.config.enable_imports_on_the_fly { return None; } - let receiver = dot_access.receiver.as_ref()?; - let ty = dot_access.receiver_ty.as_ref()?; + if let PatternContext { record_pat: Some(_), .. } = pat_ctx { + return None; + } + let potential_import_name = import_name(ctx); - let import_assets = ImportAssets::for_fuzzy_method_call( - ctx.module, - ty.original.clone(), - potential_import_name.clone(), - receiver.syntax().clone(), - )?; + let import_assets = import_assets_for_path(ctx, &potential_import_name, None)?; import_on_the_fly( acc, ctx, - None, + &PathCompletionCtx { + has_call_parens: false, + has_macro_bang: false, + qualified: Qualified::No, + parent: None, + kind: crate::context::PathKind::Pat { pat_ctx: pat_ctx.clone() }, + has_type_args: false, + use_tree_parent: false, + }, import_assets, - receiver.syntax().clone(), + ctx.original_token.parent()?, potential_import_name, ) } -pub(crate) fn import_on_the_fly_pat( +pub(crate) fn import_on_the_fly_dot( acc: &mut Completions, ctx: &CompletionContext, - pat_ctx: &PatternContext, + dot_access: &DotAccess, ) -> Option<()> { if !ctx.config.enable_imports_on_the_fly { return None; } - let kind = match pat_ctx { - PatternContext { record_pat: None, .. } => PathKind::Pat { pat_ctx: pat_ctx.clone() }, - _ => return None, - }; - + let receiver = dot_access.receiver.as_ref()?; + let ty = dot_access.receiver_ty.as_ref()?; let potential_import_name = import_name(ctx); - let import_assets = import_assets_for_path(ctx, &potential_import_name, None)?; + let import_assets = ImportAssets::for_fuzzy_method_call( + ctx.module, + ty.original.clone(), + potential_import_name.clone(), + receiver.syntax().clone(), + )?; - import_on_the_fly( + import_on_the_fly_method( acc, ctx, - Some(&kind), + dot_access, import_assets, - ctx.original_token.parent()?, + receiver.syntax().clone(), potential_import_name, ) } @@ -203,7 +210,7 @@ pub(crate) fn import_on_the_fly_pat( fn import_on_the_fly( acc: &mut Completions, ctx: &CompletionContext, - path_kind: Option<&PathKind>, + path_ctx @ PathCompletionCtx { kind, .. }: &PathCompletionCtx, import_assets: ImportAssets, position: SyntaxNode, potential_import_name: String, @@ -215,11 +222,7 @@ fn import_on_the_fly( } let ns_filter = |import: &LocatedImport| { - let path_kind = match path_kind { - Some(it) => it, - None => return true, - }; - match (path_kind, import.original_item) { + match (kind, import.original_item) { // Aren't handled in flyimport (PathKind::Vis { .. } | PathKind::Use, _) => false, // modules are always fair game @@ -276,12 +279,49 @@ fn import_on_the_fly( &user_input_lowercased, ) }) - .filter_map(|import| render_resolution_with_import(RenderContext::new(ctx), import)) + .filter_map(|import| { + render_resolution_with_import(RenderContext::new(ctx), path_ctx, import) + }) .map(|builder| builder.build()), ); Some(()) } +fn import_on_the_fly_method( + acc: &mut Completions, + ctx: &CompletionContext, + dot_access: &DotAccess, + import_assets: ImportAssets, + position: SyntaxNode, + potential_import_name: String, +) -> Option<()> { + let _p = profile::span("import_on_the_fly").detail(|| potential_import_name.clone()); + + if ImportScope::find_insert_use_container(&position, &ctx.sema).is_none() { + return None; + } + + let user_input_lowercased = potential_import_name.to_lowercase(); + + import_assets + .search_for_imports(&ctx.sema, ctx.config.insert_use.prefix_kind) + .into_iter() + .filter(|import| { + !ctx.is_item_hidden(&import.item_to_import) + && !ctx.is_item_hidden(&import.original_item) + }) + .sorted_by_key(|located_import| { + compute_fuzzy_completion_order_key(&located_import.import_path, &user_input_lowercased) + }) + .for_each(|import| match import.original_item { + ItemInNs::Values(hir::ModuleDef::Function(f)) => { + acc.add_method_with_import(ctx, dot_access, f, import); + } + _ => (), + }); + Some(()) +} + fn import_name(ctx: &CompletionContext) -> String { let token_kind = ctx.token.kind(); if matches!(token_kind, T![.] | T![::]) { |