mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge branch 'develop' into versions-menu-overflow
This commit is contained in:
commit
489d1a4428
@ -691,7 +691,7 @@ defaults:
|
|||||||
name: t_native_test_ext_prb_math
|
name: t_native_test_ext_prb_math
|
||||||
project: prb-math
|
project: prb-math
|
||||||
binary_type: native
|
binary_type: native
|
||||||
image: cimg/node:18.16
|
image: cimg/rust:1.70
|
||||||
|
|
||||||
- job_native_test_ext_elementfi: &job_native_test_ext_elementfi
|
- job_native_test_ext_elementfi: &job_native_test_ext_elementfi
|
||||||
<<: *requires_b_ubu_static
|
<<: *requires_b_ubu_static
|
||||||
@ -1724,11 +1724,13 @@ workflows:
|
|||||||
- t_native_test_ext_yield_liquidator
|
- t_native_test_ext_yield_liquidator
|
||||||
- t_native_test_ext_perpetual_pools
|
- t_native_test_ext_perpetual_pools
|
||||||
- t_native_test_ext_uniswap
|
- t_native_test_ext_uniswap
|
||||||
- t_native_test_ext_prb_math
|
|
||||||
- t_native_test_ext_elementfi
|
- t_native_test_ext_elementfi
|
||||||
- t_native_test_ext_brink
|
- t_native_test_ext_brink
|
||||||
# NOTE: We are disabling gp2 tests due to constant failures.
|
# NOTE: We are disabling gp2 tests due to constant failures.
|
||||||
#- t_native_test_ext_gp2
|
#- t_native_test_ext_gp2
|
||||||
|
# TODO: Dropping prb-math from the benchmarks since it is not implemented yet
|
||||||
|
# in the new Foundry external testing infrastructure.
|
||||||
|
# - t_native_test_ext_prb_math
|
||||||
# NOTE: The external tests below were commented because they
|
# NOTE: The external tests below were commented because they
|
||||||
# depend on a specific version of hardhat which does not support shanghai EVM.
|
# depend on a specific version of hardhat which does not support shanghai EVM.
|
||||||
#- t_native_test_ext_trident
|
#- t_native_test_ext_trident
|
||||||
|
@ -7,6 +7,7 @@ Compiler Features:
|
|||||||
|
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
* NatSpec: Fix internal error when requesting userdoc or devdoc for a contract that emits an event defined in a foreign contract or interface.
|
||||||
|
|
||||||
|
|
||||||
### 0.8.21 (2023-07-19)
|
### 0.8.21 (2023-07-19)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
### Requirements
|
### Requirements
|
||||||
- [ ] GitHub account with access to [solidity](https://github.com/ethereum/solidity), [solc-js](https://github.com/ethereum/solc-js),
|
- [ ] GitHub account with access to [solidity](https://github.com/ethereum/solidity), [solc-js](https://github.com/ethereum/solc-js),
|
||||||
[solc-bin](https://github.com/ethereum/solc-bin), [homebrew-ethereum](https://github.com/ethereum/homebrew-ethereum),
|
[solc-bin](https://github.com/ethereum/solc-bin), [homebrew-ethereum](https://github.com/ethereum/homebrew-ethereum),
|
||||||
[solidity-blog](https://github.com/ethereum/solidity-blog) and [solidity-portal](https://github.com/ethereum/solidity-portal) repositories.
|
[solidity-website](https://github.com/ethereum/solidity-website).
|
||||||
- [ ] DockerHub account with push rights to the [``solc`` image](https://hub.docker.com/r/ethereum/solc).
|
- [ ] DockerHub account with push rights to the [``solc`` image](https://hub.docker.com/r/ethereum/solc).
|
||||||
- [ ] Launchpad (Ubuntu One) account with a membership in the ["Ethereum" team](https://launchpad.net/~ethereum) and
|
- [ ] Launchpad (Ubuntu One) account with a membership in the ["Ethereum" team](https://launchpad.net/~ethereum) and
|
||||||
a gnupg key for your email in the ``ethereum.org`` domain (has to be version 1, gpg2 won't work).
|
a gnupg key for your email in the ``ethereum.org`` domain (has to be version 1, gpg2 won't work).
|
||||||
@ -37,8 +37,8 @@ At least a day before the release:
|
|||||||
- [ ] Prepare drafts of Twitter, Reddit and Solidity Forum announcements.
|
- [ ] Prepare drafts of Twitter, Reddit and Solidity Forum announcements.
|
||||||
|
|
||||||
### Blog Post
|
### Blog Post
|
||||||
- [ ] Create a post on [solidity-blog](https://github.com/ethereum/solidity-blog) in the ``Releases`` category and explain some of the new features or concepts.
|
- [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the ``Releases`` category and explain some of the new features or concepts.
|
||||||
- [ ] Create a post on [solidity-blog](https://github.com/ethereum/solidity-blog) in the ``Security Alerts`` category in case of important bug(s).
|
- [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the ``Security Alerts`` category in case of important bug(s).
|
||||||
|
|
||||||
### Changelog
|
### Changelog
|
||||||
- [ ] Sort the changelog entries alphabetically and correct any errors you notice. Commit it.
|
- [ ] Sort the changelog entries alphabetically and correct any errors you notice. Commit it.
|
||||||
@ -104,9 +104,9 @@ At least a day before the release:
|
|||||||
- [ ] Make sure the documentation for the new release has been published successfully.
|
- [ ] Make sure the documentation for the new release has been published successfully.
|
||||||
Go to the [documentation status page at ReadTheDocs](https://readthedocs.org/projects/solidity/) and verify that the new version is listed, works and is marked as default.
|
Go to the [documentation status page at ReadTheDocs](https://readthedocs.org/projects/solidity/) and verify that the new version is listed, works and is marked as default.
|
||||||
- [ ] Remove "still in progress" warning from the [release notes](https://github.com/ethereum/solidity/releases).
|
- [ ] Remove "still in progress" warning from the [release notes](https://github.com/ethereum/solidity/releases).
|
||||||
- [ ] Merge the [blog posts](https://github.com/ethereum/solidity-blog/pulls) related to the release.
|
- [ ] Merge the [blog posts](https://github.com/ethereum/solidity-website/pulls) related to the release.
|
||||||
- [ ] Create a commit to increase the version number on ``develop`` in ``CMakeLists.txt`` and add a new skeleton changelog entry.
|
- [ ] Create a commit to increase the version number on ``develop`` in ``CMakeLists.txt`` and add a new skeleton changelog entry.
|
||||||
- [ ] Update the release information section [in the source of soliditylang.org](https://github.com/ethereum/solidity-portal/blob/master/index.html).
|
- [ ] Update the release information section [in the source of soliditylang.org](https://github.com/ethereum/solidity-website/blob/main/src/pages/index.tsx).
|
||||||
- [ ] Announce on [Twitter](https://twitter.com/solidity_lang), including links to the release and the blog post.
|
- [ ] Announce on [Twitter](https://twitter.com/solidity_lang), including links to the release and the blog post.
|
||||||
- [ ] Announce on [Fosstodon](https://fosstodon.org/@solidity/), including links to the release and the blog post.
|
- [ ] Announce on [Fosstodon](https://fosstodon.org/@solidity/), including links to the release and the blog post.
|
||||||
- [ ] Share the announcement on Reddit in [``/r/ethdev``](https://reddit.com/r/ethdev/), cross-posted to [``/r/ethereum``](https://reddit.com/r/ethereum/).
|
- [ ] Share the announcement on Reddit in [``/r/ethdev``](https://reddit.com/r/ethdev/), cross-posted to [``/r/ethereum``](https://reddit.com/r/ethereum/).
|
||||||
|
@ -80,14 +80,6 @@ Json::Value Natspec::userDocumentation(ContractDefinition const& _contractDef)
|
|||||||
|
|
||||||
for (auto const& event: uniqueInterfaceEvents(_contractDef))
|
for (auto const& event: uniqueInterfaceEvents(_contractDef))
|
||||||
{
|
{
|
||||||
ContractDefinition const* eventOrigin = event->annotation().contract;
|
|
||||||
solAssert(eventOrigin);
|
|
||||||
solAssert(
|
|
||||||
*eventOrigin == _contractDef ||
|
|
||||||
(!eventOrigin->isLibrary() && _contractDef.derivesFrom(*eventOrigin)) ||
|
|
||||||
(eventOrigin->isLibrary() && !_contractDef.derivesFrom(*eventOrigin))
|
|
||||||
);
|
|
||||||
|
|
||||||
string value = extractDoc(event->annotation().docTags, "notice");
|
string value = extractDoc(event->annotation().docTags, "notice");
|
||||||
if (!value.empty())
|
if (!value.empty())
|
||||||
doc["events"][event->functionType(true)->externalSignature()]["notice"] = value;
|
doc["events"][event->functionType(true)->externalSignature()]["notice"] = value;
|
||||||
@ -178,16 +170,7 @@ Json::Value Natspec::devDocumentation(ContractDefinition const& _contractDef)
|
|||||||
|
|
||||||
for (auto const& event: uniqueInterfaceEvents(_contractDef))
|
for (auto const& event: uniqueInterfaceEvents(_contractDef))
|
||||||
if (auto devDoc = devDocumentation(event->annotation().docTags); !devDoc.empty())
|
if (auto devDoc = devDocumentation(event->annotation().docTags); !devDoc.empty())
|
||||||
{
|
|
||||||
ContractDefinition const* eventOrigin = event->annotation().contract;
|
|
||||||
solAssert(eventOrigin);
|
|
||||||
solAssert(
|
|
||||||
*eventOrigin == _contractDef ||
|
|
||||||
(!eventOrigin->isLibrary() && _contractDef.derivesFrom(*eventOrigin)) ||
|
|
||||||
(eventOrigin->isLibrary() && !_contractDef.derivesFrom(*eventOrigin))
|
|
||||||
);
|
|
||||||
doc["events"][event->functionType(true)->externalSignature()] = devDoc;
|
doc["events"][event->functionType(true)->externalSignature()] = devDoc;
|
||||||
}
|
|
||||||
for (auto const& error: _contractDef.interfaceErrors())
|
for (auto const& error: _contractDef.interfaceErrors())
|
||||||
if (auto devDoc = devDocumentation(error->annotation().docTags); !devDoc.empty())
|
if (auto devDoc = devDocumentation(error->annotation().docTags); !devDoc.empty())
|
||||||
doc["errors"][error->functionType(true)->externalSignature()].append(devDoc);
|
doc["errors"][error->functionType(true)->externalSignature()].append(devDoc);
|
||||||
|
172
scripts/externalTests/runners/base.py
Normal file
172
scripts/externalTests/runners/base.py
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# solidity is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2023 solidity contributors.
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
from abc import ABCMeta
|
||||||
|
from abc import abstractmethod
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from dataclasses import field
|
||||||
|
from pathlib import Path
|
||||||
|
from shutil import rmtree
|
||||||
|
from tempfile import mkdtemp
|
||||||
|
from textwrap import dedent
|
||||||
|
from typing import List
|
||||||
|
from typing import Set
|
||||||
|
|
||||||
|
from test_helpers import download_project
|
||||||
|
from test_helpers import get_solc_short_version
|
||||||
|
from test_helpers import parse_command_line
|
||||||
|
from test_helpers import parse_custom_presets
|
||||||
|
from test_helpers import parse_solc_version
|
||||||
|
from test_helpers import replace_version_pragmas
|
||||||
|
from test_helpers import settings_from_preset
|
||||||
|
from test_helpers import SettingsPreset
|
||||||
|
|
||||||
|
CURRENT_EVM_VERSION: str = "shanghai"
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class TestConfig:
|
||||||
|
name: str
|
||||||
|
repo_url: str
|
||||||
|
ref_type: str
|
||||||
|
ref: str
|
||||||
|
compile_only_presets: List[SettingsPreset] = field(default_factory=list)
|
||||||
|
settings_presets: List[SettingsPreset] = field(default_factory=lambda: list(SettingsPreset))
|
||||||
|
evm_version: str = field(default=CURRENT_EVM_VERSION)
|
||||||
|
|
||||||
|
def selected_presets(self) -> Set[SettingsPreset]:
|
||||||
|
return set(self.compile_only_presets + self.settings_presets)
|
||||||
|
|
||||||
|
|
||||||
|
class BaseRunner(metaclass=ABCMeta):
|
||||||
|
config: TestConfig
|
||||||
|
solc_binary_type: str
|
||||||
|
solc_binary_path: Path
|
||||||
|
presets: Set[SettingsPreset]
|
||||||
|
|
||||||
|
def __init__(self, argv, config: TestConfig):
|
||||||
|
args = parse_command_line(f"{config.name} external tests", argv)
|
||||||
|
self.config = config
|
||||||
|
self.solc_binary_type = args.solc_binary_type
|
||||||
|
self.solc_binary_path = args.solc_binary_path
|
||||||
|
self.presets = parse_custom_presets(args.selected_presets) if args.selected_presets else config.selected_presets()
|
||||||
|
self.env = os.environ.copy()
|
||||||
|
self.tmp_dir = mkdtemp(prefix=f"ext-test-{config.name}-")
|
||||||
|
self.test_dir = Path(self.tmp_dir) / "ext"
|
||||||
|
|
||||||
|
def setup_solc(self) -> str:
|
||||||
|
if self.solc_binary_type == "solcjs":
|
||||||
|
# TODO: add support to solc-js
|
||||||
|
raise NotImplementedError()
|
||||||
|
print("Setting up solc...")
|
||||||
|
solc_version_output = subprocess.check_output(
|
||||||
|
[self.solc_binary_path, "--version"],
|
||||||
|
shell=False,
|
||||||
|
encoding="utf-8"
|
||||||
|
).split(":")[1]
|
||||||
|
return parse_solc_version(solc_version_output)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def enter_test_dir(fn):
|
||||||
|
"""Run a function inside the test directory"""
|
||||||
|
|
||||||
|
previous_dir = os.getcwd()
|
||||||
|
def f(self, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
assert self.test_dir is not None
|
||||||
|
os.chdir(self.test_dir)
|
||||||
|
return fn(self, *args, **kwargs)
|
||||||
|
finally:
|
||||||
|
# Restore the previous directory after execute fn
|
||||||
|
os.chdir(previous_dir)
|
||||||
|
return f
|
||||||
|
|
||||||
|
def setup_environment(self):
|
||||||
|
"""Configure the project build environment"""
|
||||||
|
print("Configuring Runner building environment...")
|
||||||
|
replace_version_pragmas(self.test_dir)
|
||||||
|
|
||||||
|
@enter_test_dir
|
||||||
|
def clean(self):
|
||||||
|
"""Clean temporary directories"""
|
||||||
|
rmtree(self.tmp_dir)
|
||||||
|
|
||||||
|
@enter_test_dir
|
||||||
|
@abstractmethod
|
||||||
|
def configure(self):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@enter_test_dir
|
||||||
|
@abstractmethod
|
||||||
|
def compile(self, preset: SettingsPreset):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@enter_test_dir
|
||||||
|
@abstractmethod
|
||||||
|
def run_test(self):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def run_test(runner: BaseRunner):
|
||||||
|
print(f"Testing {runner.config.name}...\n===========================")
|
||||||
|
print(f"Selected settings presets: {' '.join(p.value for p in runner.presets)}")
|
||||||
|
|
||||||
|
# Configure solc compiler
|
||||||
|
solc_version = runner.setup_solc()
|
||||||
|
print(f"Using compiler version {solc_version}")
|
||||||
|
|
||||||
|
# Download project
|
||||||
|
download_project(runner.test_dir, runner.config.repo_url, runner.config.ref_type, runner.config.ref)
|
||||||
|
|
||||||
|
# Configure run environment
|
||||||
|
runner.setup_environment()
|
||||||
|
|
||||||
|
# Configure TestRunner instance
|
||||||
|
print(dedent(f"""\
|
||||||
|
Configuring runner's profiles with:
|
||||||
|
-------------------------------------
|
||||||
|
Binary type: {runner.solc_binary_type}
|
||||||
|
Compiler path: {runner.solc_binary_path}
|
||||||
|
-------------------------------------
|
||||||
|
"""))
|
||||||
|
runner.configure()
|
||||||
|
for preset in runner.presets:
|
||||||
|
print("Running compile function...")
|
||||||
|
settings = settings_from_preset(preset, runner.config.evm_version)
|
||||||
|
print(dedent(f"""\
|
||||||
|
-------------------------------------
|
||||||
|
Settings preset: {preset.value}
|
||||||
|
Settings: {settings}
|
||||||
|
EVM version: {runner.config.evm_version}
|
||||||
|
Compiler version: {get_solc_short_version(solc_version)}
|
||||||
|
Compiler version (full): {solc_version}
|
||||||
|
-------------------------------------
|
||||||
|
"""))
|
||||||
|
runner.compile(preset)
|
||||||
|
# TODO: COMPILE_ONLY should be a command-line option
|
||||||
|
if os.environ.get("COMPILE_ONLY") == "1" or preset in runner.config.compile_only_presets:
|
||||||
|
print("Skipping test function...")
|
||||||
|
else:
|
||||||
|
print("Running test function...")
|
||||||
|
runner.run_test()
|
||||||
|
# TODO: store_benchmark_report
|
||||||
|
runner.clean()
|
||||||
|
print("Done.")
|
110
scripts/externalTests/runners/foundry.py
Normal file
110
scripts/externalTests/runners/foundry.py
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# solidity is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2023 solidity contributors.
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
from shutil import which
|
||||||
|
from textwrap import dedent
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from runners.base import BaseRunner
|
||||||
|
from test_helpers import SettingsPreset
|
||||||
|
from test_helpers import settings_from_preset
|
||||||
|
|
||||||
|
def run_forge_command(command: str, env: Optional[dict] = None):
|
||||||
|
subprocess.run(
|
||||||
|
command.split(),
|
||||||
|
env=env if env is not None else os.environ.copy(),
|
||||||
|
check=True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class FoundryRunner(BaseRunner):
|
||||||
|
"""Configure and run Foundry-based projects"""
|
||||||
|
|
||||||
|
FOUNDRY_CONFIG_FILE = "foundry.toml"
|
||||||
|
|
||||||
|
def setup_environment(self):
|
||||||
|
super().setup_environment()
|
||||||
|
if which("forge") is None:
|
||||||
|
raise RuntimeError("Forge not found.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def profile_name(preset: SettingsPreset):
|
||||||
|
"""Returns foundry profile name"""
|
||||||
|
# Replace - or + by underscore to avoid invalid toml syntax
|
||||||
|
return re.sub(r"(\-|\+)+", "_", preset.value)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def profile_section(profile_fields: dict) -> str:
|
||||||
|
return dedent("""\
|
||||||
|
[profile.{name}]
|
||||||
|
gas_reports = ["*"]
|
||||||
|
auto_detect_solc = false
|
||||||
|
solc = "{solc}"
|
||||||
|
evm_version = "{evm_version}"
|
||||||
|
optimizer = {optimizer}
|
||||||
|
via_ir = {via_ir}
|
||||||
|
|
||||||
|
[profile.{name}.optimizer_details]
|
||||||
|
yul = {yul}
|
||||||
|
""").format(**profile_fields)
|
||||||
|
|
||||||
|
@BaseRunner.enter_test_dir
|
||||||
|
def configure(self):
|
||||||
|
"""Configure forge tests profiles"""
|
||||||
|
|
||||||
|
profiles = []
|
||||||
|
for preset in self.presets:
|
||||||
|
settings = settings_from_preset(preset, self.config.evm_version)
|
||||||
|
profiles.append(self.profile_section({
|
||||||
|
"name": self.profile_name(preset),
|
||||||
|
"solc": self.solc_binary_path,
|
||||||
|
"evm_version": self.config.evm_version,
|
||||||
|
"optimizer": str(settings["optimizer"]["enabled"]).lower(),
|
||||||
|
"via_ir": str(settings["viaIR"]).lower(),
|
||||||
|
"yul": str(settings["optimizer"]["details"]["yul"]).lower(),
|
||||||
|
}))
|
||||||
|
|
||||||
|
with open(
|
||||||
|
file=self.test_dir / self.FOUNDRY_CONFIG_FILE,
|
||||||
|
mode="a",
|
||||||
|
encoding="utf-8",
|
||||||
|
) as f:
|
||||||
|
for profile in profiles:
|
||||||
|
f.write(profile)
|
||||||
|
|
||||||
|
run_forge_command("forge install", self.env)
|
||||||
|
|
||||||
|
@BaseRunner.enter_test_dir
|
||||||
|
def compile(self, preset: SettingsPreset):
|
||||||
|
"""Compile project"""
|
||||||
|
|
||||||
|
# Set the Foundry profile environment variable
|
||||||
|
self.env.update({"FOUNDRY_PROFILE": self.profile_name(preset)})
|
||||||
|
run_forge_command("forge build", self.env)
|
||||||
|
|
||||||
|
@BaseRunner.enter_test_dir
|
||||||
|
def run_test(self):
|
||||||
|
"""Run project tests"""
|
||||||
|
|
||||||
|
run_forge_command("forge test --gas-report", self.env)
|
151
scripts/externalTests/test_helpers.py
Normal file
151
scripts/externalTests/test_helpers.py
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# solidity is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2023 solidity contributors.
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
from enum import Enum
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import List
|
||||||
|
from typing import Set
|
||||||
|
|
||||||
|
# Our scripts/ is not a proper Python package so we need to modify PYTHONPATH to import from it
|
||||||
|
# pragma pylint: disable=import-error,wrong-import-position
|
||||||
|
PROJECT_ROOT = Path(__file__).parents[2]
|
||||||
|
sys.path.insert(0, f"{PROJECT_ROOT}/scripts/common")
|
||||||
|
|
||||||
|
from git_helpers import git_commit_hash
|
||||||
|
|
||||||
|
SOLC_FULL_VERSION_REGEX = re.compile(r"^[a-zA-Z: ]*(.*)$")
|
||||||
|
SOLC_SHORT_VERSION_REGEX = re.compile(r"^([0-9.]+).*\+|\-$")
|
||||||
|
|
||||||
|
|
||||||
|
class SettingsPreset(Enum):
|
||||||
|
LEGACY_NO_OPTIMIZE = 'legacy-no-optimize'
|
||||||
|
IR_NO_OPTIMIZE = 'ir-no-optimize'
|
||||||
|
LEGACY_OPTIMIZE_EVM_ONLY = 'legacy-optimize-evm-only'
|
||||||
|
IR_OPTIMIZE_EVM_ONLY = 'ir-optimize-evm-only'
|
||||||
|
LEGACY_OPTIMIZE_EVM_YUL = 'legacy-optimize-evm+yul'
|
||||||
|
IR_OPTIMIZE_EVM_YUL = 'ir-optimize-evm+yul'
|
||||||
|
|
||||||
|
|
||||||
|
def compiler_settings(evm_version: str, via_ir: bool = False, optimizer: bool = False, yul: bool = False) -> dict:
|
||||||
|
return {
|
||||||
|
"optimizer": {"enabled": optimizer, "details": {"yul": yul}},
|
||||||
|
"evmVersion": evm_version,
|
||||||
|
"viaIR": via_ir,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def settings_from_preset(preset: SettingsPreset, evm_version: str) -> dict:
|
||||||
|
return {
|
||||||
|
SettingsPreset.LEGACY_NO_OPTIMIZE: compiler_settings(evm_version),
|
||||||
|
SettingsPreset.IR_NO_OPTIMIZE: compiler_settings(evm_version, via_ir=True),
|
||||||
|
SettingsPreset.LEGACY_OPTIMIZE_EVM_ONLY: compiler_settings(evm_version, optimizer=True),
|
||||||
|
SettingsPreset.IR_OPTIMIZE_EVM_ONLY: compiler_settings(evm_version, via_ir=True, optimizer=True),
|
||||||
|
SettingsPreset.LEGACY_OPTIMIZE_EVM_YUL: compiler_settings(evm_version, optimizer=True, yul=True),
|
||||||
|
SettingsPreset.IR_OPTIMIZE_EVM_YUL: compiler_settings(evm_version, via_ir=True, optimizer=True, yul=True),
|
||||||
|
}[preset]
|
||||||
|
|
||||||
|
|
||||||
|
def parse_custom_presets(presets: List[str]) -> Set[SettingsPreset]:
|
||||||
|
return {SettingsPreset(p) for p in presets}
|
||||||
|
|
||||||
|
def parse_command_line(description: str, args: List[str]):
|
||||||
|
arg_parser = ArgumentParser(description)
|
||||||
|
arg_parser.add_argument(
|
||||||
|
"solc_binary_type",
|
||||||
|
metavar="solc-binary-type",
|
||||||
|
type=str,
|
||||||
|
default="native",
|
||||||
|
choices=["native", "solcjs"],
|
||||||
|
help="""Solidity compiler binary type""",
|
||||||
|
)
|
||||||
|
arg_parser.add_argument(
|
||||||
|
"solc_binary_path",
|
||||||
|
metavar="solc-binary-path",
|
||||||
|
type=Path,
|
||||||
|
help="""Path to solc binary""",
|
||||||
|
)
|
||||||
|
arg_parser.add_argument(
|
||||||
|
"selected_presets",
|
||||||
|
metavar="selected-presets",
|
||||||
|
help="""List of compiler settings presets""",
|
||||||
|
nargs='*',
|
||||||
|
)
|
||||||
|
return arg_parser.parse_args(args)
|
||||||
|
|
||||||
|
|
||||||
|
def download_project(test_dir: Path, repo_url: str, ref_type: str = "branch", ref: str = "master"):
|
||||||
|
assert ref_type in ("commit", "branch", "tag")
|
||||||
|
|
||||||
|
print(f"Cloning {ref_type} {ref} of {repo_url}...")
|
||||||
|
if ref_type == "commit":
|
||||||
|
os.mkdir(test_dir)
|
||||||
|
os.chdir(test_dir)
|
||||||
|
subprocess.run(["git", "init"], check=True)
|
||||||
|
subprocess.run(["git", "remote", "add", "origin", repo_url], check=True)
|
||||||
|
subprocess.run(["git", "fetch", "--depth", "1", "origin", ref], check=True)
|
||||||
|
subprocess.run(["git", "reset", "--hard", "FETCH_HEAD"], check=True)
|
||||||
|
else:
|
||||||
|
os.chdir(test_dir.parent)
|
||||||
|
subprocess.run(["git", "clone", "--no-progress", "--depth", "1", repo_url, "-b", ref, test_dir.resolve()], check=True)
|
||||||
|
if not test_dir.exists():
|
||||||
|
raise RuntimeError("Failed to clone the project.")
|
||||||
|
os.chdir(test_dir)
|
||||||
|
|
||||||
|
if (test_dir / ".gitmodules").exists():
|
||||||
|
subprocess.run(["git", "submodule", "update", "--init"], check=True)
|
||||||
|
|
||||||
|
print(f"Current commit hash: {git_commit_hash()}")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_solc_version(solc_version_string: str) -> str:
|
||||||
|
solc_version_match = re.search(SOLC_FULL_VERSION_REGEX, solc_version_string)
|
||||||
|
if solc_version_match is None:
|
||||||
|
raise RuntimeError(f"Solc version could not be found in: {solc_version_string}.")
|
||||||
|
return solc_version_match.group(1)
|
||||||
|
|
||||||
|
|
||||||
|
def get_solc_short_version(solc_full_version: str) -> str:
|
||||||
|
solc_short_version_match = re.search(SOLC_SHORT_VERSION_REGEX, solc_full_version)
|
||||||
|
if solc_short_version_match is None:
|
||||||
|
raise RuntimeError(f"Error extracting short version string from: {solc_full_version}.")
|
||||||
|
return solc_short_version_match.group(1)
|
||||||
|
|
||||||
|
|
||||||
|
def store_benchmark_report(self):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
def replace_version_pragmas(test_dir: Path):
|
||||||
|
"""
|
||||||
|
Replace fixed-version pragmas (part of Consensys best practice).
|
||||||
|
Include all directories to also cover node dependencies.
|
||||||
|
"""
|
||||||
|
print("Replacing fixed-version pragmas...")
|
||||||
|
for source in test_dir.glob("**/*.sol"):
|
||||||
|
content = source.read_text(encoding="utf-8")
|
||||||
|
content = re.sub(r"pragma solidity [^;]+;", r"pragma solidity >=0.0;", content)
|
||||||
|
with open(source, "w", encoding="utf-8") as f:
|
||||||
|
f.write(content)
|
@ -63,3 +63,7 @@ expected-line-ending-format=LF
|
|||||||
|
|
||||||
# Maximum number of characters on a single line.
|
# Maximum number of characters on a single line.
|
||||||
max-line-length=130
|
max-line-length=130
|
||||||
|
|
||||||
|
[MISCELLANEOUS]
|
||||||
|
|
||||||
|
notes=XXX,TMP
|
||||||
|
53
test/externalTests/prb-math.py
Executable file
53
test/externalTests/prb-math.py
Executable file
@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# solidity is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2023 solidity contributors.
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Our scripts/ is not a proper Python package so we need to modify PYTHONPATH to import from it
|
||||||
|
# pragma pylint: disable=import-error,wrong-import-position
|
||||||
|
PROJECT_ROOT = Path(__file__).parents[2]
|
||||||
|
sys.path.insert(0, f"{PROJECT_ROOT}/scripts/externalTests")
|
||||||
|
|
||||||
|
from runners.base import run_test
|
||||||
|
from runners.base import TestConfig
|
||||||
|
from runners.foundry import FoundryRunner
|
||||||
|
from test_helpers import SettingsPreset
|
||||||
|
|
||||||
|
test_config = TestConfig(
|
||||||
|
name="PRBMath",
|
||||||
|
repo_url="https://github.com/PaulRBerg/prb-math.git",
|
||||||
|
ref_type="branch",
|
||||||
|
ref="main",
|
||||||
|
compile_only_presets=[
|
||||||
|
# pylint: disable=line-too-long
|
||||||
|
# SettingsPreset.IR_NO_OPTIMIZE, # Error: Yul exception:Variable expr_15699_address is 2 slot(s) too deep inside the stack. Stack too deep.
|
||||||
|
# SettingsPreset.IR_OPTIMIZE_EVM_ONLY, # Error: Yul exception:Variable expr_15699_address is 2 slot(s) too deep inside the stack. Stack too deep.
|
||||||
|
],
|
||||||
|
settings_presets=[
|
||||||
|
SettingsPreset.LEGACY_NO_OPTIMIZE,
|
||||||
|
SettingsPreset.LEGACY_OPTIMIZE_EVM_ONLY,
|
||||||
|
SettingsPreset.LEGACY_OPTIMIZE_EVM_YUL,
|
||||||
|
SettingsPreset.IR_OPTIMIZE_EVM_YUL,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
sys.exit(run_test(FoundryRunner(argv=sys.argv[1:], config=test_config)))
|
@ -1,116 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# This file is part of solidity.
|
|
||||||
#
|
|
||||||
# solidity is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# solidity is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
#
|
|
||||||
# (c) 2022 solidity contributors.
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
source scripts/common.sh
|
|
||||||
source scripts/externalTests/common.sh
|
|
||||||
|
|
||||||
REPO_ROOT=$(realpath "$(dirname "$0")/../..")
|
|
||||||
|
|
||||||
verify_input "$@"
|
|
||||||
BINARY_TYPE="$1"
|
|
||||||
BINARY_PATH="$(realpath "$2")"
|
|
||||||
SELECTED_PRESETS="$3"
|
|
||||||
|
|
||||||
function compile_fn { yarn compile; }
|
|
||||||
# NOTE: `yarn test` runs `mocha` which seems to disable the gas reporter.
|
|
||||||
function test_fn { npx --no hardhat --no-compile test; }
|
|
||||||
|
|
||||||
function prb_math_test
|
|
||||||
{
|
|
||||||
local repo="https://github.com/paulrberg/prb-math"
|
|
||||||
local ref_type=branch
|
|
||||||
# We currently pin the prb-math version to the latest version that support hardhat
|
|
||||||
# Please see here for details: https://github.com/ethereum/solidity/issues/13767
|
|
||||||
local ref=v2.5.0
|
|
||||||
local config_file="hardhat.config.ts"
|
|
||||||
local config_var="config"
|
|
||||||
|
|
||||||
local compile_only_presets=(
|
|
||||||
ir-no-optimize # Tests fail with "Error: Transaction reverted: trying to deploy a contract whose code is too large"
|
|
||||||
)
|
|
||||||
local settings_presets=(
|
|
||||||
"${compile_only_presets[@]}"
|
|
||||||
ir-optimize-evm-only
|
|
||||||
ir-optimize-evm+yul
|
|
||||||
legacy-optimize-evm-only
|
|
||||||
legacy-optimize-evm+yul
|
|
||||||
legacy-no-optimize
|
|
||||||
)
|
|
||||||
|
|
||||||
[[ $SELECTED_PRESETS != "" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg "${settings_presets[@]}")
|
|
||||||
print_presets_or_exit "$SELECTED_PRESETS"
|
|
||||||
|
|
||||||
setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH"
|
|
||||||
download_project "$repo" "$ref_type" "$ref" "$DIR"
|
|
||||||
|
|
||||||
cp .env.example .env
|
|
||||||
|
|
||||||
# The project has yarn 3.1.0 binary stored in the repo and yarnrc forces the yarn 1.x binary
|
|
||||||
# installed system-wide to use it. Unfortunately Yarn 3 fails in weird ways when we remove
|
|
||||||
# yarn.lock. Remove the config to restore Yarn 1.x.
|
|
||||||
rm .yarnrc.yml
|
|
||||||
|
|
||||||
# Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables
|
|
||||||
# them for other presets but that's fine - we want same code run for benchmarks to be comparable.
|
|
||||||
# TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/3365).
|
|
||||||
pushd test/contracts/prbMathUd60x18/pure/
|
|
||||||
sed -i 's|context(\("when the sum overflows"\)|context.skip(\1|g' add.test.ts
|
|
||||||
sed -i 's|context(\("when the sum does not overflow"\)|context.skip(\1|g' add.test.ts
|
|
||||||
sed -i 's|context(\("when both operands are zero"\)|context.skip(\1|g' avg.test.ts
|
|
||||||
sed -i 's|context(\("when one operand is zero and the other is not zero"\)|context.skip(\1|g' avg.test.ts
|
|
||||||
sed -i 's|context(\("when the denominator is zero"\)|context.skip(\1|g' div.test.ts
|
|
||||||
sed -i 's|context(\("when x is zero"\)|context.skip(\1|g' inv.test.ts
|
|
||||||
popd
|
|
||||||
pushd test/contracts/prbMathSd59x18/pure/
|
|
||||||
sed -i 's|context(\("when the sum overflows"\)|context.skip(\1|g' add.test.ts
|
|
||||||
sed -i 's|context(\("when the sum underflows"\)|context.skip(\1|g' add.test.ts
|
|
||||||
sed -i 's|context(\("when the denominator is zero"\)|context.skip(\1|g' div.test.ts
|
|
||||||
sed -i 's|context(\("when x is zero"\)|context.skip(\1|g' inv.test.ts
|
|
||||||
sed -i 's|context(\("when the difference underflows"\)|context.skip(\1|g' sub.test.ts
|
|
||||||
sed -i 's|context(\("when the difference overflows"\)|context.skip(\1|g' sub.test.ts
|
|
||||||
popd
|
|
||||||
|
|
||||||
neutralize_package_lock
|
|
||||||
neutralize_package_json_hooks
|
|
||||||
force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH"
|
|
||||||
force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var"
|
|
||||||
yarn install --no-lock-file
|
|
||||||
yarn add hardhat-gas-reporter
|
|
||||||
|
|
||||||
# Workaround for error caused by the last release of hardhat-waffle@2.0.6 that bumps ethereum-waffle
|
|
||||||
# to version 4.0.10 and breaks prb-math build with the following error:
|
|
||||||
#
|
|
||||||
# Cannot find module 'ethereum-waffle/dist/cjs/src/deployContract'
|
|
||||||
#
|
|
||||||
# See: https://github.com/NomicFoundation/hardhat-waffle/commit/83ee9cb36ee59d0bedacbbd00043f030af104ad0
|
|
||||||
yarn add '@nomiclabs/hardhat-waffle@2.0.5'
|
|
||||||
|
|
||||||
replace_version_pragmas
|
|
||||||
|
|
||||||
for preset in $SELECTED_PRESETS; do
|
|
||||||
hardhat_run_test "$config_file" "$preset" "${compile_only_presets[*]}" compile_fn test_fn "$config_var"
|
|
||||||
store_benchmark_report hardhat prb-math "$repo" "$preset"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
external_test PRBMath prb_math_test
|
|
@ -36,7 +36,7 @@ def detect_external_tests() -> dict:
|
|||||||
return {
|
return {
|
||||||
file_path.stem: file_path
|
file_path.stem: file_path
|
||||||
for file_path in Path(EXTERNAL_TESTS_DIR).iterdir()
|
for file_path in Path(EXTERNAL_TESTS_DIR).iterdir()
|
||||||
if file_path.is_file() and file_path.suffix == ".sh"
|
if file_path.is_file() and file_path.suffix in (".sh", ".py")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
112
test/libsolidity/ABIJson/event_emitted_from_foreign_contract.sol
Normal file
112
test/libsolidity/ABIJson/event_emitted_from_foreign_contract.sol
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
interface I {
|
||||||
|
event Event(uint256 value);
|
||||||
|
}
|
||||||
|
contract C {
|
||||||
|
event Event(address indexed sender);
|
||||||
|
}
|
||||||
|
contract D {
|
||||||
|
event Event(address indexed sender);
|
||||||
|
function test(address sender) public {
|
||||||
|
emit I.Event(1);
|
||||||
|
emit C.Event(msg.sender);
|
||||||
|
emit Event(msg.sender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// :C
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// "anonymous": false,
|
||||||
|
// "inputs":
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// "indexed": true,
|
||||||
|
// "internalType": "address",
|
||||||
|
// "name": "sender",
|
||||||
|
// "type": "address"
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// "name": "Event",
|
||||||
|
// "type": "event"
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// :D
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// "anonymous": false,
|
||||||
|
// "inputs":
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// "indexed": false,
|
||||||
|
// "internalType": "uint256",
|
||||||
|
// "name": "value",
|
||||||
|
// "type": "uint256"
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// "name": "Event",
|
||||||
|
// "type": "event"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "anonymous": false,
|
||||||
|
// "inputs":
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// "indexed": true,
|
||||||
|
// "internalType": "address",
|
||||||
|
// "name": "sender",
|
||||||
|
// "type": "address"
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// "name": "Event",
|
||||||
|
// "type": "event"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "anonymous": false,
|
||||||
|
// "inputs":
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// "indexed": true,
|
||||||
|
// "internalType": "address",
|
||||||
|
// "name": "sender",
|
||||||
|
// "type": "address"
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// "name": "Event",
|
||||||
|
// "type": "event"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "inputs":
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// "internalType": "address",
|
||||||
|
// "name": "sender",
|
||||||
|
// "type": "address"
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// "name": "test",
|
||||||
|
// "outputs": [],
|
||||||
|
// "stateMutability": "nonpayable",
|
||||||
|
// "type": "function"
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// :I
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// "anonymous": false,
|
||||||
|
// "inputs":
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// "indexed": false,
|
||||||
|
// "internalType": "uint256",
|
||||||
|
// "name": "value",
|
||||||
|
// "type": "uint256"
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// "name": "Event",
|
||||||
|
// "type": "event"
|
||||||
|
// }
|
||||||
|
// ]
|
@ -0,0 +1,289 @@
|
|||||||
|
{
|
||||||
|
"absolutePath": "a",
|
||||||
|
"exportedSymbols":
|
||||||
|
{
|
||||||
|
"C":
|
||||||
|
[
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"D":
|
||||||
|
[
|
||||||
|
19
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"id": 20,
|
||||||
|
"nodeType": "SourceUnit",
|
||||||
|
"nodes":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"abstract": false,
|
||||||
|
"baseContracts": [],
|
||||||
|
"canonicalName": "C",
|
||||||
|
"contractDependencies": [],
|
||||||
|
"contractKind": "contract",
|
||||||
|
"fullyImplemented": true,
|
||||||
|
"id": 5,
|
||||||
|
"linearizedBaseContracts":
|
||||||
|
[
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"name": "C",
|
||||||
|
"nameLocation": "9:1:1",
|
||||||
|
"nodeType": "ContractDefinition",
|
||||||
|
"nodes":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"eventSelector": "bd1155618a34fd53d1a2de9f705f42f3582842cba0b985b25c59888d86e0c929",
|
||||||
|
"id": 4,
|
||||||
|
"name": "E",
|
||||||
|
"nameLocation": "23:1:1",
|
||||||
|
"nodeType": "EventDefinition",
|
||||||
|
"parameters":
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"nodeType": "ParameterList",
|
||||||
|
"parameters":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"id": 2,
|
||||||
|
"indexed": true,
|
||||||
|
"mutability": "mutable",
|
||||||
|
"name": "sender",
|
||||||
|
"nameLocation": "41:6:1",
|
||||||
|
"nodeType": "VariableDeclaration",
|
||||||
|
"scope": 4,
|
||||||
|
"src": "25:22:1",
|
||||||
|
"stateVariable": false,
|
||||||
|
"storageLocation": "default",
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_address",
|
||||||
|
"typeString": "address"
|
||||||
|
},
|
||||||
|
"typeName":
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "address",
|
||||||
|
"nodeType": "ElementaryTypeName",
|
||||||
|
"src": "25:7:1",
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_address",
|
||||||
|
"typeString": "address"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"visibility": "internal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"src": "24:24:1"
|
||||||
|
},
|
||||||
|
"src": "17:32:1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scope": 20,
|
||||||
|
"src": "0:51:1",
|
||||||
|
"usedErrors": [],
|
||||||
|
"usedEvents":
|
||||||
|
[
|
||||||
|
4
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"abstract": false,
|
||||||
|
"baseContracts": [],
|
||||||
|
"canonicalName": "D",
|
||||||
|
"contractDependencies": [],
|
||||||
|
"contractKind": "contract",
|
||||||
|
"fullyImplemented": true,
|
||||||
|
"id": 19,
|
||||||
|
"linearizedBaseContracts":
|
||||||
|
[
|
||||||
|
19
|
||||||
|
],
|
||||||
|
"name": "D",
|
||||||
|
"nameLocation": "61:1:1",
|
||||||
|
"nodeType": "ContractDefinition",
|
||||||
|
"nodes":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"body":
|
||||||
|
{
|
||||||
|
"id": 17,
|
||||||
|
"nodeType": "Block",
|
||||||
|
"src": "106:37:1",
|
||||||
|
"statements":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"eventCall":
|
||||||
|
{
|
||||||
|
"arguments":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"expression":
|
||||||
|
{
|
||||||
|
"id": 13,
|
||||||
|
"name": "msg",
|
||||||
|
"nodeType": "Identifier",
|
||||||
|
"overloadedDeclarations": [],
|
||||||
|
"referencedDeclaration": -15,
|
||||||
|
"src": "125:3:1",
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_magic_message",
|
||||||
|
"typeString": "msg"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": 14,
|
||||||
|
"isConstant": false,
|
||||||
|
"isLValue": false,
|
||||||
|
"isPure": false,
|
||||||
|
"lValueRequested": false,
|
||||||
|
"memberLocation": "129:6:1",
|
||||||
|
"memberName": "sender",
|
||||||
|
"nodeType": "MemberAccess",
|
||||||
|
"src": "125:10:1",
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_address",
|
||||||
|
"typeString": "address"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"expression":
|
||||||
|
{
|
||||||
|
"argumentTypes":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_address",
|
||||||
|
"typeString": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"expression":
|
||||||
|
{
|
||||||
|
"id": 10,
|
||||||
|
"name": "C",
|
||||||
|
"nodeType": "Identifier",
|
||||||
|
"overloadedDeclarations": [],
|
||||||
|
"referencedDeclaration": 5,
|
||||||
|
"src": "121:1:1",
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_type$_t_contract$_C_$5_$",
|
||||||
|
"typeString": "type(contract C)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": 12,
|
||||||
|
"isConstant": false,
|
||||||
|
"isLValue": false,
|
||||||
|
"isPure": false,
|
||||||
|
"lValueRequested": false,
|
||||||
|
"memberLocation": "123:1:1",
|
||||||
|
"memberName": "E",
|
||||||
|
"nodeType": "MemberAccess",
|
||||||
|
"referencedDeclaration": 4,
|
||||||
|
"src": "121:3:1",
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_function_event_nonpayable$_t_address_$returns$__$",
|
||||||
|
"typeString": "function (address)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": 15,
|
||||||
|
"isConstant": false,
|
||||||
|
"isLValue": false,
|
||||||
|
"isPure": false,
|
||||||
|
"kind": "functionCall",
|
||||||
|
"lValueRequested": false,
|
||||||
|
"nameLocations": [],
|
||||||
|
"names": [],
|
||||||
|
"nodeType": "FunctionCall",
|
||||||
|
"src": "121:15:1",
|
||||||
|
"tryCall": false,
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_tuple$__$",
|
||||||
|
"typeString": "tuple()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": 16,
|
||||||
|
"nodeType": "EmitStatement",
|
||||||
|
"src": "116:20:1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"functionSelector": "bb29998e",
|
||||||
|
"id": 18,
|
||||||
|
"implemented": true,
|
||||||
|
"kind": "function",
|
||||||
|
"modifiers": [],
|
||||||
|
"name": "test",
|
||||||
|
"nameLocation": "78:4:1",
|
||||||
|
"nodeType": "FunctionDefinition",
|
||||||
|
"parameters":
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"nodeType": "ParameterList",
|
||||||
|
"parameters":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"id": 7,
|
||||||
|
"mutability": "mutable",
|
||||||
|
"name": "sender",
|
||||||
|
"nameLocation": "91:6:1",
|
||||||
|
"nodeType": "VariableDeclaration",
|
||||||
|
"scope": 18,
|
||||||
|
"src": "83:14:1",
|
||||||
|
"stateVariable": false,
|
||||||
|
"storageLocation": "default",
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_address",
|
||||||
|
"typeString": "address"
|
||||||
|
},
|
||||||
|
"typeName":
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"name": "address",
|
||||||
|
"nodeType": "ElementaryTypeName",
|
||||||
|
"src": "83:7:1",
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_address",
|
||||||
|
"typeString": "address"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"visibility": "internal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"src": "82:16:1"
|
||||||
|
},
|
||||||
|
"returnParameters":
|
||||||
|
{
|
||||||
|
"id": 9,
|
||||||
|
"nodeType": "ParameterList",
|
||||||
|
"parameters": [],
|
||||||
|
"src": "106:0:1"
|
||||||
|
},
|
||||||
|
"scope": 19,
|
||||||
|
"src": "69:74:1",
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"virtual": false,
|
||||||
|
"visibility": "public"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scope": 20,
|
||||||
|
"src": "52:93:1",
|
||||||
|
"usedErrors": [],
|
||||||
|
"usedEvents":
|
||||||
|
[
|
||||||
|
4
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"src": "0:146:1"
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
contract C {
|
||||||
|
event E(address indexed sender);
|
||||||
|
}
|
||||||
|
contract D {
|
||||||
|
function test(address sender) public {
|
||||||
|
emit C.E(msg.sender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
@ -0,0 +1,194 @@
|
|||||||
|
{
|
||||||
|
"absolutePath": "a",
|
||||||
|
"id": 20,
|
||||||
|
"nodeType": "SourceUnit",
|
||||||
|
"nodes":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"abstract": false,
|
||||||
|
"baseContracts": [],
|
||||||
|
"contractDependencies": [],
|
||||||
|
"contractKind": "contract",
|
||||||
|
"id": 5,
|
||||||
|
"name": "C",
|
||||||
|
"nameLocation": "9:1:1",
|
||||||
|
"nodeType": "ContractDefinition",
|
||||||
|
"nodes":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"id": 4,
|
||||||
|
"name": "E",
|
||||||
|
"nameLocation": "23:1:1",
|
||||||
|
"nodeType": "EventDefinition",
|
||||||
|
"parameters":
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"nodeType": "ParameterList",
|
||||||
|
"parameters":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"id": 2,
|
||||||
|
"indexed": true,
|
||||||
|
"mutability": "mutable",
|
||||||
|
"name": "sender",
|
||||||
|
"nameLocation": "41:6:1",
|
||||||
|
"nodeType": "VariableDeclaration",
|
||||||
|
"src": "25:22:1",
|
||||||
|
"stateVariable": false,
|
||||||
|
"storageLocation": "default",
|
||||||
|
"typeDescriptions": {},
|
||||||
|
"typeName":
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "address",
|
||||||
|
"nodeType": "ElementaryTypeName",
|
||||||
|
"src": "25:7:1",
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"typeDescriptions": {}
|
||||||
|
},
|
||||||
|
"visibility": "internal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"src": "24:24:1"
|
||||||
|
},
|
||||||
|
"src": "17:32:1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"src": "0:51:1",
|
||||||
|
"usedErrors": [],
|
||||||
|
"usedEvents": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"abstract": false,
|
||||||
|
"baseContracts": [],
|
||||||
|
"contractDependencies": [],
|
||||||
|
"contractKind": "contract",
|
||||||
|
"id": 19,
|
||||||
|
"name": "D",
|
||||||
|
"nameLocation": "61:1:1",
|
||||||
|
"nodeType": "ContractDefinition",
|
||||||
|
"nodes":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"body":
|
||||||
|
{
|
||||||
|
"id": 17,
|
||||||
|
"nodeType": "Block",
|
||||||
|
"src": "106:37:1",
|
||||||
|
"statements":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"eventCall":
|
||||||
|
{
|
||||||
|
"arguments":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"expression":
|
||||||
|
{
|
||||||
|
"id": 13,
|
||||||
|
"name": "msg",
|
||||||
|
"nodeType": "Identifier",
|
||||||
|
"overloadedDeclarations": [],
|
||||||
|
"src": "125:3:1",
|
||||||
|
"typeDescriptions": {}
|
||||||
|
},
|
||||||
|
"id": 14,
|
||||||
|
"memberLocation": "129:6:1",
|
||||||
|
"memberName": "sender",
|
||||||
|
"nodeType": "MemberAccess",
|
||||||
|
"src": "125:10:1",
|
||||||
|
"typeDescriptions": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"expression":
|
||||||
|
{
|
||||||
|
"expression":
|
||||||
|
{
|
||||||
|
"id": 10,
|
||||||
|
"name": "C",
|
||||||
|
"nodeType": "Identifier",
|
||||||
|
"overloadedDeclarations": [],
|
||||||
|
"src": "121:1:1",
|
||||||
|
"typeDescriptions": {}
|
||||||
|
},
|
||||||
|
"id": 12,
|
||||||
|
"memberLocation": "123:1:1",
|
||||||
|
"memberName": "E",
|
||||||
|
"nodeType": "MemberAccess",
|
||||||
|
"src": "121:3:1",
|
||||||
|
"typeDescriptions": {}
|
||||||
|
},
|
||||||
|
"id": 15,
|
||||||
|
"nameLocations": [],
|
||||||
|
"names": [],
|
||||||
|
"nodeType": "FunctionCall",
|
||||||
|
"src": "121:15:1",
|
||||||
|
"tryCall": false,
|
||||||
|
"typeDescriptions": {}
|
||||||
|
},
|
||||||
|
"id": 16,
|
||||||
|
"nodeType": "EmitStatement",
|
||||||
|
"src": "116:20:1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"id": 18,
|
||||||
|
"implemented": true,
|
||||||
|
"kind": "function",
|
||||||
|
"modifiers": [],
|
||||||
|
"name": "test",
|
||||||
|
"nameLocation": "78:4:1",
|
||||||
|
"nodeType": "FunctionDefinition",
|
||||||
|
"parameters":
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"nodeType": "ParameterList",
|
||||||
|
"parameters":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"id": 7,
|
||||||
|
"mutability": "mutable",
|
||||||
|
"name": "sender",
|
||||||
|
"nameLocation": "91:6:1",
|
||||||
|
"nodeType": "VariableDeclaration",
|
||||||
|
"src": "83:14:1",
|
||||||
|
"stateVariable": false,
|
||||||
|
"storageLocation": "default",
|
||||||
|
"typeDescriptions": {},
|
||||||
|
"typeName":
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"name": "address",
|
||||||
|
"nodeType": "ElementaryTypeName",
|
||||||
|
"src": "83:7:1",
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"typeDescriptions": {}
|
||||||
|
},
|
||||||
|
"visibility": "internal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"src": "82:16:1"
|
||||||
|
},
|
||||||
|
"returnParameters":
|
||||||
|
{
|
||||||
|
"id": 9,
|
||||||
|
"nodeType": "ParameterList",
|
||||||
|
"parameters": [],
|
||||||
|
"src": "106:0:1"
|
||||||
|
},
|
||||||
|
"src": "69:74:1",
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"virtual": false,
|
||||||
|
"visibility": "public"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"src": "52:93:1",
|
||||||
|
"usedErrors": [],
|
||||||
|
"usedEvents": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"src": "0:146:1"
|
||||||
|
}
|
@ -485,6 +485,179 @@ BOOST_AUTO_TEST_CASE(event)
|
|||||||
checkNatspec(sourceCode, "ERC20", userDoc, true);
|
checkNatspec(sourceCode, "ERC20", userDoc, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(emit_event_from_foreign_contract)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract X {
|
||||||
|
/// @notice Userdoc for event E.
|
||||||
|
/// @dev Devdoc for event E.
|
||||||
|
event E();
|
||||||
|
}
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
function g() public {
|
||||||
|
emit X.E();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
char const* devDoc = R"ABCDEF(
|
||||||
|
{
|
||||||
|
"events":
|
||||||
|
{
|
||||||
|
"E()":
|
||||||
|
{
|
||||||
|
"details": "Devdoc for event E."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"kind": "dev",
|
||||||
|
"methods": {},
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
|
)ABCDEF";
|
||||||
|
checkNatspec(sourceCode, "C", devDoc, false);
|
||||||
|
|
||||||
|
char const* userDoc = R"ABCDEF(
|
||||||
|
{
|
||||||
|
"events":
|
||||||
|
{
|
||||||
|
"E()":
|
||||||
|
{
|
||||||
|
"notice": "Userdoc for event E."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"kind": "user",
|
||||||
|
"methods": {},
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
|
)ABCDEF";
|
||||||
|
checkNatspec(sourceCode, "C", userDoc, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(emit_event_from_foreign_contract_with_same_signature)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract C {
|
||||||
|
/// @notice C.E event
|
||||||
|
/// @dev C.E event
|
||||||
|
event E(uint256 value);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract D {
|
||||||
|
/// @notice D.E event
|
||||||
|
/// @dev D.E event
|
||||||
|
event E(uint256 value);
|
||||||
|
|
||||||
|
function test() public {
|
||||||
|
emit C.E(1);
|
||||||
|
emit E(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
char const* devDocC = R"ABCDEF(
|
||||||
|
{
|
||||||
|
"events":
|
||||||
|
{
|
||||||
|
"E(uint256)":
|
||||||
|
{
|
||||||
|
"details": "C.E event"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"kind": "dev",
|
||||||
|
"methods": {},
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
|
)ABCDEF";
|
||||||
|
checkNatspec(sourceCode, "C", devDocC, false);
|
||||||
|
|
||||||
|
char const* devDocD = R"ABCDEF(
|
||||||
|
{
|
||||||
|
"events":
|
||||||
|
{
|
||||||
|
"E(uint256)":
|
||||||
|
{
|
||||||
|
"details": "D.E event"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"kind": "dev",
|
||||||
|
"methods": {},
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
|
)ABCDEF";
|
||||||
|
checkNatspec(sourceCode, "D", devDocD, false);
|
||||||
|
|
||||||
|
char const* userDocC = R"ABCDEF(
|
||||||
|
{
|
||||||
|
"events":
|
||||||
|
{
|
||||||
|
"E(uint256)":
|
||||||
|
{
|
||||||
|
"notice": "C.E event"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"kind": "user",
|
||||||
|
"methods": {},
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
|
)ABCDEF";
|
||||||
|
checkNatspec(sourceCode, "C", userDocC, true);
|
||||||
|
|
||||||
|
char const* userDocD = R"ABCDEF(
|
||||||
|
{
|
||||||
|
"events":
|
||||||
|
{
|
||||||
|
"E(uint256)":
|
||||||
|
{
|
||||||
|
"notice": "D.E event"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"kind": "user",
|
||||||
|
"methods": {},
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
|
)ABCDEF";
|
||||||
|
checkNatspec(sourceCode, "D", userDocD, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that emitting an event from contract C in contract D does not inherit natspec from C.E
|
||||||
|
BOOST_AUTO_TEST_CASE(emit_event_from_foreign_contract_no_inheritance)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract C {
|
||||||
|
/// @notice C.E event
|
||||||
|
/// @dev C.E event
|
||||||
|
event E();
|
||||||
|
}
|
||||||
|
|
||||||
|
contract D {
|
||||||
|
event E();
|
||||||
|
|
||||||
|
function test() public {
|
||||||
|
emit C.E();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
char const* devDoc = R"ABCDEF(
|
||||||
|
{
|
||||||
|
"kind": "dev",
|
||||||
|
"methods": {},
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
|
)ABCDEF";
|
||||||
|
checkNatspec(sourceCode, "D", devDoc, false);
|
||||||
|
|
||||||
|
char const* userDoc = R"ABCDEF(
|
||||||
|
{
|
||||||
|
"kind": "user",
|
||||||
|
"methods": {},
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
|
)ABCDEF";
|
||||||
|
checkNatspec(sourceCode, "D", userDoc, true);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(emit_same_signature_event_library_contract)
|
BOOST_AUTO_TEST_CASE(emit_same_signature_event_library_contract)
|
||||||
{
|
{
|
||||||
char const* sourceCode = R"(
|
char const* sourceCode = R"(
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
contract C {
|
||||||
|
event E();
|
||||||
|
}
|
||||||
|
|
||||||
|
contract D {
|
||||||
|
function test() public {
|
||||||
|
emit C.E();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// test() ->
|
||||||
|
// ~ emit E()
|
@ -0,0 +1,17 @@
|
|||||||
|
contract C {
|
||||||
|
event E(uint256 value);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract D {
|
||||||
|
event E(uint256 value);
|
||||||
|
|
||||||
|
function test() public {
|
||||||
|
emit C.E(1);
|
||||||
|
emit E(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// test() ->
|
||||||
|
// ~ emit E(uint256): 0x01
|
||||||
|
// ~ emit E(uint256): 0x02
|
@ -0,0 +1,19 @@
|
|||||||
|
interface I {
|
||||||
|
event E();
|
||||||
|
}
|
||||||
|
|
||||||
|
library L {
|
||||||
|
function f() internal {
|
||||||
|
emit I.E();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
function g() public {
|
||||||
|
L.f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// g() ->
|
||||||
|
// ~ emit E()
|
@ -0,0 +1,13 @@
|
|||||||
|
interface I {
|
||||||
|
event Event(address indexed _from, uint256 _value);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
function emitEvent(uint256 _value) public {
|
||||||
|
emit I.Event(msg.sender, _value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// emitEvent(uint256): 100 ->
|
||||||
|
// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64
|
Loading…
Reference in New Issue
Block a user