Skip to content

Commit

Permalink
Completion List Updates (#1011)
Browse files Browse the repository at this point in the history
Ignore "Microsoft.Quantum.Unstable" and internal items from completion
list. Internal items are only ignored if the user would not have access
to them at the cursor.
  • Loading branch information
ScottCarda-MS authored Jan 11, 2024
1 parent b454828 commit 6a450b9
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 5 deletions.
36 changes: 31 additions & 5 deletions language_service/src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::display::CodeDisplay;
use crate::protocol::{CompletionItem, CompletionItemKind, CompletionList};
use crate::qsc_utils::{protocol_span, span_contains};
use qsc::ast::visit::{self, Visitor};
use qsc::hir::{ItemKind, Package, PackageId};
use qsc::hir::{ItemKind, Package, PackageId, Visibility};
use qsc::resolve::{Local, LocalKind};
use rustc_hash::FxHashSet;
use std::rc::Rc;
Expand Down Expand Up @@ -385,11 +385,33 @@ impl CompletionListBuilder {
.package;
let display = CodeDisplay { compilation };

let is_user_package = compilation.user_package_id == package_id;

package.items.values().filter_map(move |i| {
// We only want items whose parents are namespaces
if let Some(item_id) = i.parent {
if let Some(parent) = package.items.get(item_id) {
if let ItemKind::Namespace(namespace, _) = &parent.kind {
if namespace.name.starts_with("Microsoft.Quantum.Unstable") {
return None;
}
// If the item's visibility is internal, the item may be ignored
if matches!(i.visibility, Visibility::Internal) {
if !is_user_package {
return None; // ignore item if not in the user's package
}
// ignore item if the user is not in the item's namespace
match &current_namespace_name {
Some(curr_ns) => {
if *curr_ns != namespace.name {
return None;
}
}
None => {
return None;
}
}
}
return match &i.kind {
ItemKind::Callable(callable_decl) => {
let name = callable_decl.name.name.as_ref();
Expand Down Expand Up @@ -498,10 +520,14 @@ impl CompletionListBuilder {

fn get_namespaces(package: &'_ Package) -> impl Iterator<Item = CompletionItem> + '_ {
package.items.values().filter_map(|i| match &i.kind {
ItemKind::Namespace(namespace, _) => Some(CompletionItem::new(
namespace.name.to_string(),
CompletionItemKind::Module,
)),
ItemKind::Namespace(namespace, _)
if !namespace.name.starts_with("Microsoft.Quantum.Unstable") =>
{
Some(CompletionItem::new(
namespace.name.to_string(),
CompletionItemKind::Module,
))
}
_ => None,
})
}
Expand Down
141 changes: 141 additions & 0 deletions language_service/src/completion/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,147 @@ fn assert_no_duplicates(mut actual_completions: CompletionList) {
assert!(dups.is_empty(), "duplicate completions found: {dups:#?}");
}

#[test]
fn ignore_unstable_namespace() {
check(
r#"
namespace Test {
open ↘
}"#,
&["FakeStdLib", "Microsoft.Quantum.Unstable"],
&expect![[r#"
[
Some(
CompletionItem {
label: "FakeStdLib",
kind: Module,
sort_text: Some(
"1101FakeStdLib",
),
detail: None,
additional_text_edits: None,
},
),
None,
]
"#]],
);
}

#[test]
fn ignore_unstable_callable() {
check(
r#"
namespace Test {
open Microsoft.Quantum.Unstable;
operation Foo() : Unit {
}
}"#,
&["Fake", "UnstableFake"],
&expect![[r#"
[
Some(
CompletionItem {
label: "Fake",
kind: Function,
sort_text: Some(
"0700Fake",
),
detail: Some(
"operation Fake() : Unit",
),
additional_text_edits: Some(
[
(
Span {
start: 38,
end: 38,
},
"open FakeStdLib;\n ",
),
],
),
},
),
None,
]
"#]],
);
}

#[test]
fn ignore_internal_callable() {
check(
r#"
namespace Test {
internal operation Foo() : Unit {}
operation Bar() : Unit {
}
}
namespace Test {
internal operation Baz() : Unit {}
}"#,
&["Fake", "Foo", "Baz", "Hidden"],
&expect![[r#"
[
Some(
CompletionItem {
label: "Fake",
kind: Function,
sort_text: Some(
"0700Fake",
),
detail: Some(
"operation Fake() : Unit",
),
additional_text_edits: Some(
[
(
Span {
start: 38,
end: 38,
},
"open FakeStdLib;\n ",
),
],
),
},
),
Some(
CompletionItem {
label: "Foo",
kind: Function,
sort_text: Some(
"0600Foo",
),
detail: Some(
"operation Foo() : Unit",
),
additional_text_edits: None,
},
),
Some(
CompletionItem {
label: "Baz",
kind: Function,
sort_text: Some(
"0600Baz",
),
detail: Some(
"operation Baz() : Unit",
),
additional_text_edits: None,
},
),
None,
]
"#]],
);
}

#[test]
fn in_block_contains_std_functions_from_open_namespace() {
check(
Expand Down
5 changes: 5 additions & 0 deletions language_service/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ fn compile_fake_stdlib() -> (PackageStore, PackageId) {
Fake();
}
operation FakeWithTypeParam<'A>(a : 'A) : 'A { a }
internal operation Hidden() : Unit {}
}
namespace Microsoft.Quantum.Unstable {
operation UnstableFake() : Unit {}
}"#
.into(),
)],
Expand Down

0 comments on commit 6a450b9

Please sign in to comment.