1 //! This module defines an accumulator for completions which are going to be presented to user.
2
3 pub(crate) mod attribute;
4 pub(crate) mod dot;
5 pub(crate) mod expr;
6 pub(crate) mod extern_abi;
7 pub(crate) mod field;
8 pub(crate) mod flyimport;
9 pub(crate) mod fn_param;
10 pub(crate) mod format_string;
11 pub(crate) mod item_list;
12 pub(crate) mod keyword;
13 pub(crate) mod lifetime;
14 pub(crate) mod mod_;
15 pub(crate) mod pattern;
16 pub(crate) mod postfix;
17 pub(crate) mod record;
18 pub(crate) mod snippet;
19 pub(crate) mod r#type;
20 pub(crate) mod use_;
21 pub(crate) mod vis;
22 pub(crate) mod env_vars;
23
24 use std::iter;
25
26 use hir::{known, HasAttrs, ScopeDef, Variant};
27 use ide_db::{imports::import_assets::LocatedImport, RootDatabase, SymbolKind};
28 use syntax::ast;
29
30 use crate::{
31 context::{
32 DotAccess, ItemListKind, NameContext, NameKind, NameRefContext, NameRefKind,
33 PathCompletionCtx, PathKind, PatternContext, TypeLocation, Visible,
34 },
35 item::Builder,
36 render::{
37 const_::render_const,
38 function::{render_fn, render_method},
39 literal::{render_struct_literal, render_variant_lit},
40 macro_::render_macro,
41 pattern::{render_struct_pat, render_variant_pat},
42 render_field, render_path_resolution, render_pattern_resolution, render_tuple_field,
43 type_alias::{render_type_alias, render_type_alias_with_eq},
44 union_literal::render_union_literal,
45 RenderContext,
46 },
47 CompletionContext, CompletionItem, CompletionItemKind,
48 };
49
50 /// Represents an in-progress set of completions being built.
51 #[derive(Debug, Default)]
52 pub struct Completions {
53 buf: Vec<CompletionItem>,
54 }
55
56 impl From<Completions> for Vec<CompletionItem> {
from(val: Completions) -> Self57 fn from(val: Completions) -> Self {
58 val.buf
59 }
60 }
61
62 impl Builder {
63 /// Convenience method, which allows to add a freshly created completion into accumulator
64 /// without binding it to the variable.
add_to(self, acc: &mut Completions, db: &RootDatabase)65 pub(crate) fn add_to(self, acc: &mut Completions, db: &RootDatabase) {
66 acc.add(self.build(db))
67 }
68 }
69
70 impl Completions {
add(&mut self, item: CompletionItem)71 fn add(&mut self, item: CompletionItem) {
72 self.buf.push(item)
73 }
74
add_opt(&mut self, item: Option<CompletionItem>)75 fn add_opt(&mut self, item: Option<CompletionItem>) {
76 if let Some(item) = item {
77 self.buf.push(item)
78 }
79 }
80
add_keyword(&mut self, ctx: &CompletionContext<'_>, keyword: &'static str)81 pub(crate) fn add_keyword(&mut self, ctx: &CompletionContext<'_>, keyword: &'static str) {
82 let item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), keyword);
83 item.add_to(self, ctx.db);
84 }
85
add_nameref_keywords_with_colon(&mut self, ctx: &CompletionContext<'_>)86 pub(crate) fn add_nameref_keywords_with_colon(&mut self, ctx: &CompletionContext<'_>) {
87 ["self::", "crate::"].into_iter().for_each(|kw| self.add_keyword(ctx, kw));
88
89 if ctx.depth_from_crate_root > 0 {
90 self.add_keyword(ctx, "super::");
91 }
92 }
93
add_nameref_keywords(&mut self, ctx: &CompletionContext<'_>)94 pub(crate) fn add_nameref_keywords(&mut self, ctx: &CompletionContext<'_>) {
95 ["self", "crate"].into_iter().for_each(|kw| self.add_keyword(ctx, kw));
96
97 if ctx.depth_from_crate_root > 0 {
98 self.add_keyword(ctx, "super");
99 }
100 }
101
add_super_keyword( &mut self, ctx: &CompletionContext<'_>, super_chain_len: Option<usize>, )102 pub(crate) fn add_super_keyword(
103 &mut self,
104 ctx: &CompletionContext<'_>,
105 super_chain_len: Option<usize>,
106 ) {
107 if let Some(len) = super_chain_len {
108 if len > 0 && len < ctx.depth_from_crate_root {
109 self.add_keyword(ctx, "super::");
110 }
111 }
112 }
113
add_keyword_snippet_expr( &mut self, ctx: &CompletionContext<'_>, incomplete_let: bool, kw: &str, snippet: &str, )114 pub(crate) fn add_keyword_snippet_expr(
115 &mut self,
116 ctx: &CompletionContext<'_>,
117 incomplete_let: bool,
118 kw: &str,
119 snippet: &str,
120 ) {
121 let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw);
122
123 match ctx.config.snippet_cap {
124 Some(cap) => {
125 if incomplete_let && snippet.ends_with('}') {
126 // complete block expression snippets with a trailing semicolon, if inside an incomplete let
127 cov_mark::hit!(let_semi);
128 item.insert_snippet(cap, format!("{snippet};"));
129 } else {
130 item.insert_snippet(cap, snippet);
131 }
132 }
133 None => {
134 item.insert_text(if snippet.contains('$') { kw } else { snippet });
135 }
136 };
137 item.add_to(self, ctx.db);
138 }
139
add_keyword_snippet( &mut self, ctx: &CompletionContext<'_>, kw: &str, snippet: &str, )140 pub(crate) fn add_keyword_snippet(
141 &mut self,
142 ctx: &CompletionContext<'_>,
143 kw: &str,
144 snippet: &str,
145 ) {
146 let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw);
147
148 match ctx.config.snippet_cap {
149 Some(cap) => item.insert_snippet(cap, snippet),
150 None => item.insert_text(if snippet.contains('$') { kw } else { snippet }),
151 };
152 item.add_to(self, ctx.db);
153 }
154
add_crate_roots( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, )155 pub(crate) fn add_crate_roots(
156 &mut self,
157 ctx: &CompletionContext<'_>,
158 path_ctx: &PathCompletionCtx,
159 ) {
160 ctx.process_all_names(&mut |name, res, doc_aliases| match res {
161 ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root() => {
162 self.add_module(ctx, path_ctx, m, name, doc_aliases);
163 }
164 _ => (),
165 });
166 }
167
add_path_resolution( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, local_name: hir::Name, resolution: hir::ScopeDef, doc_aliases: Vec<syntax::SmolStr>, )168 pub(crate) fn add_path_resolution(
169 &mut self,
170 ctx: &CompletionContext<'_>,
171 path_ctx: &PathCompletionCtx,
172 local_name: hir::Name,
173 resolution: hir::ScopeDef,
174 doc_aliases: Vec<syntax::SmolStr>,
175 ) {
176 if !ctx.check_stability(resolution.attrs(ctx.db).as_deref()) {
177 return;
178 }
179 let is_private_editable = match ctx.def_is_visible(&resolution) {
180 Visible::Yes => false,
181 Visible::Editable => true,
182 Visible::No => return,
183 };
184 self.add(
185 render_path_resolution(
186 RenderContext::new(ctx)
187 .private_editable(is_private_editable)
188 .doc_aliases(doc_aliases),
189 path_ctx,
190 local_name,
191 resolution,
192 )
193 .build(ctx.db),
194 );
195 }
196
add_pattern_resolution( &mut self, ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, local_name: hir::Name, resolution: hir::ScopeDef, )197 pub(crate) fn add_pattern_resolution(
198 &mut self,
199 ctx: &CompletionContext<'_>,
200 pattern_ctx: &PatternContext,
201 local_name: hir::Name,
202 resolution: hir::ScopeDef,
203 ) {
204 if !ctx.check_stability(resolution.attrs(ctx.db).as_deref()) {
205 return;
206 }
207 let is_private_editable = match ctx.def_is_visible(&resolution) {
208 Visible::Yes => false,
209 Visible::Editable => true,
210 Visible::No => return,
211 };
212 self.add(
213 render_pattern_resolution(
214 RenderContext::new(ctx).private_editable(is_private_editable),
215 pattern_ctx,
216 local_name,
217 resolution,
218 )
219 .build(ctx.db),
220 );
221 }
222
add_enum_variants( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, e: hir::Enum, )223 pub(crate) fn add_enum_variants(
224 &mut self,
225 ctx: &CompletionContext<'_>,
226 path_ctx: &PathCompletionCtx,
227 e: hir::Enum,
228 ) {
229 if !ctx.check_stability(Some(&e.attrs(ctx.db))) {
230 return;
231 }
232 e.variants(ctx.db)
233 .into_iter()
234 .for_each(|variant| self.add_enum_variant(ctx, path_ctx, variant, None));
235 }
236
add_module( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, module: hir::Module, local_name: hir::Name, doc_aliases: Vec<syntax::SmolStr>, )237 pub(crate) fn add_module(
238 &mut self,
239 ctx: &CompletionContext<'_>,
240 path_ctx: &PathCompletionCtx,
241 module: hir::Module,
242 local_name: hir::Name,
243 doc_aliases: Vec<syntax::SmolStr>,
244 ) {
245 if !ctx.check_stability(Some(&module.attrs(ctx.db))) {
246 return;
247 }
248 self.add_path_resolution(
249 ctx,
250 path_ctx,
251 local_name,
252 hir::ScopeDef::ModuleDef(module.into()),
253 doc_aliases,
254 );
255 }
256
add_macro( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, mac: hir::Macro, local_name: hir::Name, )257 pub(crate) fn add_macro(
258 &mut self,
259 ctx: &CompletionContext<'_>,
260 path_ctx: &PathCompletionCtx,
261 mac: hir::Macro,
262 local_name: hir::Name,
263 ) {
264 if !ctx.check_stability(Some(&mac.attrs(ctx.db))) {
265 return;
266 }
267 let is_private_editable = match ctx.is_visible(&mac) {
268 Visible::Yes => false,
269 Visible::Editable => true,
270 Visible::No => return,
271 };
272 self.add(
273 render_macro(
274 RenderContext::new(ctx).private_editable(is_private_editable),
275 path_ctx,
276 local_name,
277 mac,
278 )
279 .build(ctx.db),
280 );
281 }
282
add_function( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, func: hir::Function, local_name: Option<hir::Name>, )283 pub(crate) fn add_function(
284 &mut self,
285 ctx: &CompletionContext<'_>,
286 path_ctx: &PathCompletionCtx,
287 func: hir::Function,
288 local_name: Option<hir::Name>,
289 ) {
290 if !ctx.check_stability(Some(&func.attrs(ctx.db))) {
291 return;
292 }
293 let is_private_editable = match ctx.is_visible(&func) {
294 Visible::Yes => false,
295 Visible::Editable => true,
296 Visible::No => return,
297 };
298 let doc_aliases = ctx.doc_aliases(&func);
299 self.add(
300 render_fn(
301 RenderContext::new(ctx)
302 .private_editable(is_private_editable)
303 .doc_aliases(doc_aliases),
304 path_ctx,
305 local_name,
306 func,
307 )
308 .build(ctx.db),
309 );
310 }
311
add_method( &mut self, ctx: &CompletionContext<'_>, dot_access: &DotAccess, func: hir::Function, receiver: Option<hir::Name>, local_name: Option<hir::Name>, )312 pub(crate) fn add_method(
313 &mut self,
314 ctx: &CompletionContext<'_>,
315 dot_access: &DotAccess,
316 func: hir::Function,
317 receiver: Option<hir::Name>,
318 local_name: Option<hir::Name>,
319 ) {
320 if !ctx.check_stability(Some(&func.attrs(ctx.db))) {
321 return;
322 }
323 let is_private_editable = match ctx.is_visible(&func) {
324 Visible::Yes => false,
325 Visible::Editable => true,
326 Visible::No => return,
327 };
328 let doc_aliases = ctx.doc_aliases(&func);
329 self.add(
330 render_method(
331 RenderContext::new(ctx)
332 .private_editable(is_private_editable)
333 .doc_aliases(doc_aliases),
334 dot_access,
335 receiver,
336 local_name,
337 func,
338 )
339 .build(ctx.db),
340 );
341 }
342
add_method_with_import( &mut self, ctx: &CompletionContext<'_>, dot_access: &DotAccess, func: hir::Function, import: LocatedImport, )343 pub(crate) fn add_method_with_import(
344 &mut self,
345 ctx: &CompletionContext<'_>,
346 dot_access: &DotAccess,
347 func: hir::Function,
348 import: LocatedImport,
349 ) {
350 if !ctx.check_stability(Some(&func.attrs(ctx.db))) {
351 return;
352 }
353 let is_private_editable = match ctx.is_visible(&func) {
354 Visible::Yes => false,
355 Visible::Editable => true,
356 Visible::No => return,
357 };
358 let doc_aliases = ctx.doc_aliases(&func);
359 self.add(
360 render_method(
361 RenderContext::new(ctx)
362 .private_editable(is_private_editable)
363 .doc_aliases(doc_aliases)
364 .import_to_add(Some(import)),
365 dot_access,
366 None,
367 None,
368 func,
369 )
370 .build(ctx.db),
371 );
372 }
373
add_const(&mut self, ctx: &CompletionContext<'_>, konst: hir::Const)374 pub(crate) fn add_const(&mut self, ctx: &CompletionContext<'_>, konst: hir::Const) {
375 if !ctx.check_stability(Some(&konst.attrs(ctx.db))) {
376 return;
377 }
378 let is_private_editable = match ctx.is_visible(&konst) {
379 Visible::Yes => false,
380 Visible::Editable => true,
381 Visible::No => return,
382 };
383 self.add_opt(render_const(
384 RenderContext::new(ctx).private_editable(is_private_editable),
385 konst,
386 ));
387 }
388
add_type_alias( &mut self, ctx: &CompletionContext<'_>, type_alias: hir::TypeAlias, )389 pub(crate) fn add_type_alias(
390 &mut self,
391 ctx: &CompletionContext<'_>,
392 type_alias: hir::TypeAlias,
393 ) {
394 if !ctx.check_stability(Some(&type_alias.attrs(ctx.db))) {
395 return;
396 }
397 let is_private_editable = match ctx.is_visible(&type_alias) {
398 Visible::Yes => false,
399 Visible::Editable => true,
400 Visible::No => return,
401 };
402 self.add_opt(render_type_alias(
403 RenderContext::new(ctx).private_editable(is_private_editable),
404 type_alias,
405 ));
406 }
407
add_type_alias_with_eq( &mut self, ctx: &CompletionContext<'_>, type_alias: hir::TypeAlias, )408 pub(crate) fn add_type_alias_with_eq(
409 &mut self,
410 ctx: &CompletionContext<'_>,
411 type_alias: hir::TypeAlias,
412 ) {
413 if !ctx.check_stability(Some(&type_alias.attrs(ctx.db))) {
414 return;
415 }
416 self.add_opt(render_type_alias_with_eq(RenderContext::new(ctx), type_alias));
417 }
418
add_qualified_enum_variant( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, variant: hir::Variant, path: hir::ModPath, )419 pub(crate) fn add_qualified_enum_variant(
420 &mut self,
421 ctx: &CompletionContext<'_>,
422 path_ctx: &PathCompletionCtx,
423 variant: hir::Variant,
424 path: hir::ModPath,
425 ) {
426 if !ctx.check_stability(Some(&variant.attrs(ctx.db))) {
427 return;
428 }
429 if let Some(builder) =
430 render_variant_lit(RenderContext::new(ctx), path_ctx, None, variant, Some(path))
431 {
432 self.add(builder.build(ctx.db));
433 }
434 }
435
add_enum_variant( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, variant: hir::Variant, local_name: Option<hir::Name>, )436 pub(crate) fn add_enum_variant(
437 &mut self,
438 ctx: &CompletionContext<'_>,
439 path_ctx: &PathCompletionCtx,
440 variant: hir::Variant,
441 local_name: Option<hir::Name>,
442 ) {
443 if !ctx.check_stability(Some(&variant.attrs(ctx.db))) {
444 return;
445 }
446 if let PathCompletionCtx { kind: PathKind::Pat { pat_ctx }, .. } = path_ctx {
447 cov_mark::hit!(enum_variant_pattern_path);
448 self.add_variant_pat(ctx, pat_ctx, Some(path_ctx), variant, local_name);
449 return;
450 }
451
452 if let Some(builder) =
453 render_variant_lit(RenderContext::new(ctx), path_ctx, local_name, variant, None)
454 {
455 self.add(builder.build(ctx.db));
456 }
457 }
458
add_field( &mut self, ctx: &CompletionContext<'_>, dot_access: &DotAccess, receiver: Option<hir::Name>, field: hir::Field, ty: &hir::Type, )459 pub(crate) fn add_field(
460 &mut self,
461 ctx: &CompletionContext<'_>,
462 dot_access: &DotAccess,
463 receiver: Option<hir::Name>,
464 field: hir::Field,
465 ty: &hir::Type,
466 ) {
467 if !ctx.check_stability(Some(&field.attrs(ctx.db))) {
468 return;
469 }
470 let is_private_editable = match ctx.is_visible(&field) {
471 Visible::Yes => false,
472 Visible::Editable => true,
473 Visible::No => return,
474 };
475 let doc_aliases = ctx.doc_aliases(&field);
476 let item = render_field(
477 RenderContext::new(ctx).private_editable(is_private_editable).doc_aliases(doc_aliases),
478 dot_access,
479 receiver,
480 field,
481 ty,
482 );
483 self.add(item);
484 }
485
add_struct_literal( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, strukt: hir::Struct, path: Option<hir::ModPath>, local_name: Option<hir::Name>, )486 pub(crate) fn add_struct_literal(
487 &mut self,
488 ctx: &CompletionContext<'_>,
489 path_ctx: &PathCompletionCtx,
490 strukt: hir::Struct,
491 path: Option<hir::ModPath>,
492 local_name: Option<hir::Name>,
493 ) {
494 if !ctx.check_stability(Some(&strukt.attrs(ctx.db))) {
495 return;
496 }
497 if let Some(builder) =
498 render_struct_literal(RenderContext::new(ctx), path_ctx, strukt, path, local_name)
499 {
500 self.add(builder.build(ctx.db));
501 }
502 }
503
add_union_literal( &mut self, ctx: &CompletionContext<'_>, un: hir::Union, path: Option<hir::ModPath>, local_name: Option<hir::Name>, )504 pub(crate) fn add_union_literal(
505 &mut self,
506 ctx: &CompletionContext<'_>,
507 un: hir::Union,
508 path: Option<hir::ModPath>,
509 local_name: Option<hir::Name>,
510 ) {
511 if !ctx.check_stability(Some(&un.attrs(ctx.db))) {
512 return;
513 }
514 let item = render_union_literal(RenderContext::new(ctx), un, path, local_name);
515 self.add_opt(item);
516 }
517
add_tuple_field( &mut self, ctx: &CompletionContext<'_>, receiver: Option<hir::Name>, field: usize, ty: &hir::Type, )518 pub(crate) fn add_tuple_field(
519 &mut self,
520 ctx: &CompletionContext<'_>,
521 receiver: Option<hir::Name>,
522 field: usize,
523 ty: &hir::Type,
524 ) {
525 // Only used for (unnamed) tuples, whose all fields *are* stable. No need to check
526 // stability here.
527 let item = render_tuple_field(RenderContext::new(ctx), receiver, field, ty);
528 self.add(item);
529 }
530
add_lifetime(&mut self, ctx: &CompletionContext<'_>, name: hir::Name)531 pub(crate) fn add_lifetime(&mut self, ctx: &CompletionContext<'_>, name: hir::Name) {
532 CompletionItem::new(SymbolKind::LifetimeParam, ctx.source_range(), name.to_smol_str())
533 .add_to(self, ctx.db)
534 }
535
add_label(&mut self, ctx: &CompletionContext<'_>, name: hir::Name)536 pub(crate) fn add_label(&mut self, ctx: &CompletionContext<'_>, name: hir::Name) {
537 CompletionItem::new(SymbolKind::Label, ctx.source_range(), name.to_smol_str())
538 .add_to(self, ctx.db)
539 }
540
add_variant_pat( &mut self, ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, path_ctx: Option<&PathCompletionCtx>, variant: hir::Variant, local_name: Option<hir::Name>, )541 pub(crate) fn add_variant_pat(
542 &mut self,
543 ctx: &CompletionContext<'_>,
544 pattern_ctx: &PatternContext,
545 path_ctx: Option<&PathCompletionCtx>,
546 variant: hir::Variant,
547 local_name: Option<hir::Name>,
548 ) {
549 if !ctx.check_stability(Some(&variant.attrs(ctx.db))) {
550 return;
551 }
552 self.add_opt(render_variant_pat(
553 RenderContext::new(ctx),
554 pattern_ctx,
555 path_ctx,
556 variant,
557 local_name,
558 None,
559 ));
560 }
561
add_qualified_variant_pat( &mut self, ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, variant: hir::Variant, path: hir::ModPath, )562 pub(crate) fn add_qualified_variant_pat(
563 &mut self,
564 ctx: &CompletionContext<'_>,
565 pattern_ctx: &PatternContext,
566 variant: hir::Variant,
567 path: hir::ModPath,
568 ) {
569 if !ctx.check_stability(Some(&variant.attrs(ctx.db))) {
570 return;
571 }
572 let path = Some(&path);
573 self.add_opt(render_variant_pat(
574 RenderContext::new(ctx),
575 pattern_ctx,
576 None,
577 variant,
578 None,
579 path,
580 ));
581 }
582
add_struct_pat( &mut self, ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, strukt: hir::Struct, local_name: Option<hir::Name>, )583 pub(crate) fn add_struct_pat(
584 &mut self,
585 ctx: &CompletionContext<'_>,
586 pattern_ctx: &PatternContext,
587 strukt: hir::Struct,
588 local_name: Option<hir::Name>,
589 ) {
590 if !ctx.check_stability(Some(&strukt.attrs(ctx.db))) {
591 return;
592 }
593 self.add_opt(render_struct_pat(RenderContext::new(ctx), pattern_ctx, strukt, local_name));
594 }
595 }
596
597 /// Calls the callback for each variant of the provided enum with the path to the variant.
598 /// Skips variants that are visible with single segment paths.
enum_variants_with_paths( acc: &mut Completions, ctx: &CompletionContext<'_>, enum_: hir::Enum, impl_: &Option<ast::Impl>, cb: impl Fn(&mut Completions, &CompletionContext<'_>, hir::Variant, hir::ModPath), )599 fn enum_variants_with_paths(
600 acc: &mut Completions,
601 ctx: &CompletionContext<'_>,
602 enum_: hir::Enum,
603 impl_: &Option<ast::Impl>,
604 cb: impl Fn(&mut Completions, &CompletionContext<'_>, hir::Variant, hir::ModPath),
605 ) {
606 let mut process_variant = |variant: Variant| {
607 let self_path = hir::ModPath::from_segments(
608 hir::PathKind::Plain,
609 iter::once(known::SELF_TYPE).chain(iter::once(variant.name(ctx.db))),
610 );
611
612 cb(acc, ctx, variant, self_path);
613 };
614
615 let variants = enum_.variants(ctx.db);
616
617 if let Some(impl_) = impl_.as_ref().and_then(|impl_| ctx.sema.to_def(impl_)) {
618 if impl_.self_ty(ctx.db).as_adt() == Some(hir::Adt::Enum(enum_)) {
619 variants.iter().for_each(|variant| process_variant(*variant));
620 }
621 }
622
623 for variant in variants {
624 if let Some(path) = ctx.module.find_use_path(
625 ctx.db,
626 hir::ModuleDef::from(variant),
627 ctx.config.prefer_no_std,
628 ) {
629 // Variants with trivial paths are already added by the existing completion logic,
630 // so we should avoid adding these twice
631 if path.segments().len() > 1 {
632 cb(acc, ctx, variant, path);
633 }
634 }
635 }
636 }
637
638 pub(super) fn complete_name(
639 acc: &mut Completions,
640 ctx: &CompletionContext<'_>,
641 NameContext { name, kind }: &NameContext,
642 ) {
643 match kind {
644 NameKind::Const => {
645 item_list::trait_impl::complete_trait_impl_const(acc, ctx, name);
646 }
647 NameKind::Function => {
648 item_list::trait_impl::complete_trait_impl_fn(acc, ctx, name);
649 }
650 NameKind::IdentPat(pattern_ctx) => {
651 if ctx.token.kind() != syntax::T![_] {
652 complete_patterns(acc, ctx, pattern_ctx)
653 }
654 }
655 NameKind::Module(mod_under_caret) => {
656 mod_::complete_mod(acc, ctx, mod_under_caret);
657 }
658 NameKind::TypeAlias => {
659 item_list::trait_impl::complete_trait_impl_type_alias(acc, ctx, name);
660 }
661 NameKind::RecordField => {
662 field::complete_field_list_record_variant(acc, ctx);
663 }
664 NameKind::ConstParam
665 | NameKind::Enum
666 | NameKind::MacroDef
667 | NameKind::MacroRules
668 | NameKind::Rename
669 | NameKind::SelfParam
670 | NameKind::Static
671 | NameKind::Struct
672 | NameKind::Trait
673 | NameKind::TypeParam
674 | NameKind::Union
675 | NameKind::Variant => (),
676 }
677 }
678
679 pub(super) fn complete_name_ref(
680 acc: &mut Completions,
681 ctx: &CompletionContext<'_>,
682 NameRefContext { nameref, kind }: &NameRefContext,
683 ) {
684 match kind {
685 NameRefKind::Path(path_ctx) => {
686 flyimport::import_on_the_fly_path(acc, ctx, path_ctx);
687
688 match &path_ctx.kind {
689 PathKind::Expr { expr_ctx } => {
690 expr::complete_expr_path(acc, ctx, path_ctx, expr_ctx);
691
692 dot::complete_undotted_self(acc, ctx, path_ctx, expr_ctx);
693 item_list::complete_item_list_in_expr(acc, ctx, path_ctx, expr_ctx);
694 snippet::complete_expr_snippet(acc, ctx, path_ctx, expr_ctx);
695 }
696 PathKind::Type { location } => {
697 r#type::complete_type_path(acc, ctx, path_ctx, location);
698
699 match location {
700 TypeLocation::TupleField => {
701 field::complete_field_list_tuple_variant(acc, ctx, path_ctx);
702 }
703 TypeLocation::TypeAscription(ascription) => {
704 r#type::complete_ascribed_type(acc, ctx, path_ctx, ascription);
705 }
706 TypeLocation::GenericArgList(_)
707 | TypeLocation::TypeBound
708 | TypeLocation::ImplTarget
709 | TypeLocation::ImplTrait
710 | TypeLocation::Other => (),
711 }
712 }
713 PathKind::Attr { attr_ctx } => {
714 attribute::complete_attribute_path(acc, ctx, path_ctx, attr_ctx);
715 }
716 PathKind::Derive { existing_derives } => {
717 attribute::complete_derive_path(acc, ctx, path_ctx, existing_derives);
718 }
719 PathKind::Item { kind } => {
720 item_list::complete_item_list(acc, ctx, path_ctx, kind);
721
722 snippet::complete_item_snippet(acc, ctx, path_ctx, kind);
723 if let ItemListKind::TraitImpl(impl_) = kind {
724 item_list::trait_impl::complete_trait_impl_item_by_name(
725 acc, ctx, path_ctx, nameref, impl_,
726 );
727 }
728 }
729 PathKind::Pat { .. } => {
730 pattern::complete_pattern_path(acc, ctx, path_ctx);
731 }
732 PathKind::Vis { has_in_token } => {
733 vis::complete_vis_path(acc, ctx, path_ctx, has_in_token);
734 }
735 PathKind::Use => {
736 use_::complete_use_path(acc, ctx, path_ctx, nameref);
737 }
738 }
739 }
740 NameRefKind::DotAccess(dot_access) => {
741 flyimport::import_on_the_fly_dot(acc, ctx, dot_access);
742 dot::complete_dot(acc, ctx, dot_access);
743 postfix::complete_postfix(acc, ctx, dot_access);
744 }
745 NameRefKind::Keyword(item) => {
746 keyword::complete_for_and_where(acc, ctx, item);
747 }
748 NameRefKind::RecordExpr { dot_prefix, expr } => {
749 record::complete_record_expr_fields(acc, ctx, expr, dot_prefix);
750 }
751 NameRefKind::Pattern(pattern_ctx) => complete_patterns(acc, ctx, pattern_ctx),
752 }
753 }
754
complete_patterns( acc: &mut Completions, ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, )755 fn complete_patterns(
756 acc: &mut Completions,
757 ctx: &CompletionContext<'_>,
758 pattern_ctx: &PatternContext,
759 ) {
760 flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx);
761 fn_param::complete_fn_param(acc, ctx, pattern_ctx);
762 pattern::complete_pattern(acc, ctx, pattern_ctx);
763 record::complete_record_pattern_fields(acc, ctx, pattern_ctx);
764 }
765