lib/rubocop/cop/style/lambda.rb in rubocop-0.29.1 vs lib/rubocop/cop/style/lambda.rb in rubocop-0.30.0
- old
+ new
@@ -5,10 +5,12 @@
module Style
# This cop checks for uses of the pre 1.9 lambda syntax for one-line
# anonymous functions and uses of the 1.9 lambda syntax for multi-line
# anonymous functions.
class Lambda < Cop
+ include AutocorrectUnlessChangingAST
+
SINGLE_MSG = 'Use the new lambda literal syntax `->(params) {...}`.'
SINGLE_NO_ARG_MSG = 'Use the new lambda literal syntax `-> {...}`.'
MULTI_MSG = 'Use the `lambda` method for multi-line lambdas.'
TARGET = s(:send, nil, :lambda)
@@ -20,55 +22,59 @@
# ...)
block_method, args, = *node
return unless block_method == TARGET
selector = block_method.loc.selector.source
- lambda_length = lambda_length(node)
+ length = lambda_length(node)
- if selector != '->' && lambda_length == 0
- add_offense_for_single_line(block_method, args)
- elsif selector == '->' && lambda_length > 0
- add_offense(block_method, :expression, MULTI_MSG)
+ if selector != '->' && length == 1
+ add_offense_for_single_line(node, block_method.loc.expression, args)
+ elsif selector == '->' && length > 1
+ add_offense(node, block_method.loc.expression, MULTI_MSG)
end
end
private
- def add_offense_for_single_line(block_method, args)
+ def add_offense_for_single_line(block_node, location, args)
if args.children.empty?
- add_offense(block_method, :expression, SINGLE_NO_ARG_MSG)
+ add_offense(block_node, location, SINGLE_NO_ARG_MSG)
else
- add_offense(block_method, :expression, SINGLE_MSG)
+ add_offense(block_node, location, SINGLE_MSG)
end
end
def lambda_length(block_node)
start_line = block_node.loc.begin.line
end_line = block_node.loc.end.line
- end_line - start_line
+ end_line - start_line + 1
end
- def autocorrect(node)
- ancestor = node.ancestors.first
+ def correction(node)
+ lambda do |corrector|
+ block_method, _args = *node
- @corrections << lambda do |corrector|
- if node.loc.expression.source == 'lambda'
- autocorrect_old_to_new(corrector, ancestor)
+ if block_method.loc.expression.source == 'lambda'
+ autocorrect_old_to_new(corrector, node)
else
- autocorrect_new_to_old(corrector, ancestor)
+ autocorrect_new_to_old(corrector, node)
end
end
end
def autocorrect_new_to_old(corrector, node)
block_method, args = *node
+ # Avoid correcting to `lambdado` by inserting whitespace
+ # if none exists before or after the lambda arguments.
+ if needs_whitespace?(block_method, args, node)
+ corrector.insert_before(node.loc.begin, ' ')
+ end
corrector.replace(block_method.loc.expression, 'lambda')
+ corrector.remove(args.loc.expression) if args.loc.expression
return if args.children.empty?
-
arg_str = " |#{lambda_arg_string(args)}|"
- corrector.remove(args.loc.expression)
corrector.insert_after(node.loc.begin, arg_str)
end
def autocorrect_old_to_new(corrector, node)
block_method, args = *node
@@ -77,9 +83,18 @@
arg_str = "(#{lambda_arg_string(args)})"
whitespace_and_old_args = node.loc.begin.end.join(args.loc.end)
corrector.insert_after(block_method.loc.expression, arg_str)
corrector.remove(whitespace_and_old_args)
+ end
+
+ def needs_whitespace?(block_method, args, node)
+ selector_end = block_method.loc.selector.end.end_pos
+ args_begin = args.loc.begin && args.loc.begin.begin_pos
+ args_end = args.loc.end && args.loc.end.end_pos
+ block_begin = node.loc.begin.begin_pos
+ (block_begin == args_end && selector_end == args_begin) ||
+ (block_begin == selector_end)
end
def lambda_arg_string(args)
args.children.map { |a| a.loc.expression.source }.join(', ')
end