rubocop 1.6.1 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +48 -6
- data/lib/rubocop.rb +4 -0
- data/lib/rubocop/config.rb +8 -5
- data/lib/rubocop/config_loader.rb +10 -6
- data/lib/rubocop/config_loader_resolver.rb +21 -4
- data/lib/rubocop/config_obsoletion.rb +5 -3
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +3 -2
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +145 -0
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +19 -3
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +14 -0
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -10
- data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +64 -0
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +13 -10
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -2
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +59 -0
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +7 -2
- data/lib/rubocop/cop/lint/duplicate_branch.rb +64 -2
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +50 -17
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -11
- data/lib/rubocop/cop/lint/unreachable_loop.rb +17 -0
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +59 -5
- data/lib/rubocop/cop/registry.rb +10 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +3 -1
- data/lib/rubocop/cop/style/collection_methods.rb +14 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +22 -5
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/hash_except.rb +95 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +12 -2
- data/lib/rubocop/cop/style/lambda_call.rb +2 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +3 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +16 -6
- data/lib/rubocop/cop/style/method_def_parentheses.rb +7 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +26 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +3 -1
- data/lib/rubocop/cop/style/mutable_constant.rb +13 -3
- data/lib/rubocop/cop/style/raise_args.rb +2 -0
- data/lib/rubocop/cop/style/redundant_argument.rb +7 -1
- data/lib/rubocop/cop/style/redundant_freeze.rb +8 -4
- data/lib/rubocop/cop/style/single_line_methods.rb +4 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +5 -4
- data/lib/rubocop/cop/util.rb +3 -1
- data/lib/rubocop/options.rb +9 -9
- data/lib/rubocop/rspec/cop_helper.rb +0 -4
- data/lib/rubocop/rspec/expect_offense.rb +34 -22
- data/lib/rubocop/runner.rb +16 -1
- data/lib/rubocop/target_finder.rb +4 -2
- data/lib/rubocop/util.rb +16 -0
- data/lib/rubocop/version.rb +8 -2
- metadata +8 -3
@@ -106,23 +106,13 @@ module RuboCop
|
|
106
106
|
error && error.ancestors[1] == SystemCallError
|
107
107
|
end
|
108
108
|
|
109
|
-
def silence_warnings
|
110
|
-
# Replaces Kernel::silence_warnings since it hides any warnings,
|
111
|
-
# including the RuboCop ones
|
112
|
-
old_verbose = $VERBOSE
|
113
|
-
$VERBOSE = nil
|
114
|
-
yield
|
115
|
-
ensure
|
116
|
-
$VERBOSE = old_verbose
|
117
|
-
end
|
118
|
-
|
119
109
|
def evaluate_exceptions(group)
|
120
110
|
rescued_exceptions = group.exceptions
|
121
111
|
|
122
112
|
if rescued_exceptions.any?
|
123
113
|
rescued_exceptions.each_with_object([]) do |exception, converted|
|
124
114
|
begin
|
125
|
-
silence_warnings do
|
115
|
+
RuboCop::Util.silence_warnings do
|
126
116
|
# Avoid printing deprecation warnings about constants
|
127
117
|
converted << Kernel.const_get(exception.source)
|
128
118
|
end
|
@@ -9,6 +9,12 @@ module RuboCop
|
|
9
9
|
# In rare cases where only one iteration (or at most one iteration) is intended behavior,
|
10
10
|
# the code should be refactored to use `if` conditionals.
|
11
11
|
#
|
12
|
+
# NOTE: Block methods that are used with `Enumerable`s are considered to be loops.
|
13
|
+
#
|
14
|
+
# `IgnoredPatterns` can be used to match against the block receiver in order to allow
|
15
|
+
# code that would otherwise be registered as an offense (eg. `times` used not in an
|
16
|
+
# `Enumerable` context).
|
17
|
+
#
|
12
18
|
# @example
|
13
19
|
# # bad
|
14
20
|
# while node
|
@@ -70,7 +76,16 @@ module RuboCop
|
|
70
76
|
# raise NotFoundError
|
71
77
|
# end
|
72
78
|
#
|
79
|
+
# # bad
|
80
|
+
# 2.times { raise ArgumentError }
|
81
|
+
#
|
82
|
+
# @example IgnoredPatterns: [/(exactly|at_least|at_most)\(\d+\)\.times/] (default)
|
83
|
+
#
|
84
|
+
# # good
|
85
|
+
# exactly(2).times { raise StandardError }
|
73
86
|
class UnreachableLoop < Base
|
87
|
+
include IgnoredPattern
|
88
|
+
|
74
89
|
MSG = 'This loop will have at most one iteration.'
|
75
90
|
|
76
91
|
def on_while(node)
|
@@ -91,6 +106,8 @@ module RuboCop
|
|
91
106
|
return false unless node.block_type?
|
92
107
|
|
93
108
|
send_node = node.send_node
|
109
|
+
return false if matches_ignored_pattern?(send_node.source)
|
110
|
+
|
94
111
|
send_node.enumerable_method? || send_node.enumerator_method? || send_node.method?(:loop)
|
95
112
|
end
|
96
113
|
|
@@ -4,7 +4,9 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Naming
|
6
6
|
# This cop checks for memoized methods whose instance variable name
|
7
|
-
# does not match the method name.
|
7
|
+
# does not match the method name. Applies to both regular methods
|
8
|
+
# (defined with `def`) and dynamic methods (defined with
|
9
|
+
# `define_method` or `define_singleton_method`).
|
8
10
|
#
|
9
11
|
# This cop can be configured with the EnforcedStyleForLeadingUnderscores
|
10
12
|
# directive. It can be configured to allow for memoized instance variables
|
@@ -48,6 +50,17 @@ module RuboCop
|
|
48
50
|
# @foo ||= calculate_expensive_thing(helper_variable)
|
49
51
|
# end
|
50
52
|
#
|
53
|
+
# # good
|
54
|
+
# define_method(:foo) do
|
55
|
+
# @foo ||= calculate_expensive_thing
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# # good
|
59
|
+
# define_method(:foo) do
|
60
|
+
# return @foo if defined?(@foo)
|
61
|
+
# @foo = calculate_expensive_thing
|
62
|
+
# end
|
63
|
+
#
|
51
64
|
# @example EnforcedStyleForLeadingUnderscores: required
|
52
65
|
# # bad
|
53
66
|
# def foo
|
@@ -79,6 +92,17 @@ module RuboCop
|
|
79
92
|
# @_foo = calculate_expensive_thing
|
80
93
|
# end
|
81
94
|
#
|
95
|
+
# # good
|
96
|
+
# define_method(:foo) do
|
97
|
+
# @_foo ||= calculate_expensive_thing
|
98
|
+
# end
|
99
|
+
#
|
100
|
+
# # good
|
101
|
+
# define_method(:foo) do
|
102
|
+
# return @_foo if defined?(@_foo)
|
103
|
+
# @_foo = calculate_expensive_thing
|
104
|
+
# end
|
105
|
+
#
|
82
106
|
# @example EnforcedStyleForLeadingUnderscores :optional
|
83
107
|
# # bad
|
84
108
|
# def foo
|
@@ -105,6 +129,16 @@ module RuboCop
|
|
105
129
|
# return @_foo if defined?(@_foo)
|
106
130
|
# @_foo = calculate_expensive_thing
|
107
131
|
# end
|
132
|
+
#
|
133
|
+
# # good
|
134
|
+
# define_method(:foo) do
|
135
|
+
# @foo ||= calculate_expensive_thing
|
136
|
+
# end
|
137
|
+
#
|
138
|
+
# # good
|
139
|
+
# define_method(:foo) do
|
140
|
+
# @_foo ||= calculate_expensive_thing
|
141
|
+
# end
|
108
142
|
class MemoizedInstanceVariableName < Base
|
109
143
|
include ConfigurableEnforcedStyle
|
110
144
|
|
@@ -112,17 +146,27 @@ module RuboCop
|
|
112
146
|
'method name `%<method>s`. Use `@%<suggested_var>s` instead.'
|
113
147
|
UNDERSCORE_REQUIRED = 'Memoized variable `%<var>s` does not start ' \
|
114
148
|
'with `_`. Use `@%<suggested_var>s` instead.'
|
149
|
+
DYNAMIC_DEFINE_METHODS = %i[define_method define_singleton_method].to_set.freeze
|
150
|
+
|
151
|
+
def_node_matcher :method_definition?, <<~PATTERN
|
152
|
+
${
|
153
|
+
(block (send _ %DYNAMIC_DEFINE_METHODS ({sym str} $_)) ...)
|
154
|
+
(def $_ ...)
|
155
|
+
(defs _ $_ ...)
|
156
|
+
}
|
157
|
+
PATTERN
|
115
158
|
|
116
159
|
# rubocop:disable Metrics/AbcSize
|
117
160
|
def on_or_asgn(node)
|
118
161
|
lhs, _value = *node
|
119
162
|
return unless lhs.ivasgn_type?
|
120
|
-
|
163
|
+
|
164
|
+
method_node, method_name = find_definition(node)
|
165
|
+
return unless method_node
|
121
166
|
|
122
167
|
body = method_node.body
|
123
168
|
return unless body == node || body.children.last == node
|
124
169
|
|
125
|
-
method_name = method_node.method_name
|
126
170
|
return if matches?(method_name, lhs)
|
127
171
|
|
128
172
|
msg = format(
|
@@ -147,11 +191,10 @@ module RuboCop
|
|
147
191
|
arg = node.arguments.first
|
148
192
|
return unless arg.ivar_type?
|
149
193
|
|
150
|
-
method_node = node
|
194
|
+
method_node, method_name = find_definition(node)
|
151
195
|
return unless method_node
|
152
196
|
|
153
197
|
var_name = arg.children.first
|
154
|
-
method_name = method_node.method_name
|
155
198
|
defined_memoized?(method_node.body, var_name) do |defined_ivar, return_ivar, ivar_assign|
|
156
199
|
return if matches?(method_name, ivar_assign)
|
157
200
|
|
@@ -174,6 +217,17 @@ module RuboCop
|
|
174
217
|
'EnforcedStyleForLeadingUnderscores'
|
175
218
|
end
|
176
219
|
|
220
|
+
def find_definition(node)
|
221
|
+
# Methods can be defined in a `def` or `defs`,
|
222
|
+
# or dynamically via a `block` node.
|
223
|
+
node.each_ancestor(:def, :defs, :block).each do |ancestor|
|
224
|
+
method_node, method_name = method_definition?(ancestor)
|
225
|
+
return [method_node, method_name] if method_node
|
226
|
+
end
|
227
|
+
|
228
|
+
nil
|
229
|
+
end
|
230
|
+
|
177
231
|
def matches?(method_name, ivar_assign)
|
178
232
|
return true if ivar_assign.nil? || method_name == :initialize
|
179
233
|
|
data/lib/rubocop/cop/registry.rb
CHANGED
@@ -204,6 +204,12 @@ module RuboCop
|
|
204
204
|
to_h[cop_name].first
|
205
205
|
end
|
206
206
|
|
207
|
+
def freeze
|
208
|
+
clear_enrollment_queue
|
209
|
+
unqualified_cop_names # build cache
|
210
|
+
super
|
211
|
+
end
|
212
|
+
|
207
213
|
@global = new
|
208
214
|
|
209
215
|
class << self
|
@@ -228,6 +234,10 @@ module RuboCop
|
|
228
234
|
@global = previous
|
229
235
|
end
|
230
236
|
|
237
|
+
def self.reset!
|
238
|
+
@global = new
|
239
|
+
end
|
240
|
+
|
231
241
|
private
|
232
242
|
|
233
243
|
def initialize_copy(reg)
|
@@ -87,7 +87,9 @@ module RuboCop
|
|
87
87
|
return if allow_modifiers_on_symbols?(node)
|
88
88
|
|
89
89
|
if offense?(node)
|
90
|
-
add_offense(node.loc.selector)
|
90
|
+
add_offense(node.loc.selector) do
|
91
|
+
opposite_style_detected
|
92
|
+
end
|
91
93
|
else
|
92
94
|
correct_style_detected
|
93
95
|
end
|
@@ -48,7 +48,7 @@ module RuboCop
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def on_send(node)
|
51
|
-
return unless
|
51
|
+
return unless implicit_block?(node)
|
52
52
|
|
53
53
|
check_method_node(node)
|
54
54
|
end
|
@@ -64,9 +64,22 @@ module RuboCop
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
+
def implicit_block?(node)
|
68
|
+
return false unless node.arguments.any?
|
69
|
+
|
70
|
+
node.last_argument.block_pass_type? ||
|
71
|
+
node.last_argument.sym_type? && methods_accepting_symbol.include?(node.method_name.to_s)
|
72
|
+
end
|
73
|
+
|
67
74
|
def message(node)
|
68
75
|
format(MSG, prefer: preferred_method(node.method_name), current: node.method_name)
|
69
76
|
end
|
77
|
+
|
78
|
+
# Some enumerable methods accept a bare symbol (ie. _not_ Symbol#to_proc) instead
|
79
|
+
# of a block.
|
80
|
+
def methods_accepting_symbol
|
81
|
+
Array(cop_config['MethodsAcceptingSymbol'])
|
82
|
+
end
|
70
83
|
end
|
71
84
|
end
|
72
85
|
end
|
@@ -4,12 +4,15 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
6
|
# This cop checks for comments put on the same line as some keywords.
|
7
|
-
# These keywords are: `
|
7
|
+
# These keywords are: `class`, `module`, `def`, `begin`, `end`.
|
8
8
|
#
|
9
9
|
# Note that some comments
|
10
10
|
# (`:nodoc:`, `:yields:`, `rubocop:disable` and `rubocop:todo`)
|
11
11
|
# are allowed.
|
12
12
|
#
|
13
|
+
# Auto-correction removes comments from `end` keyword and keeps comments
|
14
|
+
# for `class`, `module`, `def` and `begin` above the keyword.
|
15
|
+
#
|
13
16
|
# @example
|
14
17
|
# # bad
|
15
18
|
# if condition
|
@@ -34,16 +37,17 @@ module RuboCop
|
|
34
37
|
# y
|
35
38
|
# end
|
36
39
|
class CommentedKeyword < Base
|
40
|
+
include RangeHelp
|
41
|
+
extend AutoCorrector
|
42
|
+
|
37
43
|
MSG = 'Do not place comments on the same line as the ' \
|
38
44
|
'`%<keyword>s` keyword.'
|
39
45
|
|
40
46
|
def on_new_investigation
|
41
47
|
processed_source.comments.each do |comment|
|
42
|
-
next unless (match = line(comment).match(/(?<keyword>\S+).*#/))
|
48
|
+
next unless (match = line(comment).match(/(?<keyword>\S+).*#/)) && offensive?(comment)
|
43
49
|
|
44
|
-
|
45
|
-
add_offense(comment, message: format(MSG, keyword: match[:keyword]))
|
46
|
-
end
|
50
|
+
register_offense(comment, match[:keyword])
|
47
51
|
end
|
48
52
|
end
|
49
53
|
|
@@ -60,6 +64,19 @@ module RuboCop
|
|
60
64
|
].freeze
|
61
65
|
ALLOWED_COMMENT_REGEXES = ALLOWED_COMMENTS.map { |c| /#\s*#{c}/ }.freeze
|
62
66
|
|
67
|
+
def register_offense(comment, matched_keyword)
|
68
|
+
add_offense(comment, message: format(MSG, keyword: matched_keyword)) do |corrector|
|
69
|
+
range = range_with_surrounding_space(range: comment.loc.expression, newlines: false)
|
70
|
+
corrector.remove(range)
|
71
|
+
|
72
|
+
unless matched_keyword == 'end'
|
73
|
+
corrector.insert_before(
|
74
|
+
range.source_buffer.line_range(comment.loc.line), "#{comment.text}\n"
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
63
80
|
def offensive?(comment)
|
64
81
|
line = line(comment)
|
65
82
|
KEYWORD_REGEXES.any? { |r| r.match?(line) } &&
|
@@ -51,6 +51,7 @@ module RuboCop
|
|
51
51
|
if style == :each
|
52
52
|
add_offense(node, message: PREFER_EACH) do |corrector|
|
53
53
|
ForToEachCorrector.new(node).call(corrector)
|
54
|
+
opposite_style_detected
|
54
55
|
end
|
55
56
|
else
|
56
57
|
correct_style_detected
|
@@ -63,6 +64,7 @@ module RuboCop
|
|
63
64
|
if style == :for
|
64
65
|
add_offense(node, message: PREFER_FOR) do |corrector|
|
65
66
|
EachToForCorrector.new(node).call(corrector)
|
67
|
+
opposite_style_detected
|
66
68
|
end
|
67
69
|
else
|
68
70
|
correct_style_detected
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for usages of `Hash#reject`, `Hash#select`, and `Hash#filter` methods
|
7
|
+
# that can be replaced with `Hash#except` method.
|
8
|
+
#
|
9
|
+
# This cop should only be enabled on Ruby version 3.0 or higher.
|
10
|
+
# (`Hash#except` was added in Ruby 3.0.)
|
11
|
+
#
|
12
|
+
# For safe detection, it is limited to commonly used string and symbol comparisons
|
13
|
+
# when used `==`.
|
14
|
+
# And do not check `Hash#delete_if` and `Hash#keep_if` to change receiver object.
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
#
|
18
|
+
# # bad
|
19
|
+
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| k == :bar }
|
20
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| k != :bar }
|
21
|
+
# {foo: 1, bar: 2, baz: 3}.filter {|k, v| k != :bar }
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# {foo: 1, bar: 2, baz: 3}.except(:bar)
|
25
|
+
#
|
26
|
+
class HashExcept < Base
|
27
|
+
include RangeHelp
|
28
|
+
extend TargetRubyVersion
|
29
|
+
extend AutoCorrector
|
30
|
+
|
31
|
+
minimum_target_ruby_version 3.0
|
32
|
+
|
33
|
+
MSG = 'Use `%<prefer>s` instead.'
|
34
|
+
RESTRICT_ON_SEND = %i[reject select filter].freeze
|
35
|
+
|
36
|
+
def_node_matcher :bad_method?, <<~PATTERN
|
37
|
+
(block
|
38
|
+
(send _ _)
|
39
|
+
(args
|
40
|
+
(arg _)
|
41
|
+
(arg _))
|
42
|
+
(send
|
43
|
+
_ {:== :!= :eql?} _))
|
44
|
+
PATTERN
|
45
|
+
|
46
|
+
def on_send(node)
|
47
|
+
block = node.parent
|
48
|
+
return unless bad_method?(block) && semantically_except_method?(node, block)
|
49
|
+
|
50
|
+
except_key = except_key(block)
|
51
|
+
return unless safe_to_register_offense?(block, except_key)
|
52
|
+
|
53
|
+
range = offense_range(node)
|
54
|
+
preferred_method = "except(#{except_key.source})"
|
55
|
+
|
56
|
+
add_offense(range, message: format(MSG, prefer: preferred_method)) do |corrector|
|
57
|
+
corrector.replace(range, preferred_method)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def semantically_except_method?(send, block)
|
64
|
+
body = block.body
|
65
|
+
|
66
|
+
case send.method_name
|
67
|
+
when :reject
|
68
|
+
body.method?('==') || body.method?('eql?')
|
69
|
+
when :select, :filter
|
70
|
+
body.method?('!=')
|
71
|
+
else
|
72
|
+
false
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def safe_to_register_offense?(block, except_key)
|
77
|
+
return true if block.body.method?('eql?')
|
78
|
+
|
79
|
+
except_key.sym_type? || except_key.str_type?
|
80
|
+
end
|
81
|
+
|
82
|
+
def except_key(node)
|
83
|
+
key_argument = node.argument_list.first
|
84
|
+
lhs, _method_name, rhs = *node.body
|
85
|
+
|
86
|
+
[lhs, rhs].find { |operand| operand.source != key_argument.source }
|
87
|
+
end
|
88
|
+
|
89
|
+
def offense_range(node)
|
90
|
+
range_between(node.loc.selector.begin_pos, node.parent.loc.end.end_pos)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -21,6 +21,16 @@ module RuboCop
|
|
21
21
|
# # body omitted
|
22
22
|
# end
|
23
23
|
#
|
24
|
+
# # bad
|
25
|
+
# do_something do |first: false, second:, third: 10|
|
26
|
+
# # body omitted
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# # good
|
30
|
+
# do_something do |second:, first: false, third: 10|
|
31
|
+
# # body omitted
|
32
|
+
# end
|
33
|
+
#
|
24
34
|
class KeywordParametersOrder < Base
|
25
35
|
include RangeHelp
|
26
36
|
extend AutoCorrector
|
@@ -35,7 +45,7 @@ module RuboCop
|
|
35
45
|
if node.parent.find(&:kwoptarg_type?) == node
|
36
46
|
corrector.insert_before(node, "#{kwarg_nodes.map(&:source).join(', ')}, ")
|
37
47
|
|
38
|
-
arguments = node.each_ancestor(:def, :defs).first.arguments
|
48
|
+
arguments = node.each_ancestor(:def, :defs, :block).first.arguments
|
39
49
|
append_newline_to_last_kwoptarg(arguments, corrector) unless parentheses?(arguments)
|
40
50
|
|
41
51
|
remove_kwargs(kwarg_nodes, corrector)
|
@@ -50,7 +60,7 @@ module RuboCop
|
|
50
60
|
return if last_argument.kwrestarg_type? || last_argument.blockarg_type?
|
51
61
|
|
52
62
|
last_kwoptarg = arguments.reverse.find(&:kwoptarg_type?)
|
53
|
-
corrector.insert_after(last_kwoptarg, "\n")
|
63
|
+
corrector.insert_after(last_kwoptarg, "\n") unless arguments.parent.block_type?
|
54
64
|
end
|
55
65
|
|
56
66
|
def remove_kwargs(kwarg_nodes, corrector)
|