From 6d71e15b34a9f07bb2c510a6f4ab6b2ffc2d7f2e Mon Sep 17 00:00:00 2001 From: Runming Li Date: Mon, 23 May 2022 21:24:40 -0400 Subject: [PATCH] Populate source location for using_for construct (#1) * feat: populate the source location of using_for construct to facilitate https://github.com/CertiKProject/slither-task/issues/71 --- slither/core/declarations/contract.py | 6 ++++++ slither/solc_parsing/declarations/contract.py | 10 +++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/slither/core/declarations/contract.py b/slither/core/declarations/contract.py index dc71ccf5a9..36d2e542db 100644 --- a/slither/core/declarations/contract.py +++ b/slither/core/declarations/contract.py @@ -37,6 +37,7 @@ from slither.slithir.variables.variable import SlithIRVariable from slither.core.variables.variable import Variable from slither.core.variables.state_variable import StateVariable + from slither.core.declarations.structure import Structure from slither.core.compilation_unit import SlitherCompilationUnit from slither.core.declarations.custom_error_contract import CustomErrorContract from slither.core.scope.scope import FileScope @@ -74,6 +75,7 @@ def __init__(self, compilation_unit: "SlitherCompilationUnit", scope: "FileScope # The only str is "*" self._using_for: Dict[Union[str, Type], List[str]] = {} + self._using_for_src: Dict[Union[str, Type], List[Tuple[str, "Structure"]]] = {} self._kind: Optional[str] = None self._is_interface: bool = False @@ -246,6 +248,10 @@ def events_as_dict(self) -> Dict[str, "Event"]: def using_for(self) -> Dict[Union[str, Type], List[str]]: return self._using_for + @property + def using_for_src(self) -> Dict[Union[str, Type], List[Tuple[str, "Structure"]]]: + return self._using_for_src + # endregion ################################################################################### ################################################################################### diff --git a/slither/solc_parsing/declarations/contract.py b/slither/solc_parsing/declarations/contract.py index 0cdb5d8483..b4afbd3792 100644 --- a/slither/solc_parsing/declarations/contract.py +++ b/slither/solc_parsing/declarations/contract.py @@ -1,7 +1,7 @@ import logging from typing import List, Dict, Callable, TYPE_CHECKING, Union, Set -from slither.core.declarations import Modifier, Event, EnumContract, StructureContract, Function +from slither.core.declarations import Modifier, Event, EnumContract, StructureContract, Function, Structure from slither.core.declarations.contract import Contract from slither.core.declarations.custom_error_contract import CustomErrorContract from slither.core.declarations.function_contract import FunctionContract @@ -559,7 +559,15 @@ def analyze_using_for(self): type_name = "*" if type_name not in self._contract.using_for: self._contract.using_for[type_name] = [] + self._contract.using_for_src[type_name] = [] + # This is to populate the source location of using_for construct + # We reuse the Structure class to store the source location instead + # of creating a new class `UsingFor` for simplicity + uf = Structure(self._contract.compilation_unit) + uf.set_offset(using_for["src"], self._contract.compilation_unit) + uf.canonical_name = uf.name = f"using {lib_name} for {type_name} in {self._contract}" self._contract.using_for[type_name].append(lib_name) + self._contract.using_for_src[type_name].append((lib_name, uf)) else: for using_for in self._usingForNotParsed: children = using_for[self.get_children()]