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