aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/completions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src/completions.rs')
-rw-r--r--crates/ide_completion/src/completions.rs62
1 files changed, 57 insertions, 5 deletions
diff --git a/crates/ide_completion/src/completions.rs b/crates/ide_completion/src/completions.rs
index 151bf3783..0f0553a65 100644
--- a/crates/ide_completion/src/completions.rs
+++ b/crates/ide_completion/src/completions.rs
@@ -18,8 +18,10 @@ pub(crate) mod unqualified_path;
18 18
19use std::iter; 19use std::iter;
20 20
21use hir::known; 21use either::Either;
22use hir::{known, HasVisibility};
22use ide_db::SymbolKind; 23use ide_db::SymbolKind;
24use rustc_hash::FxHashSet;
23 25
24use crate::{ 26use crate::{
25 item::{Builder, CompletionKind}, 27 item::{Builder, CompletionKind},
@@ -69,18 +71,25 @@ impl Completions {
69 items.into_iter().for_each(|item| self.add(item.into())) 71 items.into_iter().for_each(|item| self.add(item.into()))
70 } 72 }
71 73
72 pub(crate) fn add_field(&mut self, ctx: &CompletionContext, field: hir::Field, ty: &hir::Type) { 74 pub(crate) fn add_field(
73 let item = render_field(RenderContext::new(ctx), field, ty); 75 &mut self,
76 ctx: &CompletionContext,
77 receiver: Option<String>,
78 field: hir::Field,
79 ty: &hir::Type,
80 ) {
81 let item = render_field(RenderContext::new(ctx), receiver, field, ty);
74 self.add(item); 82 self.add(item);
75 } 83 }
76 84
77 pub(crate) fn add_tuple_field( 85 pub(crate) fn add_tuple_field(
78 &mut self, 86 &mut self,
79 ctx: &CompletionContext, 87 ctx: &CompletionContext,
88 receiver: Option<String>,
80 field: usize, 89 field: usize,
81 ty: &hir::Type, 90 ty: &hir::Type,
82 ) { 91 ) {
83 let item = render_tuple_field(RenderContext::new(ctx), field, ty); 92 let item = render_tuple_field(RenderContext::new(ctx), receiver, field, ty);
84 self.add(item); 93 self.add(item);
85 } 94 }
86 95
@@ -132,9 +141,11 @@ impl Completions {
132 &mut self, 141 &mut self,
133 ctx: &CompletionContext, 142 ctx: &CompletionContext,
134 func: hir::Function, 143 func: hir::Function,
144 receiver: Option<String>,
135 local_name: Option<hir::Name>, 145 local_name: Option<hir::Name>,
136 ) { 146 ) {
137 if let Some(item) = render_method(RenderContext::new(ctx), None, local_name, func) { 147 if let Some(item) = render_method(RenderContext::new(ctx), None, receiver, local_name, func)
148 {
138 self.add(item) 149 self.add(item)
139 } 150 }
140 } 151 }
@@ -243,3 +254,44 @@ fn complete_enum_variants(
243 } 254 }
244 } 255 }
245} 256}
257
258fn complete_fields(
259 ctx: &CompletionContext,
260 receiver: &hir::Type,
261 mut f: impl FnMut(Either<hir::Field, usize>, hir::Type),
262) {
263 for receiver in receiver.autoderef(ctx.db) {
264 for (field, ty) in receiver.fields(ctx.db) {
265 if ctx.scope.module().map_or(false, |m| !field.is_visible_from(ctx.db, m)) {
266 // Skip private field. FIXME: If the definition location of the
267 // field is editable, we should show the completion
268 continue;
269 }
270 f(Either::Left(field), ty);
271 }
272 for (i, ty) in receiver.tuple_fields(ctx.db).into_iter().enumerate() {
273 // FIXME: Handle visibility
274 f(Either::Right(i), ty);
275 }
276 }
277}
278
279fn complete_methods(
280 ctx: &CompletionContext,
281 receiver: &hir::Type,
282 mut f: impl FnMut(hir::Function),
283) {
284 if let Some(krate) = ctx.krate {
285 let mut seen_methods = FxHashSet::default();
286 let traits_in_scope = ctx.scope.traits_in_scope();
287 receiver.iterate_method_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, func| {
288 if func.self_param(ctx.db).is_some()
289 && ctx.scope.module().map_or(true, |m| func.is_visible_from(ctx.db, m))
290 && seen_methods.insert(func.name(ctx.db))
291 {
292 f(func);
293 }
294 None::<()>
295 });
296 }
297}