Skip to content

Commit

Permalink
Make using-for utils
Browse files Browse the repository at this point in the history
  • Loading branch information
smonicas committed Mar 26, 2024
1 parent 9a0fc30 commit ecf8c3d
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 43 deletions.
25 changes: 6 additions & 19 deletions slither/core/declarations/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
from crytic_compile.platform import Type as PlatformType

from slither.core.cfg.scope import Scope
from slither.core.solidity_types.type import Type
from slither.core.source_mapping.source_mapping import SourceMapping

from slither.utils.using_for import USING_FOR, _merge_using_for
from slither.core.declarations.function import Function, FunctionType, FunctionLanguage
from slither.utils.erc import (
ERC20_signatures,
Expand Down Expand Up @@ -50,9 +49,6 @@

LOGGER = logging.getLogger("Contract")

USING_FOR_KEY = Union[str, Type]
USING_FOR_ITEM = List[Union[Type, Function]]


class Contract(SourceMapping): # pylint: disable=too-many-public-methods
"""
Expand Down Expand Up @@ -87,8 +83,8 @@ def __init__(self, compilation_unit: "SlitherCompilationUnit", scope: "FileScope
self._type_aliases: Dict[str, "TypeAliasContract"] = {}

# The only str is "*"
self._using_for: Dict[USING_FOR_KEY, USING_FOR_ITEM] = {}
self._using_for_complete: Optional[Dict[USING_FOR_KEY, USING_FOR_ITEM]] = None
self._using_for: USING_FOR = {}
self._using_for_complete: Optional[USING_FOR] = None
self._kind: Optional[str] = None
self._is_interface: bool = False
self._is_library: bool = False
Expand Down Expand Up @@ -310,24 +306,15 @@ def events_as_dict(self) -> Dict[str, "EventContract"]:
###################################################################################

@property
def using_for(self) -> Dict[USING_FOR_KEY, USING_FOR_ITEM]:
def using_for(self) -> USING_FOR:
return self._using_for

@property
def using_for_complete(self) -> Dict[USING_FOR_KEY, USING_FOR_ITEM]:
def using_for_complete(self) -> USING_FOR:
"""
Dict[Union[str, Type], List[Type]]: Dict of merged local using for directive with top level directive
USING_FOR: Dict of merged local using for directive with top level directive
"""

def _merge_using_for(
uf1: Dict[USING_FOR_KEY, USING_FOR_ITEM], uf2: Dict[USING_FOR_KEY, USING_FOR_ITEM]
) -> Dict[USING_FOR_KEY, USING_FOR_ITEM]:
result = {**uf1, **uf2}
for key, value in result.items():
if key in uf1 and key in uf2:
result[key] = value + uf1[key]
return result

if self._using_for_complete is None:
result = self.using_for
top_level_using_for = self.file_scope.using_for_directives
Expand Down
22 changes: 5 additions & 17 deletions slither/core/declarations/function_top_level.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,34 @@
"""
Function module
"""
from typing import Dict, List, Tuple, TYPE_CHECKING, Union, Optional
from typing import Dict, List, Tuple, TYPE_CHECKING, Optional

from slither.core.declarations import Function
from slither.core.declarations.top_level import TopLevel
from slither.core.solidity_types.type import Type
from slither.utils.using_for import USING_FOR, _merge_using_for

if TYPE_CHECKING:
from slither.core.compilation_unit import SlitherCompilationUnit
from slither.core.scope.scope import FileScope
from slither.slithir.variables.state_variable import StateIRVariable

USING_FOR_KEY = Union[str, Type]
USING_FOR_ITEM = List[Union[Type, Function]]


class FunctionTopLevel(Function, TopLevel):
def __init__(self, compilation_unit: "SlitherCompilationUnit", scope: "FileScope") -> None:
super().__init__(compilation_unit)
self._scope: "FileScope" = scope
self._using_for_complete: Optional[Dict[USING_FOR_KEY, USING_FOR_ITEM]] = None
self._using_for_complete: Optional[USING_FOR] = None

@property
def file_scope(self) -> "FileScope":
return self._scope

@property
def using_for_complete(self) -> Dict[USING_FOR_KEY, USING_FOR_ITEM]:
def using_for_complete(self) -> USING_FOR:
"""
Dict[Union[str, Type], List[Type]]: Dict of top level directive
USING_FOR: Dict of top level directive
"""

def _merge_using_for(
uf1: Dict[USING_FOR_KEY, USING_FOR_ITEM], uf2: Dict[USING_FOR_KEY, USING_FOR_ITEM]
) -> Dict[USING_FOR_KEY, USING_FOR_ITEM]:
result = {**uf1, **uf2}
for key, value in result.items():
if key in uf1 and key in uf2:
result[key] = value + uf1[key]
return result

if self._using_for_complete is None:
result = {}
for uftl in self.file_scope.using_for_directives:
Expand Down
4 changes: 2 additions & 2 deletions slither/core/declarations/using_for_top_level.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from typing import TYPE_CHECKING, List, Dict, Union

from slither.core.declarations.contract import USING_FOR_KEY, USING_FOR_ITEM
from slither.core.solidity_types.type import Type
from slither.core.declarations.top_level import TopLevel
from slither.utils.using_for import USING_FOR

if TYPE_CHECKING:
from slither.core.scope.scope import FileScope
Expand All @@ -15,5 +15,5 @@ def __init__(self, scope: "FileScope") -> None:
self.file_scope: "FileScope" = scope

@property
def using_for(self) -> Dict[USING_FOR_KEY, USING_FOR_ITEM]:
def using_for(self) -> USING_FOR:
return self._using_for
8 changes: 4 additions & 4 deletions slither/slithir/convert.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
from pathlib import Path
from typing import Any, List, TYPE_CHECKING, Union, Optional, Dict
from typing import Any, List, TYPE_CHECKING, Union, Optional

# pylint: disable= too-many-lines,import-outside-toplevel,too-many-branches,too-many-statements,too-many-nested-blocks
from slither.core.declarations import (
Expand All @@ -13,7 +13,6 @@
SolidityVariableComposed,
Structure,
)
from slither.core.declarations.contract import USING_FOR_KEY, USING_FOR_ITEM
from slither.core.declarations.custom_error import CustomError
from slither.core.declarations.function_contract import FunctionContract
from slither.core.declarations.function_top_level import FunctionTopLevel
Expand Down Expand Up @@ -84,6 +83,7 @@
from slither.slithir.variables import TupleVariable
from slither.utils.function import get_function_id
from slither.utils.type import export_nested_types_from_variable
from slither.utils.using_for import USING_FOR
from slither.visitors.slithir.expression_to_slithir import ExpressionToSlithIR

if TYPE_CHECKING:
Expand Down Expand Up @@ -595,7 +595,7 @@ def propagate_types(ir: Operation, node: "Node"): # pylint: disable=too-many-lo
# propagate the type
node_function = node.function

using_for: Dict[USING_FOR_KEY, USING_FOR_ITEM] = {}
using_for: USING_FOR = {}
if isinstance(node_function, FunctionContract):
using_for = node_function.contract.using_for_complete
elif isinstance(node_function, FunctionTopLevel):
Expand Down Expand Up @@ -1211,7 +1211,7 @@ def extract_tmp_call(ins: TmpCall, contract: Optional[Contract]) -> Union[Call,
internalcall.set_expression(ins.expression)
return internalcall

raise Exception(f"Not extracted {type(ins.called)} {ins}") # pylint: disable=bad-option-value
raise Exception(f"Not extracted {type(ins.called)} {ins}") # pylint: disable=bad-option-value

Check warning on line 1214 in slither/slithir/convert.py

View workflow job for this annotation

GitHub Actions / Lint Code Base

W0719: Raising too general exception: Exception (broad-exception-raised)


# endregion
Expand Down
3 changes: 2 additions & 1 deletion slither/solc_parsing/declarations/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
StructureContract,
Function,
)
from slither.core.declarations.contract import Contract, USING_FOR_KEY
from slither.core.declarations.contract import Contract
from slither.core.declarations.custom_error_contract import CustomErrorContract
from slither.core.declarations.function_contract import FunctionContract
from slither.core.solidity_types import ElementaryType, TypeAliasContract
Expand All @@ -23,6 +23,7 @@
from slither.solc_parsing.exceptions import ParsingError, VariableNotFound
from slither.solc_parsing.solidity_types.type_parsing import parse_type
from slither.solc_parsing.variables.state_variable import StateVariableSolc
from slither.utils.using_for import USING_FOR_KEY

LOGGER = logging.getLogger("ContractSolcParsing")

Expand Down
17 changes: 17 additions & 0 deletions slither/utils/using_for.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from typing import Dict, List, TYPE_CHECKING, Union
from slither.core.solidity_types.type import Type

if TYPE_CHECKING:
from slither.core.declarations import Function

USING_FOR_KEY = Union[str, Type]
USING_FOR_ITEM = List[Union[Type, "Function"]]
USING_FOR = Dict[USING_FOR_KEY, USING_FOR_ITEM]


def _merge_using_for(uf1: USING_FOR, uf2: USING_FOR) -> USING_FOR:
result = {**uf1, **uf2}
for key, value in result.items():
if key in uf1 and key in uf2:
result[key] = value + uf1[key]
return result

0 comments on commit ecf8c3d

Please sign in to comment.