Skip to content

Commit bbd1df2

Browse files
authored
StackTrace requests support for inlined functions (#75)
Closes #14 commit-id:c549ee5c
1 parent 216bf29 commit bbd1df2

File tree

3 files changed

+49
-20
lines changed

3 files changed

+49
-20
lines changed

.DS_Store

6 KB
Binary file not shown.

src/debugger/call_stack.rs

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::iter::once;
22
use std::path::Path;
33

4-
use cairo_annotations::annotations::coverage::CodeLocation;
4+
use cairo_annotations::annotations::coverage::{CodeLocation, SourceFileFullPath};
5+
use cairo_annotations::annotations::profiler::FunctionName;
56
use cairo_lang_sierra::program::StatementIdx;
67
use dap::types::{Scope, ScopePresentationhint, StackFrame, Variable};
78
use dap::types::{Source, StackFramePresentationhint};
@@ -64,8 +65,8 @@ impl CallStack {
6465
.map(|(call_statement_idx, _)| call_statement_idx)
6566
.cloned()
6667
.chain(once(statement_idx))
67-
.map(|statement_idx| self.build_stack_frame(ctx, statement_idx))
6868
.rev()
69+
.flat_map(|statement_idx| self.build_stack_frames(ctx, statement_idx))
6970
.collect()
7071
}
7172

@@ -92,19 +93,34 @@ impl CallStack {
9293
vec![]
9394
}
9495

95-
fn build_stack_frame(&self, ctx: &Context, statement_idx: StatementIdx) -> StackFrame {
96-
let id = MIN_OBJECT_REFERENCE + 2 * self.call_ids.len() as i64;
97-
let Some(CodeLocation(source_file, code_span, _)) =
98-
ctx.code_location_for_statement_idx(statement_idx)
99-
else {
100-
return unknown_frame();
96+
/// Builds a vector of stack frames, ordered from the most nested (innermost) to the least nested (outermost) element.
97+
fn build_stack_frames(&self, ctx: &Context, statement_idx: StatementIdx) -> Vec<StackFrame> {
98+
let Some(code_locations) = ctx.code_locations_for_statement_idx(statement_idx) else {
99+
return vec![unknown_frame()];
101100
};
102101

103-
let file_path = Path::new(&source_file.0);
104-
let name = ctx
105-
.function_name_for_statement_idx(statement_idx)
106-
.map(|name| name.0)
107-
.unwrap_or("test".to_string());
102+
let default_function_names = vec![FunctionName("test".to_string())];
103+
let function_names =
104+
ctx.function_names_for_statement_idx(statement_idx).unwrap_or(&default_function_names);
105+
106+
code_locations
107+
.iter()
108+
.zip(function_names)
109+
.map(|(code_location, function_name)| {
110+
self.build_stack_frame(code_location, function_name, ctx)
111+
})
112+
.collect()
113+
}
114+
115+
fn build_stack_frame(
116+
&self,
117+
CodeLocation(SourceFileFullPath(source_file), code_span, _): &CodeLocation,
118+
FunctionName(function_name): &FunctionName,
119+
ctx: &Context,
120+
) -> StackFrame {
121+
let id = MIN_OBJECT_REFERENCE + 2 * self.call_ids.len() as i64;
122+
let file_path = Path::new(&source_file);
123+
let name = function_name.clone();
108124

109125
let is_user_code = file_path.starts_with(&ctx.root_path);
110126
let presentation_hint = Some(if is_user_code {
@@ -121,7 +137,11 @@ impl CallStack {
121137
StackFrame {
122138
id,
123139
name,
124-
source: Some(Source { name: None, path: Some(source_file.0), ..Default::default() }),
140+
source: Some(Source {
141+
name: None,
142+
path: Some(source_file.clone()),
143+
..Default::default()
144+
}),
125145
line,
126146
column,
127147
presentation_hint,

src/debugger/context.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ impl Context {
8686
)
8787
}
8888

89+
/// Return code location for the current statement, not including inlined code locations.
8990
pub fn code_location_for_statement_idx(
9091
&self,
9192
statement_idx: StatementIdx,
@@ -96,14 +97,22 @@ impl Context {
9697
.and_then(|locations| locations.first().cloned())
9798
}
9899

99-
pub fn function_name_for_statement_idx(
100+
/// Return code locations for the current statement, including inlined code locations.
101+
/// The first element is not inlined.
102+
pub fn code_locations_for_statement_idx(
100103
&self,
101104
statement_idx: StatementIdx,
102-
) -> Option<FunctionName> {
103-
self.function_names
104-
.statements_functions
105-
.get(&statement_idx)
106-
.and_then(|locations| locations.first().cloned())
105+
) -> Option<&Vec<CodeLocation>> {
106+
self.code_locations.statements_code_locations.get(&statement_idx)
107+
}
108+
109+
/// Return function names for the current statement, including inlined function names.
110+
/// The first element is not inlined.
111+
pub fn function_names_for_statement_idx(
112+
&self,
113+
statement_idx: StatementIdx,
114+
) -> Option<&Vec<FunctionName>> {
115+
self.function_names.statements_functions.get(&statement_idx)
107116
}
108117

109118
pub fn statement_idxs_for_breakpoint(

0 commit comments

Comments
 (0)