microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.27.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/compiler/qsc/src/interpret/debug.rs

112lines · modeblame

e178f8ddIan Davis3 years ago1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#[cfg(test)]
5mod tests;
6
0d39fa9dorpuente-MS1 years ago7use qsc_data_structures::line_column::{Encoding, Position};
18718319Ian Davis2 years ago8use qsc_eval::debug::Frame;
7db6f1abCésar Zaragoza Cortés2 years ago9use qsc_fir::fir::{Global, PackageStoreLookup, StoreItemId};
e178f8ddIan Davis3 years ago10use qsc_frontend::compile::PackageStore;
2b583ddaIan Davis3 years ago11use qsc_hir::hir;
e178f8ddIan Davis3 years ago12use qsc_hir::hir::{Item, ItemKind};
18718319Ian Davis2 years ago13use qsc_lowerer::map_fir_package_to_hir;
1fcdcc84Stefan J. Wernli1 years ago14use std::fmt::Write;
82fc78d1Alex Hansen2 years ago15use std::rc::Rc;
e178f8ddIan Davis3 years ago16
17#[must_use]
2b583ddaIan Davis3 years ago18pub(crate) fn format_call_stack(
e178f8ddIan Davis3 years ago19store: &PackageStore,
7db6f1abCésar Zaragoza Cortés2 years ago20globals: &impl PackageStoreLookup,
2b583ddaIan Davis3 years ago21frames: Vec<Frame>,
e178f8ddIan Davis3 years ago22error: &dyn std::error::Error,
23) -> String {
24let mut trace = String::new();
1fcdcc84Stefan J. Wernli1 years ago25writeln!(trace, "Error: {error}").expect("writing to string should succeed");
e178f8ddIan Davis3 years ago26trace.push_str("Call stack:\n");
27
2b583ddaIan Davis3 years ago28let mut frames = frames;
e178f8ddIan Davis3 years ago29frames.reverse();
30
31for frame in frames {
7db6f1abCésar Zaragoza Cortés2 years ago32let Some(Global::Callable(call)) = globals.get_global(frame.id) else {
9cf3b306Stefan J. Wernli2 years ago33panic!("missing global");
34};
e178f8ddIan Davis3 years ago35
36trace.push_str(" at ");
37if frame.functor.adjoint {
38trace.push_str("Adjoint ");
39}
40if frame.functor.controlled > 0 {
1fcdcc84Stefan J. Wernli1 years ago41write!(trace, "Controlled({}) ", frame.functor.controlled)
42.expect("writing to string should succeed");
e178f8ddIan Davis3 years ago43}
8a033a27orpuente-MS9 months ago44if let Some(item) = get_item_parent(store, frame.id)
45&& let Some(ns) = get_ns_name(&item)
46{
47write!(trace, "{ns}.").expect("writing to string should succeed");
e178f8ddIan Davis3 years ago48}
1fcdcc84Stefan J. Wernli1 years ago49write!(trace, "{}", call.name.name).expect("writing to string should succeed");
e178f8ddIan Davis3 years ago50
51let name = get_item_file_name(store, frame.id);
65c9d967Mine Starks7 months ago52let pos = get_position(&frame, store);
0d39fa9dorpuente-MS1 years ago53write!(
54trace,
55" in {}:{}:{}",
56name.unwrap_or("<expression>".to_string()),
a3590c80Copilot1 years ago57pos.line + 1,
58pos.column + 1,
0d39fa9dorpuente-MS1 years ago59)
60.expect("writing to string should succeed");
e178f8ddIan Davis3 years ago61
62trace.push('\n');
63}
64trace
65}
66
67#[must_use]
7db6f1abCésar Zaragoza Cortés2 years ago68fn get_item_parent(store: &PackageStore, id: StoreItemId) -> Option<Item> {
2b583ddaIan Davis3 years ago69let package = map_fir_package_to_hir(id.package);
70let item = hir::LocalItemId::from(usize::from(id.item));
71store.get(package).and_then(|unit| {
72let item = unit.package.items.get(item)?;
e178f8ddIan Davis3 years ago73if let Some(parent) = item.parent {
74let parent = unit.package.items.get(parent)?;
75Some(parent.clone())
76} else {
77None
78}
79})
80}
81
82#[must_use]
7db6f1abCésar Zaragoza Cortés2 years ago83fn get_item_file_name(store: &PackageStore, id: StoreItemId) -> Option<String> {
2b583ddaIan Davis3 years ago84let package = map_fir_package_to_hir(id.package);
85let item = hir::LocalItemId::from(usize::from(id.item));
86store.get(package).and_then(|unit| {
87let item = unit.package.items.get(item)?;
91afda4eMine Starks3 years ago88let source = unit.sources.find_by_offset(item.span.lo);
89source.map(|s| s.name.to_string())
e178f8ddIan Davis3 years ago90})
91}
92
93#[must_use]
82fc78d1Alex Hansen2 years ago94fn get_ns_name(item: &Item) -> Option<Rc<str>> {
95let ItemKind::Namespace(ns, _) = &item.kind else {
96return None;
97};
98Some(ns.name())
e178f8ddIan Davis3 years ago99}
0d39fa9dorpuente-MS1 years ago100
101/// Converts the [`Span`] of [`Frame`] into a [`Position`].
65c9d967Mine Starks7 months ago102fn get_position(frame: &Frame, store: &PackageStore) -> Position {
0d39fa9dorpuente-MS1 years ago103let filename = get_item_file_name(store, frame.id).expect("file should exist");
104let package_id = map_fir_package_to_hir(frame.id.package);
105let unit = store.get(package_id).expect("package should exist");
106let source = unit
107.sources
108.find_by_name(&filename)
109.expect("source should exist");
110let contents = &source.contents;
b5de5837orpuente-MS1 years ago111Position::from_utf8_byte_offset(Encoding::Utf8, contents, frame.span.lo - source.offset)
0d39fa9dorpuente-MS1 years ago112}