Commit aab72634 by Maxime Perrotin

### Check coverage of boolean decisions

parent a838c2d8
 ... @@ -3472,7 +3472,7 @@ def decision(root, parent, context): ... @@ -3472,7 +3472,7 @@ def decision(root, parent, context): covered_ranges = defaultdict(list) covered_ranges = defaultdict(list) qmin, qmax = 0, 0 qmin, qmax = 0, 0 need_else = False need_else = False is_enum = False is_enum, is_bool = False, False for ans in dec.answers: for ans in dec.answers: if dec.kind in ('informal_text', 'any'): if dec.kind in ('informal_text', 'any'): break break ... @@ -3495,6 +3495,12 @@ def decision(root, parent, context): ... @@ -3495,6 +3495,12 @@ def decision(root, parent, context): continue continue covered_ranges[ans].append(ans.inputString) covered_ranges[ans].append(ans.inputString) is_enum = True is_enum = True elif q_basic.kind == 'BooleanType': covered_ranges[ans].append(ans.inputString) is_bool = True if not ans.constant.is_raw: need_else = True continue if not q_basic.kind.startswith(('Integer', 'Real')): if not q_basic.kind.startswith(('Integer', 'Real')): # Check numeric questions - ignore others # Check numeric questions - ignore others continue continue ... @@ -3648,7 +3654,7 @@ def decision(root, parent, context): ... @@ -3648,7 +3654,7 @@ def decision(root, parent, context): new_q_ranges = [] new_q_ranges = [] # (2) Check that decision range is fully covered # (2) Check that decision range is fully covered for ans_ref, ranges in covered_ranges.viewitems(): for ans_ref, ranges in covered_ranges.viewitems(): if is_enum: if is_enum or is_bool: continue continue for mina, maxa in ranges: for mina, maxa in ranges: for minq, maxq in q_ranges: for minq, maxq in q_ranges: ... @@ -3683,7 +3689,7 @@ def decision(root, parent, context): ... @@ -3683,7 +3689,7 @@ def decision(root, parent, context): .format(dec.inputString)) .format(dec.inputString)) # (5) check coverage of enumerated types # (5) check coverage of enumerated types if is_enum: if is_enum or is_bool: # check duplicate answers # check duplicate answers answers = [a.lower() answers = [a.lower() for a in chain.from_iterable(covered_ranges.viewvalues())] for a in chain.from_iterable(covered_ranges.viewvalues())] ... @@ -3691,8 +3697,12 @@ def decision(root, parent, context): ... @@ -3691,8 +3697,12 @@ def decision(root, parent, context): if dupl: if dupl: qerr.append('Decision "{}": duplicate answers "{}"' qerr.append('Decision "{}": duplicate answers "{}"' .format(dec.inputString, '", "'.join(dupl))) .format(dec.inputString, '", "'.join(dupl))) enumerants = [en.replace('-', '_').lower() if is_bool: for en in q_basic.EnumValues.keys()] # Boolean special case: values are just True and False enumerants = ['true', 'false'] else: enumerants = [en.replace('-', '_').lower() for en in q_basic.EnumValues.keys()] # check for missing answers # check for missing answers if set(answers) != set(enumerants) and not has_else: if set(answers) != set(enumerants) and not has_else: qerr.append('Decision "{}": Missing branches for answer(s) "{}"' qerr.append('Decision "{}": Missing branches for answer(s) "{}"' ... ...
 ... @@ -3,9 +3,12 @@ ... @@ -3,9 +3,12 @@ [ERROR] Decision "var6": No answer to cover range 10.0 .. 10.5 [ERROR] Decision "var6": No answer to cover range 10.0 .. 10.5 [ERROR] Decision "var6": No answer to cover value 10.0 [ERROR] Decision "var6": No answer to cover value 10.0 [ERROR] Decision "var6": answers >=10.0 and <=10.0 are overlapping in range 10.0 .. 10.0 [ERROR] Decision "var6": answers >=10.0 and <=10.0 are overlapping in range 10.0 .. 10.0 [ERROR] Decision "varbool": Missing branches for answer(s) "false" [ERROR] Decision "varbool": Missing branches for answer(s) "false" [ERROR] Too many errors, cannot generate code [ERROR] Too many errors, cannot generate code [INFO] Checking ['myfunction.pr', 'system_structure.pr'] [INFO] Checking ['myfunction.pr', 'system_structure.pr'] [INFO] Parsing complete. Summary, found 2 warnings and 5 errors [INFO] Parsing complete. Summary, found 3 warnings and 7 errors [INFO] myfunction.pr [INFO] myfunction.pr [WARNING] Decision "var6": Range -10.0 .. -5.0 is unreachable [WARNING] Decision "var6": Range -10.0 .. -5.0 is unreachable [WARNING] Decision "var6": Range 100.0 .. 150.0 is unreachable [WARNING] Decision "var6": Range 100.0 .. 150.0 is unreachable [WARNING] Decision "varbool": Missing ELSE branch