Class: OrigenTesters::ATP::Processors::Condition
- Inherits:
-
OrigenTesters::ATP::Processor
- Object
- OrigenTesters::ATP::Processor
- OrigenTesters::ATP::Processors::Condition
- Defined in:
- lib/origen_testers/atp/processors/condition.rb
Overview
This optimizes the condition nodes such that any adjacent flow nodes that have the same condition, will be grouped together under a single condition wrapper.
For example this AST:
(flow
(group
(name "g1")
(test
(name "test1"))
(flow-flag "bitmap" true
(test
(name "test2"))))
(flow-flag "bitmap" true
(group
(name "g1")
(flow-flag "x" true
(test
(name "test3")))
(flow-flag "y" true
(flow-flag "x" true
(test
(name "test4")))))))
Will be optimized to this:
(flow
(group
(name "g1")
(test
(name "test1"))
(flow-flag "bitmap" true
(test
(name "test2"))
(flow-flag "x" true
(test
(name "test3"))
(flow-flag "y" true
(test
(name "test4")))))))
Instance Method Summary collapse
- #can_be_combined?(node1, node2) ⇒ Boolean
- #combine(node1, node2) ⇒ Object
- #condition_node?(node) ⇒ Boolean
- #conditions(node) ⇒ Object
- #conditions_to_remove ⇒ Object
- #on_condition_node(node) ⇒ Object
- #on_flow(node) ⇒ Object
- #on_group(node) ⇒ Object
- #on_sub_flow(node) ⇒ Object
- #optimize(nodes) ⇒ Object
Methods inherited from OrigenTesters::ATP::Processor
#clean_flag, #extract_volatiles, #handler_missing, #process, #process_all, #run, #volatile?, #volatile_flags
Instance Method Details
#can_be_combined?(node1, node2) ⇒ Boolean
128 129 130 131 132 133 134 |
# File 'lib/origen_testers/atp/processors/condition.rb', line 128 def can_be_combined?(node1, node2) if condition_node?(node1) && condition_node?(node2) !(conditions(node1) & conditions(node2)).empty? else false end end |
#combine(node1, node2) ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/origen_testers/atp/processors/condition.rb', line 141 def combine(node1, node2) common = conditions(node1) & conditions(node2) common.each { |condition| conditions_to_remove << condition } node1 = process(node1) node1 = [node1] unless node1.is_a?(Array) node2 = process(node2) node2 = [node2] unless node2.is_a?(Array) common.size.times { conditions_to_remove.pop } node = nil common.reverse_each do |condition| if node node = condition.updated(nil, condition.children + [node]) else node = condition.updated(nil, condition.children + node1 + node2) end end node end |
#condition_node?(node) ⇒ Boolean
136 137 138 139 |
# File 'lib/origen_testers/atp/processors/condition.rb', line 136 def condition_node?(node) # [:flow_flag, :run_flag, :test_result, :group, :job, :test_executed].include?(node.type) node.respond_to?(:type) && OrigenTesters::ATP::Flow::CONDITION_KEYS[node.type] end |
#conditions(node) ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/origen_testers/atp/processors/condition.rb', line 161 def conditions(node) result = [] # if [:flow_flag, :run_flag].include?(node.type) if [:if_enabled, :unless_enabled, :if_flag, :unless_flag].include?(node.type) flag, *children = *node unless volatile?(flag) result << node.updated(nil, [flag]) end result += conditions(children.first) if children.first && children.size == 1 # elsif [:test_result, :job, :test_executed].include?(node.type) elsif node.type == :group name, *children = *node # Sometimes a group can have an ID if children.first.try(:type) == :id result << node.updated(nil, [name, children.shift]) else result << node.updated(nil, [name]) end result += conditions(children.first) if children.first && children.size == 1 elsif OrigenTesters::ATP::Flow::CONDITION_NODE_TYPES.include?(node.type) flag, *children = *node result << node.updated(nil, [flag]) result += conditions(children.first) if children.first && children.size == 1 end result end |
#conditions_to_remove ⇒ Object
188 189 190 |
# File 'lib/origen_testers/atp/processors/condition.rb', line 188 def conditions_to_remove @conditions_to_remove ||= [] end |
#on_condition_node(node) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/origen_testers/atp/processors/condition.rb', line 83 def on_condition_node(node) flag, *nodes = *node if conditions_to_remove.any? { |c| node.type == c.type && c.to_a == [flag] } if volatile?(flag) result = node.updated(:inline, optimize(process_all(nodes))) else # This ensures any duplicate conditions matching the current one get removed conditions_to_remove << node.updated(nil, [flag]) result = node.updated(:inline, optimize(process_all(nodes))) conditions_to_remove.pop end else if volatile?(flag) result = node.updated(nil, [flag] + optimize(process_all(nodes))) else conditions_to_remove << node.updated(nil, [flag]) result = node.updated(nil, [flag] + optimize(process_all(nodes))) conditions_to_remove.pop end end result end |
#on_flow(node) ⇒ Object
46 47 48 49 |
# File 'lib/origen_testers/atp/processors/condition.rb', line 46 def on_flow(node) extract_volatiles(node) node.updated(nil, optimize(process_all(node.children))) end |
#on_group(node) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/origen_testers/atp/processors/condition.rb', line 55 def on_group(node) array_for_update = [] if node.find(:bypass) && node.find(:comment) name, bypass, comment, *nodes = *node array_for_update = [name, bypass, comment] elsif node.find(:bypass) name, bypass, *nodes = *node array_for_update = [name, bypass] elsif node.find(:comment) name, comment, *nodes = *node array_for_update = [name, comment] else name, *nodes = *node array_for_update = [name] end if conditions_to_remove.any? { |c| node.type == c.type && c.to_a == [name] } conditions_to_remove << node.updated(nil, array_for_update) result = node.updated(:inline, optimize(process_all(nodes))) conditions_to_remove.pop else conditions_to_remove << node.updated(nil, [name, bypass, comment]) result = node.updated(nil, array_for_update + optimize(process_all(nodes))) conditions_to_remove.pop end result end |
#on_sub_flow(node) ⇒ Object
51 52 53 |
# File 'lib/origen_testers/atp/processors/condition.rb', line 51 def on_sub_flow(node) node.updated(nil, optimize(process_all(node.children))) end |
#optimize(nodes) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/origen_testers/atp/processors/condition.rb', line 109 def optimize(nodes) results = [] node1 = nil nodes.each do |node2| if node1 if can_be_combined?(node1, node2) node1 = process(combine(node1, node2)) else results << node1 node1 = node2 end else node1 = node2 end end results << node1 if node1 results end |