rubocop 0.36.0 → 0.37.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubocop might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +62 -2
- data/README.md +10 -1
- data/assets/output.html.erb +55 -1
- data/config/default.yml +9 -3
- data/config/disabled.yml +21 -0
- data/config/enabled.yml +11 -10
- data/lib/rubocop.rb +9 -2
- data/lib/rubocop/ast_node.rb +67 -19
- data/lib/rubocop/ast_node/builder.rb +1 -0
- data/lib/rubocop/ast_node/sexp.rb +1 -0
- data/lib/rubocop/ast_node/traversal.rb +171 -0
- data/lib/rubocop/cached_data.rb +4 -1
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/config.rb +36 -20
- data/lib/rubocop/config_loader.rb +6 -5
- data/lib/rubocop/cop/commissioner.rb +27 -18
- data/lib/rubocop/cop/cop.rb +7 -6
- data/lib/rubocop/cop/lint/duplicated_key.rb +1 -8
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +18 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +5 -1
- data/lib/rubocop/cop/lint/unneeded_disable.rb +1 -1
- data/lib/rubocop/cop/mixin/array_hash_indentation.rb +1 -0
- data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +9 -2
- data/lib/rubocop/cop/mixin/check_assignment.rb +1 -1
- data/lib/rubocop/cop/mixin/classish_length.rb +3 -4
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +8 -4
- data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +2 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +35 -0
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/min_body_length.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +58 -0
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -2
- data/lib/rubocop/cop/performance/case_when_splat.rb +7 -0
- data/lib/rubocop/cop/performance/casecmp.rb +56 -17
- data/lib/rubocop/cop/performance/redundant_block_call.rb +17 -3
- data/lib/rubocop/cop/performance/redundant_merge.rb +7 -1
- data/lib/rubocop/cop/performance/times_map.rb +3 -4
- data/lib/rubocop/cop/severity.rb +1 -1
- data/lib/rubocop/cop/style/align_hash.rb +1 -1
- data/lib/rubocop/cop/style/align_parameters.rb +1 -1
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/block_comments.rb +2 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +2 -0
- data/lib/rubocop/cop/style/copyright.rb +2 -2
- data/lib/rubocop/cop/style/documentation.rb +19 -29
- data/lib/rubocop/cop/style/each_with_object.rb +1 -1
- data/lib/rubocop/cop/style/else_alignment.rb +2 -2
- data/lib/rubocop/cop/style/encoding.rb +1 -1
- data/lib/rubocop/cop/style/first_parameter_indentation.rb +1 -1
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -12
- data/lib/rubocop/cop/style/guard_clause.rb +2 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -8
- data/lib/rubocop/cop/style/indent_assignment.rb +1 -1
- data/lib/rubocop/cop/style/indentation_width.rb +3 -7
- data/lib/rubocop/cop/style/method_call_parentheses.rb +2 -1
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/multiline_array_brace_layout.rb +3 -41
- data/lib/rubocop/cop/style/multiline_hash_brace_layout.rb +57 -0
- data/lib/rubocop/cop/style/multiline_method_call_brace_layout.rb +65 -0
- data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +5 -4
- data/lib/rubocop/cop/style/multiline_method_definition_brace_layout.rb +62 -0
- data/lib/rubocop/cop/style/multiline_operation_indentation.rb +9 -3
- data/lib/rubocop/cop/style/mutable_constant.rb +18 -3
- data/lib/rubocop/cop/style/nested_modifier.rb +5 -2
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -1
- data/lib/rubocop/cop/style/next.rb +32 -11
- data/lib/rubocop/cop/style/option_hash.rb +1 -1
- data/lib/rubocop/cop/style/redundant_freeze.rb +13 -3
- data/lib/rubocop/cop/style/redundant_parentheses.rb +33 -7
- data/lib/rubocop/cop/style/send.rb +1 -1
- data/lib/rubocop/cop/style/space_around_keyword.rb +198 -0
- data/lib/rubocop/cop/style/space_around_operators.rb +2 -12
- data/lib/rubocop/cop/style/space_inside_block_braces.rb +1 -1
- data/lib/rubocop/cop/style/special_global_vars.rb +4 -4
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/trailing_blank_lines.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +1 -0
- data/lib/rubocop/cop/style/trailing_comma_in_literal.rb +1 -0
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/zero_length_predicate.rb +55 -0
- data/lib/rubocop/cop/team.rb +30 -5
- data/lib/rubocop/cop/util.rb +16 -1
- data/lib/rubocop/cop/variable_force.rb +3 -12
- data/lib/rubocop/cop/variable_force/assignment.rb +3 -3
- data/lib/rubocop/cop/variable_force/locatable.rb +25 -6
- data/lib/rubocop/cop/variable_force/reference.rb +3 -3
- data/lib/rubocop/cop/variable_force/scope.rb +8 -7
- data/lib/rubocop/cop/variable_force/variable.rb +3 -3
- data/lib/rubocop/cop/variable_force/variable_table.rb +1 -1
- data/lib/rubocop/formatter/formatter_set.rb +2 -2
- data/lib/rubocop/node_pattern.rb +1 -1
- data/lib/rubocop/options.rb +10 -10
- data/lib/rubocop/path_util.rb +5 -0
- data/lib/rubocop/processed_source.rb +8 -2
- data/lib/rubocop/result_cache.rb +1 -1
- data/lib/rubocop/runner.rb +1 -1
- data/lib/rubocop/token.rb +2 -2
- data/lib/rubocop/version.rb +1 -1
- data/relnotes/v0.30.1.md +1 -0
- data/relnotes/v0.33.0.md +1 -1
- data/relnotes/v0.36.0.md +2 -1
- data/relnotes/v0.37.0.md +200 -0
- data/rubocop.gemspec +2 -1
- metadata +28 -7
- data/lib/rubocop/cop/style/space_after_control_keyword.rb +0 -35
- data/lib/rubocop/cop/style/space_before_modifier_keyword.rb +0 -38
@@ -25,6 +25,10 @@ module RuboCop
|
|
25
25
|
# end
|
26
26
|
class RedundantBlockCall < Cop
|
27
27
|
MSG = 'Use `yield` instead of `%s.call`.'.freeze
|
28
|
+
YIELD = 'yield'.freeze
|
29
|
+
OPEN_PAREN = '('.freeze
|
30
|
+
CLOSE_PAREN = ')'.freeze
|
31
|
+
SPACE = ' '.freeze
|
28
32
|
|
29
33
|
def_node_matcher :blockarg_def, <<-END
|
30
34
|
{(def _ (args ... (blockarg $_)) $_)
|
@@ -37,6 +41,7 @@ module RuboCop
|
|
37
41
|
|
38
42
|
def on_def(node)
|
39
43
|
blockarg_def(node) do |argname, body|
|
44
|
+
next unless body
|
40
45
|
blockarg_calls(body, argname) do |blockcall|
|
41
46
|
add_offense(blockcall, :expression, format(MSG, argname))
|
42
47
|
end
|
@@ -46,9 +51,18 @@ module RuboCop
|
|
46
51
|
# offenses are registered on the `block.call` nodes
|
47
52
|
def autocorrect(node)
|
48
53
|
_receiver, _method, *args = *node
|
49
|
-
new_source =
|
50
|
-
|
51
|
-
|
54
|
+
new_source = String.new(YIELD)
|
55
|
+
unless args.empty?
|
56
|
+
new_source += if parentheses?(node)
|
57
|
+
OPEN_PAREN
|
58
|
+
else
|
59
|
+
SPACE
|
60
|
+
end
|
61
|
+
|
62
|
+
new_source << args.map(&:source).join(', ')
|
63
|
+
end
|
64
|
+
|
65
|
+
new_source << CLOSE_PAREN if parentheses?(node)
|
52
66
|
->(corrector) { corrector.replace(node.source_range, new_source) }
|
53
67
|
end
|
54
68
|
end
|
@@ -15,13 +15,15 @@ module RuboCop
|
|
15
15
|
AREF_ASGN = '%s[%s] = %s'.freeze
|
16
16
|
MSG = 'Use `%s` instead of `%s`.'.freeze
|
17
17
|
|
18
|
-
def_node_matcher :redundant_merge,
|
18
|
+
def_node_matcher :redundant_merge,
|
19
|
+
'(send $_ {:merge! :update} (hash $...))'
|
19
20
|
def_node_matcher :modifier_flow_control, '[{if while until} #modifier?]'
|
20
21
|
|
21
22
|
def on_send(node)
|
22
23
|
redundant_merge(node) do |receiver, pairs|
|
23
24
|
next if node.value_used?
|
24
25
|
next if pairs.size > 1 && !receiver.pure?
|
26
|
+
next if pairs.size > max_key_value_pairs
|
25
27
|
|
26
28
|
assignments = to_assignments(receiver, pairs).join('; ')
|
27
29
|
message = format(MSG, assignments, node.source)
|
@@ -79,6 +81,10 @@ module RuboCop
|
|
79
81
|
def modifier?(node)
|
80
82
|
node.loc.respond_to?(:end) && node.loc.end.nil?
|
81
83
|
end
|
84
|
+
|
85
|
+
def max_key_value_pairs
|
86
|
+
cop_config['MaxKeyValuePairs'].to_i
|
87
|
+
end
|
82
88
|
end
|
83
89
|
end
|
84
90
|
end
|
@@ -33,15 +33,14 @@ module RuboCop
|
|
33
33
|
private
|
34
34
|
|
35
35
|
def check(node)
|
36
|
-
|
37
|
-
if map_or_collect
|
36
|
+
times_map_call(node) do |map_or_collect|
|
38
37
|
add_offense(node, :expression, format(MSG, map_or_collect))
|
39
38
|
end
|
40
39
|
end
|
41
40
|
|
42
41
|
def_node_matcher :times_map_call, <<-END
|
43
|
-
{(block (send (send
|
44
|
-
(send (send
|
42
|
+
{(block (send (send !nil :times) ${:map :collect}) ...)
|
43
|
+
(send (send !nil :times) ${:map :collect} (block_pass ...))}
|
45
44
|
END
|
46
45
|
end
|
47
46
|
end
|
data/lib/rubocop/cop/severity.rb
CHANGED
@@ -33,7 +33,7 @@ module RuboCop
|
|
33
33
|
def initialize(name_or_code)
|
34
34
|
name = Severity.name_from_code(name_or_code)
|
35
35
|
unless NAMES.include?(name)
|
36
|
-
|
36
|
+
raise ArgumentError, "Unknown severity: #{name}"
|
37
37
|
end
|
38
38
|
@name = name.freeze
|
39
39
|
freeze
|
@@ -234,7 +234,7 @@ module RuboCop
|
|
234
234
|
when 'key' then KeyAlignment.new
|
235
235
|
when 'table' then TableAlignment.new
|
236
236
|
when 'separator' then SeparatorAlignment.new
|
237
|
-
else
|
237
|
+
else raise "Unknown #{key}: #{cop_config[key]}"
|
238
238
|
end
|
239
239
|
end
|
240
240
|
|
@@ -23,6 +23,7 @@ module RuboCop
|
|
23
23
|
|
24
24
|
lambda do |corrector|
|
25
25
|
corrector.remove(eq_begin)
|
26
|
+
# rubocop:disable Style/ZeroLengthPredicate
|
26
27
|
unless contents.length == 0
|
27
28
|
corrector.replace(contents,
|
28
29
|
contents.source
|
@@ -30,6 +31,7 @@ module RuboCop
|
|
30
31
|
.gsub(/\n\n/, "\n#\n")
|
31
32
|
.gsub(/\n(?=[^\z#])/, "\n# "))
|
32
33
|
end
|
34
|
+
# rubocop:enable Style/ZeroLengthPredicate
|
33
35
|
corrector.remove(eq_end)
|
34
36
|
end
|
35
37
|
end
|
@@ -69,10 +69,10 @@ module RuboCop
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def autocorrect(token)
|
72
|
-
|
72
|
+
raise Warning, 'An AutocorrectNotice must be defined in ' \
|
73
73
|
'your RuboCop config' if autocorrect_notice.empty?
|
74
74
|
regex = Regexp.new(notice)
|
75
|
-
|
75
|
+
raise Warning, "AutocorrectNotice '#{autocorrect_notice}' must " \
|
76
76
|
"match Notice /#{notice}/" unless autocorrect_notice =~ regex
|
77
77
|
|
78
78
|
lambda do |corrector|
|
@@ -19,37 +19,29 @@ module RuboCop
|
|
19
19
|
|
20
20
|
def_node_matcher :constant_definition?, '{class module casgn}'
|
21
21
|
|
22
|
-
def
|
23
|
-
|
24
|
-
return unless
|
22
|
+
def on_class(node)
|
23
|
+
_name, _superclass, body = *node
|
24
|
+
return unless body
|
25
|
+
return if namespace?(body)
|
26
|
+
|
27
|
+
ast_with_comments = processed_source.ast_with_comments
|
28
|
+
return if associated_comment?(node, ast_with_comments)
|
29
|
+
return if nodoc_comment?(node, ast_with_comments)
|
30
|
+
add_offense(node, :keyword, format(MSG, :class))
|
31
|
+
end
|
25
32
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
)
|
33
|
+
def on_module(node)
|
34
|
+
_name, body = *node
|
35
|
+
return if namespace?(body)
|
30
36
|
|
31
|
-
|
37
|
+
ast_with_comments = processed_source.ast_with_comments
|
38
|
+
return if associated_comment?(node, ast_with_comments)
|
39
|
+
return if nodoc_comment?(node, ast_with_comments)
|
40
|
+
add_offense(node, :keyword, format(MSG, :module))
|
32
41
|
end
|
33
42
|
|
34
43
|
private
|
35
44
|
|
36
|
-
def check(ast, ast_with_comments)
|
37
|
-
ast.each_node(:class, :module) do |node|
|
38
|
-
case node.type
|
39
|
-
when :class
|
40
|
-
_name, _superclass, body = *node
|
41
|
-
when :module
|
42
|
-
_name, body = *node
|
43
|
-
end
|
44
|
-
|
45
|
-
next if node.type == :class && !body
|
46
|
-
next if namespace?(body)
|
47
|
-
next if associated_comment?(node, ast_with_comments)
|
48
|
-
next if nodoc?(node, ast_with_comments)
|
49
|
-
add_offense(node, :keyword, format(MSG, node.type.to_s))
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
45
|
def namespace?(body_node)
|
54
46
|
return false unless body_node
|
55
47
|
|
@@ -77,8 +69,6 @@ module RuboCop
|
|
77
69
|
end
|
78
70
|
|
79
71
|
def preceding_comments(node, ast_with_comments)
|
80
|
-
return [] unless node && ast_with_comments
|
81
|
-
|
82
72
|
ast_with_comments[node].select { |c| c.loc.line < node.loc.line }
|
83
73
|
end
|
84
74
|
|
@@ -93,7 +83,7 @@ module RuboCop
|
|
93
83
|
# proceeds to check its ancestors for :nodoc: all.
|
94
84
|
# Note: How end-of-line comments are associated with code changed in
|
95
85
|
# parser-2.2.0.4.
|
96
|
-
def
|
86
|
+
def nodoc_comment?(node, ast_with_comments, require_all = false)
|
97
87
|
return false unless node
|
98
88
|
nodoc_node = node.children.first
|
99
89
|
return false unless nodoc_node
|
@@ -104,7 +94,7 @@ module RuboCop
|
|
104
94
|
return true if comment.text =~ regex
|
105
95
|
end
|
106
96
|
|
107
|
-
|
97
|
+
nodoc_comment?(node.ancestors.first, ast_with_comments, true)
|
108
98
|
end
|
109
99
|
end
|
110
100
|
end
|
@@ -5,7 +5,7 @@ module RuboCop
|
|
5
5
|
module Cop
|
6
6
|
module Style
|
7
7
|
# This cop looks for inject / reduce calls where the passed in object is
|
8
|
-
# returned at the end and so could be
|
8
|
+
# returned at the end and so could be replaced by each_with_object without
|
9
9
|
# the need to return the object at the end.
|
10
10
|
#
|
11
11
|
# However, we can't replace with each_with_object if the accumulator
|
@@ -87,7 +87,7 @@ module RuboCop
|
|
87
87
|
return unless rhs
|
88
88
|
|
89
89
|
end_config = config.for_cop('Lint/EndAlignment')
|
90
|
-
style = end_config['
|
90
|
+
style = end_config['AlignWith'] || 'keyword'
|
91
91
|
base = variable_alignment?(node.loc, rhs, style.to_sym) ? node : rhs
|
92
92
|
|
93
93
|
return if rhs.type != :if
|
@@ -99,7 +99,7 @@ module RuboCop
|
|
99
99
|
def check_alignment(base_range, else_range)
|
100
100
|
return unless begins_its_line?(else_range)
|
101
101
|
|
102
|
-
@column_delta = base_range
|
102
|
+
@column_delta = effective_column(base_range) - else_range.column
|
103
103
|
return if @column_delta == 0
|
104
104
|
|
105
105
|
add_offense(else_range, else_range,
|
@@ -11,10 +11,9 @@ module RuboCop
|
|
11
11
|
# comment. The frozen string literal comment is only valid in Ruby 2.3+.
|
12
12
|
class FrozenStringLiteralComment < Cop
|
13
13
|
include ConfigurableEnforcedStyle
|
14
|
+
include FrozenStringLiteral
|
14
15
|
|
15
16
|
MSG = 'Missing frozen string literal comment.'.freeze
|
16
|
-
FROZEN_STRING_LITERAL = '# frozen_string_literal:'.freeze
|
17
|
-
FROZEN_STRING_LITERAL_ENABLED = '# frozen_string_literal: true'.freeze
|
18
17
|
SHEBANG = '#!'.freeze
|
19
18
|
|
20
19
|
def_node_matcher :frozen_strings, '{(send {dstr str} :<< ...)
|
@@ -30,8 +29,8 @@ module RuboCop
|
|
30
29
|
end
|
31
30
|
|
32
31
|
def on_send(node)
|
33
|
-
return if target_ruby_version < 2.3 && RUBY_VERSION < '2.3.0'
|
34
32
|
return unless style == :when_needed
|
33
|
+
return if target_ruby_version < 2.3
|
35
34
|
return if frozen_string_literal_comment_exists?(processed_source)
|
36
35
|
|
37
36
|
frozen_strings(node) { offense(processed_source) }
|
@@ -52,15 +51,6 @@ module RuboCop
|
|
52
51
|
|
53
52
|
private
|
54
53
|
|
55
|
-
def frozen_string_literal_comment_exists?(processed_source)
|
56
|
-
first_three_lines =
|
57
|
-
[processed_source[0], processed_source[1], processed_source[2]]
|
58
|
-
first_three_lines.compact!
|
59
|
-
first_three_lines.any? do |line|
|
60
|
-
line.start_with?(FROZEN_STRING_LITERAL)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
54
|
def last_special_comment(processed_source)
|
65
55
|
token_number = 0
|
66
56
|
if processed_source.tokens[token_number].text.start_with?(SHEBANG)
|
@@ -112,8 +112,9 @@ module RuboCop
|
|
112
112
|
def line_too_long?(node, body, keyword, condition)
|
113
113
|
max = config.for_cop('Metrics/LineLength')['Max'] || 80
|
114
114
|
indent = node.loc.column
|
115
|
+
source = body && body.source || ''
|
115
116
|
# 2 is for spaces on left and right of keyword
|
116
|
-
indent + (
|
117
|
+
indent + (source + keyword + condition.source).length + 2 > max
|
117
118
|
end
|
118
119
|
end
|
119
120
|
end
|
@@ -24,18 +24,11 @@ module RuboCop
|
|
24
24
|
return if modifier_if?(node)
|
25
25
|
return if elsif?(node)
|
26
26
|
return if if_else?(node)
|
27
|
-
return if chained?
|
27
|
+
return if node.chained?
|
28
28
|
return unless fit_within_line_as_modifier_form?(node)
|
29
29
|
add_offense(node, :keyword, message(node.loc.keyword.source))
|
30
30
|
end
|
31
31
|
|
32
|
-
def chained?(node)
|
33
|
-
# Don't register offense for `if ... end.method`
|
34
|
-
return false if node.parent.nil? || !node.parent.send_type?
|
35
|
-
receiver = node.parent.children[0]
|
36
|
-
node.equal?(receiver)
|
37
|
-
end
|
38
|
-
|
39
32
|
def parenthesize?(node)
|
40
33
|
# Parenthesize corrected expression if changing to modifier-if form
|
41
34
|
# would change the meaning of the parent expression
|
@@ -34,7 +34,7 @@ module RuboCop
|
|
34
34
|
return unless node.loc.operator
|
35
35
|
return if node.loc.operator.line == rhs.loc.line
|
36
36
|
|
37
|
-
base = node.source_range
|
37
|
+
base = display_column(node.source_range)
|
38
38
|
check_alignment([rhs], base + configured_indentation_width)
|
39
39
|
end
|
40
40
|
end
|
@@ -89,11 +89,7 @@ module RuboCop
|
|
89
89
|
*_, body = *args.first
|
90
90
|
|
91
91
|
def_end_config = config.for_cop('Lint/DefEndAlignment')
|
92
|
-
style =
|
93
|
-
def_end_config['AlignWith']
|
94
|
-
else
|
95
|
-
'start_of_line'
|
96
|
-
end
|
92
|
+
style = def_end_config['AlignWith'] || 'start_of_line'
|
97
93
|
base = style == 'def' ? args.first : node
|
98
94
|
|
99
95
|
check_indentation(base.source_range, body)
|
@@ -174,7 +170,7 @@ module RuboCop
|
|
174
170
|
return unless rhs
|
175
171
|
|
176
172
|
end_config = config.for_cop('Lint/EndAlignment')
|
177
|
-
style = end_config['
|
173
|
+
style = end_config['AlignWith'] || 'keyword'
|
178
174
|
base = variable_alignment?(node.loc, rhs, style.to_sym) ? node : rhs
|
179
175
|
|
180
176
|
case rhs.type
|
@@ -202,7 +198,7 @@ module RuboCop
|
|
202
198
|
def check_indentation(base_loc, body_node, style = 'normal')
|
203
199
|
return unless indentation_to_check?(base_loc, body_node)
|
204
200
|
|
205
|
-
indentation = body_node.loc.column - base_loc
|
201
|
+
indentation = body_node.loc.column - effective_column(base_loc)
|
206
202
|
@column_delta = configured_indentation_width - indentation
|
207
203
|
return if @column_delta == 0
|
208
204
|
|
@@ -19,6 +19,7 @@ module RuboCop
|
|
19
19
|
return unless args.empty? && node.loc.begin
|
20
20
|
return if same_name_assignment?(node)
|
21
21
|
return if lambda_call_syntax?(node)
|
22
|
+
return if node.keyword_not?
|
22
23
|
|
23
24
|
add_offense(node, :begin)
|
24
25
|
end
|
@@ -35,7 +36,7 @@ module RuboCop
|
|
35
36
|
def same_name_assignment?(node)
|
36
37
|
_receiver, method_name, *_args = *node
|
37
38
|
|
38
|
-
node.each_ancestor(ASGN_NODES).any? do |asgn_node|
|
39
|
+
node.each_ancestor(*ASGN_NODES).any? do |asgn_node|
|
39
40
|
if asgn_node.masgn_type?
|
40
41
|
mlhs_node, _mrhs_node = *asgn_node
|
41
42
|
asgn_node = mlhs_node.children[node.sibling_index]
|
@@ -38,6 +38,8 @@ module RuboCop
|
|
38
38
|
# :b
|
39
39
|
# ]
|
40
40
|
class MultilineArrayBraceLayout < Cop
|
41
|
+
include MultilineLiteralBraceLayout
|
42
|
+
|
41
43
|
SAME_LINE_MESSAGE = 'Closing array brace must be on the same line as ' \
|
42
44
|
'the last array element when opening brace is on the same line as ' \
|
43
45
|
'the first array element.'.freeze
|
@@ -47,47 +49,7 @@ module RuboCop
|
|
47
49
|
'from the first array element.'.freeze
|
48
50
|
|
49
51
|
def on_array(node)
|
50
|
-
|
51
|
-
return if node.children.empty? # Ignore empty arrays.
|
52
|
-
|
53
|
-
if opening_brace_on_same_line?(node)
|
54
|
-
return if closing_brace_on_same_line?(node)
|
55
|
-
|
56
|
-
add_offense(node, :expression, SAME_LINE_MESSAGE)
|
57
|
-
else
|
58
|
-
return unless closing_brace_on_same_line?(node)
|
59
|
-
|
60
|
-
add_offense(node, :expression, NEW_LINE_MESSAGE)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def autocorrect(node)
|
65
|
-
if closing_brace_on_same_line?(node)
|
66
|
-
lambda do |corrector|
|
67
|
-
corrector.insert_before(node.loc.end, "\n".freeze)
|
68
|
-
end
|
69
|
-
else
|
70
|
-
range = Parser::Source::Range.new(
|
71
|
-
node.source_range.source_buffer,
|
72
|
-
node.children.last.source_range.end_pos,
|
73
|
-
node.loc.end.begin_pos)
|
74
|
-
|
75
|
-
->(corrector) { corrector.remove(range) }
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
private
|
80
|
-
|
81
|
-
# This method depends on the fact that we have guarded
|
82
|
-
# against implicit and empty arrays.
|
83
|
-
def opening_brace_on_same_line?(node)
|
84
|
-
node.loc.begin.line == node.children.first.loc.first_line
|
85
|
-
end
|
86
|
-
|
87
|
-
# This method depends on the fact that we have guarded
|
88
|
-
# against implicit and empty arrays.
|
89
|
-
def closing_brace_on_same_line?(node)
|
90
|
-
node.loc.end.line == node.children.last.loc.last_line
|
52
|
+
check_brace_layout(node)
|
91
53
|
end
|
92
54
|
end
|
93
55
|
end
|