Class: Pacer::Filter::WhereFilter::NodeVisitor
- Inherits:
-
Object
- Object
- Pacer::Filter::WhereFilter::NodeVisitor
- Defined in:
- lib/pacer/filter/where_filter/node_visitor.rb
Overview
NOTE: the property filter also uses this to build { key: Set[v1, v2] } filters as or statements.
Defined Under Namespace
Constant Summary collapse
- NeverPipe =
Pacer::Pipes::NeverPipe
- IdentityPipe =
Pacer::Pipes::IdentityPipe
- PropertyComparisonFilterPipe =
Pacer::Pipes::PropertyComparisonFilterPipe
- Pipeline =
Pacer::Pipes::Pipeline
- CrossProductTransformPipe =
Pacer::Pipes::CrossProductTransformPipe
- UnaryTransformPipe =
Pacer::Pipes::UnaryTransformPipe
- BlockFilterPipe =
Pacer::Pipes::BlockFilterPipe
- Filters =
{ '==' => Compare::EQUAL, '=' => Compare::EQUAL, '!=' => Compare::NOT_EQUAL, '>' => Compare::GREATER_THAN, '<' => Compare::LESS_THAN, '>=' => Compare::GREATER_THAN_EQUAL, '<=' => Compare::LESS_THAN_EQUAL }
- ReverseFilters =
Filters.merge( '<' => Compare::GREATER_THAN, '>' => Compare::LESS_THAN, '<=' => Compare::GREATER_THAN_EQUAL, '>=' => Compare::LESS_THAN_EQUAL )
- COMPARATORS =
%w[ == != > < >= <= ]
- METHODS =
%w[ + - * / % ]
- REGEX_COMPARATORS =
%w[ =~ !~ ]
- VALID_OPERATIONS =
+ REGEX_COMPARATORS
COMPARATORS + METHODS
Instance Attribute Summary collapse
-
#route ⇒ Object
readonly
Returns the value of attribute route.
-
#values ⇒ Object
readonly
Returns the value of attribute values.
Instance Method Summary collapse
- #build_comparison(a, b, name) ⇒ Object
- #comparable_pipe(pipe) ⇒ Object
-
#initialize(route, values = {}) ⇒ NodeVisitor
constructor
A new instance of NodeVisitor.
- #negate(pipe) ⇒ Object
- #visitAndNode(node) ⇒ Object
- #visitArrayNode(node) ⇒ Object
- #visitBignumNode(node) ⇒ Object
- #visitCallNode(node) ⇒ Object
- #visitConstDeclNode(node) ⇒ Object
- #visitConstNode(node) ⇒ Object
- #visitFalseNode(node) ⇒ Object
- #visitFixnumNode(node) ⇒ Object
- #visitFloatNode(node) ⇒ Object
- #visitHashNode(node) ⇒ Object
- #visitLocalAsgnNode(node) ⇒ Object
- #visitLocalVarNode(node) ⇒ Object
- #visitNewlineNode(node) ⇒ Object
- #visitNilNode(node) ⇒ Object
- #visitOrNode(node) ⇒ Object
- #visitRootNode(node) ⇒ Object
- #visitStrNode(node) ⇒ Object
- #visitSymbolNode(node) ⇒ Object
- #visitTrueNode(node) ⇒ Object
- #visitVCallNode(node) ⇒ Object
- #visitXStrNode(node) ⇒ Object
- #visitYieldNode(node) ⇒ Object
- #visitZArrayNode(node) ⇒ Object
Constructor Details
#initialize(route, values = {}) ⇒ NodeVisitor
Returns a new instance of NodeVisitor.
115 116 117 118 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 115 def initialize(route, values = {}) @route = route @values = values end |
Instance Attribute Details
#route ⇒ Object (readonly)
Returns the value of attribute route.
113 114 115 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 113 def route @route end |
#values ⇒ Object (readonly)
Returns the value of attribute values.
113 114 115 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 113 def values @values end |
Instance Method Details
#build_comparison(a, b, name) ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 120 def build_comparison(a, b, name) # TODO: support regex matches raise "Operation not supported: #{ name }" unless VALID_OPERATIONS.include? name if COMPARATORS.include? name if a.is_a? Value and b.is_a? Value if a.value.send name, b.value Pipe.new IdentityPipe else Pipe.new NeverPipe end elsif a.pipe == PropertyPipe and b.pipe == PropertyPipe Pipe.new PropertyComparisonFilterPipe, a, b, Filters[name] elsif b.pipe == PropertyPipe and a.is_a? Value Pipe.new Pipeline, b, Pipe.new(ObjectFilterPipe, a, ReverseFilters[name]) else Pipe.new Pipeline, a, Pipe.new(ObjectFilterPipe, b, Filters[name]) end elsif METHODS.include? name if a.is_a? Value and b.is_a? Value Value.new a.value.send(name, b.value) else Pipe.new CrossProductTransformPipe, name, a, b end end end |
#comparable_pipe(pipe) ⇒ Object
151 152 153 154 155 156 157 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 151 def comparable_pipe(pipe) if pipe.pipe == PropertyPipe build_comparison(pipe, Value.new(nil), '!=') else pipe end end |
#negate(pipe) ⇒ Object
147 148 149 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 147 def negate(pipe) Pipe.new(Pipeline, pipe, Pipe.new(HasCountPipe, -1, 0), Pipe.new(ObjectFilterPipe, true, Filters['=='])) end |
#visitAndNode(node) ⇒ Object
234 235 236 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 234 def visitAndNode(node) visit_and_or(AndFilterPipe, node) end |
#visitArrayNode(node) ⇒ Object
159 160 161 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 159 def visitArrayNode(node) Value.new Value.new(node.child_nodes.map { |n| n.accept self }).values! end |
#visitBignumNode(node) ⇒ Object
163 164 165 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 163 def visitBignumNode(node) Value.new node.value.to_s end |
#visitCallNode(node) ⇒ Object
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 167 def visitCallNode(node) a = node.receiver_node.accept(self) if node.args_node b = node.args_node.child_nodes.first.accept(self) build_comparison(a, b, node.name) else return a if node.name == '+' if a.is_a? Value Value.new a.value.send(a.name) elsif a.pipe == PropertyPipe if node.name == '!' negate(comparable_pipe(a)) else Pipe.new(UnaryTransformPipe, node.name, a) end else case node.name when '!' # Special case for "a == 1 and not (b == 1)", etc. negate a else raise 'not sure' end end end end |
#visitConstDeclNode(node) ⇒ Object
216 217 218 219 220 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 216 def visitConstDeclNode(node) a = Pipe.new PropertyPipe, node.name b = node.value_node.accept(self) build_comparison(a, b, '==') end |
#visitConstNode(node) ⇒ Object
273 274 275 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 273 def visitConstNode(node) Pipe.new PropertyPipe, node.name end |
#visitFalseNode(node) ⇒ Object
194 195 196 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 194 def visitFalseNode(node) Pipe.new NeverPipe end |
#visitFixnumNode(node) ⇒ Object
198 199 200 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 198 def visitFixnumNode(node) Value.new node.value end |
#visitFloatNode(node) ⇒ Object
202 203 204 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 202 def visitFloatNode(node) Value.new node.value end |
#visitHashNode(node) ⇒ Object
206 207 208 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 206 def visitHashNode(node) Value.new Hash[*node.child_nodes.first.accept(self).value.map { |v| v.value }] end |
#visitLocalAsgnNode(node) ⇒ Object
210 211 212 213 214 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 210 def visitLocalAsgnNode(node) a = Pipe.new PropertyPipe, node.name b = node.value_node.accept(self) build_comparison(a, b, '==') end |
#visitLocalVarNode(node) ⇒ Object
222 223 224 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 222 def visitLocalVarNode(node) Pipe.new PropertyPipe, node.name end |
#visitNewlineNode(node) ⇒ Object
226 227 228 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 226 def visitNewlineNode(node) node.next_node.accept(self) end |
#visitNilNode(node) ⇒ Object
230 231 232 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 230 def visitNilNode(node) Value.new nil end |
#visitOrNode(node) ⇒ Object
238 239 240 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 238 def visitOrNode(node) visit_and_or(OrFilterPipe, node) end |
#visitRootNode(node) ⇒ Object
242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 242 def visitRootNode(node) pipe = node.body_node.accept self if pipe.pipe == AndFilterPipe or pipe.pipe == OrFilterPipe pipe elsif pipe.is_a? Value if pipe.value Pipe.new IdentityPipe else Pipe.new NeverPipe end else Pipe.new AndFilterPipe, comparable_pipe(pipe) end end |
#visitStrNode(node) ⇒ Object
257 258 259 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 257 def visitStrNode(node) Value.new node.value end |
#visitSymbolNode(node) ⇒ Object
261 262 263 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 261 def visitSymbolNode(node) Value.new values.fetch(node.name.to_sym, node.name.to_sym) end |
#visitTrueNode(node) ⇒ Object
265 266 267 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 265 def visitTrueNode(node) Pipe.new IdentityPipe end |
#visitVCallNode(node) ⇒ Object
269 270 271 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 269 def visitVCallNode(node) Pipe.new PropertyPipe, node.name end |
#visitXStrNode(node) ⇒ Object
277 278 279 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 277 def visitXStrNode(node) Pipe.new PropertyPipe, node.value end |
#visitYieldNode(node) ⇒ Object
281 282 283 284 |
# File 'lib/pacer/filter/where_filter/node_visitor.rb', line 281 def visitYieldNode(node) block = node.args_node.child_nodes.first.accept(self) Pipe.new BlockFilterPipe, Value.new(route), block end |