Skip to content

Commit f64fe13

Browse files
BobfaceclabbyEvalir
authored
feat: print event definitions (foundry-rs#4455)
* feat: print event definitions * fix: implement requested pr changes * fix: color event signature cyan * feat: print event parameters Co-authored-by: clabby <[email protected]> * fix: missing comma Co-authored-by: clabby <[email protected]> * fix: add missing import --------- Co-authored-by: clabby <[email protected]> Co-authored-by: Enrique Ortiz <[email protected]>
1 parent f7145c7 commit f64fe13

File tree

1 file changed

+92
-9
lines changed

1 file changed

+92
-9
lines changed

crates/chisel/src/executor.rs

+92-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! This module contains the execution logic for the [SessionSource].
44
55
use crate::prelude::{
6-
ChiselDispatcher, ChiselResult, ChiselRunner, IntermediateOutput, SessionSource,
6+
ChiselDispatcher, ChiselResult, ChiselRunner, IntermediateOutput, SessionSource, SolidityHelper,
77
};
88
use core::fmt::Debug;
99
use ethers::{
@@ -136,17 +136,44 @@ impl SessionSource {
136136
Err(_) => return Ok((true, None)),
137137
};
138138

139-
// TODO: Any tuple fails compilation due to it not being able to be encoded in `inspectoor`
140-
let mut res = match source.execute().await {
141-
Ok((_, res)) => res,
142-
Err(e) => {
143-
if self.config.foundry_config.verbosity >= 3 {
144-
eprintln!("Could not inspect: {e}");
139+
let mut source_without_inspector = self.clone();
140+
141+
// Events and tuples fails compilation due to it not being able to be encoded in
142+
// `inspectoor`. If that happens, try executing without the inspector.
143+
let (mut res, has_inspector) = match source.execute().await {
144+
Ok((_, res)) => (res, true),
145+
Err(e) => match source_without_inspector.execute().await {
146+
Ok((_, res)) => (res, false),
147+
Err(_) => {
148+
if self.config.foundry_config.verbosity >= 3 {
149+
eprintln!("Could not inspect: {e}");
150+
}
151+
return Ok((true, None))
145152
}
146-
return Ok((true, None))
147-
}
153+
},
148154
};
149155

156+
// If abi-encoding the input failed, check whether it is an event
157+
if !has_inspector {
158+
let generated_output = source_without_inspector
159+
.generated_output
160+
.as_ref()
161+
.ok_or_else(|| eyre::eyre!("Could not find generated output!"))?;
162+
163+
let intermediate_contract = generated_output
164+
.intermediate
165+
.intermediate_contracts
166+
.get("REPL")
167+
.ok_or_else(|| eyre::eyre!("Could not find intermediate contract!"))?;
168+
169+
if let Some(event_definition) = intermediate_contract.event_definitions.get(input) {
170+
let formatted = format_event_definition(event_definition)?;
171+
return Ok((false, Some(formatted)))
172+
}
173+
174+
return Ok((false, None))
175+
}
176+
150177
let Some((stack, memory, _)) = &res.state else {
151178
// Show traces and logs, if there are any, and return an error
152179
if let Ok(decoder) = ChiselDispatcher::decode_traces(&source.config, &mut res) {
@@ -376,6 +403,62 @@ fn format_token(token: Token) -> String {
376403
}
377404
}
378405

406+
/// Formats a [pt::EventDefinition] into an inspection message
407+
///
408+
/// ### Takes
409+
///
410+
/// An borrowed [pt::EventDefinition]
411+
///
412+
/// ### Returns
413+
///
414+
/// A formatted [pt::EventDefinition] for use in inspection output.
415+
///
416+
/// TODO: Verbosity option
417+
fn format_event_definition(event_definition: &pt::EventDefinition) -> Result<String> {
418+
let event_name = event_definition.name.as_ref().expect("Event has a name").to_string();
419+
let inputs = event_definition
420+
.fields
421+
.iter()
422+
.map(|param| {
423+
let name = param
424+
.name
425+
.as_ref()
426+
.map(ToString::to_string)
427+
.unwrap_or_else(|| "<anonymous>".to_string());
428+
let kind = Type::from_expression(&param.ty)
429+
.and_then(Type::into_builtin)
430+
.ok_or_else(|| eyre::eyre!("Invalid type in event {event_name}"))?;
431+
Ok(ethabi::EventParam { name, kind, indexed: param.indexed })
432+
})
433+
.collect::<Result<Vec<_>>>()?;
434+
let event = ethabi::Event { name: event_name, inputs, anonymous: event_definition.anonymous };
435+
436+
Ok(format!(
437+
"Type: {}\n├ Name: {}\n└ Signature: {:?}",
438+
Paint::red("event"),
439+
SolidityHelper::highlight(&format!(
440+
"{}({})",
441+
&event.name,
442+
&event
443+
.inputs
444+
.iter()
445+
.map(|param| format!(
446+
"{}{}{}",
447+
param.kind,
448+
if param.indexed { " indexed" } else { "" },
449+
if param.name.is_empty() {
450+
String::default()
451+
} else {
452+
format!(" {}", &param.name)
453+
},
454+
))
455+
.collect::<Vec<_>>()
456+
.join(", ")
457+
)),
458+
Paint::cyan(event.signature()),
459+
))
460+
}
461+
379462
// =============================================
380463
// Modified from
381464
// [soli](https://github.com/jpopesculian/soli)

0 commit comments

Comments
 (0)