Skip to content

Commit

Permalink
chore: more chisel debug and print compile error (foundry-rs#6647)
Browse files Browse the repository at this point in the history
* chore: more chisel debug and print compile error

* rustfmt
  • Loading branch information
mattsse authored and RPate97 committed Jan 12, 2024
1 parent 8777c13 commit 47c36c0
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 18 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/chisel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ strum = { version = "0.25", features = ["derive"] }
time = { version = "0.3", features = ["formatting"] }
tokio = { version = "1", features = ["full"] }
yansi = "0.5"
tracing.workspace = true

[dev-dependencies]
criterion = { version = "0.5", features = ["async_tokio"] }
Expand Down
10 changes: 8 additions & 2 deletions crates/chisel/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use foundry_config::{
};
use rustyline::{config::Configurer, error::ReadlineError, Editor};
use std::path::PathBuf;
use tracing::debug;
use yansi::Paint;

// Loads project's figment and merges the build cli arguments into it
Expand Down Expand Up @@ -180,6 +181,7 @@ async fn main() -> eyre::Result<()> {
// Get the prompt from the dispatcher
// Variable based on status of the last entry
let prompt = dispatcher.get_prompt();

rl.helper_mut().unwrap().set_errored(dispatcher.errored);

// Read the next line
Expand All @@ -188,6 +190,7 @@ async fn main() -> eyre::Result<()> {
// Try to read the string
match next_string {
Ok(line) => {
debug!("dispatching next line: {line}");
// Clear interrupt flag
interrupt = false;

Expand Down Expand Up @@ -231,8 +234,11 @@ impl Provider for ChiselParser {
/// Evaluate a single Solidity line.
async fn dispatch_repl_line(dispatcher: &mut ChiselDispatcher, line: &str) {
match dispatcher.dispatch(line).await {
DispatchResult::Success(msg) | DispatchResult::CommandSuccess(msg) => if let Some(msg) = msg {
println!("{}", Paint::green(msg));
DispatchResult::Success(msg) | DispatchResult::CommandSuccess(msg) => {
debug!(%line, ?msg, "dispatch success");
if let Some(msg) = msg {
println!("{}", Paint::green(msg));
}
},
DispatchResult::UnrecognizedCommand(e) => eprintln!("{e}"),
DispatchResult::SolangParserFailed(e) => {
Expand Down
11 changes: 9 additions & 2 deletions crates/chisel/src/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use serde::{Deserialize, Serialize};
use solang_parser::diagnostics::Diagnostic;
use std::{borrow::Cow, error::Error, io::Write, path::PathBuf, process::Command};
use strum::IntoEnumIterator;
use tracing::debug;
use yansi::Paint;

/// Prompt arrow character
Expand Down Expand Up @@ -807,6 +808,7 @@ impl ChiselDispatcher {
}
}
if input.trim().is_empty() {
debug!("empty dispatch input");
return DispatchResult::Success(None)
}

Expand All @@ -822,6 +824,7 @@ impl ChiselDispatcher {

// If the input is a comment, add it to the run code so we avoid running with empty input
if COMMENT_RE.is_match(input) {
debug!(%input, "matched comment");
source.with_run_code(input);
return DispatchResult::Success(None)
}
Expand Down Expand Up @@ -858,7 +861,10 @@ impl ChiselDispatcher {
Ok((true, Some(res))) => println!("{res}"),
Ok((true, None)) => {}
// Return successfully
Ok((false, res)) => return DispatchResult::Success(res),
Ok((false, res)) => {
debug!(%input, ?res, "inspect success");
return DispatchResult::Success(res)
}

// Return with the error
Err(e) => {
Expand Down Expand Up @@ -915,7 +921,8 @@ impl ChiselDispatcher {
}
} else {
match new_source.build() {
Ok(_) => {
Ok(out) => {
debug!(%input, ?out, "skipped execute and rebuild source");
self.session.session_source = Some(new_source);
self.errored = false;
DispatchResult::Success(None)
Expand Down
43 changes: 29 additions & 14 deletions crates/chisel/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use foundry_evm::{
};
use solang_parser::pt::{self, CodeLocation};
use std::str::FromStr;
use tracing::debug;
use yansi::Paint;

const USIZE_MAX_AS_U256: U256 = U256::from_limbs([usize::MAX as u64, 0, 0, 0]);
Expand All @@ -30,6 +31,8 @@ impl SessionSource {
///
/// Optionally, a tuple containing the [Address] of the deployed REPL contract as well as
/// the [ChiselResult].
///
/// Returns an error if compilation fails.
pub async fn execute(&mut self) -> Result<(Address, ChiselResult)> {
// Recompile the project and ensure no errors occurred.
let compiled = self.build()?;
Expand Down Expand Up @@ -125,35 +128,41 @@ impl SessionSource {
///
/// ### Returns
///
/// If the input is valid `Ok((formatted_output, continue))` where:
/// If the input is valid `Ok((continue, formatted_output))` where:
/// - `continue` is true if the input should be appended to the source
/// - `formatted_output` is the formatted value
/// - `formatted_output` is the formatted value, if any
pub async fn inspect(&self, input: &str) -> Result<(bool, Option<String>)> {
let line = format!("bytes memory inspectoor = abi.encode({input});");
let mut source = match self.clone_with_new_line(line) {
let mut source = match self.clone_with_new_line(line.clone()) {
Ok((source, _)) => source,
Err(_) => return Ok((true, None)),
Err(err) => {
debug!(%err, "failed to build new source");
return Ok((true, None))
}
};

let mut source_without_inspector = self.clone();

// Events and tuples fails compilation due to it not being able to be encoded in
// `inspectoor`. If that happens, try executing without the inspector.
let (mut res, has_inspector) = match source.execute().await {
Ok((_, res)) => (res, true),
Err(e) => match source_without_inspector.execute().await {
Ok((_, res)) => (res, false),
Err(_) => {
if self.config.foundry_config.verbosity >= 3 {
eprintln!("Could not inspect: {e}");
let (mut res, err) = match source.execute().await {
Ok((_, res)) => (res, None),
Err(err) => {
debug!(?err, %input, "execution failed");
match source_without_inspector.execute().await {
Ok((_, res)) => (res, Some(err)),
Err(_) => {
if self.config.foundry_config.verbosity >= 3 {
eprintln!("Could not inspect: {err}");
}
return Ok((true, None))
}
return Ok((true, None))
}
},
}
};

// If abi-encoding the input failed, check whether it is an event
if !has_inspector {
if let Some(err) = err {
let generated_output = source_without_inspector
.generated_output
.as_ref()
Expand All @@ -170,6 +179,12 @@ impl SessionSource {
return Ok((false, Some(formatted)))
}

// we were unable to check the event
if self.config.foundry_config.verbosity >= 3 {
eprintln!("Failed eval: {err}");
}

debug!(%err, %input, "failed abi encode input");
return Ok((false, None))
}

Expand Down

0 comments on commit 47c36c0

Please sign in to comment.