mirror of https://github.com/crytic/slither
Add support for user defined types (#1135)
* Add support for user defined types - Create a new core object TypeAlias (top level or contract) - Add support for wrap/unwrap - Add testspull/746/merge
parent
496c8e1910
commit
5863c30747
@ -0,0 +1,41 @@ |
||||
from typing import TYPE_CHECKING, Tuple |
||||
|
||||
from slither.core.children.child_contract import ChildContract |
||||
from slither.core.declarations.top_level import TopLevel |
||||
from slither.core.solidity_types import Type |
||||
|
||||
if TYPE_CHECKING: |
||||
from slither.core.declarations import Contract |
||||
from slither.core.scope.scope import FileScope |
||||
|
||||
|
||||
class TypeAlias(Type): |
||||
def __init__(self, underlying_type: Type, name: str): |
||||
super().__init__() |
||||
self.name = name |
||||
self.underlying_type = underlying_type |
||||
|
||||
@property |
||||
def storage_size(self) -> Tuple[int, bool]: |
||||
return self.underlying_type.storage_size |
||||
|
||||
def __hash__(self): |
||||
return hash(str(self)) |
||||
|
||||
|
||||
class TypeAliasTopLevel(TypeAlias, TopLevel): |
||||
def __init__(self, underlying_type: Type, name: str, scope: "FileScope"): |
||||
super().__init__(underlying_type, name) |
||||
self.file_scope: "FileScope" = scope |
||||
|
||||
def __str__(self): |
||||
return self.name |
||||
|
||||
|
||||
class TypeAliasContract(TypeAlias, ChildContract): |
||||
def __init__(self, underlying_type: Type, name: str, contract: "Contract"): |
||||
super().__init__(underlying_type, name) |
||||
self._contract: "Contract" = contract |
||||
|
||||
def __str__(self): |
||||
return self.contract.name + "." + self.name |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,10 @@ |
||||
{ |
||||
"B": { |
||||
"u()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n", |
||||
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n}\n" |
||||
}, |
||||
"D": {}, |
||||
"C": { |
||||
"f(Left[])": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" |
||||
} |
||||
} |
@ -0,0 +1,10 @@ |
||||
{ |
||||
"B": { |
||||
"u()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n", |
||||
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n}\n" |
||||
}, |
||||
"D": {}, |
||||
"C": { |
||||
"f(Left[])": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" |
||||
} |
||||
} |
@ -0,0 +1,10 @@ |
||||
{ |
||||
"B": { |
||||
"u()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n", |
||||
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n}\n" |
||||
}, |
||||
"D": {}, |
||||
"C": { |
||||
"f(Left[])": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" |
||||
} |
||||
} |
@ -0,0 +1,10 @@ |
||||
{ |
||||
"B": { |
||||
"u()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n}\n", |
||||
"f()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n}\n" |
||||
}, |
||||
"D": {}, |
||||
"C": { |
||||
"f(Left[])": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" |
||||
} |
||||
} |
@ -0,0 +1,30 @@ |
||||
type MyInt is uint; |
||||
|
||||
contract B { |
||||
type MyInt is int; |
||||
|
||||
function u() internal returns(int) {} |
||||
|
||||
function f() public{ |
||||
MyInt mi = MyInt.wrap(u()); |
||||
} |
||||
} |
||||
|
||||
function f(MyInt a) pure returns (MyInt b) { |
||||
b = MyInt(a); |
||||
} |
||||
|
||||
contract D |
||||
{ |
||||
B.MyInt x = B.MyInt.wrap(int(1)); |
||||
} |
||||
|
||||
contract C { |
||||
function f(Left[] memory a) internal returns(Left){ |
||||
return a[0]; |
||||
} |
||||
} |
||||
type Left is bytes2; |
||||
|
||||
MyInt constant x = MyInt.wrap(20); |
||||
|
Loading…
Reference in new issue