lib/atp/processors/condition.rb in atp-0.2.0 vs lib/atp/processors/condition.rb in atp-0.2.1
- old
+ new
@@ -63,11 +63,13 @@
def on_boolean_condition(node)
children = node.children.dup
name = children.shift
state = children.shift
+ remove_condition << node
children = optimize_siblings(n(:temp, children))
+ remove_condition.pop
if condition_to_be_removed?(node)
process_all(children)
else
node.updated(nil, [name, state] + process_all(children))
end
@@ -77,11 +79,13 @@
alias_method :on_test_executed, :on_boolean_condition
def on_condition(node)
children = node.children.dup
name = children.shift
+ remove_condition << node
children = optimize_siblings(n(:temp, children))
+ remove_condition.pop
if condition_to_be_removed?(node)
process_all(children)
else
node.updated(nil, [name] + process_all(children))
end
@@ -98,11 +102,11 @@
end
end
end
def condition_to_be_removed?(node)
- remove_condition.last && equal_conditions?(remove_condition.last, node)
+ remove_condition.any? { |c| equal_conditions?(c, node) }
end
def equal_conditions?(node1, node2)
if node1.type == node2.type
if node1.type == :group || node1.type == :job
@@ -116,15 +120,21 @@
def condition?(node)
node.is_a?(ATP::AST::Node) && CONDITION_NODES.include?(node.type)
end
def on_flow(node)
- node.updated(nil, optimize_siblings(node))
+ # The extract_common_embedded_conditions method can probably do the whole job,
+ # but it might get a little complicated with regards to optimizing adjacent groups,
+ # so have left the original logic to have the first crack and deal with the groups
+ # for now.
+ nodes = optimize_siblings(node)
+ nodes = extract_common_embedded_conditions(nodes)
+ node.updated(nil, nodes)
end
def on_members(node)
- node.updated(nil, optimize_siblings(node))
+ node.updated(nil, extract_common_embedded_conditions(optimize_siblings(node)))
end
def optimize_siblings(top_node)
children = []
unprocessed_children = []
@@ -162,9 +172,49 @@
children << process(node)
end
end
end
children.flatten
+ end
+
+ def extract_common_embedded_conditions(nodes)
+ nodes = [nodes] unless nodes.is_a?(Array)
+ result = []
+ cond_a = nil
+ test_a = nil
+ ConditionExtractor.new.run(nodes).each do |cond_b, test_b|
+ if cond_a
+ common = cond_a & cond_b
+ if common.empty?
+ result << combine(cond_a, extract_common_embedded_conditions(test_a))
+ cond_a = cond_b
+ test_a = test_b
+ else
+ a = combine(cond_a - common, test_a)
+ b = combine(cond_b - common, test_b)
+ cond_a = common
+ test_a = [a, b].flatten
+ end
+ else
+ cond_a = cond_b
+ test_a = test_b
+ end
+ end
+ if nodes == [test_a]
+ nodes
+ else
+ result << combine(cond_a, extract_common_embedded_conditions(test_a))
+ result.flatten
+ end
+ end
+
+ def combine(conditions, node)
+ if conditions && !conditions.empty?
+ conditions.reverse_each do |n|
+ node = n.updated(nil, n.children + (node.is_a?(Array) ? node : [node]))
+ end
+ end
+ node
end
def remove_condition
@remove_condition ||= []
end