From 4f8abd5f689854ddaf0ce126ae8b502268494751 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Fri, 26 Jul 2024 15:33:21 +0800 Subject: [PATCH] fix: better compatibility with older AST --- crates/artifacts/solc/src/ast/mod.rs | 25 +++++++++++++++++-------- crates/artifacts/solc/src/ast/util.rs | 1 - crates/artifacts/solc/src/ast/utils.rs | 26 ++++++++++++++++++++++++++ crates/compilers/src/flatten.rs | 3 +++ 4 files changed, 46 insertions(+), 9 deletions(-) delete mode 100644 crates/artifacts/solc/src/ast/util.rs create mode 100644 crates/artifacts/solc/src/ast/utils.rs diff --git a/crates/artifacts/solc/src/ast/mod.rs b/crates/artifacts/solc/src/ast/mod.rs index 76b9fd38e..31142f7c2 100644 --- a/crates/artifacts/solc/src/ast/mod.rs +++ b/crates/artifacts/solc/src/ast/mod.rs @@ -15,7 +15,7 @@ mod macros; mod misc; pub use misc::*; -pub mod util; +pub mod utils; pub mod visitor; /// A low fidelity representation of the AST. @@ -173,7 +173,7 @@ ast_node!( contract_dependencies: Vec, #[serde(rename = "contractKind")] kind: ContractKind, - documentation: Option, + documentation: Option, fully_implemented: bool, linearized_base_contracts: Vec, nodes: Vec, @@ -526,7 +526,7 @@ ast_node!( /// [`VariableDeclaration::mutability()`]. #[serde(default)] state_variable: bool, - documentation: Option, + documentation: Option, function_selector: Option, // TODO #[serde(default)] indexed: bool, @@ -568,6 +568,13 @@ ast_node!( } ); +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum Documentation { + Structured(StructuredDocumentation), + Raw(String), +} + ast_node!( /// An override specifier. struct OverrideSpecifier { @@ -670,7 +677,7 @@ ast_node!( name: String, #[serde(default, with = "serde_helpers::display_from_str_opt")] name_location: Option, - documentation: Option, + documentation: Option, error_selector: Option, // TODO parameters: ParameterList, } @@ -684,7 +691,7 @@ ast_node!( name_location: Option, anonymous: bool, event_selector: Option, // TODO - documentation: Option, + documentation: Option, parameters: ParameterList, } ); @@ -698,7 +705,7 @@ ast_node!( #[serde(default, deserialize_with = "serde_helpers::default_for_null")] base_functions: Vec, body: Option, - documentation: Option, + documentation: Option, function_selector: Option, // TODO implemented: bool, modifiers: Vec, @@ -865,9 +872,11 @@ ast_node!( struct InlineAssembly { documentation: Option, #[serde(rename = "AST")] - ast: YulBlock, + ast: Option, + operations: Option, // TODO: We need this camel case for the AST, but pascal case other places in ethers-solc //evm_version: EvmVersion, + #[serde(deserialize_with = "utils::deserialize_external_assembly_references")] external_references: Vec, #[serde(default, deserialize_with = "serde_helpers::default_for_null")] flags: Vec, @@ -1001,7 +1010,7 @@ ast_node!( #[serde(default, deserialize_with = "serde_helpers::default_for_null")] base_modifiers: Vec, body: Option, - documentation: Option, + documentation: Option, overrides: Option, parameters: ParameterList, #[serde(default, rename = "virtual")] diff --git a/crates/artifacts/solc/src/ast/util.rs b/crates/artifacts/solc/src/ast/util.rs deleted file mode 100644 index 8b1378917..000000000 --- a/crates/artifacts/solc/src/ast/util.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/crates/artifacts/solc/src/ast/utils.rs b/crates/artifacts/solc/src/ast/utils.rs new file mode 100644 index 000000000..9e0eb34bb --- /dev/null +++ b/crates/artifacts/solc/src/ast/utils.rs @@ -0,0 +1,26 @@ +use super::ExternalInlineAssemblyReference; +use serde::{Deserialize, Deserializer, Serialize}; +use std::collections::BTreeMap; + +pub fn deserialize_external_assembly_references<'de, D>( + deserializer: D, +) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + #[derive(Serialize, Deserialize)] + #[serde(untagged)] + enum ExternalReferencesHelper { + Plain(Vec), + /// Older solc versions produce external referrences as arrays of mappings {"variable" => + /// external reference object}, so we have to handle this. + Map(Vec>), + } + + ExternalReferencesHelper::deserialize(deserializer).map(|v| match v { + ExternalReferencesHelper::Plain(vec) => vec, + ExternalReferencesHelper::Map(vec) => { + vec.into_iter().flat_map(|v| v.into_values()).collect() + } + }) +} diff --git a/crates/compilers/src/flatten.rs b/crates/compilers/src/flatten.rs index bdc26fdc0..b410d8614 100644 --- a/crates/compilers/src/flatten.rs +++ b/crates/compilers/src/flatten.rs @@ -493,6 +493,9 @@ impl Flattener { }); docs.for_each(|doc| { + let Documentation::Structured(doc) = doc else { + return + }; let src_start = doc.src.start.unwrap(); let src_end = src_start + doc.src.length.unwrap();