microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.17.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc/src/compile.rs

162lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use miette::{Diagnostic, Report};
5use qsc_data_structures::{language_features::LanguageFeatures, target::TargetCapabilityFlags};
6pub use qsc_frontend::compile::Dependencies;
7use qsc_frontend::{
8 compile::{CompileUnit, PackageStore, SourceMap},
9 error::WithSource,
10};
11use qsc_passes::{run_core_passes, run_default_passes, PackageType};
12use thiserror::Error;
13
14pub type Error = WithSource<ErrorKind>;
15
16#[derive(Clone, Debug, Diagnostic, Error)]
17#[error(transparent)]
18/// `ErrorKind` represents the different kinds of errors that can occur in the compiler.
19/// Each variant of the enum corresponds to a different stage of the compilation process.
20pub enum ErrorKind {
21 /// `Frontend` variant represents errors that occur during the frontend stage of the compiler.
22 /// These errors are typically related to syntax and semantic checks.
23 #[diagnostic(transparent)]
24 Frontend(#[from] qsc_frontend::compile::Error),
25
26 /// `Pass` variant represents errors that occur during the `qsc_passes` stage of the compiler.
27 /// These errors are typically related to optimization, transformation, code generation, passes,
28 /// and static analysis passes.
29 #[diagnostic(transparent)]
30 Pass(#[from] qsc_passes::Error),
31
32 /// `Lint` variant represents lints generated during the linting stage. These diagnostics are
33 /// typically emitted from the language server and happens after all other compilation passes.
34 #[diagnostic(transparent)]
35 Lint(#[from] qsc_linter::Lint),
36
37 #[error("Cycle in dependency graph")]
38 /// `DependencyCycle` occurs when there is a cycle in the dependency graph.
39 DependencyCycle,
40
41 #[error("{0}")]
42 /// `CircuitParse` variant represents errors that occur while parsing circuit files.
43 CircuitParse(String),
44
45 /// `OpenQASM` compilation errors.
46 #[diagnostic(transparent)]
47 OpenQasm(#[from] crate::qasm::error::Error),
48}
49
50/// Compiles a package from its AST representation.
51#[must_use]
52#[allow(clippy::module_name_repetitions)]
53pub fn compile_ast(
54 store: &PackageStore,
55 dependencies: &Dependencies,
56 ast_package: qsc_ast::ast::Package,
57 sources: SourceMap,
58 package_type: PackageType,
59 capabilities: TargetCapabilityFlags,
60) -> (CompileUnit, Vec<Error>) {
61 let unit = qsc_frontend::compile::compile_ast(
62 store,
63 dependencies,
64 ast_package,
65 sources,
66 capabilities,
67 vec![],
68 );
69 process_compile_unit(store, package_type, unit)
70}
71
72/// Compiles a package from its source representation.
73#[must_use]
74pub fn compile(
75 store: &PackageStore,
76 dependencies: &Dependencies,
77 sources: SourceMap,
78 package_type: PackageType,
79 capabilities: TargetCapabilityFlags,
80 language_features: LanguageFeatures,
81) -> (CompileUnit, Vec<Error>) {
82 let unit = qsc_frontend::compile::compile(
83 store,
84 dependencies,
85 sources,
86 capabilities,
87 language_features,
88 );
89 process_compile_unit(store, package_type, unit)
90}
91
92#[must_use]
93#[allow(clippy::module_name_repetitions)]
94fn process_compile_unit(
95 store: &PackageStore,
96 package_type: PackageType,
97 mut unit: CompileUnit,
98) -> (CompileUnit, Vec<Error>) {
99 let mut errors = Vec::new();
100 for error in unit.errors.drain(..) {
101 errors.push(WithSource::from_map(&unit.sources, error.into()));
102 }
103
104 if errors.is_empty() {
105 for error in run_default_passes(store.core(), &mut unit, package_type) {
106 errors.push(WithSource::from_map(&unit.sources, error.into()));
107 }
108 }
109
110 (unit, errors)
111}
112
113#[must_use]
114pub fn package_store_with_stdlib(
115 capabilities: TargetCapabilityFlags,
116) -> (qsc_hir::hir::PackageId, PackageStore) {
117 let mut store = PackageStore::new(core());
118 let std_id = store.insert(std(&store, capabilities));
119 (std_id, store)
120}
121
122/// Compiles the core library.
123///
124/// # Panics
125///
126/// Panics if the core library compiles with errors.
127#[must_use]
128pub fn core() -> CompileUnit {
129 let mut unit = qsc_frontend::compile::core();
130 let pass_errors = run_core_passes(&mut unit);
131 if pass_errors.is_empty() {
132 unit
133 } else {
134 for error in pass_errors {
135 let report = Report::new(WithSource::from_map(&unit.sources, error));
136 eprintln!("{report:?}");
137 }
138
139 panic!("could not compile core library")
140 }
141}
142
143/// Compiles the standard library.
144///
145/// # Panics
146///
147/// Panics if the standard library does not compile without errors.
148#[must_use]
149pub fn std(store: &PackageStore, capabilities: TargetCapabilityFlags) -> CompileUnit {
150 let mut unit = qsc_frontend::compile::std(store, capabilities);
151 let pass_errors = run_default_passes(store.core(), &mut unit, PackageType::Lib);
152 if pass_errors.is_empty() {
153 unit
154 } else {
155 for error in pass_errors {
156 let report = Report::new(WithSource::from_map(&unit.sources, error));
157 eprintln!("{report:?}");
158 }
159
160 panic!("could not compile standard library")
161 }
162}
163