fix(solc): support constructor user docs (#1283)

This commit is contained in:
Matthias Seitz 2022-05-19 20:02:10 +02:00 committed by GitHub
parent 4c75e4ae19
commit fb39d36697
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 86 additions and 6 deletions

View File

@ -1299,15 +1299,17 @@ pub struct UserDoc {
#[serde(default, skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "Option::is_none")]
pub kind: Option<String>, pub kind: Option<String>,
#[serde(default, skip_serializing_if = "::std::collections::BTreeMap::is_empty")] #[serde(default, skip_serializing_if = "::std::collections::BTreeMap::is_empty")]
pub methods: BTreeMap<String, MethodNotice>, pub methods: BTreeMap<String, UserDocNotice>,
#[serde(default, skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "Option::is_none")]
pub notice: Option<String>, pub notice: Option<String>,
} }
#[derive(Clone, Debug, Default, Serialize, Deserialize, Eq, PartialEq)] #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
pub struct MethodNotice { #[serde(untagged)]
#[serde(default, skip_serializing_if = "Option::is_none")] pub enum UserDocNotice {
pub notice: Option<String>, // NOTE: this a variant used for constructors on older solc versions
Constructor(String),
Method { notice: String },
} }
#[derive(Clone, Debug, Default, Serialize, Deserialize, Eq, PartialEq)] #[derive(Clone, Debug, Default, Serialize, Deserialize, Eq, PartialEq)]

View File

@ -9,7 +9,10 @@ use std::{
use ethers_core::types::Address; use ethers_core::types::Address;
use ethers_solc::{ use ethers_solc::{
artifacts::{BytecodeHash, Libraries, ModelCheckerEngine::CHC, ModelCheckerSettings}, artifacts::{
BytecodeHash, Libraries, ModelCheckerEngine::CHC, ModelCheckerSettings, UserDoc,
UserDocNotice,
},
cache::{SolFilesCache, SOLIDITY_FILES_CACHE_FILENAME}, cache::{SolFilesCache, SOLIDITY_FILES_CACHE_FILENAME},
project_util::*, project_util::*,
remappings::Remapping, remappings::Remapping,
@ -1411,3 +1414,78 @@ fn can_purge_obsolete_artifacts() {
assert!(!compiled.is_unchanged()); assert!(!compiled.is_unchanged());
assert_eq!(compiled.into_artifacts().count(), 1); assert_eq!(compiled.into_artifacts().count(), 1);
} }
#[test]
fn can_parse_notice() {
let mut project = TempProject::<ConfigurableArtifacts>::dapptools().unwrap();
project.project_mut().artifacts.additional_values.userdoc = true;
project.project_mut().solc_config.settings = project.project_mut().artifacts.settings();
let contract = r#"
pragma solidity $VERSION;
contract Contract {
string greeting;
/**
* @notice hello
*/
constructor(string memory _greeting) public {
greeting = _greeting;
}
/**
* @notice hello
*/
function xyz() public {
}
/// @notice hello
function abc() public {
}
}
"#;
project.add_source("Contract", contract.replace("$VERSION", "=0.5.17")).unwrap();
let mut compiled = project.compile().unwrap();
assert!(!compiled.has_compiler_errors());
assert!(!compiled.is_unchanged());
assert!(compiled.find("Contract").is_some());
let userdoc = compiled.remove("Contract").unwrap().userdoc;
assert_eq!(
userdoc,
Some(UserDoc {
version: None,
kind: None,
methods: BTreeMap::from([
("abc()".to_string(), UserDocNotice::Method { notice: "hello".to_string() }),
("xyz()".to_string(), UserDocNotice::Method { notice: "hello".to_string() }),
("constructor".to_string(), UserDocNotice::Constructor("hello".to_string())),
]),
notice: None
})
);
project.add_source("Contract", contract.replace("$VERSION", "^0.8.10")).unwrap();
let mut compiled = project.compile().unwrap();
assert!(!compiled.has_compiler_errors());
assert!(!compiled.is_unchanged());
assert!(compiled.find("Contract").is_some());
let userdoc = compiled.remove("Contract").unwrap().userdoc;
assert_eq!(
userdoc,
Some(UserDoc {
version: Some(1),
kind: Some("user".to_string()),
methods: BTreeMap::from([
("abc()".to_string(), UserDocNotice::Method { notice: "hello".to_string() }),
("xyz()".to_string(), UserDocNotice::Method { notice: "hello".to_string() }),
("constructor".to_string(), UserDocNotice::Method { notice: "hello".to_string() }),
]),
notice: None
})
);
}