Skip to content

Commit

Permalink
Added function error predicate
Browse files Browse the repository at this point in the history
  • Loading branch information
smythi93 committed Apr 11, 2024
1 parent dddb34a commit bd85c8e
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 4 deletions.
21 changes: 21 additions & 0 deletions resources/subjects/tests/test_error/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import sys


def f(x: int):
if x < 0:
raise ValueError("x must be non-negative")
else:
return x


def g(x: int):
if x < 0:
return -x
else:
return x


if __name__ == "__main__":
x_ = int(sys.argv[1])
g(x_)
f(x_)
25 changes: 25 additions & 0 deletions src/sflkit/analysis/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
ContainsDigitPredicate,
ContainsSpecialPredicate,
EmptyBytesPredicate,
FunctionErrorPredicate,
)
from sflkit.analysis.spectra import Line, Function, Loop, DefUse, Length
from sflkit.model.scope import Scope
Expand Down Expand Up @@ -429,6 +430,29 @@ def get_analysis(self, event, scope: Scope = None) -> List[AnalysisObject]:
return self.objects[key][:]


class FunctionErrorFactory(AnalysisFactory):
def __init__(self):
super().__init__()
self.function_mapping = dict()

def get_analysis(self, event, scope: Scope = None) -> List[AnalysisObject]:
if event.event_type == EventType.FUNCTION_ENTER:
self.function_mapping[event.function_id] = event.line
if event.event_type in (EventType.FUNCTION_ERROR, EventType.FUNCTION_EXIT):
line = self.function_mapping[event.function_id]
key = (
FunctionErrorPredicate.analysis_type(),
event.file,
line,
event.function_id,
)
if key not in self.objects:
self.objects[key] = FunctionErrorPredicate(
event.file, line, event.function
)
return [self.objects[key]]


analysis_factory_mapping = {
AnalysisType.LINE: LineFactory,
AnalysisType.BRANCH: BranchFactory,
Expand All @@ -446,4 +470,5 @@ def get_analysis(self, event, scope: Scope = None) -> List[AnalysisObject]:
AnalysisType.VARIABLE: VariableFactory,
AnalysisType.SCALAR_PAIR: ScalarPairFactory,
AnalysisType.FUNCTION: FunctionFactory,
AnalysisType.FUNCTION_ERROR: FunctionErrorFactory,
}
2 changes: 2 additions & 0 deletions src/sflkit/analysis/mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
VariablePredicate,
ReturnPredicate,
NonePredicate,
FunctionErrorPredicate,
)
from sflkit.analysis.predicate import (
EmptyStringPredicate,
Expand Down Expand Up @@ -39,6 +40,7 @@
analysis_mapping[AnalysisType.DIGIT_STRING] = ContainsDigitPredicate
analysis_mapping[AnalysisType.SPECIAL_STRING] = ContainsSpecialPredicate
analysis_mapping[AnalysisType.CONDITION] = Condition
analysis_mapping[AnalysisType.FUNCTION_ERROR] = FunctionErrorPredicate

"""
If you want to add new spectra or predicates, please register them here and in sdtools/analysis/analysis_type.py
Expand Down
2 changes: 1 addition & 1 deletion src/sflkit/language/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def __init__(self):
self.random = random.randbytes(4).hex()

def get_var_name(self):
var = f"sd_tmp_{self.random}_{self._tmp_count}"
var = f"sk_tmp_{self.random}_{self._tmp_count}"
self._tmp_count += 1
return var

Expand Down
2 changes: 1 addition & 1 deletion src/sflkit/language/python/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ def visit_function(
function_error_event = FunctionErrorEvent(
self.file,
node.lineno,
self.get_function_event_id(node, self.event_id_generator),
self.event_id_generator.get_next_id(),
node.name,
self.get_function_id(node),
)
Expand Down
8 changes: 6 additions & 2 deletions src/sflkit/mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@ def get_path(identifier: str):
def load(config: Any):
if not hasattr(config, "identifier"):
raise InstrumentationError(f"Argument does not have an identifier")
file = EventMapping.get_path(config.identifier())
return EventMapping.load_from_file(config.identifier())

@staticmethod
def load_from_file(identifier: str):
file = EventMapping.get_path(identifier)
if file.exists():
return EventMapping(load_json(file))
else:
raise InstrumentationError(
f"Cannot find information about instrumentation of {config.identifier()}"
f"Cannot find information about instrumentation of {identifier or file}"
)

def write(self, config):
Expand Down

0 comments on commit bd85c8e

Please sign in to comment.