kspec: minor improvements

pull/364/head
Josselin 5 years ago
parent b872f70738
commit 6e35805137
  1. 37
      slither/tools/kspec_coverage/analysis.py
  2. 2
      slither/tools/kspec_coverage/kspec_coverage.py

@ -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
@ -46,13 +49,12 @@ 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
@ -60,7 +62,7 @@ def _get_slither_functions(slither):
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))
@ -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))
@ -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)
@ -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,
@ -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)

@ -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)

Loading…
Cancel
Save