diff --git a/slither/core/declarations/__init__.py b/slither/core/declarations/__init__.py index 92e0b9eca3..f341187518 100644 --- a/slither/core/declarations/__init__.py +++ b/slither/core/declarations/__init__.py @@ -18,3 +18,5 @@ from .function_contract import FunctionContract from .function_top_level import FunctionTopLevel from .custom_error_contract import CustomErrorContract +from .custom_error_top_level import CustomErrorTopLevel +from .custom_error import CustomError diff --git a/slither/core/declarations/custom_error_contract.py b/slither/core/declarations/custom_error_contract.py index cd279a3a62..2c8bec9efa 100644 --- a/slither/core/declarations/custom_error_contract.py +++ b/slither/core/declarations/custom_error_contract.py @@ -16,3 +16,7 @@ def is_declared_by(self, contract: "Contract") -> bool: :return: """ return self.contract == contract + + @property + def canonical_name(self) -> str: + return self.contract.name + "." + self.full_name diff --git a/slither/core/declarations/custom_error_top_level.py b/slither/core/declarations/custom_error_top_level.py index 64a6a85353..b80356b245 100644 --- a/slither/core/declarations/custom_error_top_level.py +++ b/slither/core/declarations/custom_error_top_level.py @@ -12,3 +12,7 @@ class CustomErrorTopLevel(CustomError, TopLevel): def __init__(self, compilation_unit: "SlitherCompilationUnit", scope: "FileScope") -> None: super().__init__(compilation_unit) self.file_scope: "FileScope" = scope + + @property + def canonical_name(self) -> str: + return self.full_name diff --git a/slither/utils/output.py b/slither/utils/output.py index 84c9ac65a1..4a91ca9b9b 100644 --- a/slither/utils/output.py +++ b/slither/utils/output.py @@ -18,6 +18,7 @@ Structure, Pragma, FunctionContract, + CustomError, ) from slither.core.source_mapping.source_mapping import SourceMapping from slither.core.variables.local_variable import LocalVariable @@ -438,6 +439,8 @@ def add(self, add: SupportedOutput, additional_fields: Optional[Dict] = None) -> self.add_event(add, additional_fields=additional_fields) elif isinstance(add, Structure): self.add_struct(add, additional_fields=additional_fields) + elif isinstance(add, CustomError): + self.add_custom_error(add, additional_fields=additional_fields) elif isinstance(add, Pragma): self.add_pragma(add, additional_fields=additional_fields) elif isinstance(add, Node): @@ -585,6 +588,32 @@ def add_event(self, event: Event, additional_fields: Optional[Dict] = None) -> N self._data["elements"].append(element) + # endregion + ################################################################################### + ################################################################################### + # region CustomError + ################################################################################### + ################################################################################### + + def add_custom_error( + self, custom_error: CustomError, additional_fields: Optional[Dict] = None + ) -> None: + if additional_fields is None: + additional_fields = {} + type_specific_fields = { + "parent": _create_parent_element(custom_error), + "signature": custom_error.full_name, + } + element = _create_base_element( + "custom_error", + custom_error.name, + custom_error.source_mapping.to_json(), + type_specific_fields, + additional_fields, + ) + + self._data["elements"].append(element) + # endregion ################################################################################### ###################################################################################