From 68809a09f6704c74b35d7831e61429f9e62fac83 Mon Sep 17 00:00:00 2001 From: Oliver Stolz Date: Fri, 16 Feb 2024 11:54:01 +0100 Subject: [PATCH] Move helper method into semantic error checker - Enable plugins to overload this method --- pfdl_scheduler/utils/helpers.py | 23 +----------- .../validation/semantic_error_checker.py | 35 +++++++++++++++---- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/pfdl_scheduler/utils/helpers.py b/pfdl_scheduler/utils/helpers.py index b2eebef..358439c 100644 --- a/pfdl_scheduler/utils/helpers.py +++ b/pfdl_scheduler/utils/helpers.py @@ -7,7 +7,7 @@ """Helper functions used in the project (especially in the SemanticErrorChecker).""" # standard libraries -from typing import Any, Dict, List, Union +from typing import Dict, List, Union import operator # local sources @@ -15,27 +15,6 @@ from pfdl_scheduler.model.task import Task -def check_type_of_value(value: Any, value_type: str) -> bool: - """Checks if the given value is the given type in the DSL. - - Returns: - True if the value is from the given value type. - """ - if value_type == "number": - # bool is a subclass of int so check it before - if isinstance(value, bool): - return False - return isinstance(value, (int, float)) - if value_type == "boolean": - return isinstance(value, bool) - if value_type == "string": - return isinstance(value, str) - if isinstance(value, Struct): - return value.name == value_type - # value was a string - return True - - def get_type_of_variable_list( var_list: List[str], task: Task, struct_definitions: Dict[str, Struct] ) -> str: diff --git a/pfdl_scheduler/validation/semantic_error_checker.py b/pfdl_scheduler/validation/semantic_error_checker.py index 431b0db..d8e5254 100644 --- a/pfdl_scheduler/validation/semantic_error_checker.py +++ b/pfdl_scheduler/validation/semantic_error_checker.py @@ -7,7 +7,7 @@ """Contains the SemanticErrorChecker class.""" # standard libraries -from typing import Dict, List, Union +from typing import Dict, List, Union, Any # 3rd party libraries from antlr4.ParserRuleContext import ParserRuleContext @@ -29,7 +29,7 @@ from pfdl_scheduler.utils import helpers # global defines -from pfdl_scheduler.parser.pfdl_tree_visitor import PRIMITIVE_DATATYPES, IN_KEY, OUT_KEY, START_TASK +from pfdl_scheduler.parser.pfdl_tree_visitor import IN_KEY, OUT_KEY, START_TASK class SemanticErrorChecker: @@ -602,7 +602,6 @@ def check_for_wrong_attribute_type_in_struct( if isinstance(correct_attribute_type, str): if correct_attribute_type in self.structs: - # check for structs which has structs as attribute if isinstance(attribute, Struct): attribute.name = correct_attribute_type @@ -621,7 +620,7 @@ def check_for_wrong_attribute_type_in_struct( ) self.error_handler.print_error(error_msg, context=struct_instance.context) return False - if not helpers.check_type_of_value(attribute, correct_attribute_type): + if not self.check_type_of_value(attribute, correct_attribute_type): error_msg = ( f"Attribute '{identifier}' has the wrong type in the instantiated" f" Struct '{struct_instance.name}', expected '{correct_attribute_type}'" @@ -656,7 +655,7 @@ def check_array(self, instantiated_array: Array, array_definition: Array) -> boo value.name = array_definition.type_of_elements if not self.check_instantiated_struct_attributes(value): return False - if not helpers.check_type_of_value(value, element_type): + if not self.check_type_of_value(value, element_type): error_msg = ( f"Array has elements that does not match " f"with the defined type '{element_type}'" @@ -773,6 +772,7 @@ def check_single_expression( if not self.check_attribute_access(expression, context, task): return False + # only numbers and booleans are allowed, so check the variable type variable_type = helpers.get_type_of_variable_list(expression, task, self.structs) if not (isinstance(variable_type, str) and variable_type in ["number", "boolean"]): msg = "The given attribute can not be resolved to a boolean expression" @@ -806,7 +806,10 @@ def check_binary_operation(self, expression, context: ParserRuleContext, task: T if self.expression_is_string(left, task) and self.expression_is_string(right, task): return True - msg = "Types of Right and left side of the comparison dont match" + msg = ( + "Types of right and left side of the comparison dont match. " + "This might be caused by some of the Rule parameters that are not initialised." + ) self.error_handler.print_error(msg, context=context) return False if expression["binOp"] in ["*", "/", "+", "-"]: @@ -911,6 +914,26 @@ def variable_type_exists(self, variable_type: str) -> bool: return False return True + def check_type_of_value(self, value: Any, value_type: str) -> bool: + """Checks if the given value is the given type in the DSL. + + Returns: + True if the value is from the given value type. + """ + if value_type == "number": + # bool is a subclass of int so check it before + if isinstance(value, bool): + return False + return isinstance(value, (int, float)) + if value_type == "boolean": + return isinstance(value, bool) + if value_type == "string": + return isinstance(value, str) + if isinstance(value, Struct): + return value.name == value_type + # value was a string + return True + def instantiated_array_length_correct( self, instantiated_array: Array, array_definition: Array ) -> bool: