diff --git a/Cargo.lock b/Cargo.lock index c8e6545369bf6..3126a4f12d8a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3638,6 +3638,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", + "serde_json", "syn 2.0.100", ] diff --git a/crates/sol-macro-gen/Cargo.toml b/crates/sol-macro-gen/Cargo.toml index 2010fe3a569b6..79b47880f33f9 100644 --- a/crates/sol-macro-gen/Cargo.toml +++ b/crates/sol-macro-gen/Cargo.toml @@ -23,5 +23,6 @@ proc-macro2.workspace = true quote.workspace = true syn.workspace = true prettyplease.workspace = true +serde_json.workspace = true eyre.workspace = true diff --git a/crates/sol-macro-gen/src/sol_macro_gen.rs b/crates/sol-macro-gen/src/sol_macro_gen.rs index ad30580f6c3f4..133f4ed218f9b 100644 --- a/crates/sol-macro-gen/src/sol_macro_gen.rs +++ b/crates/sol-macro-gen/src/sol_macro_gen.rs @@ -15,6 +15,7 @@ use eyre::{Context, OptionExt, Result}; use foundry_common::fs; use proc_macro2::{Span, TokenStream}; use std::{ + env::temp_dir, fmt::Write, path::{Path, PathBuf}, str::FromStr, @@ -82,7 +83,37 @@ impl MultiSolMacroGen { } fn generate_binding(instance: &mut SolMacroGen, all_derives: bool) -> Result<()> { - let input = instance.get_sol_input()?.normalize_json()?; + // TODO: in `get_sol_input` we currently can't handle unlinked bytecode: + let input = match instance.get_sol_input() { + Ok(input) => input.normalize_json()?, + Err(error) => { + // TODO(mattsse): remove after + if error.to_string().contains("expected bytecode, found unlinked bytecode") { + // we attempt to do a little hack here until we have this properly supported by + // removing the bytecode objects from the json file and using a tmpfile (very + // hacky) + let content = std::fs::read_to_string(&instance.path)?; + let mut value = serde_json::from_str::(&content)?; + let obj = value.as_object_mut().expect("valid abi"); + + // clear unlinked bytecode + obj.remove("bytecode"); + obj.remove("deployedBytecode"); + + let tmpdir = temp_dir(); + let mut tmp_file = tmpdir.join(instance.path.file_name().unwrap()); + std::fs::write(&tmp_file, serde_json::to_string(&value)?)?; + + // try again + std::mem::swap(&mut tmp_file, &mut instance.path); + let input = instance.get_sol_input()?.normalize_json()?; + std::mem::swap(&mut tmp_file, &mut instance.path); + input.normalize_json()? + } else { + return Err(error) + } + } + }; let SolInput { attrs: _, path: _, kind } = input;