Skip to content

Commit 335de05

Browse files
authored
fix: honor function visibility in LSP completion (#5809)
# Description ## Problem Resolves #5808 ## Summary Reuses the same logic done when resolving a `use` or `Path` in the compiler. ## Additional Context It's debatable whether this functionality is desired, because sometimes you add a function, want to use it and autocompletion doesn't suggest it, and it takes a while for you to realize that you forgot to add `pub`. However, a lot of the suggested functions come from the std or external crates, and it doesn't make sense to reveal these private functions. This is also how Rust Analyzer works too. ## Documentation Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings.
1 parent 1c84038 commit 335de05

3 files changed

Lines changed: 55 additions & 32 deletions

File tree

compiler/noirc_frontend/src/hir/resolution/import.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,9 @@ fn resolve_external_dep(
374374
resolve_path_to_ns(&dep_directive, dep_module.krate, importing_crate, def_maps, path_references)
375375
}
376376

377-
// Issue an error if the given private function is being called from a non-child module, or
378-
// if the given pub(crate) function is being called from another crate
379-
fn can_reference_module_id(
377+
// Returns false if the given private function is being called from a non-child module, or
378+
// if the given pub(crate) function is being called from another crate. Otherwise returns true.
379+
pub fn can_reference_module_id(
380380
def_maps: &BTreeMap<CrateId, CrateDefMap>,
381381
importing_crate: CrateId,
382382
current_module: LocalModuleId,

tooling/lsp/src/requests/completion.rs

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,19 @@ use noirc_errors::{Location, Span};
1616
use noirc_frontend::{
1717
ast::{
1818
AsTraitPath, BlockExpression, CallExpression, ConstructorExpression, Expression,
19-
ExpressionKind, ForLoopStatement, Ident, IfExpression, LValue, Lambda, LetStatement,
20-
MemberAccessExpression, MethodCallExpression, NoirFunction, NoirStruct, NoirTraitImpl,
21-
Path, PathKind, PathSegment, Pattern, Statement, StatementKind, TraitItem, TypeImpl,
22-
UnresolvedGeneric, UnresolvedGenerics, UnresolvedType, UnresolvedTypeData, UseTree,
23-
UseTreeKind,
19+
ExpressionKind, ForLoopStatement, Ident, IfExpression, ItemVisibility, LValue, Lambda,
20+
LetStatement, MemberAccessExpression, MethodCallExpression, NoirFunction, NoirStruct,
21+
NoirTraitImpl, Path, PathKind, PathSegment, Pattern, Statement, StatementKind, TraitItem,
22+
TypeImpl, UnresolvedGeneric, UnresolvedGenerics, UnresolvedType, UnresolvedTypeData,
23+
UseTree, UseTreeKind,
2424
},
2525
graph::{CrateId, Dependency},
2626
hir::{
2727
def_map::{CrateDefMap, LocalModuleId, ModuleId},
28-
resolution::path_resolver::{PathResolver, StandardPathResolver},
28+
resolution::{
29+
import::can_reference_module_id,
30+
path_resolver::{PathResolver, StandardPathResolver},
31+
},
2932
},
3033
hir_def::traits::Trait,
3134
macros_api::{ModuleDefId, NodeInterner},
@@ -1238,29 +1241,33 @@ impl<'a> NodeFinder<'a> {
12381241

12391242
if name_matches(name, prefix) {
12401243
let per_ns = module_data.find_name(ident);
1241-
if let Some((module_def_id, _, _)) = per_ns.types {
1242-
if let Some(completion_item) = self.module_def_id_completion_item(
1243-
module_def_id,
1244-
name.clone(),
1245-
function_completion_kind,
1246-
function_kind,
1247-
requested_items,
1248-
) {
1249-
self.completion_items.push(completion_item);
1250-
self.suggested_module_def_ids.insert(module_def_id);
1244+
if let Some((module_def_id, visibility, _)) = per_ns.types {
1245+
if is_visible(module_id, self.module_id, visibility, self.def_maps) {
1246+
if let Some(completion_item) = self.module_def_id_completion_item(
1247+
module_def_id,
1248+
name.clone(),
1249+
function_completion_kind,
1250+
function_kind,
1251+
requested_items,
1252+
) {
1253+
self.completion_items.push(completion_item);
1254+
self.suggested_module_def_ids.insert(module_def_id);
1255+
}
12511256
}
12521257
}
12531258

1254-
if let Some((module_def_id, _, _)) = per_ns.values {
1255-
if let Some(completion_item) = self.module_def_id_completion_item(
1256-
module_def_id,
1257-
name.clone(),
1258-
function_completion_kind,
1259-
function_kind,
1260-
requested_items,
1261-
) {
1262-
self.completion_items.push(completion_item);
1263-
self.suggested_module_def_ids.insert(module_def_id);
1259+
if let Some((module_def_id, visibility, _)) = per_ns.values {
1260+
if is_visible(module_id, self.module_id, visibility, self.def_maps) {
1261+
if let Some(completion_item) = self.module_def_id_completion_item(
1262+
module_def_id,
1263+
name.clone(),
1264+
function_completion_kind,
1265+
function_kind,
1266+
requested_items,
1267+
) {
1268+
self.completion_items.push(completion_item);
1269+
self.suggested_module_def_ids.insert(module_def_id);
1270+
}
12641271
}
12651272
}
12661273
}
@@ -1384,6 +1391,21 @@ fn module_def_id_from_reference_id(reference_id: ReferenceId) -> Option<ModuleDe
13841391
}
13851392
}
13861393

1394+
fn is_visible(
1395+
target_module_id: ModuleId,
1396+
current_module_id: ModuleId,
1397+
visibility: ItemVisibility,
1398+
def_maps: &BTreeMap<CrateId, CrateDefMap>,
1399+
) -> bool {
1400+
can_reference_module_id(
1401+
def_maps,
1402+
current_module_id.krate,
1403+
current_module_id.local_id,
1404+
target_module_id,
1405+
visibility,
1406+
)
1407+
}
1408+
13871409
#[cfg(test)]
13881410
mod completion_name_matches_tests {
13891411
use crate::requests::completion::name_matches;

tooling/lsp/src/requests/completion/tests.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ mod completion_tests {
182182
async fn test_use_function() {
183183
let src = r#"
184184
mod foo {
185-
fn bar(x: i32) -> u64 { 0 }
185+
pub fn bar(x: i32) -> u64 { 0 }
186+
fn bar_is_private(x: i32) -> u64 { 0 }
186187
}
187188
use foo::>|<
188189
"#;
@@ -1703,7 +1704,7 @@ mod completion_tests {
17031704
async fn test_completes_after_colon_in_the_middle_of_an_ident_middle_segment() {
17041705
let src = r#"
17051706
mod foo {
1706-
fn bar() {}
1707+
pub fn bar() {}
17071708
}
17081709
17091710
fn main() {
@@ -1725,7 +1726,7 @@ mod completion_tests {
17251726
async fn test_completes_at_function_call_name() {
17261727
let src = r#"
17271728
mod foo {
1728-
fn bar() {}
1729+
pub fn bar() {}
17291730
}
17301731
17311732
fn main() {

0 commit comments

Comments
 (0)