foundry_debugger/
builder.rs

1//! Debugger builder.
2
3use crate::{DebugNode, Debugger, node::flatten_call_trace};
4use alloy_primitives::{Address, map::AddressHashMap};
5use foundry_common::get_contract_name;
6use foundry_evm_core::Breakpoints;
7use foundry_evm_traces::{CallTraceArena, CallTraceDecoder, Traces, debug::ContractSources};
8
9/// Debugger builder.
10#[derive(Debug, Default)]
11#[must_use = "builders do nothing unless you call `build` on them"]
12pub struct DebuggerBuilder {
13    /// Debug traces returned from the EVM execution.
14    debug_arena: Vec<DebugNode>,
15    /// Identified contracts.
16    identified_contracts: AddressHashMap<String>,
17    /// Map of source files.
18    sources: ContractSources,
19    /// Map of the debugger breakpoints.
20    breakpoints: Breakpoints,
21}
22
23impl DebuggerBuilder {
24    /// Creates a new debugger builder.
25    #[inline]
26    pub fn new() -> Self {
27        Self::default()
28    }
29
30    /// Extends the debug arena.
31    #[inline]
32    pub fn traces(mut self, traces: Traces) -> Self {
33        for (_, arena) in traces {
34            self = self.trace_arena(arena.arena);
35        }
36        self
37    }
38
39    /// Extends the debug arena.
40    #[inline]
41    pub fn trace_arena(mut self, arena: CallTraceArena) -> Self {
42        flatten_call_trace(arena, &mut self.debug_arena);
43        self
44    }
45
46    /// Extends the identified contracts from multiple decoders.
47    #[inline]
48    pub fn decoders(mut self, decoders: &[CallTraceDecoder]) -> Self {
49        for decoder in decoders {
50            self = self.decoder(decoder);
51        }
52        self
53    }
54
55    /// Extends the identified contracts from a decoder.
56    #[inline]
57    pub fn decoder(self, decoder: &CallTraceDecoder) -> Self {
58        let c = decoder.contracts.iter().map(|(k, v)| (*k, get_contract_name(v).to_string()));
59        self.identified_contracts(c)
60    }
61
62    /// Extends the identified contracts.
63    #[inline]
64    pub fn identified_contracts(
65        mut self,
66        identified_contracts: impl IntoIterator<Item = (Address, String)>,
67    ) -> Self {
68        self.identified_contracts.extend(identified_contracts);
69        self
70    }
71
72    /// Sets the sources for the debugger.
73    #[inline]
74    pub fn sources(mut self, sources: ContractSources) -> Self {
75        self.sources = sources;
76        self
77    }
78
79    /// Sets the breakpoints for the debugger.
80    #[inline]
81    pub fn breakpoints(mut self, breakpoints: Breakpoints) -> Self {
82        self.breakpoints = breakpoints;
83        self
84    }
85
86    /// Builds the debugger.
87    #[inline]
88    pub fn build(self) -> Debugger {
89        let Self { debug_arena, identified_contracts, sources, breakpoints } = self;
90        Debugger::new(debug_arena, identified_contracts, sources, breakpoints)
91    }
92}