Skip to content

Commit

Permalink
Remove interface from inheritance graph.
Browse files Browse the repository at this point in the history
  • Loading branch information
DarkaMaul committed Apr 9, 2024
1 parent 4164039 commit 20fa97c
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 8 deletions.
6 changes: 3 additions & 3 deletions slither/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,10 +336,10 @@ def parse_args(
)

group_printer.add_argument(
"--exclude-interfaces",
help= "Exclude interfaces from inheritance-graph printer",
"--include-interfaces",
help="Include interfaces from inheritance-graph printer",
action="store_true",
dest="exclude_interfaces",
dest="include_interfaces",
default=False,
)

Expand Down
17 changes: 14 additions & 3 deletions slither/printers/inheritance/inheritance_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,14 @@ def _summary(self, contract):
"""
ret = ""

# Remove contracts that have "mock" in the name and if --exclude-interface removes inherited interfaces
inheritance = [i for i in contract.immediate_inheritance if "mock" not in i.name.lower() and (not self.slither.exclude_interfaces or self.slither.exclude_interfaces and not i.is_interface)]
# Remove contracts that have "mock" in the name and if --include-interfaces in False (default)
# removes inherited interfaces
inheritance = [
i
for i in contract.immediate_inheritance
if "mock" not in i.name.lower()
and (not i.is_interface or self.slither.include_interfaces)
]

# Add arrows (number them if there is more than one path so we know order of declaration for inheritance).
if len(inheritance) == 1:
Expand All @@ -116,6 +122,7 @@ def _summary(self, contract):
for f in contract.functions
if not f.is_constructor
and not f.is_constructor_variables
and not f.is_virtual
and f.contract_declarer == contract
and f.visibility in visibilities
]
Expand Down Expand Up @@ -198,7 +205,11 @@ def output(self, filename):

content = 'digraph "" {\n'
for c in self.contracts:
if c.is_top_level or "mock" in c.name.lower() or c.is_library or (self.slither.exclude_interfaces and c.is_interface):
if (
"mock" in c.name.lower()
or c.is_library
or (c.is_interface and not self.slither.include_interfaces)
):
continue
content += self._summary(c) + "\n"
content += "}"
Expand Down
2 changes: 1 addition & 1 deletion slither/slither.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ def __init__(self, target: Union[str, CryticCompile], **kwargs) -> None:
self.skip_data_dependency = True

# Used in inheritance-graph printer
self.exclude_interfaces = kwargs.get("exclude_interfaces", False)
self.include_interfaces = kwargs.get("include_interfaces", False)

self._init_parsing_and_analyses(kwargs.get("skip_analyze", False))

Expand Down
16 changes: 15 additions & 1 deletion tests/e2e/printers/test_data/test_contract_names/C.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
import "./A.sol";

contract C is A {
interface MyInterfaceX {
function count() external view returns (uint256);

function increment() external;
}

contract C is A, MyInterfaceX {
function c_main() public pure {
a_main();
}

function count() external view override returns (uint256){
return 1;
}

function increment() external override {

}
}
12 changes: 12 additions & 0 deletions tests/e2e/printers/test_printers.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,15 @@ def test_inheritance_printer(solc_binary_path) -> None:

assert counter["B -> A"] == 2
assert counter["C -> A"] == 1

# Lets also test the include/exclude interface behavior
# Check that the interface is not included
assert "MyInterfaceX" not in content

slither.include_interfaces = True
output = printer.output("test_printer.dot")
content = output.elements[0]["name"]["content"]
assert "MyInterfaceX" in content

# Remove test generated files
Path("test_printer.dot").unlink(missing_ok=True)

0 comments on commit 20fa97c

Please sign in to comment.