11use std:: iter:: once;
22use 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 ;
56use cairo_lang_sierra:: program:: StatementIdx ;
67use dap:: types:: { Scope , ScopePresentationhint , StackFrame , Variable } ;
78use 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,
0 commit comments