1+ //! The file dumper implementation 
2+ 
3+ use  std:: collections:: { BTreeMap ,  HashMap } ; 
4+ use  std:: path:: PathBuf ; 
5+ use  alloy_primitives:: Address ; 
6+ use  serde:: Serialize ; 
7+ 
8+ use  crate :: context:: DebuggerContext ; 
9+ use  eyre:: Result ; 
10+ use  foundry_compilers:: artifacts:: ContractBytecodeSome ; 
11+ use  foundry_common:: compile:: ContractSources ; 
12+ use  foundry_common:: fs:: { write_json_file} ; 
13+ use  foundry_evm_core:: debug:: DebugNodeFlat ; 
14+ use  foundry_evm_core:: utils:: PcIcMap ; 
15+ 
16+ /// The file dumper 
17+ pub  struct  FileDumper < ' a >  { 
18+     path :  & ' a  PathBuf , 
19+     debugger_context :  & ' a  mut  DebuggerContext , 
20+ } 
21+ 
22+ impl < ' a >  FileDumper < ' a >  { 
23+     pub  fn  new ( path :  & ' a  PathBuf ,  debugger_context :  & ' a  mut  DebuggerContext ,  )  -> Self  { 
24+         Self  {  path,  debugger_context } 
25+     } 
26+ 
27+     pub  fn  run ( & mut  self )  -> Result < ( ) >  { 
28+         let  data = DebuggerDump :: from ( self . debugger_context ) ; 
29+         write_json_file ( self . path ,  & data) . unwrap ( ) ; 
30+         Ok ( ( ) ) 
31+     } 
32+ } 
33+ 
34+ #[ derive( Serialize ) ]  
35+ struct  DebuggerDump < ' a >  { 
36+     calls :  & ' a  Vec < DebugNodeFlat > , 
37+     identified_contracts :  & ' a  HashMap < Address ,  String > , 
38+     /// Source map of contract sources 
39+      contracts_sources :  ContractSourcesDump , 
40+     /// A mapping of source -> (PC -> IC map for deploy code, PC -> IC map for runtime code) 
41+      pc_ic_maps :  PcIcMapDump , 
42+ } 
43+ 
44+ impl  < ' a >  DebuggerDump < ' a >  { 
45+     fn  from ( debugger_context :  & ' a  DebuggerContext )  -> DebuggerDump  { 
46+         Self  { 
47+             calls :  & debugger_context. debug_arena , 
48+             identified_contracts :  & debugger_context. identified_contracts , 
49+             contracts_sources :  ContractSourcesDump :: from ( & debugger_context. contracts_sources ) , 
50+             pc_ic_maps :  PcIcMapDump :: from ( & debugger_context. pc_ic_maps ) , 
51+         } 
52+     } 
53+ } 
54+ 
55+ #[ derive( Serialize ) ]  
56+ struct  ContractSourcesDump  { 
57+     #[ serde( flatten) ]  
58+     inner :  HashMap < String ,  Vec < ContractSourcesItemDump > > , 
59+ } 
60+ 
61+ #[ derive( Serialize ) ]  
62+ struct  ContractSourcesItemDump  { 
63+     id :  u32 , 
64+     source :  String , 
65+     #[ serde( flatten) ]  
66+     bytecode :  ContractBytecodeSome , 
67+ } 
68+ 
69+ impl  ContractSourcesDump  { 
70+     fn  from ( contract_sources :  & ContractSources )  -> ContractSourcesDump  { 
71+         let  mut  inner:  HashMap < String ,  Vec < ContractSourcesItemDump > >  = HashMap :: new ( ) ; 
72+ 
73+         for  ( name,  ids)  in  & contract_sources. ids_by_name  { 
74+             let  list = inner. entry ( name. clone ( ) ) . or_insert ( Default :: default ( ) ) ; 
75+             for  id in  ids { 
76+                 if  let  Some ( ( source,  bytecode) )  = contract_sources. sources_by_id . get ( id)  { 
77+                     list. push ( ContractSourcesItemDump { id :  * id,  source :  source. clone ( ) ,  bytecode :  bytecode. clone ( ) } ) ; 
78+                 } 
79+             } 
80+         } 
81+ 
82+         Self  {  inner } 
83+     } 
84+ } 
85+ 
86+ #[ derive( Serialize ) ]  
87+ struct  PcIcMapDump  { 
88+     #[ serde( flatten) ]  
89+     inner :  HashMap < String ,  PcIcMapItemDump > , 
90+ } 
91+ 
92+ impl  PcIcMapDump  { 
93+     fn  from ( pc_ic_map :  & BTreeMap < String ,  ( PcIcMap ,  PcIcMap ) > )  -> PcIcMapDump  { 
94+         let  mut  inner = HashMap :: new ( ) ; 
95+ 
96+         for  ( k,  v)  in  pc_ic_map. iter ( )  { 
97+             inner. insert ( k. clone ( ) ,  PcIcMapItemDump :: from ( v) ) ; 
98+         } 
99+ 
100+         Self  {  inner } 
101+     } 
102+ } 
103+ 
104+ #[ derive( Serialize ) ]  
105+ struct  PcIcMapItemDump  { 
106+     deploy_code_map :  HashMap < usize ,  usize > , 
107+     runtime_code_map :  HashMap < usize ,  usize > , 
108+ } 
109+ 
110+ impl  PcIcMapItemDump  { 
111+     fn  from ( pc_ic_map :  & ( PcIcMap ,  PcIcMap ) )  -> PcIcMapItemDump  { 
112+         let  mut  deploy_code_map= HashMap :: new ( ) ; 
113+         let  mut  runtime_code_map = HashMap :: new ( ) ; 
114+ 
115+         for  ( k,  v)  in  pc_ic_map. 0 . inner . iter ( )  { 
116+             deploy_code_map. insert ( k. clone ( ) ,  v. clone ( ) ) ; 
117+         } 
118+ 
119+         for  ( k,  v)  in  pc_ic_map. 1 . inner . iter ( )  { 
120+             runtime_code_map. insert ( k. clone ( ) ,  v. clone ( ) ) ; 
121+         } 
122+ 
123+         Self  {  deploy_code_map,  runtime_code_map } 
124+     } 
125+ } 
0 commit comments