microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.9.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc/src/compile.rs

154lines · 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
42/// Compiles a package from its AST representation.
43#[must_use]
44#[allow(clippy::module_name_repetitions)]
45pub fn compile_ast(
46 store: &PackageStore,
47 dependencies: &Dependencies,
48 ast_package: qsc_ast::ast::Package,
49 sources: SourceMap,
50 package_type: PackageType,
51 capabilities: TargetCapabilityFlags,
52) -> (CompileUnit, Vec<Error>) {
53 let unit = qsc_frontend::compile::compile_ast(
54 store,
55 dependencies,
56 ast_package,
57 sources,
58 capabilities,
59 vec![],
60 );
61 process_compile_unit(store, package_type, unit)
62}
63
64/// Compiles a package from its source representation.
65#[must_use]
66pub fn compile(
67 store: &PackageStore,
68 dependencies: &Dependencies,
69 sources: SourceMap,
70 package_type: PackageType,
71 capabilities: TargetCapabilityFlags,
72 language_features: LanguageFeatures,
73) -> (CompileUnit, Vec<Error>) {
74 let unit = qsc_frontend::compile::compile(
75 store,
76 dependencies,
77 sources,
78 capabilities,
79 language_features,
80 );
81 process_compile_unit(store, package_type, unit)
82}
83
84#[must_use]
85#[allow(clippy::module_name_repetitions)]
86fn process_compile_unit(
87 store: &PackageStore,
88 package_type: PackageType,
89 mut unit: CompileUnit,
90) -> (CompileUnit, Vec<Error>) {
91 let mut errors = Vec::new();
92 for error in unit.errors.drain(..) {
93 errors.push(WithSource::from_map(&unit.sources, error.into()));
94 }
95
96 if errors.is_empty() {
97 for error in run_default_passes(store.core(), &mut unit, package_type) {
98 errors.push(WithSource::from_map(&unit.sources, error.into()));
99 }
100 }
101
102 (unit, errors)
103}
104
105#[must_use]
106pub fn package_store_with_stdlib(
107 capabilities: TargetCapabilityFlags,
108) -> (qsc_hir::hir::PackageId, PackageStore) {
109 let mut store = PackageStore::new(core());
110 let std_id = store.insert(std(&store, capabilities));
111 (std_id, store)
112}
113
114/// Compiles the core library.
115///
116/// # Panics
117///
118/// Panics if the core library compiles with errors.
119#[must_use]
120pub fn core() -> CompileUnit {
121 let mut unit = qsc_frontend::compile::core();
122 let pass_errors = run_core_passes(&mut unit);
123 if pass_errors.is_empty() {
124 unit
125 } else {
126 for error in pass_errors {
127 let report = Report::new(WithSource::from_map(&unit.sources, error));
128 eprintln!("{report:?}");
129 }
130
131 panic!("could not compile core library")
132 }
133}
134
135/// Compiles the standard library.
136///
137/// # Panics
138///
139/// Panics if the standard library does not compile without errors.
140#[must_use]
141pub fn std(store: &PackageStore, capabilities: TargetCapabilityFlags) -> CompileUnit {
142 let mut unit = qsc_frontend::compile::std(store, capabilities);
143 let pass_errors = run_default_passes(store.core(), &mut unit, PackageType::Lib);
144 if pass_errors.is_empty() {
145 unit
146 } else {
147 for error in pass_errors {
148 let report = Report::new(WithSource::from_map(&unit.sources, error));
149 eprintln!("{report:?}");
150 }
151
152 panic!("could not compile standard library")
153 }
154}
155