Skip to content

Commit

Permalink
kspec: minor improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
montyly committed Nov 6, 2019
1 parent b872f70 commit 6e35805
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 12 deletions.
37 changes: 26 additions & 11 deletions slither/tools/kspec_coverage/analysis.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import re
import logging

from slither.core.declarations import Function
from slither.core.variables.variable import Variable
from slither.utils.colors import yellow, green, red
from slither.utils import json_utils

Expand Down Expand Up @@ -46,21 +49,20 @@ def _get_all_covered_kspec_functions(target):
def _get_slither_functions(slither):
# Use contract == contract_declarer to avoid dupplicate
all_functions_declared = [f for f in slither.functions if (f.contract == f.contract_declarer
and f.is_implemented
and not f.is_constructor
and not f.is_empty
and not f.is_constructor_variables)]
# Use list(set()) because same state variable instances can be shared accross contracts
# TODO: integrate state variables
# all_functions_declared += list(set([s for s in slither.state_variables if s.visibility in ['public', 'external']]))
#
all_functions_declared += list(set([s for s in slither.state_variables if s.visibility in ['public', 'external']]))
slither_functions = {(function.contract.name, function.full_name): function for function in all_functions_declared}

return slither_functions

def _generate_output(kspec, message, color, generate_json):
info = ""
for function in kspec:
info += f"{message} {function.contract.name}.{function.full_name}"
info += f"{message} {function.contract.name}.{function.full_name}\n"
if info:
logger.info(color(info))

Expand All @@ -74,7 +76,7 @@ def _generate_output(kspec, message, color, generate_json):
def _generate_output_unresolved(kspec, message, color, generate_json):
info = ""
for contract, function in kspec:
info += f"{message} {contract}.{function}"
info += f"{message} {contract}.{function}\n"
if info:
logger.info(color(info))

Expand All @@ -84,7 +86,6 @@ def _generate_output_unresolved(kspec, message, color, generate_json):
return None



def _run_coverage_analysis(args, slither, kspec_functions):
# Collect all slither functions
slither_functions = _get_slither_functions(slither)
Expand All @@ -108,7 +109,14 @@ def _run_coverage_analysis(args, slither, kspec_functions):

logger.info('## Check for functions coverage')
json_kspec_present = _generate_output(kspec_present, "[✓]", green, args.json)
json_kspec_missing = _generate_output(kspec_missing, "[ ] (Missing)", red, args.json)
json_kspec_missing_functions = _generate_output([f for f in kspec_missing if isinstance(f, Function)],
"[ ] (Missing function)",
red,
args.json)
json_kspec_missing_variables = _generate_output([f for f in kspec_missing if isinstance(f, Variable)],
"[ ] (Missing variable)",
yellow,
args.json)
json_kspec_unresolved = _generate_output_unresolved(kspec_functions_unresolved,
"[ ] (Unresolved)",
yellow,
Expand All @@ -117,14 +125,21 @@ def _run_coverage_analysis(args, slither, kspec_functions):
# Handle unresolved kspecs
if args.json:
json_utils.output_json(args.json, None, {
"kspec_present": json_kspec_present,
"kspec_missing": json_kspec_missing,
"kspec_unresolved": json_kspec_unresolved
"functions_present": json_kspec_present,
"functions_missing": json_kspec_missing_functions,
"variables_missing": json_kspec_missing_variables,
"functions_unresolved": json_kspec_unresolved
})

def run_analysis(args, slither, kspec):
# Get all of our kspec'd functions (tuple(contract_name, function_name)).
kspec_functions = _get_all_covered_kspec_functions(kspec)
if ',' in kspec:
kspecs = kspec.split(',')
kspec_functions = set()
for kspec in kspecs:
kspec_functions |= _get_all_covered_kspec_functions(kspec)
else:
kspec_functions = _get_all_covered_kspec_functions(kspec)

# Run coverage analysis
_run_coverage_analysis(args, slither, kspec_functions)
Expand Down
2 changes: 1 addition & 1 deletion slither/tools/kspec_coverage/kspec_coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def kspec_coverage(args):
contract = args.contract
kspec = args.kspec

slither = Slither(contract)
slither = Slither(contract, **vars(args))

# Run the analysis on the Klab specs
run_analysis(args, slither, kspec)
Expand Down

0 comments on commit 6e35805

Please sign in to comment.