Class: OrigenTesters::ATP::Processors::Condition
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
#add_global_flag, #clean_flag, #extract_globals, #extract_volatiles, #global_flag?, #global_flags, #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)
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 [: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 node.type == :group
name, *children = *node
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
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)
(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, , *nodes = *node
array_for_update = [name, bypass, ]
elsif node.find(:bypass)
name, bypass, *nodes = *node
array_for_update = [name, bypass]
elsif node.find(:comment)
name, , *nodes = *node
array_for_update = [name, ]
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, ])
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
|