From ca49fbe0a1f6acc1352f6628c36bb7dfe3a950e5 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 28 May 2021 14:02:53 +0200 Subject: Complete `self.` prefixed fields and methods inside methods --- crates/ide_completion/src/completions.rs | 62 +++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) (limited to 'crates/ide_completion/src/completions.rs') 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; use std::iter; -use hir::known; +use either::Either; +use hir::{known, HasVisibility}; use ide_db::SymbolKind; +use rustc_hash::FxHashSet; use crate::{ item::{Builder, CompletionKind}, @@ -69,18 +71,25 @@ impl Completions { items.into_iter().for_each(|item| self.add(item.into())) } - pub(crate) fn add_field(&mut self, ctx: &CompletionContext, field: hir::Field, ty: &hir::Type) { - let item = render_field(RenderContext::new(ctx), field, ty); + pub(crate) fn add_field( + &mut self, + ctx: &CompletionContext, + receiver: Option, + field: hir::Field, + ty: &hir::Type, + ) { + let item = render_field(RenderContext::new(ctx), receiver, field, ty); self.add(item); } pub(crate) fn add_tuple_field( &mut self, ctx: &CompletionContext, + receiver: Option, field: usize, ty: &hir::Type, ) { - let item = render_tuple_field(RenderContext::new(ctx), field, ty); + let item = render_tuple_field(RenderContext::new(ctx), receiver, field, ty); self.add(item); } @@ -132,9 +141,11 @@ impl Completions { &mut self, ctx: &CompletionContext, func: hir::Function, + receiver: Option, local_name: Option, ) { - if let Some(item) = render_method(RenderContext::new(ctx), None, local_name, func) { + if let Some(item) = render_method(RenderContext::new(ctx), None, receiver, local_name, func) + { self.add(item) } } @@ -243,3 +254,44 @@ fn complete_enum_variants( } } } + +fn complete_fields( + ctx: &CompletionContext, + receiver: &hir::Type, + mut f: impl FnMut(Either, hir::Type), +) { + for receiver in receiver.autoderef(ctx.db) { + for (field, ty) in receiver.fields(ctx.db) { + if ctx.scope.module().map_or(false, |m| !field.is_visible_from(ctx.db, m)) { + // Skip private field. FIXME: If the definition location of the + // field is editable, we should show the completion + continue; + } + f(Either::Left(field), ty); + } + for (i, ty) in receiver.tuple_fields(ctx.db).into_iter().enumerate() { + // FIXME: Handle visibility + f(Either::Right(i), ty); + } + } +} + +fn complete_methods( + ctx: &CompletionContext, + receiver: &hir::Type, + mut f: impl FnMut(hir::Function), +) { + if let Some(krate) = ctx.krate { + let mut seen_methods = FxHashSet::default(); + let traits_in_scope = ctx.scope.traits_in_scope(); + receiver.iterate_method_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, func| { + if func.self_param(ctx.db).is_some() + && ctx.scope.module().map_or(true, |m| func.is_visible_from(ctx.db, m)) + && seen_methods.insert(func.name(ctx.db)) + { + f(func); + } + None::<()> + }); + } +} -- cgit v1.2.3 From d346f5bf75bfe3c7dc357c748c257569c0fb23c3 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 28 May 2021 14:38:09 +0200 Subject: Less strings, more hir::Names --- crates/ide_completion/src/completions.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'crates/ide_completion/src/completions.rs') diff --git a/crates/ide_completion/src/completions.rs b/crates/ide_completion/src/completions.rs index 0f0553a65..dd92bc510 100644 --- a/crates/ide_completion/src/completions.rs +++ b/crates/ide_completion/src/completions.rs @@ -74,7 +74,7 @@ impl Completions { pub(crate) fn add_field( &mut self, ctx: &CompletionContext, - receiver: Option, + receiver: Option, field: hir::Field, ty: &hir::Type, ) { @@ -85,7 +85,7 @@ impl Completions { pub(crate) fn add_tuple_field( &mut self, ctx: &CompletionContext, - receiver: Option, + receiver: Option, field: usize, ty: &hir::Type, ) { @@ -141,7 +141,7 @@ impl Completions { &mut self, ctx: &CompletionContext, func: hir::Function, - receiver: Option, + receiver: Option, local_name: Option, ) { if let Some(item) = render_method(RenderContext::new(ctx), None, receiver, local_name, func) -- cgit v1.2.3 From 4507382f2e66cd0e6498228bfdffb16769063b0f Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 28 May 2021 15:09:10 +0200 Subject: Move unprefixed field/method completion to `dot` --- crates/ide_completion/src/completions.rs | 45 +------------------------------- 1 file changed, 1 insertion(+), 44 deletions(-) (limited to 'crates/ide_completion/src/completions.rs') diff --git a/crates/ide_completion/src/completions.rs b/crates/ide_completion/src/completions.rs index dd92bc510..ffdcdc930 100644 --- a/crates/ide_completion/src/completions.rs +++ b/crates/ide_completion/src/completions.rs @@ -18,10 +18,8 @@ pub(crate) mod unqualified_path; use std::iter; -use either::Either; -use hir::{known, HasVisibility}; +use hir::known; use ide_db::SymbolKind; -use rustc_hash::FxHashSet; use crate::{ item::{Builder, CompletionKind}, @@ -254,44 +252,3 @@ fn complete_enum_variants( } } } - -fn complete_fields( - ctx: &CompletionContext, - receiver: &hir::Type, - mut f: impl FnMut(Either, hir::Type), -) { - for receiver in receiver.autoderef(ctx.db) { - for (field, ty) in receiver.fields(ctx.db) { - if ctx.scope.module().map_or(false, |m| !field.is_visible_from(ctx.db, m)) { - // Skip private field. FIXME: If the definition location of the - // field is editable, we should show the completion - continue; - } - f(Either::Left(field), ty); - } - for (i, ty) in receiver.tuple_fields(ctx.db).into_iter().enumerate() { - // FIXME: Handle visibility - f(Either::Right(i), ty); - } - } -} - -fn complete_methods( - ctx: &CompletionContext, - receiver: &hir::Type, - mut f: impl FnMut(hir::Function), -) { - if let Some(krate) = ctx.krate { - let mut seen_methods = FxHashSet::default(); - let traits_in_scope = ctx.scope.traits_in_scope(); - receiver.iterate_method_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, func| { - if func.self_param(ctx.db).is_some() - && ctx.scope.module().map_or(true, |m| func.is_visible_from(ctx.db, m)) - && seen_methods.insert(func.name(ctx.db)) - { - f(func); - } - None::<()> - }); - } -} -- cgit v1.2.3