microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.2.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc/src/interpret/debug.rs

90lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#[cfg(test)]
5mod tests;
6
7use qsc_eval::debug::{map_fir_package_to_hir, Frame};
8use qsc_fir::fir::{Global, PackageStoreLookup, StoreItemId};
9use qsc_frontend::compile::PackageStore;
10use qsc_hir::hir;
11use qsc_hir::hir::{Item, ItemKind};
12
13#[must_use]
14pub(crate) fn format_call_stack(
15 store: &PackageStore,
16 globals: &impl PackageStoreLookup,
17 frames: Vec<Frame>,
18 error: &dyn std::error::Error,
19) -> String {
20 let mut trace = String::new();
21 trace.push_str(&format!("Error: {error}\n"));
22 trace.push_str("Call stack:\n");
23
24 let mut frames = frames;
25 frames.reverse();
26
27 for frame in frames {
28 let Some(Global::Callable(call)) = globals.get_global(frame.id) else {
29 panic!("missing global");
30 };
31
32 trace.push_str(" at ");
33 if frame.functor.adjoint {
34 trace.push_str("Adjoint ");
35 }
36 if frame.functor.controlled > 0 {
37 trace.push_str(&format!("Controlled({}) ", frame.functor.controlled));
38 }
39 if let Some(item) = get_item_parent(store, frame.id) {
40 if let Some(ns) = get_ns_name(&item) {
41 trace.push_str(&format!("{ns}."));
42 }
43 }
44 trace.push_str(&format!("{}", call.name.name));
45
46 let name = get_item_file_name(store, frame.id);
47 trace.push_str(&format!(
48 " in {}",
49 name.unwrap_or("<expression>".to_string())
50 ));
51
52 trace.push('\n');
53 }
54 trace
55}
56
57#[must_use]
58fn get_item_parent(store: &PackageStore, id: StoreItemId) -> Option<Item> {
59 let package = map_fir_package_to_hir(id.package);
60 let item = hir::LocalItemId::from(usize::from(id.item));
61 store.get(package).and_then(|unit| {
62 let item = unit.package.items.get(item)?;
63 if let Some(parent) = item.parent {
64 let parent = unit.package.items.get(parent)?;
65 Some(parent.clone())
66 } else {
67 None
68 }
69 })
70}
71
72#[must_use]
73fn get_item_file_name(store: &PackageStore, id: StoreItemId) -> Option<String> {
74 let package = map_fir_package_to_hir(id.package);
75 let item = hir::LocalItemId::from(usize::from(id.item));
76 store.get(package).and_then(|unit| {
77 let item = unit.package.items.get(item)?;
78 let source = unit.sources.find_by_offset(item.span.lo);
79 source.map(|s| s.name.to_string())
80 })
81}
82
83#[must_use]
84fn get_ns_name(item: &Item) -> Option<String> {
85 if let ItemKind::Namespace(ns, _) = &item.kind {
86 Some(ns.name.to_string())
87 } else {
88 None
89 }
90}
91