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/openqasm.rs

100lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use std::iter::once;
5
6use crate::{
7 Compilation,
8 completion::{AstContext, Fields, Globals, collect_path_segments},
9 protocol::{CompletionItemKind, CompletionList},
10};
11
12use super::{Completion, Locals, into_completion_list};
13
14pub(super) fn completions(
15 compilation: &Compilation,
16 source_contents: &str,
17 cursor_offset: u32,
18) -> CompletionList {
19 let expected_words_at_cursor =
20 qsc::qasm::completion::possible_words_at_offset_in_source(source_contents, cursor_offset);
21
22 // Now that we have the information from the parser about what kinds of
23 // words are expected, gather the actual words (identifiers, keywords, etc) for each kind.
24
25 // Keywords and other hardcoded words
26 let hardcoded_completions = collect_hardcoded_words(expected_words_at_cursor);
27
28 // The tricky bit: locals, names we need to gather from the compilation.
29 let name_completions = collect_names_qasm(expected_words_at_cursor, cursor_offset, compilation);
30
31 // We have all the data, put everything into a completion list.
32 into_completion_list(once(hardcoded_completions).chain(name_completions))
33}
34
35#[allow(clippy::items_after_statements)]
36fn collect_hardcoded_words(
37 expected: qsc::qasm::completion::word_kinds::WordKinds,
38) -> Vec<Completion> {
39 let mut completions = Vec::new();
40 for word_kind in expected.iter_hardcoded_ident_kinds() {
41 match word_kind {
42 qsc::qasm::completion::word_kinds::HardcodedIdentKind::Annotation => {
43 completions.extend([Completion::new(
44 "SimulatableIntrinsic".to_string(),
45 CompletionItemKind::Interface,
46 )]);
47 }
48 }
49 }
50
51 for keyword in expected.iter_keywords() {
52 completions.push(Completion::new(
53 keyword.to_string(),
54 CompletionItemKind::Keyword,
55 ));
56 }
57
58 completions
59}
60
61#[allow(clippy::items_after_statements)]
62fn collect_paths(
63 expected: qsc::qasm::completion::word_kinds::PathKind,
64 locals_at_cursor: &Locals,
65) -> Vec<Vec<Completion>> {
66 let mut locals_and_builtins = Vec::new();
67 match expected {
68 qsc::qasm::completion::word_kinds::PathKind::Expr => {
69 locals_and_builtins.push(locals_at_cursor.expr_names());
70 }
71 }
72 locals_and_builtins
73}
74
75#[allow(clippy::items_after_statements)]
76fn collect_names_qasm(
77 expected: qsc::qasm::completion::word_kinds::WordKinds,
78 cursor_offset: u32,
79 compilation: &Compilation,
80) -> Vec<Vec<Completion>> {
81 let mut groups = Vec::new();
82 use qsc::qasm::completion::word_kinds::NameKind;
83 for name_kind in expected.iter_name_kinds() {
84 match name_kind {
85 NameKind::Path(path_kind) => {
86 let locals = Locals::new(cursor_offset, compilation);
87 groups.extend(collect_paths(path_kind, &locals));
88 }
89 NameKind::PathSegment => {
90 let globals = Globals::init(cursor_offset, compilation);
91 let ast_context =
92 AstContext::init(cursor_offset, &compilation.user_unit().ast.package);
93 let fields = Fields::new(compilation, &ast_context);
94
95 groups.extend(collect_path_segments(&ast_context, &globals, &fields));
96 }
97 }
98 }
99 groups
100}
101