microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
iadavis/qiskit2-explore

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/compiler/qsc/src/compile.rs

169lines · modecode

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