Skip to content

Commit

Permalink
handle solidity files with no contracts (#333)
Browse files Browse the repository at this point in the history
  • Loading branch information
karmacoma-eth authored Jul 29, 2024
1 parent d4c0124 commit 31bb794
Showing 1 changed file with 30 additions and 19 deletions.
49 changes: 30 additions & 19 deletions src/halmos/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1300,6 +1300,19 @@ def mk_arrlen(args: HalmosConfig) -> Dict[str, int]:
return arrlen


def get_contract_type(
ast_nodes: Dict, contract_name: str
) -> Tuple[str | None, str | None]:
for node in ast_nodes:
if node["nodeType"] == "ContractDefinition" and node["name"] == contract_name:
abstract = "abstract " if node.get("abstract") else ""
contract_type = abstract + node["contractKind"]
natspec = node.get("documentation")
return contract_type, natspec

return None, None


def parse_build_out(args: HalmosConfig) -> Dict:
result = {} # compiler version -> source filename -> contract name -> (json, type)

Expand Down Expand Up @@ -1328,35 +1341,33 @@ def parse_build_out(args: HalmosConfig) -> Dict:
with open(json_path, encoding="utf8") as f:
json_out = json.load(f)

compiler_version = json_out["metadata"]["compiler"]["version"]
if compiler_version not in result:
result[compiler_version] = {}
if sol_dirname not in result[compiler_version]:
result[compiler_version][sol_dirname] = {}
contract_map = result[compiler_version][sol_dirname]

# cut off compiler version number as well
contract_name = json_filename.split(".")[0]

contract_type = None
for node in json_out["ast"]["nodes"]:
if (
node["nodeType"] == "ContractDefinition"
and node["name"] == contract_name
):
abstract = "abstract " if node.get("abstract") else ""
contract_type = abstract + node["contractKind"]
natspec = node.get("documentation")
break
ast_nodes = json_out["ast"]["nodes"]
contract_type, natspec = get_contract_type(ast_nodes, contract_name)

# can happen to solidity files for multiple reasons:
# - import only (like console2.log)
# - defines only structs or enums
# - defines only free functions
# - ...
if contract_type is None:
raise ValueError("no contract type", contract_name)
if args.debug:
debug(f"Skipped {json_filename}, no contract definition found")
continue

compiler_version = json_out["metadata"]["compiler"]["version"]
result.setdefault(compiler_version, {})
result[compiler_version].setdefault(sol_dirname, {})
contract_map = result[compiler_version][sol_dirname]

if contract_name in contract_map:
raise ValueError(
"duplicate contract names in the same file",
contract_name,
sol_dirname,
)

contract_map[contract_name] = (json_out, contract_type, natspec)

try:
Expand Down

0 comments on commit 31bb794

Please sign in to comment.