microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.19.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/compiler/qsc_fir/src/extensions.rs

123lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::{
5 fir::{CallableDecl, LocalVarId, Package, Pat, PatId, PatKind},
6 ty::Ty,
7};
8use qsc_data_structures::index_map::IndexMap;
9
10/// The index corresponding to an input parameter.
11#[derive(Clone, Copy, Debug, Eq, PartialEq)]
12pub struct InputParamIndex(usize);
13
14impl From<InputParamIndex> for usize {
15 fn from(value: InputParamIndex) -> Self {
16 value.0
17 }
18}
19
20impl From<usize> for InputParamIndex {
21 fn from(value: usize) -> Self {
22 Self(value)
23 }
24}
25
26/// An input parameter.
27#[derive(Clone, Debug)]
28pub struct InputParam {
29 pub index: InputParamIndex,
30 pub pat: PatId,
31 pub ty: Ty,
32 pub var: Option<LocalVarId>,
33}
34
35impl Package {
36 #[must_use]
37 pub fn derive_callable_input_params(&self, callable: &CallableDecl) -> Vec<InputParam> {
38 let input_elements = derive_callable_input_pattern_elements(callable, &self.pats);
39 let mut input_params = Vec::new();
40 let mut param_index = InputParamIndex(0);
41 for element in input_elements {
42 let maybe_input_param = match &element.kind {
43 InputPatternElementKind::Discard => Some(InputParam {
44 index: param_index,
45 pat: element.pat,
46 ty: element.ty.clone(),
47 var: None,
48 }),
49 InputPatternElementKind::Ident(local_var_id) => Some(InputParam {
50 index: param_index,
51 pat: element.pat,
52 ty: element.ty.clone(),
53 var: Some(*local_var_id),
54 }),
55 InputPatternElementKind::Tuple => None,
56 };
57
58 if let Some(input_param) = maybe_input_param {
59 input_params.push(input_param);
60 param_index.0 += 1;
61 }
62 }
63
64 input_params
65 }
66}
67
68/// An element related to an input pattern.
69#[derive(Debug)]
70struct InputPatternElement {
71 pub pat: PatId,
72 pub ty: Ty,
73 pub kind: InputPatternElementKind,
74}
75
76/// Kinds of input pattern elements.
77#[derive(Debug)]
78enum InputPatternElementKind {
79 Discard,
80 Ident(LocalVarId),
81 Tuple,
82}
83
84/// Creates a vector of flattened input pattern elements.
85fn derive_callable_input_pattern_elements(
86 callable: &CallableDecl,
87 pats: &IndexMap<PatId, Pat>,
88) -> Vec<InputPatternElement> {
89 fn create_input_elements(
90 pat_id: PatId,
91 pats: &IndexMap<PatId, Pat>,
92 ) -> Vec<InputPatternElement> {
93 let pat = pats.get(pat_id).expect("pattern should exist");
94 match &pat.kind {
95 PatKind::Bind(ident) => {
96 vec![InputPatternElement {
97 pat: pat_id,
98 ty: pat.ty.clone(),
99 kind: InputPatternElementKind::Ident(ident.id),
100 }]
101 }
102 PatKind::Tuple(tuple_pats) => {
103 let mut tuple_params = vec![InputPatternElement {
104 pat: pat_id,
105 ty: pat.ty.clone(),
106 kind: InputPatternElementKind::Tuple,
107 }];
108 for tuple_item_pat_id in tuple_pats {
109 let mut tuple_item_params = create_input_elements(*tuple_item_pat_id, pats);
110 tuple_params.append(&mut tuple_item_params);
111 }
112 tuple_params
113 }
114 PatKind::Discard => vec![InputPatternElement {
115 pat: pat_id,
116 ty: pat.ty.clone(),
117 kind: InputPatternElementKind::Discard,
118 }],
119 }
120 }
121
122 create_input_elements(callable.input, pats)
123}
124