feat: SQL between/hostvar-key alignment, class-condition parsing, gcov merge across scenario runs
This commit is contained in:
@@ -26,12 +26,36 @@ def build_branch_tree_fallback(proc_text, fields=None):
|
||||
pass
|
||||
|
||||
# New parser generates O(N) paths (not O(2^N)), so no cap needed.
|
||||
# Just use it directly when it works.
|
||||
# When new parser succeeds, also try the old parser with short timeout.
|
||||
# If old parser succeeds and has more IF nodes, use it (new parser may miss
|
||||
# nested ifs inside PERFORM UNTIL/SECTION blocks).
|
||||
old_tree, old_assigns = None, {}
|
||||
if new_tree is not None:
|
||||
old_fallback, old_fb_assigns = None, {}
|
||||
try:
|
||||
import threading
|
||||
r, e, d = [None], [None], [False]
|
||||
def run():
|
||||
try:
|
||||
r[0] = old_build(proc_text, fields)
|
||||
except Exception as ex:
|
||||
e[0] = ex
|
||||
d[0] = True
|
||||
t = threading.Thread(target=run, daemon=True)
|
||||
t.start(); t.join(3.0)
|
||||
if d[0] and not e[0] and r[0]:
|
||||
old_fallback, old_fb_assigns = r[0]
|
||||
except Exception as e:
|
||||
pass
|
||||
if old_fallback is not None:
|
||||
old_with_cond = _count_brif_with_cond(old_fallback)
|
||||
new_with_cond = _count_brif_with_cond(new_tree)
|
||||
if old_with_cond > new_with_cond:
|
||||
logger.info(f" Old parser: {old_with_cond} BrIf with cond_tree vs new parser {new_with_cond}, using old parser")
|
||||
return old_fallback, old_fb_assigns
|
||||
return new_tree, new_assigns
|
||||
|
||||
# 2. Old parser with 3s timeout (fallback only)
|
||||
old_tree, old_assigns = None, {}
|
||||
try:
|
||||
import threading
|
||||
r, e, d = [None], [None], [False]
|
||||
@@ -174,6 +198,49 @@ def _count_br_nodes(node) -> int:
|
||||
return count
|
||||
|
||||
|
||||
def _count_brif(node):
|
||||
"""Count BrIf nodes in a branch tree."""
|
||||
from .models import BrIf, BrSeq, BrEval, BrPerform, BrSearch
|
||||
count = 0
|
||||
if isinstance(node, BrIf):
|
||||
count += 1
|
||||
if isinstance(node, BrSeq):
|
||||
for c in node.children: count += _count_brif(c)
|
||||
if isinstance(node, BrIf):
|
||||
count += _count_brif(node.true_seq) + _count_brif(node.false_seq)
|
||||
if isinstance(node, BrEval):
|
||||
for _, s in node.when_list: count += _count_brif(s)
|
||||
count += _count_brif(node.other_seq)
|
||||
if isinstance(node, BrPerform):
|
||||
count += _count_brif(node.body_seq)
|
||||
if isinstance(node, BrSearch):
|
||||
count += _count_brif(node.at_end_seq)
|
||||
for _, s in node.when_list: count += _count_brif(s)
|
||||
return count
|
||||
|
||||
|
||||
def _count_brif_with_cond(node):
|
||||
"""Count BrIf nodes that have cond_tree set."""
|
||||
from .models import BrIf, BrSeq, BrEval, BrPerform, BrSearch
|
||||
count = 0
|
||||
if isinstance(node, BrIf):
|
||||
if node.cond_tree is not None:
|
||||
count += 1
|
||||
if isinstance(node, BrSeq):
|
||||
for c in node.children: count += _count_brif_with_cond(c)
|
||||
if isinstance(node, BrIf):
|
||||
count += _count_brif_with_cond(node.true_seq) + _count_brif_with_cond(node.false_seq)
|
||||
if isinstance(node, BrEval):
|
||||
for _, s in node.when_list: count += _count_brif_with_cond(s)
|
||||
count += _count_brif_with_cond(node.other_seq)
|
||||
if isinstance(node, BrPerform):
|
||||
count += _count_brif_with_cond(node.body_seq)
|
||||
if isinstance(node, BrSearch):
|
||||
count += _count_brif_with_cond(node.at_end_seq)
|
||||
for _, s in node.when_list: count += _count_brif_with_cond(s)
|
||||
return count
|
||||
|
||||
|
||||
def _assigns_list_to_dict(assigns_list: list) -> dict:
|
||||
result = {}
|
||||
for a in assigns_list:
|
||||
|
||||
Reference in New Issue
Block a user