diff options
Diffstat (limited to 'ql/ast/checkers')
| -rw-r--r-- | ql/ast/checkers/__pycache__/dependency_checker.cpython-35.pyc | bin | 0 -> 1953 bytes | |||
| -rw-r--r-- | ql/ast/checkers/__pycache__/question_checker.cpython-35.pyc | bin | 0 -> 1658 bytes | |||
| -rw-r--r-- | ql/ast/checkers/__pycache__/reference_checker.cpython-35.pyc | bin | 0 -> 2061 bytes | |||
| -rw-r--r-- | ql/ast/checkers/dependency_checker.py | 44 | ||||
| -rw-r--r-- | ql/ast/checkers/question_checker.py | 33 | ||||
| -rw-r--r-- | ql/ast/checkers/reference_checker.py | 30 |
6 files changed, 107 insertions, 0 deletions
diff --git a/ql/ast/checkers/__pycache__/dependency_checker.cpython-35.pyc b/ql/ast/checkers/__pycache__/dependency_checker.cpython-35.pyc Binary files differnew file mode 100644 index 0000000..5be2eb2 --- /dev/null +++ b/ql/ast/checkers/__pycache__/dependency_checker.cpython-35.pyc diff --git a/ql/ast/checkers/__pycache__/question_checker.cpython-35.pyc b/ql/ast/checkers/__pycache__/question_checker.cpython-35.pyc Binary files differnew file mode 100644 index 0000000..bb81f4a --- /dev/null +++ b/ql/ast/checkers/__pycache__/question_checker.cpython-35.pyc diff --git a/ql/ast/checkers/__pycache__/reference_checker.cpython-35.pyc b/ql/ast/checkers/__pycache__/reference_checker.cpython-35.pyc Binary files differnew file mode 100644 index 0000000..3bdfae5 --- /dev/null +++ b/ql/ast/checkers/__pycache__/reference_checker.cpython-35.pyc diff --git a/ql/ast/checkers/dependency_checker.py b/ql/ast/checkers/dependency_checker.py new file mode 100644 index 0000000..473ef6b --- /dev/null +++ b/ql/ast/checkers/dependency_checker.py @@ -0,0 +1,44 @@ +class DependencyChecker: + def __init__(self, combinations): + self.__errors = [] + self.__check_dependencies(combinations) + + @property + def errors(self): + return self.__errors + + def __check_dependencies(self, combinations): + for (identifier, identifier_children, identifier_metadata) in combinations: + children = self.__find_children(identifier, combinations) + + if identifier in children: + self.__errors.append('Cyclic dependency detected in question identifiers on line(s) {}' + .format(str(self.__find_lines(children, combinations))[1:-1])) + + def __find_children(self, identifier, combinations): + reference, reference_children, _ = combinations[0] + + if len(combinations) == 1 and identifier == reference: + return reference_children + elif len(combinations) == 1: + return [] + elif identifier == reference: + all_children = [] + + for new_identifier in reference_children: + all_children += self.__find_children(new_identifier, combinations[1:]) + + return all_children + reference_children + + return self.__find_children(identifier, combinations[1:]) + + @staticmethod + def __find_lines(children, combinations): + lines = [] + + for identifier, _, metadata in combinations: + for child in children: + if identifier == child: + lines.append(metadata.line) + + return lines diff --git a/ql/ast/checkers/question_checker.py b/ql/ast/checkers/question_checker.py new file mode 100644 index 0000000..5b255d8 --- /dev/null +++ b/ql/ast/checkers/question_checker.py @@ -0,0 +1,33 @@ +class QuestionChecker: + def __init__(self, questions): + self.__errors = [] + self.__warnings = [] + self.__check_questions(questions) + + @property + def errors(self): + return self.__errors + + @property + def warnings(self): + return self.__warnings + + def __check_questions(self, questions): + for question1 in questions: + for question2 in questions: + if question1 != question2: + equal_labels = question1['label'] == question2['label'] + equal_identifiers = question1['identifier'] == question2['identifier'] + different_types = question1['answer_type'] != question2['answer_type'] + + if all([equal_labels, equal_identifiers, different_types]): + self.__errors.append('Duplicate questions with different types found on lines {} and {}' + .format(question1['metadata'].line, question2['metadata'].line)) + + if equal_identifiers: + self.__errors.append('Duplicate question identifiers found on lines {} and {}' + .format(question1['metadata'].line, question2['metadata'].line)) + + if equal_labels: + self.__warnings.append('Duplicate question labels found on lines {} and {}' + .format(question1['metadata'].line, question2['metadata'].line)) diff --git a/ql/ast/checkers/reference_checker.py b/ql/ast/checkers/reference_checker.py new file mode 100644 index 0000000..71407c3 --- /dev/null +++ b/ql/ast/checkers/reference_checker.py @@ -0,0 +1,30 @@ +class ReferenceChecker: + def __init__(self, table): + self.__errors = [] + self.__check_references(table, [], []) + + @property + def errors(self): + return self.__errors + + def __check_references(self, table, known_types, unknown_types): + (local_known_types, local_unknown_types) = self.__split_known_unknown_types(table) + known_types += local_known_types + unknown_types += local_unknown_types + + self.__identifier_seen(known_types, unknown_types) + + if table['children']: + for child_scope in table['children']: + self.__check_references(child_scope, known_types, unknown_types) + + @staticmethod + def __split_known_unknown_types(table): + known_types = [row['name'] for row in table['content'] if row['type']] + unknown_types = [(row['name'], row['line']) for row in table['content'] if not (row['type'])] + return known_types, unknown_types + + def __identifier_seen(self, known_types, unknown_types): + for (identifier, line) in unknown_types: + if not (identifier in known_types): + self.__errors.append('Identifier \"{}\" at line {} is unknown'.format(identifier, line)) |