lib/preval/visitors/fasterer.rb in preval-0.4.1 vs lib/preval/visitors/fasterer.rb in preval-0.5.0
- old
+ new
@@ -7,66 +7,74 @@
def on_call(node)
left, _period, right = node.body
# replace `.reverse.each` with `.reverse_each`
# replace `.shuffle.first` with `.sample`
+ # replace `.sort.first` with `min`
+ # replace `.sort.last` with `max`
if node.type_match?(:call, :@period, :@ident) &&
- # foo.each
+ # foo.each
left.type_match?(%i[array vcall], :@period, :@ident)
- # foo.reverse
+ # foo.reverse
callleft, callperiod, callright = left.body
if callright.body == 'reverse' && right.body == 'each'
callright.update(:@ident, 'reverse_each')
node.update(:call, [callleft, callperiod, callright])
+ elsif callright.body == 'sort' && right.body == 'first'
+ callright.update(:@ident, 'min')
+ node.update(:call, [callleft, callperiod, callright])
+ elsif callright.body == 'sort' && right.body == 'last'
+ callright.update(:@ident, 'max')
+ node.update(:call, [callleft, callperiod, callright])
elsif callright.body == 'shuffle' && right.body == 'first'
callright.update(:@ident, 'sample')
node.update(:call, [callleft, callperiod, callright])
end
end
end
def on_method_add_arg(node)
# replace `.gsub('...', '...')` with `.tr('...', '...')`
if node.type_match?(:call, :arg_paren) &&
- # foo.gsub()
+ # foo.gsub()
node[0].type_match?(:vcall, :@period, :@ident) &&
- # foo.gsub
+ # foo.gsub
node[0, 2].body == 'gsub'
- # the method being called is gsub
+ # the method being called is gsub
left = node[1, 0, 0, 0, 1]
right = node[1, 0, 0, 1]
if left.is?(:string_literal) &&
right.is?(:string_literal) &&
- [left, right].all? do |node|
- node[0, 1].is?(:@tstring_content) &&
- node[0, 1].body.length == 1
+ [left, right].all? do |string|
+ string[0, 1].is?(:@tstring_content) &&
+ string[0, 1].body.length == 1
end
node[0, 2].update(:@ident, 'tr')
end
end
# replace `.map { ... }.flatten(1)` with `.flat_map { ... }`
- if node.type_match?(:call, :arg_paren) &&
- # foo.flatten()
+ if node.type_match?(:call, :arg_paren) &&
+ # foo.flatten()
node[0].type_match?(:method_add_block, :@period, :@ident) &&
- # foo.map {}
+ # foo.map {}
node[0, 0, 0].type_match?(%i[array vcall], :@period, :@ident) &&
- # foo.flatten
+ # foo.flatten
node[0, 0, 0, 2].body == 'map' &&
- # the inner call is a call to map
+ # the inner call is a call to map
node[0, 2].body == 'flatten' &&
- # the outer call is a call to flatten
+ # the outer call is a call to flatten
node[1].is?(:arg_paren) &&
- # flatten has a param
+ # flatten has a param
node[1, 0, 0].type_match?(:args_new, :@int) &&
- # there is only one argument to flatten and it is an integer
+ # there is only one argument to flatten and it is an integer
node[1, 0, 0, 1].body == '1'
- # the value of the argument to flatten is 1
+ # the value of the argument to flatten is 1
node[0, 0, 0, 2].update(:@ident, 'flat_map')
node.update(:method_add_block, node[0, 0].body)
end
end