microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.23.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

source/language_service/src/completion/tests.rs

2549lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use super::{Compilation, CompletionItem, get_completions};
5use crate::{
6 Encoding,
7 protocol::CompletionList,
8 test_utils::{
9 compile_notebook_with_markers, compile_project_with_markers,
10 compile_with_dependency_with_markers, compile_with_markers,
11 },
12};
13use expect_test::{Expect, expect};
14use indoc::indoc;
15use qsc::line_column::Position;
16
17mod class_completions;
18mod openqasm;
19
20fn check(
21 compilation: &Compilation,
22 cursor_uri: &str,
23 cursor_position: Position,
24 completions_to_check: &[&str],
25 expect: &Expect,
26) {
27 let actual_completions =
28 get_completions(compilation, cursor_uri, cursor_position, Encoding::Utf8);
29
30 let mut checked_completions: Vec<(String, Option<&CompletionItem>)> = completions_to_check
31 .iter()
32 .map(|comp| {
33 (
34 (*comp).to_string(),
35 actual_completions
36 .items
37 .iter()
38 .find(|item| item.label == **comp),
39 )
40 })
41 .collect();
42
43 // Sort by actual items' sort text
44 checked_completions.sort_by_key(|c| {
45 c.1.map_or(String::new(), |c| c.sort_text.clone().unwrap_or_default())
46 });
47
48 expect.assert_debug_eq(&ActualCompletions {
49 completions: checked_completions,
50 });
51
52 assert_no_duplicates(actual_completions);
53}
54
55fn check_single_file(source_with_cursor: &str, completions_to_check: &[&str], expect: &Expect) {
56 let (compilation, cursor_position, _) = compile_with_markers(source_with_cursor, true);
57
58 check(
59 &compilation,
60 "<source>",
61 cursor_position,
62 completions_to_check,
63 expect,
64 );
65}
66
67fn check_with_stdlib(source_with_cursor: &str, completions_to_check: &[&str], expect: &Expect) {
68 let (compilation, cursor_position, _) = compile_with_markers(source_with_cursor, false);
69
70 check(
71 &compilation,
72 "<source>",
73 cursor_position,
74 completions_to_check,
75 expect,
76 );
77}
78
79fn check_project(
80 sources_with_markers: &[(&str, &str)],
81 completions_to_check: &[&str],
82 expect: &Expect,
83) {
84 let (compilation, cursor_uri, cursor_position, _) =
85 compile_project_with_markers(sources_with_markers, true);
86
87 check(
88 &compilation,
89 &cursor_uri,
90 cursor_position,
91 completions_to_check,
92 expect,
93 );
94}
95
96fn check_notebook(
97 cells_with_markers: &[(&str, &str)],
98 completions_to_check: &[&str],
99 expect: &Expect,
100) {
101 let (compilation, cell_uri, cursor_position, _) =
102 compile_notebook_with_markers(cells_with_markers);
103
104 check(
105 &compilation,
106 &cell_uri,
107 cursor_position,
108 completions_to_check,
109 expect,
110 );
111}
112
113fn check_with_dependency(
114 source_with_cursor: &str,
115 dependency_alias: &str,
116 dependency_source: &str,
117 completions_to_check: &[&str],
118 expect: &Expect,
119) {
120 let (compilation, cursor_uri, cursor_position, _) = compile_with_dependency_with_markers(
121 &[("<source>", source_with_cursor)],
122 dependency_alias,
123 &[("<dependency_source>", dependency_source)],
124 );
125
126 check(
127 &compilation,
128 &cursor_uri,
129 cursor_position,
130 completions_to_check,
131 expect,
132 );
133}
134
135fn check_no_completions(source_with_cursor: &str) {
136 let (compilation, cursor_position, _) = compile_with_markers(source_with_cursor, true);
137 let actual_completions =
138 get_completions(&compilation, "<source>", cursor_position, Encoding::Utf8);
139 assert_eq!(actual_completions.items, Vec::default());
140}
141
142fn assert_no_duplicates(mut actual_completions: CompletionList) {
143 actual_completions
144 .items
145 .sort_by_key(|item| item.label.clone());
146 let mut dups: Vec<&CompletionItem> = vec![];
147 let mut last: Option<&CompletionItem> = None;
148 for completion in &actual_completions.items {
149 if let Some(last) = last.take()
150 && last.label == completion.label
151 {
152 dups.push(last);
153 dups.push(completion);
154 }
155 last.replace(completion);
156 }
157
158 assert!(dups.is_empty(), "duplicate completions found: {dups:#?}");
159}
160
161struct ActualCompletions<'a> {
162 completions: Vec<(String, Option<&'a CompletionItem>)>,
163}
164
165impl std::fmt::Debug for ActualCompletions<'_> {
166 fn fmt(&self, output: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
167 let (found, not_found): (Vec<_>, Vec<_>) =
168 self.completions.iter().partition(|(_, c)| c.is_some());
169
170 if !found.is_empty() {
171 write!(output, "found, sorted:")?;
172 for (label, c) in &found {
173 let c = c.expect("expected completion item");
174 write!(output, "\n {label:?} ({:?})", c.kind)?;
175 if let Some(detail) = &c.detail {
176 write!(output, "\n detail: {detail:?}")?;
177 }
178
179 if let Some(edits) = &c.additional_text_edits {
180 write!(output, "\n additional_text_edits:")?;
181 for edit in edits {
182 write!(
183 output,
184 "\n [{}:{}-{}:{}] {:?}",
185 edit.range.start.line,
186 edit.range.start.column,
187 edit.range.end.line,
188 edit.range.end.column,
189 edit.new_text,
190 )?;
191 }
192 }
193 }
194 }
195
196 if !not_found.is_empty() && !found.is_empty() {
197 write!(output, "\n\n")?; // Add blank line between sections
198 }
199
200 if !not_found.is_empty() {
201 write!(output, "not found:")?;
202 for (label, _) in not_found {
203 write!(output, "\n {label:?}")?;
204 }
205 }
206
207 Ok(())
208 }
209}
210
211#[test]
212fn ignore_unstable_namespace() {
213 check_single_file(
214 r#"
215 namespace Test {
216 open ↘
217 }"#,
218 &["FakeStdLib", "Microsoft.Quantum.Unstable"],
219 &expect![[r#"
220 found, sorted:
221 "FakeStdLib" (Module)
222
223 not found:
224 "Microsoft.Quantum.Unstable"
225 "#]],
226 );
227}
228
229#[test]
230fn ignore_unstable_callable() {
231 check_single_file(
232 r#"
233 namespace Test {
234 import Microsoft.Quantum.Unstable.*;
235 operation Foo() : Unit {
236
237 }
238 }"#,
239 &["Fake", "UnstableFake"],
240 &expect![[r#"
241 found, sorted:
242 "Fake" (Function)
243 detail: "operation Fake() : Unit"
244 additional_text_edits:
245 [2:12-2:12] "import FakeStdLib.Fake;\n "
246
247 not found:
248 "UnstableFake"
249 "#]],
250 );
251}
252
253#[test]
254fn ignore_internal_callable() {
255 check_single_file(
256 r#"
257 namespace Test {
258 internal operation Foo() : Unit {}
259 operation Bar() : Unit {
260
261 }
262 }
263
264 namespace Test {
265 internal operation Baz() : Unit {}
266 }"#,
267 &["Fake", "Foo", "Baz", "Hidden"],
268 &expect![[r#"
269 found, sorted:
270 "Baz" (Function)
271 detail: "operation Baz() : Unit"
272 "Foo" (Function)
273 detail: "operation Foo() : Unit"
274 "Fake" (Function)
275 detail: "operation Fake() : Unit"
276 additional_text_edits:
277 [2:12-2:12] "import FakeStdLib.Fake;\n "
278
279 not found:
280 "Hidden"
281 "#]],
282 );
283}
284
285#[test]
286fn in_block_contains_std_functions_from_open_namespace() {
287 check_single_file(
288 r#"
289 namespace Test {
290 open FakeStdLib;
291 operation Foo() : Unit {
292
293 }
294 }"#,
295 &["Fake", "FakeWithParam", "FakeCtlAdj"],
296 &expect![[r#"
297 found, sorted:
298 "Fake" (Function)
299 detail: "operation Fake() : Unit"
300 "FakeCtlAdj" (Function)
301 detail: "operation FakeCtlAdj() : Unit is Adj + Ctl"
302 "FakeWithParam" (Function)
303 detail: "operation FakeWithParam(x : Int) : Unit"
304 "#]],
305 );
306}
307
308#[allow(clippy::too_many_lines)]
309#[test]
310fn in_block_contains_std_functions() {
311 check_single_file(
312 indoc! {r#"
313 namespace Test {
314 operation Foo() : Unit {
315
316 }
317 }"#},
318 &["Fake", "FakeWithParam", "FakeCtlAdj"],
319 &expect![[r#"
320 found, sorted:
321 "Fake" (Function)
322 detail: "operation Fake() : Unit"
323 additional_text_edits:
324 [1:4-1:4] "import FakeStdLib.Fake;\n "
325 "FakeCtlAdj" (Function)
326 detail: "operation FakeCtlAdj() : Unit is Adj + Ctl"
327 additional_text_edits:
328 [1:4-1:4] "import FakeStdLib.FakeCtlAdj;\n "
329 "FakeWithParam" (Function)
330 detail: "operation FakeWithParam(x : Int) : Unit"
331 additional_text_edits:
332 [1:4-1:4] "import FakeStdLib.FakeWithParam;\n "
333 "#]],
334 );
335}
336
337#[test]
338fn in_block_contains_newtypes() {
339 check_single_file(
340 r#"
341 namespace Test {
342 newtype Custom = String;
343 operation Foo() : Unit {
344 let x: ↘
345 }
346 }"#,
347 &["Custom", "Udt"],
348 &expect![[r#"
349 found, sorted:
350 "Custom" (Interface)
351 detail: "newtype Custom = String"
352 "Udt" (Interface)
353 detail: "struct Udt { x : Int, y : Int }"
354 additional_text_edits:
355 [2:8-2:8] "import FakeStdLib.Udt;\n "
356 "#]],
357 );
358}
359
360#[test]
361fn types_only_in_signature() {
362 check_single_file(
363 r#"
364 namespace Test {
365 operation Foo(foo: ↘) : Unit {
366 }
367 operation Bar() : Unit {
368 }
369 }"#,
370 &["Int", "String", "Bar"],
371 &expect![[r#"
372 found, sorted:
373 "Int" (Interface)
374 "String" (Interface)
375
376 not found:
377 "Bar"
378 "#]],
379 );
380}
381
382#[test]
383fn in_block_no_auto_open() {
384 check_single_file(
385 indoc! {r#"
386 namespace Test {
387 open FakeStdLib;
388 operation Foo() : Unit {
389
390 }
391 }"#},
392 &["Fake"],
393 &expect![[r#"
394 found, sorted:
395 "Fake" (Function)
396 detail: "operation Fake() : Unit"
397 "#]],
398 );
399}
400
401#[test]
402fn in_block_with_alias() {
403 check_single_file(
404 indoc! {r#"
405 namespace Test {
406 open FakeStdLib as Alias;
407 operation Foo() : Unit {
408
409 }
410 }"#},
411 &["Alias.Fake"],
412 &expect![[r#"
413 found, sorted:
414 "Alias.Fake" (Function)
415 detail: "operation Fake() : Unit"
416 "#]],
417 );
418}
419
420#[test]
421fn members_of_aliased_namespace() {
422 check_single_file(
423 indoc! {r#"
424 namespace Test {
425 open FakeStdLib as Alias;
426 operation Foo() : Unit {
427 Alias.↘
428 }
429 }"#},
430 &["Fake", "Alias.Fake", "Library", "Alias.Library", "Foo"],
431 &expect![[r#"
432 found, sorted:
433 "Fake" (Function)
434 detail: "operation Fake() : Unit"
435 "Library" (Module)
436
437 not found:
438 "Alias.Fake"
439 "Alias.Library"
440 "Foo"
441 "#]],
442 );
443}
444
445#[test]
446fn aliased_exact_import() {
447 check_single_file(
448 indoc! {r#"
449 namespace Test {
450 import FakeStdLib.Fake as Alias;
451 operation Foo() : Unit {
452
453 }
454 }"#},
455 &["Fake", "Alias.Fake", "Alias"],
456 &expect![[r#"
457 found, sorted:
458 "Alias" (Function)
459 detail: "operation Fake() : Unit"
460
461 not found:
462 "Fake"
463 "Alias.Fake"
464 "#]],
465 );
466}
467
468#[test]
469fn open_from_dependency() {
470 check_with_dependency(
471 r"
472 namespace Test {
473 open MyDep.Dependency;
474 operation Foo() : Unit {
475
476 }
477 }",
478 "MyDep",
479 "namespace Dependency { operation Baz() : Unit {} export Baz; }",
480 &["Baz"],
481 &expect![[r#"
482 found, sorted:
483 "Baz" (Function)
484 detail: "operation Baz() : Unit"
485 "#]],
486 );
487}
488
489#[test]
490fn open_with_alias_from_dependency() {
491 check_with_dependency(
492 r"
493 namespace Test {
494 open MyDep.Dependency as Alias;
495 open SamePackage as Alias1;
496 operation Foo() : Unit {
497
498 }
499 }
500 namespace SamePackage { operation Bar() : Unit {} }",
501 "MyDep",
502 "namespace Dependency { operation Baz() : Unit {} export Baz; }",
503 &["Alias.Baz", "Baz", "Alias1.Bar", "Bar"],
504 &expect![[r#"
505 found, sorted:
506 "Alias1.Bar" (Function)
507 detail: "operation Bar() : Unit"
508 "Alias.Baz" (Function)
509 detail: "operation Baz() : Unit"
510
511 not found:
512 "Baz"
513 "Bar"
514 "#]],
515 );
516}
517
518#[test]
519fn import_ns_with_alias_from_dependency() {
520 check_with_dependency(
521 r"
522 namespace Test {
523 import MyDep.Dependency as Alias;
524 import SamePackage as Alias1;
525 operation Foo() : Unit {
526
527 }
528 }
529 namespace SamePackage { operation Bar() : Unit {} }",
530 "MyDep",
531 "namespace Dependency { operation Baz() : Unit {} export Baz; }",
532 &["Alias.Baz", "Baz", "Alias1.Bar", "Bar"],
533 &expect![[r#"
534 found, sorted:
535 "Alias1.Bar" (Function)
536 detail: "operation Bar() : Unit"
537 "Alias.Baz" (Function)
538 detail: "operation Baz() : Unit"
539
540 not found:
541 "Baz"
542 "Bar"
543 "#]],
544 );
545}
546
547#[test]
548fn exact_import_from_dependency() {
549 check_with_dependency(
550 r"
551 namespace Test {
552 import MyDep.Dependency.Baz;
553 operation Foo() : Unit {
554
555 }
556 }",
557 "MyDep",
558 "namespace Dependency { operation Baz() : Unit {} export Baz; }",
559 &["Baz"],
560 &expect![[r#"
561 found, sorted:
562 "Baz" (Function)
563 detail: "operation Baz() : Unit"
564 "#]],
565 );
566}
567
568#[test]
569fn in_block_from_other_namespace() {
570 check_single_file(
571 indoc! {r#"
572 namespace Test {
573 operation Bar() : Unit {
574
575 }
576 export Bar;
577 }
578 namespace Other {
579 operation Foo() : Unit {}
580 export Foo;
581 }"#},
582 &["Foo"],
583 &expect![[r#"
584 found, sorted:
585 "Foo" (Function)
586 detail: "operation Foo() : Unit"
587 additional_text_edits:
588 [1:4-1:4] "import Other.Foo;\n "
589 "#]],
590 );
591}
592
593#[test]
594fn auto_open_multiple_files() {
595 check_project(
596 &[
597 (
598 "foo.qs",
599 indoc! {r#"namespace Foo { operation FooOperation() : Unit {} export FooOperation; }
600 "#},
601 ),
602 (
603 "bar.qs",
604 indoc! {r#"namespace Bar { operation BarOperation() : Unit { ↘ } export BarOperation; }
605 "#},
606 ),
607 ],
608 &["FooOperation"],
609 &expect![[r#"
610 found, sorted:
611 "FooOperation" (Function)
612 detail: "operation FooOperation() : Unit"
613 additional_text_edits:
614 [0:16-0:16] "import Foo.FooOperation;\n "
615 "#]],
616 );
617}
618
619#[test]
620fn in_block_nested_op() {
621 check_single_file(
622 indoc! {r#"
623 namespace Test {
624 operation Bar() : Unit {
625 operation Foo() : Unit {}
626
627 }
628 }"#},
629 &["Foo"],
630 &expect![[r#"
631 found, sorted:
632 "Foo" (Function)
633 detail: "operation Foo() : Unit"
634 "#]],
635 );
636}
637
638#[test]
639fn in_block_hidden_nested_op() {
640 check_single_file(
641 indoc! {r#"
642 namespace Test {
643 operation Baz() : Unit {
644
645 }
646 operation Foo() : Unit {
647 operation Bar() : Unit {}
648 }
649 }"#},
650 &["Bar"],
651 &expect![[r#"
652 not found:
653 "Bar"
654 "#]],
655 );
656}
657
658#[test]
659fn in_namespace_contains_open() {
660 check_single_file(
661 indoc! {r#"
662 namespace Test {
663
664 operation Foo() : Unit {
665 }
666 }"#},
667 &["open"],
668 &expect![[r#"
669 found, sorted:
670 "open" (Keyword)
671 "#]],
672 );
673}
674
675#[test]
676fn top_level_contains_namespace() {
677 check_single_file(
678 indoc! {r#"
679 namespace Test {}
680
681 "#},
682 &["namespace"],
683 &expect![[r#"
684 found, sorted:
685 "namespace" (Keyword)
686 "#]],
687 );
688}
689
690#[test]
691fn attributes() {
692 check_single_file(
693 indoc! {r#"
694 namespace Test {
695 @↘
696 }
697 "#},
698 &["EntryPoint"],
699 &expect![[r#"
700 found, sorted:
701 "EntryPoint" (Interface)
702 "#]],
703 );
704}
705
706#[test]
707fn stdlib_udt() {
708 check_single_file(
709 indoc! {r#"
710 namespace Test {
711 operation Foo() : Unit {
712
713 }
714 "#},
715 &["TakesUdt"],
716 &expect![[r#"
717 found, sorted:
718 "TakesUdt" (Function)
719 detail: "function TakesUdt(input : Udt) : Udt"
720 additional_text_edits:
721 [1:4-1:4] "import FakeStdLib.TakesUdt;\n "
722 "#]],
723 );
724}
725
726#[test]
727fn notebook_top_level() {
728 check_notebook(
729 &[(
730 "cell1",
731 indoc! {r#"operation Foo() : Unit {}
732
733 "#},
734 )],
735 &["operation", "namespace", "let", "Fake"],
736 &expect![[r#"
737 found, sorted:
738 "let" (Keyword)
739 "namespace" (Keyword)
740 "operation" (Keyword)
741 "Fake" (Function)
742 detail: "operation Fake() : Unit"
743 additional_text_edits:
744 [0:0-0:0] "import FakeStdLib.Fake;\n"
745 "#]],
746 );
747}
748
749#[test]
750fn notebook_top_level_global() {
751 check_notebook(
752 &[(
753 "cell1",
754 indoc! {r#"operation Foo() : Unit {}
755
756 "#},
757 )],
758 &["Fake"],
759 &expect![[r#"
760 found, sorted:
761 "Fake" (Function)
762 detail: "operation Fake() : Unit"
763 additional_text_edits:
764 [0:0-0:0] "import FakeStdLib.Fake;\n"
765 "#]],
766 );
767}
768
769#[test]
770fn notebook_top_level_namespace_already_open_for_global() {
771 check_notebook(
772 &[(
773 "cell1",
774 indoc! {r#"
775 open FakeStdLib;
776 operation Foo() : Unit {}
777
778 "#},
779 )],
780 &["Fake"],
781 &expect![[r#"
782 found, sorted:
783 "Fake" (Function)
784 detail: "operation Fake() : Unit"
785 "#]],
786 );
787}
788
789#[test]
790fn notebook_block() {
791 check_notebook(
792 &[(
793 "cell1",
794 indoc! {r#"operation Foo() : Unit {
795
796 }
797 "#},
798 )],
799 &["Fake", "let"],
800 &expect![[r#"
801 found, sorted:
802 "let" (Keyword)
803 "Fake" (Function)
804 detail: "operation Fake() : Unit"
805 additional_text_edits:
806 [0:0-0:0] "import FakeStdLib.Fake;\n"
807 "#]],
808 );
809}
810
811#[test]
812fn notebook_auto_open_start_of_cell_empty() {
813 check_notebook(
814 &[
815 (
816 "cell1",
817 indoc! {"
818 //qsharp
819 namespace Foo { operation Bar() : Unit {} }"
820 },
821 ),
822 (
823 "cell2",
824 indoc! {"
825 //qsharp
826 ↘"
827 },
828 ),
829 ],
830 &["Fake"],
831 &expect![[r#"
832 found, sorted:
833 "Fake" (Function)
834 detail: "operation Fake() : Unit"
835 additional_text_edits:
836 [1:0-1:0] "import FakeStdLib.Fake;\n"
837 "#]],
838 );
839}
840
841#[test]
842fn notebook_auto_open_start_of_cell() {
843 check_notebook(
844 &[
845 (
846 "cell1",
847 indoc! {"
848 //qsharp
849 namespace Foo { operation Bar() : Unit {} }"
850 },
851 ),
852 (
853 "cell2",
854 indoc! {r#"
855 //qsharp
856 Message("hi")
857 ↘"#
858 },
859 ),
860 ],
861 &["Fake"],
862 &expect![[r#"
863 found, sorted:
864 "Fake" (Function)
865 detail: "operation Fake() : Unit"
866 additional_text_edits:
867 [1:0-1:0] "import FakeStdLib.Fake;\n"
868 "#]],
869 );
870}
871
872#[test]
873fn notebook_last_expr() {
874 check_notebook(
875 &[(
876 "cell1",
877 indoc! {"
878 //qsharp
879 function Foo() : Unit {}
880 3 + ↘"
881 },
882 )],
883 &["Foo", "Fake"],
884 &expect![[r#"
885 found, sorted:
886 "Foo" (Function)
887 detail: "function Foo() : Unit"
888 "Fake" (Function)
889 detail: "operation Fake() : Unit"
890 additional_text_edits:
891 [1:0-1:0] "import FakeStdLib.Fake;\n"
892 "#]],
893 );
894}
895
896#[test]
897fn local_vars() {
898 check_single_file(
899 r#"
900 namespace Test {
901 operation Foo() : Unit {
902 let bar = 3;
903
904 let foo = 3;
905 }
906 }"#,
907 &["foo", "bar"],
908 &expect![[r#"
909 found, sorted:
910 "bar" (Variable)
911 detail: "bar : Int"
912
913 not found:
914 "foo"
915 "#]],
916 );
917}
918
919#[test]
920fn local_items() {
921 check_single_file(
922 r#"
923 namespace Test {
924 operation Baz() : Unit {
925 operation Foo() : Unit {}
926
927 operation Bar() : Unit {}
928 newtype Custom = String;
929 }
930 }"#,
931 &["Foo", "Bar", "Custom"],
932 &expect![[r#"
933 found, sorted:
934 "Bar" (Function)
935 detail: "operation Bar() : Unit"
936 "Custom" (Interface)
937 detail: "newtype Custom = String"
938 "Foo" (Function)
939 detail: "operation Foo() : Unit"
940 "#]],
941 );
942}
943
944#[test]
945fn type_params() {
946 check_single_file(
947 r#"
948 namespace Test {
949 operation Foo<'T>() : Unit {
950 let x: ↘
951 }
952 }"#,
953 &["'T", "Bar"],
954 &expect![[r#"
955 found, sorted:
956 "'T" (TypeParameter)
957
958 not found:
959 "Bar"
960 "#]],
961 );
962}
963
964#[test]
965fn scoped_local_vars() {
966 check_single_file(
967 r#"
968 namespace Test {
969 operation Foo() : Unit {
970 {
971 let foo = 3;
972 }
973
974 }
975 }"#,
976 &["foo"],
977 &expect![[r#"
978 not found:
979 "foo"
980 "#]],
981 );
982}
983
984#[test]
985fn callable_params() {
986 check_single_file(
987 r#"
988 namespace Test {
989 newtype Custom = String;
990 operation Foo(foo: Int, bar: Custom) : Unit {
991 {
992
993 }
994 }
995 }"#,
996 &["foo", "bar"],
997 &expect![[r#"
998 found, sorted:
999 "bar" (Variable)
1000 detail: "bar : Custom"
1001 "foo" (Variable)
1002 detail: "foo : Int"
1003 "#]],
1004 );
1005}
1006
1007#[test]
1008fn local_var_in_callable_parent_scope() {
1009 check_single_file(
1010 r#"
1011 namespace Test {
1012 operation Foo(foo: Int) : Unit {
1013 let bar = 3;
1014 operation Bar() : Unit {
1015 let baz = 3;
1016
1017 }
1018 }
1019 }"#,
1020 &["foo", "bar", "baz"],
1021 &expect![[r#"
1022 found, sorted:
1023 "baz" (Variable)
1024 detail: "baz : Int"
1025
1026 not found:
1027 "foo"
1028 "bar"
1029 "#]],
1030 );
1031}
1032
1033#[test]
1034#[ignore = "completion list ignores shadowing rules for open statements"]
1035fn local_var_and_open_shadowing_rules() {
1036 check_single_file(
1037 r#"
1038 namespace Foo {
1039 operation Bar() : Unit {
1040 }
1041 }
1042
1043 namespace Test {
1044 operation Main() : Unit {
1045 let Bar = 3;
1046 Bar;
1047 {
1048 // open Foo should shadow the local Bar declaration
1049 open Foo;
1050 Bar;
1051
1052 }
1053
1054 }
1055 }"#,
1056 &["Bar"],
1057 &expect![[r#"
1058 [
1059 Some(
1060 CompletionItem {
1061 label: "Bar",
1062 kind: Function,
1063 sort_text: Some(
1064 "0700Bar",
1065 ),
1066 detail: Some(
1067 "operation Bar() : Unit",
1068 ),
1069 additional_text_edits: None,
1070 },
1071 ),
1072 ]
1073 "#]],
1074 );
1075}
1076
1077// no additional text edits for Foo or Bar because FooNs is already glob imported
1078#[test]
1079fn dont_import_if_already_glob_imported() {
1080 check_single_file(
1081 r#"
1082 namespace FooNs {
1083 operation Foo() : Unit {
1084 }
1085 operation Bar() : Unit { }
1086 }
1087
1088 namespace Test {
1089 import FooNs.*;
1090 operation Main() : Unit {
1091
1092 }
1093 }"#,
1094 &["Foo", "Bar"],
1095 &expect![[r#"
1096 found, sorted:
1097 "Bar" (Function)
1098 detail: "operation Bar() : Unit"
1099 "Foo" (Function)
1100 detail: "operation Foo() : Unit"
1101 "#]],
1102 );
1103}
1104
1105// expect an auto-import for `Foo.Bar`, separate from the preexisting glob import `Foo.Bar.*`
1106#[test]
1107fn glob_import_item_with_same_name() {
1108 check_single_file(
1109 r#"
1110 namespace Foo {
1111 operation Bar() : Unit {
1112 }
1113 }
1114
1115 namespace Foo.Bar {
1116 }
1117
1118 namespace Baz {
1119 import Foo.Bar.*;
1120 operation Main(): Unit {
1121
1122 }
1123 }"#,
1124 &["Bar"],
1125 &expect![[r#"
1126 found, sorted:
1127 "Bar" (Function)
1128 detail: "operation Bar() : Unit"
1129 additional_text_edits:
1130 [10:12-10:12] "import Foo.Bar;\n "
1131 "#]],
1132 );
1133}
1134
1135// no additional text edits for Foo because Foo is directly imported,
1136// but additional text edits for Bar because Bar is not directly imported
1137#[test]
1138fn dont_import_if_already_directly_imported() {
1139 check_single_file(
1140 r#"
1141 namespace FooNs {
1142 operation Foo() : Unit { }
1143 operation Bar() : Unit { }
1144 }
1145
1146 namespace Test {
1147 import FooNs.Foo;
1148 operation Main() : Unit {
1149
1150 }
1151 }"#,
1152 &["Foo", "Bar"],
1153 &expect![[r#"
1154 found, sorted:
1155 "Foo" (Function)
1156 detail: "operation Foo() : Unit"
1157 "Bar" (Function)
1158 detail: "operation Bar() : Unit"
1159 additional_text_edits:
1160 [7:12-7:12] "import FooNs.Bar;\n "
1161 "#]],
1162 );
1163}
1164
1165#[test]
1166fn auto_import_from_qir_runtime() {
1167 check_with_stdlib(
1168 r#"
1169 namespace Test {
1170 operation Main() : Unit {
1171 AllocateQubitA↘
1172 }
1173 }"#,
1174 &["AllocateQubitArray"],
1175 &expect![[r#"
1176 found, sorted:
1177 "AllocateQubitArray" (Function)
1178 detail: "operation AllocateQubitArray(size : Int) : Qubit[]"
1179 additional_text_edits:
1180 [2:12-2:12] "import QIR.Runtime.AllocateQubitArray;\n "
1181 "#]],
1182 );
1183}
1184
1185#[test]
1186fn dont_generate_import_for_core_prelude() {
1187 check_with_stdlib(
1188 r#"
1189 namespace Test {
1190 operation Main() : Unit {
1191 Length↘
1192 }
1193 }"#,
1194 &["Length"],
1195 // additional text edits should be None because Length is in the core prelude
1196 &expect![[r#"
1197 found, sorted:
1198 "Length" (Function)
1199 detail: "function Length<'T>(a : 'T[]) : Int"
1200 "#]],
1201 );
1202}
1203
1204#[test]
1205fn dont_generate_import_for_stdlib_prelude() {
1206 check_with_stdlib(
1207 r#"
1208 namespace Test {
1209 operation Main() : Unit {
1210 MResetZ↘
1211 }
1212 }"#,
1213 &["MResetZ"],
1214 // additional text edits should be None because MResetZ is in Std.Measurement, which
1215 // is in the prelude.
1216 &expect![[r#"
1217 found, sorted:
1218 "MResetZ" (Function)
1219 detail: "operation MResetZ(target : Qubit) : Result"
1220 "#]],
1221 );
1222}
1223
1224#[test]
1225fn callable_from_same_file() {
1226 check_single_file(
1227 r#"
1228 namespace Test {
1229 function MyCallable() : Unit {}
1230 operation Main() : Unit {
1231 MyCall↘
1232 }
1233 }"#,
1234 &["MyCallable"],
1235 &expect![[r#"
1236 found, sorted:
1237 "MyCallable" (Function)
1238 detail: "function MyCallable() : Unit"
1239 "#]],
1240 );
1241}
1242
1243#[test]
1244fn member_completion() {
1245 check_single_file(
1246 r#"
1247 namespace Test {
1248 function MyCallable() : Unit {}
1249 }
1250
1251 namespace Main {
1252 operation Main() : Unit {
1253 Test.↘
1254 }
1255 }
1256
1257 "#,
1258 &["MyCallable"],
1259 &expect![[r#"
1260 found, sorted:
1261 "MyCallable" (Function)
1262 detail: "function MyCallable() : Unit"
1263 "#]],
1264 );
1265}
1266
1267#[test]
1268fn member_completion_in_imported_namespace() {
1269 check_single_file(
1270 r#"
1271 namespace Test.Foo {
1272 function MyCallable() : Unit {}
1273 }
1274
1275 namespace Test.Foo.Bar {
1276 function CallableInBar() : Unit {}
1277 }
1278
1279 namespace Main {
1280 open Test;
1281 operation Main() : Unit {
1282 Foo.↘
1283 }
1284 }
1285
1286 "#,
1287 &["MyCallable", "Bar"],
1288 &expect![[r#"
1289 found, sorted:
1290 "MyCallable" (Function)
1291 detail: "function MyCallable() : Unit"
1292 "Bar" (Module)
1293 "#]],
1294 );
1295}
1296
1297#[test]
1298fn namespace_completion() {
1299 check_single_file(
1300 r#"
1301 namespace Test.Foo {
1302 function MyCallable() : Unit {}
1303 }
1304
1305 namespace Main {
1306 operation Main() : Unit {
1307 Test.↘
1308 }
1309 }
1310
1311 "#,
1312 &["Foo"],
1313 &expect![[r#"
1314 found, sorted:
1315 "Foo" (Module)
1316 "#]],
1317 );
1318}
1319
1320#[test]
1321fn nested_namespace() {
1322 check_single_file(
1323 r#"
1324 namespace Test.Foo {
1325 function MyCallable() : Unit {}
1326 }
1327
1328 namespace Test {
1329 function MyCallable2() : Unit {
1330 Foo.↘
1331 }
1332 }"#,
1333 &["MyCallable", "MyCallable2"],
1334 &expect![[r#"
1335 found, sorted:
1336 "MyCallable" (Function)
1337 detail: "function MyCallable() : Unit"
1338
1339 not found:
1340 "MyCallable2"
1341 "#]],
1342 );
1343}
1344
1345#[test]
1346fn std_member() {
1347 check_single_file(
1348 r#"
1349 namespace Test {
1350 function MyCallable2() : Unit {
1351 FakeStdLib.↘
1352 }
1353 }"#,
1354 &["Fake", "Library"],
1355 &expect![[r#"
1356 found, sorted:
1357 "Fake" (Function)
1358 detail: "operation Fake() : Unit"
1359 "Library" (Module)
1360 "#]],
1361 );
1362}
1363
1364#[test]
1365fn open_namespace() {
1366 check_single_file(
1367 r#"
1368 namespace Test {
1369 open FakeStdLib.↘;
1370 }"#,
1371 &["Fake", "Library"],
1372 &expect![[r#"
1373 found, sorted:
1374 "Library" (Module)
1375
1376 not found:
1377 "Fake"
1378 "#]],
1379 );
1380}
1381
1382#[test]
1383fn open_namespace_no_semi() {
1384 check_single_file(
1385 r#"
1386 namespace Test {
1387 open FakeStdLib.↘
1388 }"#,
1389 &["Fake", "Library"],
1390 &expect![[r#"
1391 found, sorted:
1392 "Library" (Module)
1393
1394 not found:
1395 "Fake"
1396 "#]],
1397 );
1398}
1399
1400#[test]
1401fn open_namespace_no_semi_followed_by_decl() {
1402 check_single_file(
1403 r#"
1404 namespace Test {
1405 open FakeStdLib.↘
1406 operation Foo() : Unit {}
1407 }"#,
1408 &["Fake", "Library"],
1409 &expect![[r#"
1410 found, sorted:
1411 "Library" (Module)
1412
1413 not found:
1414 "Fake"
1415 "#]],
1416 );
1417}
1418
1419#[test]
1420fn open_namespace_partial_path_part() {
1421 check_single_file(
1422 r#"
1423 namespace Test {
1424 open FakeStdLib.↘F
1425 operation Foo() : Unit {}
1426 }"#,
1427 &["Fake", "Library"],
1428 &expect![[r#"
1429 found, sorted:
1430 "Library" (Module)
1431
1432 not found:
1433 "Fake"
1434 "#]],
1435 );
1436}
1437
1438#[test]
1439fn let_stmt_type() {
1440 check_single_file(
1441 r#"
1442 namespace Test {
1443 function Main() : Unit {
1444 let x: ↘
1445 }
1446 }"#,
1447 &["Udt", "Qubit", "Int", "Main", "FakeWithParam"],
1448 &expect![[r#"
1449 found, sorted:
1450 "Int" (Interface)
1451 "Qubit" (Interface)
1452 "Udt" (Interface)
1453 detail: "struct Udt { x : Int, y : Int }"
1454 additional_text_edits:
1455 [2:12-2:12] "import FakeStdLib.Udt;\n "
1456
1457 not found:
1458 "Main"
1459 "FakeWithParam"
1460 "#]],
1461 );
1462}
1463
1464#[test]
1465fn let_stmt_type_before_next_stmt() {
1466 check_single_file(
1467 r#"
1468 namespace Test {
1469 function Main() : Unit {
1470 use q = Qubit();
1471 let x: ↘
1472 H(q);
1473 }
1474 }"#,
1475 &["Udt", "Qubit", "Int", "Main", "FakeWithParam"],
1476 &expect![[r#"
1477 found, sorted:
1478 "Int" (Interface)
1479 "Qubit" (Interface)
1480 "Udt" (Interface)
1481 detail: "struct Udt { x : Int, y : Int }"
1482 additional_text_edits:
1483 [2:12-2:12] "import FakeStdLib.Udt;\n "
1484
1485 not found:
1486 "Main"
1487 "FakeWithParam"
1488 "#]],
1489 );
1490}
1491
1492#[test]
1493fn type_position_namespace() {
1494 check_single_file(
1495 r#"
1496 namespace Test {
1497 function Main() : Unit {
1498 let x: FakeStdLib.↘ ;
1499 }
1500 }"#,
1501 &["Udt", "Qubit", "Int", "Main", "FakeWithParam"],
1502 &expect![[r#"
1503 found, sorted:
1504 "Udt" (Interface)
1505 detail: "struct Udt { x : Int, y : Int }"
1506
1507 not found:
1508 "Qubit"
1509 "Int"
1510 "Main"
1511 "FakeWithParam"
1512 "#]],
1513 );
1514}
1515
1516#[test]
1517fn udt_base_type_part() {
1518 check_single_file(
1519 r#"
1520 namespace Test {
1521 newtype Foo = FakeStdLib.↘
1522 }"#,
1523 &["Udt", "Qubit", "FakeWithParam"],
1524 &expect![[r#"
1525 found, sorted:
1526 "Udt" (Interface)
1527 detail: "struct Udt { x : Int, y : Int }"
1528
1529 not found:
1530 "Qubit"
1531 "FakeWithParam"
1532 "#]],
1533 );
1534}
1535
1536#[test]
1537fn struct_init() {
1538 check_single_file(
1539 r#"
1540 namespace Test {
1541 function Main() : Unit {
1542 let x = new ↘ ;
1543 }
1544 }"#,
1545 &["Udt", "Qubit", "Int", "Main", "FakeWithParam"],
1546 &expect![[r#"
1547 found, sorted:
1548 "Udt" (Interface)
1549 detail: "struct Udt { x : Int, y : Int }"
1550 additional_text_edits:
1551 [2:12-2:12] "import FakeStdLib.Udt;\n "
1552
1553 not found:
1554 "Qubit"
1555 "Int"
1556 "Main"
1557 "FakeWithParam"
1558 "#]],
1559 );
1560}
1561
1562#[test]
1563fn struct_init_path_part() {
1564 check_single_file(
1565 r#"
1566 namespace Test {
1567 function Main() : Unit {
1568 let x = new FakeStdLib.↘ ;
1569 }
1570 }"#,
1571 &["Udt", "Qubit", "Int", "Main", "FakeWithParam"],
1572 &expect![[r#"
1573 found, sorted:
1574 "Udt" (Interface)
1575 detail: "struct Udt { x : Int, y : Int }"
1576
1577 not found:
1578 "Qubit"
1579 "Int"
1580 "Main"
1581 "FakeWithParam"
1582 "#]],
1583 );
1584}
1585
1586#[test]
1587fn struct_init_path_part_in_field_assigment() {
1588 check_single_file(
1589 r#"
1590 namespace Test {
1591 function Main() : Unit {
1592 let x = new FakeStdLib.Udt { x = FakeStdLib.↘ } ;
1593 }
1594 }"#,
1595 &["Udt", "Qubit", "FakeWithParam"],
1596 &expect![[r#"
1597 found, sorted:
1598 "FakeWithParam" (Function)
1599 detail: "operation FakeWithParam(x : Int) : Unit"
1600 "Udt" (Interface)
1601 detail: "struct Udt { x : Int, y : Int }"
1602
1603 not found:
1604 "Qubit"
1605 "#]],
1606 );
1607}
1608
1609#[test]
1610fn export_path() {
1611 check_single_file(
1612 r#"
1613 namespace Test {
1614 export ↘ ;
1615 function Main() : Unit {
1616 }
1617 }"#,
1618 &["Udt", "Qubit", "Int", "Main", "FakeWithParam", "FakeStdLib"],
1619 &expect![[r#"
1620 found, sorted:
1621 "Main" (Function)
1622 detail: "function Main() : Unit"
1623 "FakeStdLib" (Module)
1624
1625 not found:
1626 "Udt"
1627 "Qubit"
1628 "Int"
1629 "FakeWithParam"
1630 "#]],
1631 );
1632}
1633
1634#[test]
1635fn export_path_part() {
1636 check_single_file(
1637 r#"
1638 namespace Test {
1639 export FakeStdLib.↘ ;
1640 function Main() : Unit {
1641 }
1642 }"#,
1643 &["Udt", "Qubit", "Int", "Main", "FakeWithParam", "FakeStdLib"],
1644 &expect![[r#"
1645 found, sorted:
1646 "FakeWithParam" (Function)
1647 detail: "operation FakeWithParam(x : Int) : Unit"
1648 "Udt" (Interface)
1649 detail: "struct Udt { x : Int, y : Int }"
1650
1651 not found:
1652 "Qubit"
1653 "Int"
1654 "Main"
1655 "FakeStdLib"
1656 "#]],
1657 );
1658}
1659
1660#[test]
1661fn partially_typed_name() {
1662 check_single_file(
1663 r#"
1664 namespace Test {
1665 export Fo↘
1666 function Foo() : Unit {
1667 }
1668 }"#,
1669 &["Foo"],
1670 &expect![[r#"
1671 found, sorted:
1672 "Foo" (Function)
1673 detail: "function Foo() : Unit"
1674 "#]],
1675 );
1676}
1677
1678#[test]
1679fn from_dependency_main() {
1680 check_with_dependency(
1681 "namespace Test { function Foo() : Unit { ↘ } }",
1682 "MyDep",
1683 "namespace Main { export MainFunc; function MainFunc() : Unit {} }
1684 namespace Other { export OtherFunc; function OtherFunc() : Unit {} }
1685 ",
1686 &["MainFunc", "OtherFunc"],
1687 &expect![[r#"
1688 found, sorted:
1689 "MainFunc" (Function)
1690 detail: "function MainFunc() : Unit"
1691 additional_text_edits:
1692 [0:17-0:17] "import MyDep.MainFunc;\n "
1693 "OtherFunc" (Function)
1694 detail: "function OtherFunc() : Unit"
1695 additional_text_edits:
1696 [0:17-0:17] "import MyDep.Other.OtherFunc;\n "
1697 "#]],
1698 );
1699}
1700
1701#[test]
1702fn package_aliases() {
1703 check_with_dependency(
1704 "namespace Test { function Foo() : Unit { ↘ } }",
1705 "MyDep",
1706 "namespace Main { export MainFunc; function MainFunc() : Unit {} }",
1707 &["MyDep", "Main"],
1708 &expect![[r#"
1709 found, sorted:
1710 "MyDep" (Module)
1711
1712 not found:
1713 "Main"
1714 "#]],
1715 );
1716}
1717
1718#[test]
1719fn package_alias_members() {
1720 check_with_dependency(
1721 "namespace Test { function Foo() : Unit { MyDep.↘ } }",
1722 "MyDep",
1723 "namespace Main { export MainFunc; function MainFunc() : Unit {} }
1724 namespace Other { export OtherFunc; function OtherFunc() : Unit {} }
1725 namespace Other.Sub { export OtherFunc; function OtherFunc() : Unit {} }
1726 ",
1727 &["Main", "Other", "MainFunc", "Other.Sub", "Sub", "Std"],
1728 &expect![[r#"
1729 found, sorted:
1730 "MainFunc" (Function)
1731 detail: "function MainFunc() : Unit"
1732 "Other" (Module)
1733
1734 not found:
1735 "Main"
1736 "Other.Sub"
1737 "Sub"
1738 "Std"
1739 "#]],
1740 );
1741}
1742
1743#[test]
1744fn dependency_namespace_members() {
1745 check_with_dependency(
1746 "namespace Test { function Foo() : Unit { MyDep.Other.↘ } }",
1747 "MyDep",
1748 "namespace Main { export MainFunc; function MainFunc() : Unit {} }
1749 namespace Other { export OtherFunc; function OtherFunc() : Unit {} }
1750 namespace Other.Sub { export OtherFunc; function OtherFunc() : Unit {} }
1751 ",
1752 &["Main", "Other", "MainFunc", "Other.Sub", "Sub", "OtherFunc"],
1753 &expect![[r#"
1754 found, sorted:
1755 "OtherFunc" (Function)
1756 detail: "function OtherFunc() : Unit"
1757 "Sub" (Module)
1758
1759 not found:
1760 "Main"
1761 "Other"
1762 "MainFunc"
1763 "Other.Sub"
1764 "#]],
1765 );
1766}
1767
1768#[test]
1769fn package_alias_members_in_open() {
1770 check_with_dependency(
1771 "namespace Test { open MyDep.↘ }",
1772 "MyDep",
1773 "namespace Main { export MainFunc; function MainFunc() : Unit {} }
1774 namespace Other { export OtherFunc; function OtherFunc() : Unit {} }
1775 namespace Other.Sub { export OtherFunc; function OtherFunc() : Unit {} }
1776 ",
1777 &["Main", "Other", "MainFunc", "Other.Sub", "Sub"],
1778 &expect![[r#"
1779 found, sorted:
1780 "Other" (Module)
1781
1782 not found:
1783 "Main"
1784 "MainFunc"
1785 "Other.Sub"
1786 "Sub"
1787 "#]],
1788 );
1789}
1790
1791#[test]
1792fn member_completion_in_imported_namespace_from_dependency() {
1793 check_with_dependency(
1794 "namespace Main {
1795 open MyDep.Test;
1796 operation Main() : Unit {
1797 Foo.↘
1798 }
1799 }",
1800 "MyDep",
1801 "
1802 namespace Test.Foo {
1803 function CallableInFoo() : Unit {}
1804 export CallableInFoo;
1805 }
1806
1807 namespace Test.Foo.Bar {
1808 function CallableInBar() : Unit {}
1809 export CallableInBar;
1810 }
1811 ",
1812 &["CallableInFoo", "Bar"],
1813 &expect![[r#"
1814 found, sorted:
1815 "CallableInFoo" (Function)
1816 detail: "function CallableInFoo() : Unit"
1817 "Bar" (Module)
1818 "#]],
1819 );
1820}
1821
1822#[test]
1823fn aliased_namespace_in_dependency() {
1824 check_with_dependency(
1825 "namespace Main {
1826 open MyDep.Test.Foo as Alias;
1827 operation Main() : Unit {
1828 Alias.↘
1829 }
1830 }",
1831 "MyDep",
1832 "
1833 namespace Test.Foo {
1834 function CallableInFoo() : Unit {}
1835 export CallableInFoo;
1836 }
1837
1838 namespace Test.Foo.Bar {
1839 function CallableInBar() : Unit {}
1840 export CallableInBar;
1841 }
1842 ",
1843 &["CallableInFoo", "Bar"],
1844 &expect![[r#"
1845 found, sorted:
1846 "CallableInFoo" (Function)
1847 detail: "function CallableInFoo() : Unit"
1848 "Bar" (Module)
1849 "#]],
1850 );
1851}
1852
1853#[test]
1854fn open_does_not_match_pkg_alias() {
1855 check_with_dependency(
1856 "namespace Main {
1857 open Test.Foo as Alias;
1858 operation Main() : Unit {
1859 Alias.↘
1860 }
1861 }",
1862 "MyDep",
1863 "
1864 namespace Test.Foo {
1865 function CallableInFoo() : Unit {}
1866 export CallableInFoo;
1867 }
1868
1869 namespace Test.Foo.Bar {
1870 function CallableInBar() : Unit {}
1871 export CallableInBar;
1872 }
1873 ",
1874 &["CallableInFoo", "Bar"],
1875 &expect![[r#"
1876 not found:
1877 "CallableInFoo"
1878 "Bar"
1879 "#]],
1880 );
1881}
1882
1883#[test]
1884fn field_access_expr() {
1885 check_single_file(
1886 "namespace Test {
1887 struct Foo {
1888 bar : Int,
1889 }
1890
1891 function Main() : Unit {
1892 (new Foo { bar = 3 }).↘
1893 }
1894 }",
1895 &["bar"],
1896 &expect![[r#"
1897 found, sorted:
1898 "bar" (Field)
1899 detail: "Int"
1900 "#]],
1901 );
1902}
1903
1904#[test]
1905fn input_type_missing() {
1906 check_single_file(
1907 "namespace Test { function Foo(x : FakeStdLib.↘ ) : Unit { body intrinsic; } }",
1908 &["Udt", "Library"],
1909 &expect![[r#"
1910 found, sorted:
1911 "Udt" (Interface)
1912 detail: "struct Udt { x : Int, y : Int }"
1913 "Library" (Module)
1914 "#]],
1915 );
1916}
1917
1918#[test]
1919fn notebook_top_level_path_part() {
1920 check_notebook(
1921 &[(
1922 "cell1",
1923 ("
1924 FakeStdLib.↘
1925 "),
1926 )],
1927 &["Udt", "Library", "FakeStdLib", "FakeWithParam"],
1928 &expect![[r#"
1929 found, sorted:
1930 "FakeWithParam" (Function)
1931 detail: "operation FakeWithParam(x : Int) : Unit"
1932 "Udt" (Interface)
1933 detail: "struct Udt { x : Int, y : Int }"
1934 "Library" (Module)
1935
1936 not found:
1937 "FakeStdLib"
1938 "#]],
1939 );
1940}
1941
1942#[test]
1943fn field_access_path() {
1944 check_single_file(
1945 "namespace Test {
1946 struct Foo {
1947 bar : Int,
1948 }
1949
1950 function Main() : Unit {
1951 let foo = new Foo { bar = 3 };
1952 foo.↘
1953 }
1954 }",
1955 &["bar"],
1956 &expect![[r#"
1957 found, sorted:
1958 "bar" (Field)
1959 detail: "Int"
1960 "#]],
1961 );
1962}
1963
1964#[test]
1965fn notebook_top_level_path_part_in_type() {
1966 check_notebook(
1967 &[(
1968 "cell1",
1969 ("
1970 let x : FakeStdLib.↘
1971 "),
1972 )],
1973 &["Udt", "Library", "FakeStdLib", "FakeWithParam"],
1974 &expect![[r#"
1975 found, sorted:
1976 "Udt" (Interface)
1977 detail: "struct Udt { x : Int, y : Int }"
1978 "Library" (Module)
1979
1980 not found:
1981 "FakeStdLib"
1982 "FakeWithParam"
1983 "#]],
1984 );
1985}
1986
1987#[test]
1988fn prefix_ops() {
1989 check_single_file(
1990 "namespace Test { function Main() : Unit { let x = ↘ ; } }",
1991 &["and", "or", "not", "Adjoint"],
1992 &expect![[r#"
1993 found, sorted:
1994 "Adjoint" (Keyword)
1995 "not" (Keyword)
1996
1997 not found:
1998 "and"
1999 "or"
2000 "#]],
2001 );
2002}
2003
2004#[test]
2005fn binary_ops() {
2006 check_single_file(
2007 "namespace Test { function Main() : Unit { let x = 1 ↘ ; } }",
2008 &["and", "or", "not"],
2009 &expect![[r#"
2010 found, sorted:
2011 "and" (Keyword)
2012 "or" (Keyword)
2013
2014 not found:
2015 "not"
2016 "#]],
2017 );
2018}
2019
2020#[test]
2021fn array_size() {
2022 check_single_file(
2023 "namespace Test { function Main() : Unit { let x = [0, ↘] ; } }",
2024 &["size"],
2025 &expect![[r#"
2026 found, sorted:
2027 "size" (Keyword)
2028 "#]],
2029 );
2030}
2031
2032#[test]
2033fn path_segment_partial_ident_is_keyword() {
2034 check_single_file(
2035 "namespace Test { import FakeStdLib.struct↘ }",
2036 &["StructFn"],
2037 &expect![[r#"
2038 found, sorted:
2039 "StructFn" (Interface)
2040 detail: "struct StructFn { inner : (Int -> Int) }"
2041 "#]],
2042 );
2043}
2044
2045#[test]
2046fn path_segment_followed_by_wslash() {
2047 // `w/` is a single token, so it gets tricky
2048 // to separate out the `w` and treat it as an identifier.
2049 // We're just not going to worry about doing anything clever here.
2050 check_single_file(
2051 "namespace Test { import FakeStdLib.w↘/ }",
2052 &["StructFn"],
2053 &expect![[r#"
2054 not found:
2055 "StructFn"
2056 "#]],
2057 );
2058}
2059
2060#[test]
2061fn path_segment_followed_by_op_token() {
2062 // Invoking in the middle of a multi-character op token
2063 // shouldn't break anything.
2064 check_single_file(
2065 "namespace Test { import FakeStdLib.<↘<< }",
2066 &["StructFn"],
2067 &expect![[r#"
2068 not found:
2069 "StructFn"
2070 "#]],
2071 );
2072}
2073
2074#[test]
2075fn path_segment_before_glob() {
2076 check_single_file(
2077 "namespace Test { import FakeStdLib.↘* }",
2078 &["StructFn"],
2079 &expect![[r#"
2080 found, sorted:
2081 "StructFn" (Interface)
2082 detail: "struct StructFn { inner : (Int -> Int) }"
2083 "#]],
2084 );
2085}
2086
2087#[test]
2088fn field_in_initializer() {
2089 check_single_file(
2090 "namespace Test {
2091 struct Foo {
2092 bar : Int,
2093 }
2094
2095 function Main() : Unit {
2096 new Foo { ↘ };
2097 }
2098 }",
2099 &["bar"],
2100 &expect![[r#"
2101 found, sorted:
2102 "bar" (Field)
2103 detail: "Int"
2104 "#]],
2105 );
2106}
2107
2108#[test]
2109fn stdlib_struct_field_init() {
2110 check_single_file(
2111 "namespace Test {
2112 import FakeStdLib.FakeStruct as StructAlias;
2113 function Main() : Unit {
2114 new StructAlias { ↘ };
2115 }
2116 }",
2117 &["x"],
2118 &expect![[r#"
2119 found, sorted:
2120 "x" (Field)
2121 detail: "Int"
2122 "#]],
2123 );
2124}
2125
2126#[test]
2127fn newtype_named_field() {
2128 check_single_file(
2129 "namespace Test {
2130 newtype Foo = (field : Int);
2131 function Main() : Unit {
2132 Foo(3).↘
2133 }
2134 }",
2135 &["field"],
2136 &expect![[r#"
2137 found, sorted:
2138 "field" (Field)
2139 detail: "Int"
2140 "#]],
2141 );
2142}
2143
2144#[test]
2145fn field_access_path_chained() {
2146 check_single_file(
2147 "namespace Test {
2148 newtype Foo = ( fieldFoo : Int );
2149 struct Bar { fieldBar : Foo );
2150 function Main() : Unit {
2151 let bar = new Bar { fieldBar = Foo(3) };
2152 bar.fieldBar.↘
2153 }
2154 }",
2155 &["fieldFoo", "fieldBar"],
2156 &expect![[r#"
2157 found, sorted:
2158 "fieldFoo" (Field)
2159 detail: "Int"
2160
2161 not found:
2162 "fieldBar"
2163 "#]],
2164 );
2165}
2166
2167#[test]
2168fn field_access_expr_chained() {
2169 check_single_file(
2170 "namespace Test {
2171 newtype Foo = ( fieldFoo : Int );
2172 struct Bar { fieldBar : Foo );
2173 function Main() : Unit {
2174 (new Bar { fieldBar = Foo(3) }).fieldBar.↘
2175 }
2176 }",
2177 &["fieldFoo", "fieldBar"],
2178 &expect![[r#"
2179 found, sorted:
2180 "fieldFoo" (Field)
2181 detail: "Int"
2182
2183 not found:
2184 "fieldBar"
2185 "#]],
2186 );
2187}
2188
2189#[test]
2190fn field_assignment_rhs() {
2191 check_single_file(
2192 "namespace Test {
2193 struct Foo {
2194 bar : Int,
2195 }
2196
2197 function Main() : Unit {
2198 let var = 3;
2199 new Foo { bar = ↘ };
2200 }
2201 }",
2202 &["bar", "var"],
2203 &expect![[r#"
2204 found, sorted:
2205 "var" (Variable)
2206 detail: "var : Int"
2207
2208 not found:
2209 "bar"
2210 "#]],
2211 );
2212}
2213
2214#[test]
2215fn field_access_local_shadows_global() {
2216 check_single_file(
2217 "namespace Test {
2218 struct Foo {
2219 bar : Int,
2220 }
2221
2222 function Main() : Unit {
2223 let FakeStdLib = new Foo { bar = 3 };
2224 FakeStdLib.↘
2225 }
2226 }",
2227 &["Fake", "bar"],
2228 &expect![[r#"
2229 found, sorted:
2230 "bar" (Field)
2231 detail: "Int"
2232
2233 not found:
2234 "Fake"
2235 "#]],
2236 );
2237}
2238
2239#[test]
2240fn ty_param_in_signature() {
2241 check_single_file(
2242 r"namespace Test {
2243 operation Test<'T>(x: ↘) : Unit {}
2244 }",
2245 &["'T", "FakeStdLib"],
2246 &expect![[r#"
2247 found, sorted:
2248 "'T" (TypeParameter)
2249 "FakeStdLib" (Module)
2250 "#]],
2251 );
2252}
2253
2254#[test]
2255fn ty_param_in_return_type() {
2256 check_single_file(
2257 r"namespace Test {
2258 operation Test<'T>(x: 'T) : ↘ {}
2259 }",
2260 &["'T", "FakeStdLib"],
2261 &expect![[r#"
2262 found, sorted:
2263 "'T" (TypeParameter)
2264 "FakeStdLib" (Module)
2265 "#]],
2266 );
2267}
2268
2269#[test]
2270fn path_segment_in_return_type() {
2271 check_single_file(
2272 r"namespace Test {
2273 operation Test(x: 'T) : FakeStdLib.↘ {}
2274 }",
2275 &["Udt"],
2276 &expect![[r#"
2277 found, sorted:
2278 "Udt" (Interface)
2279 detail: "struct Udt { x : Int, y : Int }"
2280 "#]],
2281 );
2282}
2283
2284#[test]
2285fn return_type_in_partial_callable_signature() {
2286 check_single_file(
2287 r"namespace Test {
2288 operation Test<'T>() : ↘
2289 }",
2290 &["'T", "FakeStdLib"],
2291 &expect![[r#"
2292 found, sorted:
2293 "'T" (TypeParameter)
2294 "FakeStdLib" (Module)
2295 "#]],
2296 );
2297}
2298
2299#[test]
2300fn arg_type_in_partial_callable_signature() {
2301 check_single_file(
2302 r"namespace Test {
2303 operation Test<'T>(x: ↘)
2304 }",
2305 &["'T", "FakeStdLib"],
2306 &expect![[r#"
2307 found, sorted:
2308 "'T" (TypeParameter)
2309 "FakeStdLib" (Module)
2310 "#]],
2311 );
2312}
2313
2314#[test]
2315fn incomplete_return_type_in_partial_callable_signature() {
2316 check_single_file(
2317 r"namespace Test {
2318 operation Test<'T>() : () => ↘
2319 }",
2320 &["'T", "FakeStdLib"],
2321 &expect![[r#"
2322 found, sorted:
2323 "'T" (TypeParameter)
2324 "FakeStdLib" (Module)
2325 "#]],
2326 );
2327}
2328
2329#[test]
2330fn no_path_segment_completion_inside_attr() {
2331 check_no_completions(
2332 "namespace Test {
2333
2334 @Config(FakeStdLib.↘)
2335 function Main() : Unit {
2336 }
2337 }",
2338 );
2339}
2340
2341#[test]
2342fn no_completion_inside_attr() {
2343 check_no_completions(
2344 "namespace Test {
2345
2346 @Config(↘)
2347 function Main() : Unit {
2348 }
2349 }",
2350 );
2351}
2352
2353#[test]
2354fn in_comment() {
2355 check_no_completions(
2356 "namespace Test {
2357 import Foo;
2358 // Hello there ↘
2359 import Bar;
2360 }",
2361 );
2362}
2363
2364#[test]
2365fn in_doc_comment() {
2366 check_no_completions(
2367 "namespace Test {
2368 import Foo;
2369 /// Hello there ↘
2370 import Bar;
2371 }",
2372 );
2373}
2374
2375#[test]
2376fn in_trailing_comment() {
2377 check_no_completions(
2378 "namespace Test {
2379 import Foo; // Hello there ↘
2380 }",
2381 );
2382}
2383
2384#[test]
2385fn export_from_dependency_in_scope() {
2386 check_with_dependency(
2387 r"
2388 namespace Test {
2389 open MyDep;
2390 operation Foo() : Unit {
2391
2392 }
2393 }
2394 ",
2395 "MyDep",
2396 "
2397 namespace Bar {
2398 operation Baz() : Unit {}
2399 export Baz;
2400 }
2401 namespace Main {
2402 operation Qux() : Unit {}
2403 export Qux, Bar.Baz;
2404 }
2405 ",
2406 &["Qux", "Baz", "Bar"],
2407 &expect![[r#"
2408 found, sorted:
2409 "Baz" (Function)
2410 detail: "operation Baz() : Unit"
2411 "Qux" (Function)
2412 detail: "operation Qux() : Unit"
2413 "Bar" (Module)
2414 "#]],
2415 );
2416}
2417
2418#[test]
2419fn aliased_export_from_dependency_in_scope() {
2420 check_with_dependency(
2421 r"
2422 namespace Test {
2423 open MyDep;
2424 operation Foo() : Unit {
2425
2426 }
2427 }
2428 ",
2429 "MyDep",
2430 "
2431 namespace Bar {
2432 operation Baz() : Unit {}
2433 export Baz;
2434 }
2435 namespace Main {
2436 export Bar.Baz, Bar.Baz as BazAlias;
2437 }
2438 ",
2439 &["BazAlias", "Baz"],
2440 &expect![[r#"
2441 found, sorted:
2442 "Baz" (Function)
2443 detail: "operation Baz() : Unit"
2444 "BazAlias" (Function)
2445 detail: "operation Baz() : Unit"
2446 "#]],
2447 );
2448}
2449
2450#[test]
2451fn namespace_export_from_dependency_qualified() {
2452 check_with_dependency(
2453 r"
2454 namespace Test {
2455 open MyDep.Baz.↘
2456 }",
2457 "MyDep",
2458 "namespace Foo.Bar {
2459 operation Qux() : Unit {}
2460 export Qux
2461 }
2462 namespace Baz {
2463 export Foo.Bar;
2464 }",
2465 &["Bar"],
2466 &expect![[r#"
2467 found, sorted:
2468 "Bar" (Module)
2469 "#]],
2470 );
2471}
2472
2473#[test]
2474fn export_from_dependency_qualified() {
2475 check_with_dependency(
2476 r"
2477 namespace Test {
2478 operation Test() : Unit {
2479 MyDep.↘
2480 }
2481 }",
2482 "MyDep",
2483 "namespace Foo {
2484 operation Baz() : Unit {}
2485 export Baz;
2486 }
2487 namespace Main {
2488 operation Qux() : Unit {}
2489 export Qux, Foo.Baz;
2490 }",
2491 &["Qux", "Baz"],
2492 &expect![[r#"
2493 found, sorted:
2494 "Baz" (Function)
2495 detail: "operation Baz() : Unit"
2496 "Qux" (Function)
2497 detail: "operation Qux() : Unit"
2498 "#]],
2499 );
2500}
2501
2502#[test]
2503fn reexport_namespace_from_dependency_members() {
2504 check_with_dependency(
2505 r"
2506 namespace Test {
2507 operation Main() : Unit {
2508 MyDep.Baz.Bar.↘
2509 }
2510 }",
2511 "MyDep",
2512 "namespace Foo.Bar {
2513 operation Zud() : Unit {}
2514 export Zud
2515 }
2516 namespace Baz {
2517 operation Qux() : Unit {}
2518 export Qux, Foo.Bar;
2519 }",
2520 &["Zud"],
2521 &expect![[r#"
2522 found, sorted:
2523 "Zud" (Function)
2524 detail: "operation Zud() : Unit"
2525 "#]],
2526 );
2527}
2528
2529#[test]
2530fn import_in_local_scope() {
2531 check_single_file(
2532 r"
2533 namespace Foo {
2534 operation Bar() : Unit {}
2535 }
2536 namespace A {
2537 operation Main() : Unit {
2538 import Foo.Bar;
2539
2540 }
2541 }",
2542 &["Bar"],
2543 &expect![[r#"
2544 found, sorted:
2545 "Bar" (Function)
2546 detail: "operation Bar() : Unit"
2547 "#]],
2548 );
2549}
2550