microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
0769319c38820bf91580680c984f2e793e14f6b3

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_codegen/src/qsharp/test_utils.rs

93lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#![allow(clippy::too_many_lines)]
5#![allow(clippy::needless_raw_string_hashes)]
6
7use std::sync::Arc;
8
9use expect_test::Expect;
10use qsc_ast::{ast::Package, mut_visit::MutVisitor};
11use qsc_data_structures::{language_features::LanguageFeatures, span::Span};
12use qsc_frontend::compile::{self, compile, PackageStore, RuntimeCapabilityFlags, SourceMap};
13use qsc_hir::hir::PackageId;
14use qsc_passes::{run_core_passes, run_default_passes, PackageType};
15
16use crate::qsharp::write_package_string;
17
18pub(crate) fn check(program: &str, expr: Option<&str>, expect: &Expect) {
19 let (qsharp, src_ast_str) = compile_program(expr, program);
20 expect.assert_eq(&qsharp);
21 // Run the output against the compiler to ensure that input
22 // and output both generate the same qsharp.
23 let (round_trip_qsharp, gen_ast_str) = compile_program(expr, &qsharp);
24 expect.assert_eq(&round_trip_qsharp);
25 // we've validated the output, now validate the ASTs
26 // We may have generated the same Q#, but may have changed semantics
27 difference::assert_diff!(&src_ast_str, &gen_ast_str, "\n", 0);
28}
29
30pub(crate) fn get_compilation(sources: Option<SourceMap>) -> (PackageId, PackageStore) {
31 let mut core = compile::core();
32 assert!(run_core_passes(&mut core).is_empty());
33 let mut store = PackageStore::new(core);
34 let mut std = compile::std(&store, RuntimeCapabilityFlags::empty());
35 assert!(run_default_passes(
36 store.core(),
37 &mut std,
38 PackageType::Lib,
39 RuntimeCapabilityFlags::empty()
40 )
41 .is_empty());
42 let std = store.insert(std);
43
44 let mut unit = compile(
45 &store,
46 &[std],
47 sources.unwrap_or_default(),
48 RuntimeCapabilityFlags::all(),
49 LanguageFeatures::empty(),
50 );
51 assert!(unit.errors.is_empty(), "{:?}", unit.errors);
52 assert!(run_default_passes(
53 store.core(),
54 &mut unit,
55 PackageType::Lib,
56 RuntimeCapabilityFlags::all()
57 )
58 .is_empty());
59 let package_id = store.insert(unit);
60 (package_id, store)
61}
62
63pub(crate) fn compile_program(expr: Option<&str>, program: &str) -> (String, String) {
64 let expr_as_arc: Option<Arc<str>> = expr.map(|s| Arc::from(s.to_string()));
65 let sources = SourceMap::new([("test".into(), program.into())], expr_as_arc);
66
67 let (package_id, store) = get_compilation(Some(sources));
68 let package = &store.get(package_id).expect("package must exist");
69
70 let despanned_ast = AstDespanner.despan(&package.ast.package);
71 let qsharp = write_package_string(&despanned_ast);
72 let ast = format!("{despanned_ast}");
73 (qsharp, ast)
74}
75
76struct AstDespanner;
77impl AstDespanner {
78 fn despan(&mut self, package: &Package) -> Package {
79 let mut p = package.clone();
80 self.visit_package(&mut p);
81 p
82 }
83}
84
85impl qsc_ast::mut_visit::MutVisitor for AstDespanner {
86 fn visit_span(&mut self, span: &mut Span) {
87 span.hi = 0;
88 span.lo = 0;
89 }
90 fn visit_visibility(&mut self, vis: &mut qsc_ast::ast::Visibility) {
91 self.visit_span(&mut vis.span);
92 }
93}
94