microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
4fa10c30a716d7fc2f67a0a385f3da565daa1237

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/language_service/src/completion/openqasm.rs

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