microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
iadavis/pipeline-issue-debugging

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/compiler/qsc/src/compile.rs

167lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use miette::{Diagnostic, Report};
5use qsc_data_structures::{
6 error::WithSource, language_features::LanguageFeatures, source::SourceMap, span::Span,
7 target::TargetCapabilityFlags,
8};
9pub use qsc_frontend::compile::Dependencies;
10use qsc_frontend::compile::{CompileUnit, PackageStore};
11use qsc_passes::{PackageType, run_core_passes, run_default_passes};
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::openqasm::error::Error),
48
49 #[error(
50 "The @EntryPoint attribute with a profile argument is not allowed in a Q# project (with qsharp.json). Please specify the profile in qsharp.json instead."
51 )]
52 EntryPointProfileInProject(#[label] Span),
53}
54
55/// Compiles a package from its AST representation.
56#[must_use]
57#[allow(clippy::module_name_repetitions)]
58pub fn compile_ast(
59 store: &PackageStore,
60 dependencies: &Dependencies,
61 ast_package: qsc_ast::ast::Package,
62 sources: SourceMap,
63 package_type: PackageType,
64 capabilities: TargetCapabilityFlags,
65) -> (CompileUnit, Vec<Error>) {
66 let unit = qsc_frontend::compile::compile_ast(
67 store,
68 dependencies,
69 ast_package,
70 sources,
71 capabilities,
72 vec![],
73 );
74 process_compile_unit(store, package_type, unit)
75}
76
77/// Compiles a package from its source representation.
78#[must_use]
79pub fn compile(
80 store: &PackageStore,
81 dependencies: &Dependencies,
82 sources: SourceMap,
83 package_type: PackageType,
84 capabilities: TargetCapabilityFlags,
85 language_features: LanguageFeatures,
86) -> (CompileUnit, Vec<Error>) {
87 let unit = qsc_frontend::compile::compile(
88 store,
89 dependencies,
90 sources,
91 capabilities,
92 language_features,
93 );
94 process_compile_unit(store, package_type, unit)
95}
96
97#[must_use]
98#[allow(clippy::module_name_repetitions)]
99fn process_compile_unit(
100 store: &PackageStore,
101 package_type: PackageType,
102 mut unit: CompileUnit,
103) -> (CompileUnit, Vec<Error>) {
104 let mut errors = Vec::new();
105 for error in unit.errors.drain(..) {
106 errors.push(WithSource::from_map(&unit.sources, error.into()));
107 }
108
109 if errors.is_empty() {
110 for error in run_default_passes(store.core(), &mut unit, package_type) {
111 errors.push(WithSource::from_map(&unit.sources, error.into()));
112 }
113 }
114
115 (unit, errors)
116}
117
118#[must_use]
119pub fn package_store_with_stdlib(
120 capabilities: TargetCapabilityFlags,
121) -> (qsc_hir::hir::PackageId, PackageStore) {
122 let mut store = PackageStore::new(core());
123 let std_id = store.insert(std(&store, capabilities));
124 (std_id, store)
125}
126
127/// Compiles the core library.
128///
129/// # Panics
130///
131/// Panics if the core library compiles with errors.
132#[must_use]
133pub fn core() -> CompileUnit {
134 let mut unit = qsc_frontend::compile::core();
135 let pass_errors = run_core_passes(&mut unit);
136 if pass_errors.is_empty() {
137 unit
138 } else {
139 for error in pass_errors {
140 let report = Report::new(WithSource::from_map(&unit.sources, error));
141 eprintln!("{report:?}");
142 }
143
144 panic!("could not compile core library")
145 }
146}
147
148/// Compiles the standard library.
149///
150/// # Panics
151///
152/// Panics if the standard library does not compile without errors.
153#[must_use]
154pub fn std(store: &PackageStore, capabilities: TargetCapabilityFlags) -> CompileUnit {
155 let mut unit = qsc_frontend::compile::std(store, capabilities);
156 let pass_errors = run_default_passes(store.core(), &mut unit, PackageType::Lib);
157 if pass_errors.is_empty() {
158 unit
159 } else {
160 for error in pass_errors {
161 let report = Report::new(WithSource::from_map(&unit.sources, error));
162 eprintln!("{report:?}");
163 }
164
165 panic!("could not compile standard library")
166 }
167}
168