rubocop 1.5.2 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +5 -2
- data/config/obsoletion.yml +196 -0
- data/lib/rubocop.rb +10 -0
- data/lib/rubocop/cli/command/suggest_extensions.rb +16 -44
- data/lib/rubocop/config_obsoletion.rb +63 -263
- data/lib/rubocop/config_obsoletion/changed_enforced_styles.rb +33 -0
- data/lib/rubocop/config_obsoletion/changed_parameter.rb +21 -0
- data/lib/rubocop/config_obsoletion/cop_rule.rb +34 -0
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +44 -0
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +44 -0
- data/lib/rubocop/config_obsoletion/removed_cop.rb +41 -0
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +34 -0
- data/lib/rubocop/config_obsoletion/rule.rb +41 -0
- data/lib/rubocop/config_obsoletion/split_cop.rb +27 -0
- data/lib/rubocop/config_validator.rb +11 -4
- data/lib/rubocop/cop/base.rb +17 -15
- data/lib/rubocop/cop/cop.rb +2 -2
- data/lib/rubocop/cop/correctors/string_literal_corrector.rb +6 -8
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +6 -16
- data/lib/rubocop/cop/migration/department_name.rb +1 -1
- data/lib/rubocop/cop/mixin/string_help.rb +4 -1
- data/lib/rubocop/cop/naming/accessor_method_name.rb +15 -1
- data/lib/rubocop/cop/style/character_literal.rb +10 -11
- data/lib/rubocop/cop/style/float_division.rb +44 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +4 -0
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
- data/lib/rubocop/cop/style/perl_backrefs.rb +86 -9
- data/lib/rubocop/cop/style/redundant_argument.rb +14 -1
- data/lib/rubocop/cop/style/single_line_block_params.rb +30 -7
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +12 -6
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -13
- data/lib/rubocop/cop/style/string_concatenation.rb +19 -0
- data/lib/rubocop/cop/style/string_literals.rb +14 -8
- data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +4 -3
- data/lib/rubocop/formatter/emacs_style_formatter.rb +2 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +2 -0
- data/lib/rubocop/formatter/tap_formatter.rb +2 -0
- data/lib/rubocop/lockfile.rb +40 -0
- data/lib/rubocop/version.rb +1 -1
- metadata +14 -3
@@ -58,12 +58,13 @@ module RuboCop
|
|
58
58
|
# bar: "0000000000",
|
59
59
|
# baz: "0000000000",
|
60
60
|
# }
|
61
|
-
class LineLength <
|
61
|
+
class LineLength < Base
|
62
62
|
include CheckLineBreakable
|
63
63
|
include ConfigurableMax
|
64
64
|
include IgnoredPattern
|
65
65
|
include RangeHelp
|
66
66
|
include LineLengthHelp
|
67
|
+
extend AutoCorrector
|
67
68
|
|
68
69
|
MSG = 'Line is too long. [%<length>d/%<max>d]'
|
69
70
|
|
@@ -78,28 +79,16 @@ module RuboCop
|
|
78
79
|
alias on_hash on_potential_breakable_node
|
79
80
|
alias on_send on_potential_breakable_node
|
80
81
|
|
81
|
-
def
|
82
|
+
def on_new_investigation
|
82
83
|
check_for_breakable_semicolons(processed_source)
|
83
84
|
end
|
84
85
|
|
85
|
-
def
|
86
|
+
def on_investigation_end
|
86
87
|
processed_source.lines.each_with_index do |line, line_index|
|
87
88
|
check_line(line, line_index)
|
88
89
|
end
|
89
90
|
end
|
90
91
|
|
91
|
-
def correctable?
|
92
|
-
super && !breakable_range.nil?
|
93
|
-
end
|
94
|
-
|
95
|
-
def autocorrect(range)
|
96
|
-
return if range.nil?
|
97
|
-
|
98
|
-
lambda do |corrector|
|
99
|
-
corrector.insert_before(range, "\n")
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
92
|
private
|
104
93
|
|
105
94
|
attr_accessor :breakable_range
|
@@ -203,8 +192,9 @@ module RuboCop
|
|
203
192
|
|
204
193
|
self.breakable_range = breakable_range_by_line_index[line_index]
|
205
194
|
|
206
|
-
add_offense(
|
195
|
+
add_offense(loc, message: message) do |corrector|
|
207
196
|
self.max = line_length(line)
|
197
|
+
corrector.insert_before(breakable_range, "\n") unless breakable_range.nil?
|
208
198
|
end
|
209
199
|
end
|
210
200
|
|
@@ -71,7 +71,7 @@ module RuboCop
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def qualified_legacy_cop_name(cop_name)
|
74
|
-
legacy_cop_names = RuboCop::ConfigObsoletion
|
74
|
+
legacy_cop_names = RuboCop::ConfigObsoletion.legacy_cop_names
|
75
75
|
|
76
76
|
legacy_cop_names.detect do |legacy_cop_name|
|
77
77
|
legacy_cop_name.split('/')[1] == cop_name
|
@@ -14,7 +14,10 @@ module RuboCop
|
|
14
14
|
return if part_of_ignored_node?(node)
|
15
15
|
|
16
16
|
if offense?(node)
|
17
|
-
add_offense(node)
|
17
|
+
add_offense(node) do |corrector|
|
18
|
+
opposite_style_detected
|
19
|
+
autocorrect(corrector, node) if respond_to?(:autocorrect, true)
|
20
|
+
end
|
18
21
|
else
|
19
22
|
correct_style_detected
|
20
23
|
end
|
@@ -3,7 +3,13 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Naming
|
6
|
-
# This cop makes sure that accessor methods are named properly.
|
6
|
+
# This cop makes sure that accessor methods are named properly. Applies
|
7
|
+
# to both instance and class methods.
|
8
|
+
#
|
9
|
+
# NOTE: Offenses are only registered for methods with the expected
|
10
|
+
# arity. Getters (`get_attribute`) must have no arguments to be
|
11
|
+
# registered, and setters (`set_attribute(value)`) must have exactly
|
12
|
+
# one.
|
7
13
|
#
|
8
14
|
# @example
|
9
15
|
# # bad
|
@@ -21,6 +27,14 @@ module RuboCop
|
|
21
27
|
# # good
|
22
28
|
# def attribute
|
23
29
|
# end
|
30
|
+
#
|
31
|
+
# # accepted, incorrect arity for getter
|
32
|
+
# def get_value(attr)
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# # accepted, incorrect arity for setter
|
36
|
+
# def set_value
|
37
|
+
# end
|
24
38
|
class AccessorMethodName < Base
|
25
39
|
MSG_READER = 'Do not prefix reader method names with `get_`.'
|
26
40
|
MSG_WRITER = 'Do not prefix writer method names with `set_`.'
|
@@ -14,8 +14,9 @@ module RuboCop
|
|
14
14
|
#
|
15
15
|
# # good
|
16
16
|
# ?\C-\M-d
|
17
|
-
class CharacterLiteral <
|
17
|
+
class CharacterLiteral < Base
|
18
18
|
include StringHelp
|
19
|
+
extend AutoCorrector
|
19
20
|
|
20
21
|
MSG = 'Do not use the character literal - ' \
|
21
22
|
'use string literal instead.'
|
@@ -26,17 +27,15 @@ module RuboCop
|
|
26
27
|
node.source.size.between?(2, 3)
|
27
28
|
end
|
28
29
|
|
29
|
-
def autocorrect(node)
|
30
|
-
|
31
|
-
string = node.source[1..-1]
|
30
|
+
def autocorrect(corrector, node)
|
31
|
+
string = node.source[1..-1]
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
33
|
+
# special character like \n
|
34
|
+
# or ' which needs to use "" or be escaped.
|
35
|
+
if string.length == 2 || string == "'"
|
36
|
+
corrector.replace(node, %("#{string}"))
|
37
|
+
elsif string.length == 1 # normal character
|
38
|
+
corrector.replace(node, "'#{string}'")
|
40
39
|
end
|
41
40
|
end
|
42
41
|
|
@@ -41,6 +41,8 @@ module RuboCop
|
|
41
41
|
# a.fdiv(b)
|
42
42
|
class FloatDivision < Base
|
43
43
|
include ConfigurableEnforcedStyle
|
44
|
+
extend AutoCorrector
|
45
|
+
|
44
46
|
MESSAGES = {
|
45
47
|
left_coerce: 'Prefer using `.to_f` on the left side.',
|
46
48
|
right_coerce: 'Prefer using `.to_f` on the right side.',
|
@@ -64,7 +66,20 @@ module RuboCop
|
|
64
66
|
PATTERN
|
65
67
|
|
66
68
|
def on_send(node)
|
67
|
-
|
69
|
+
return unless offense_condition?(node)
|
70
|
+
|
71
|
+
add_offense(node) do |corrector|
|
72
|
+
case style
|
73
|
+
when :left_coerce, :single_coerce
|
74
|
+
add_to_f_method(corrector, node.receiver)
|
75
|
+
remove_to_f_method(corrector, node.first_argument)
|
76
|
+
when :right_coerce
|
77
|
+
remove_to_f_method(corrector, node.receiver)
|
78
|
+
add_to_f_method(corrector, node.first_argument)
|
79
|
+
when :fdiv
|
80
|
+
correct_from_slash_to_fdiv(corrector, node, node.receiver, node.first_argument)
|
81
|
+
end
|
82
|
+
end
|
68
83
|
end
|
69
84
|
|
70
85
|
private
|
@@ -87,6 +102,34 @@ module RuboCop
|
|
87
102
|
def message(_node)
|
88
103
|
MESSAGES[style]
|
89
104
|
end
|
105
|
+
|
106
|
+
def add_to_f_method(corrector, node)
|
107
|
+
corrector.insert_after(node, '.to_f') unless node.send_type? && node.method?(:to_f)
|
108
|
+
end
|
109
|
+
|
110
|
+
def remove_to_f_method(corrector, send_node)
|
111
|
+
corrector.remove(send_node.loc.dot)
|
112
|
+
corrector.remove(send_node.loc.selector)
|
113
|
+
end
|
114
|
+
|
115
|
+
def correct_from_slash_to_fdiv(corrector, node, receiver, argument)
|
116
|
+
receiver_source = extract_receiver_source(receiver)
|
117
|
+
argument_source = extract_receiver_source(argument)
|
118
|
+
|
119
|
+
if argument.respond_to?(:parenthesized?) && !argument.parenthesized?
|
120
|
+
argument_source = "(#{argument_source})"
|
121
|
+
end
|
122
|
+
|
123
|
+
corrector.replace(node, "#{receiver_source}.fdiv#{argument_source}")
|
124
|
+
end
|
125
|
+
|
126
|
+
def extract_receiver_source(node)
|
127
|
+
if node.send_type? && node.method?(:to_f)
|
128
|
+
node.receiver.source
|
129
|
+
else
|
130
|
+
node.source
|
131
|
+
end
|
132
|
+
end
|
90
133
|
end
|
91
134
|
end
|
92
135
|
end
|
@@ -46,6 +46,10 @@ module RuboCop
|
|
46
46
|
MSG_USE_NORMAL =
|
47
47
|
'Modifier form of `%<keyword>s` makes the line too long.'
|
48
48
|
|
49
|
+
def self.autocorrect_incompatible_with
|
50
|
+
[Style::SoleNestedConditional]
|
51
|
+
end
|
52
|
+
|
49
53
|
def on_if(node)
|
50
54
|
msg = if single_line_as_modifier?(node) && !named_capture_in_condition?(node)
|
51
55
|
MSG_USE_MODIFIER
|
@@ -4,7 +4,8 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
6
|
# This cop looks for uses of Perl-style regexp match
|
7
|
-
# backreferences
|
7
|
+
# backreferences and their English versions like
|
8
|
+
# $1, $2, $&, &+, $MATCH, $PREMATCH, etc.
|
8
9
|
#
|
9
10
|
# @example
|
10
11
|
# # bad
|
@@ -15,19 +16,95 @@ module RuboCop
|
|
15
16
|
class PerlBackrefs < Base
|
16
17
|
extend AutoCorrector
|
17
18
|
|
18
|
-
|
19
|
+
MESSAGE_FORMAT = 'Prefer `%<preferred_expression>s` over `%<original_expression>s`.'
|
20
|
+
|
21
|
+
def on_back_ref(node)
|
22
|
+
on_back_ref_or_gvar_or_nth_ref(node)
|
23
|
+
end
|
24
|
+
|
25
|
+
def on_gvar(node)
|
26
|
+
on_back_ref_or_gvar_or_nth_ref(node)
|
27
|
+
end
|
19
28
|
|
20
29
|
def on_nth_ref(node)
|
21
|
-
|
22
|
-
|
23
|
-
parent_type = node.parent ? node.parent.type : nil
|
30
|
+
on_back_ref_or_gvar_or_nth_ref(node)
|
31
|
+
end
|
24
32
|
|
25
|
-
|
26
|
-
|
33
|
+
private
|
34
|
+
|
35
|
+
# @private
|
36
|
+
# @param [RuboCop::AST::Node] node
|
37
|
+
# @return [Boolean]
|
38
|
+
def derived_from_braceless_interpolation?(node)
|
39
|
+
%i[
|
40
|
+
dstr
|
41
|
+
regexp
|
42
|
+
xstr
|
43
|
+
].include?(node.parent&.type)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @private
|
47
|
+
# @param [RuboCop::AST::Node] node
|
48
|
+
# @param [String] preferred_expression
|
49
|
+
# @return [String]
|
50
|
+
def format_message(node:, preferred_expression:)
|
51
|
+
original_expression = original_expression_of(node)
|
52
|
+
format(
|
53
|
+
MESSAGE_FORMAT,
|
54
|
+
original_expression: original_expression,
|
55
|
+
preferred_expression: preferred_expression
|
56
|
+
)
|
57
|
+
end
|
27
58
|
|
28
|
-
|
29
|
-
|
59
|
+
# @private
|
60
|
+
# @param [RuboCop::AST::Node] node
|
61
|
+
# @return [String]
|
62
|
+
def original_expression_of(node)
|
63
|
+
first = node.to_a.first
|
64
|
+
if first.is_a?(::Integer)
|
65
|
+
"$#{first}"
|
66
|
+
else
|
67
|
+
first.to_s
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# @private
|
72
|
+
# @param [RuboCop::AST::Node] node
|
73
|
+
# @return [String, nil]
|
74
|
+
def preferred_expression_to(node)
|
75
|
+
first = node.to_a.first
|
76
|
+
case first
|
77
|
+
when ::Integer
|
78
|
+
"Regexp.last_match(#{first})"
|
79
|
+
when :$&, :$MATCH
|
80
|
+
'Regexp.last_match(0)'
|
81
|
+
when :$`, :$PREMATCH
|
82
|
+
'Regexp.last_match.pre_match'
|
83
|
+
when :$', :$POSTMATCH
|
84
|
+
'Regexp.last_match.post_match'
|
85
|
+
when :$+, :$LAST_PAREN_MATCH
|
86
|
+
'Regexp.last_match(-1)'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# @private
|
91
|
+
# @param [RuboCop::AST::Node] node
|
92
|
+
def on_back_ref_or_gvar_or_nth_ref(node)
|
93
|
+
preferred_expression = preferred_expression_to(node)
|
94
|
+
return unless preferred_expression
|
95
|
+
|
96
|
+
add_offense(
|
97
|
+
node,
|
98
|
+
message: format_message(
|
99
|
+
node: node,
|
100
|
+
preferred_expression: preferred_expression
|
101
|
+
)
|
102
|
+
) do |corrector|
|
103
|
+
if derived_from_braceless_interpolation?(node)
|
104
|
+
preferred_expression = "{#{preferred_expression}}"
|
30
105
|
end
|
106
|
+
|
107
|
+
corrector.replace(node, preferred_expression)
|
31
108
|
end
|
32
109
|
end
|
33
110
|
end
|
@@ -37,6 +37,9 @@ module RuboCop
|
|
37
37
|
# "first second".split
|
38
38
|
# A.foo
|
39
39
|
class RedundantArgument < Base
|
40
|
+
include RangeHelp
|
41
|
+
extend AutoCorrector
|
42
|
+
|
40
43
|
MSG = 'Argument %<arg>s is redundant because it is implied by default.'
|
41
44
|
|
42
45
|
def on_send(node)
|
@@ -44,7 +47,9 @@ module RuboCop
|
|
44
47
|
return if node.arguments.count != 1
|
45
48
|
return unless redundant_argument?(node)
|
46
49
|
|
47
|
-
add_offense(node, message: format(MSG, arg: node.arguments.first.source))
|
50
|
+
add_offense(node, message: format(MSG, arg: node.arguments.first.source)) do |corrector|
|
51
|
+
corrector.remove(argument_range(node))
|
52
|
+
end
|
48
53
|
end
|
49
54
|
|
50
55
|
private
|
@@ -69,6 +74,14 @@ module RuboCop
|
|
69
74
|
Parser::CurrentRuby.new(builder).parse(buffer)
|
70
75
|
end
|
71
76
|
end
|
77
|
+
|
78
|
+
def argument_range(node)
|
79
|
+
if node.parenthesized?
|
80
|
+
range_between(node.loc.begin.begin_pos, node.loc.end.end_pos)
|
81
|
+
else
|
82
|
+
range_with_surrounding_space(range: node.first_argument.source_range, newlines: false)
|
83
|
+
end
|
84
|
+
end
|
72
85
|
end
|
73
86
|
end
|
74
87
|
end
|
@@ -29,6 +29,8 @@ module RuboCop
|
|
29
29
|
# c + d
|
30
30
|
# end
|
31
31
|
class SingleLineBlockParams < Base
|
32
|
+
extend AutoCorrector
|
33
|
+
|
32
34
|
MSG = 'Name `%<method>s` block params `|%<params>s|`.'
|
33
35
|
|
34
36
|
def on_block(node)
|
@@ -37,20 +39,41 @@ module RuboCop
|
|
37
39
|
return unless eligible_method?(node)
|
38
40
|
return unless eligible_arguments?(node)
|
39
41
|
|
40
|
-
|
42
|
+
method_name = node.send_node.method_name
|
43
|
+
return if args_match?(method_name, node.arguments)
|
44
|
+
|
45
|
+
preferred_block_arguments = build_preferred_arguments_map(node, target_args(method_name))
|
46
|
+
joined_block_arguments = preferred_block_arguments.values.join(', ')
|
41
47
|
|
42
|
-
message =
|
48
|
+
message = format(MSG, method: method_name, params: joined_block_arguments)
|
43
49
|
|
44
|
-
add_offense(node.arguments, message: message)
|
50
|
+
add_offense(node.arguments, message: message) do |corrector|
|
51
|
+
autocorrect(corrector, node, preferred_block_arguments, joined_block_arguments)
|
52
|
+
end
|
45
53
|
end
|
46
54
|
|
47
55
|
private
|
48
56
|
|
49
|
-
def
|
50
|
-
|
51
|
-
arguments
|
57
|
+
def build_preferred_arguments_map(node, preferred_arguments)
|
58
|
+
preferred_arguments_map = {}
|
59
|
+
node.arguments.each_with_index do |current_lvar, index|
|
60
|
+
preferred_argument = preferred_arguments[index]
|
61
|
+
current_argument = current_lvar.source
|
62
|
+
preferred_argument = "_#{preferred_argument}" if current_argument.start_with?('_')
|
63
|
+
preferred_arguments_map[current_argument] = preferred_argument
|
64
|
+
end
|
65
|
+
|
66
|
+
preferred_arguments_map
|
67
|
+
end
|
68
|
+
|
69
|
+
def autocorrect(corrector, node, preferred_block_arguments, joined_block_arguments)
|
70
|
+
corrector.replace(node.arguments, "|#{joined_block_arguments}|")
|
52
71
|
|
53
|
-
|
72
|
+
node.each_descendant(:lvar) do |lvar|
|
73
|
+
if (preferred_lvar = preferred_block_arguments[lvar.source])
|
74
|
+
corrector.replace(lvar, preferred_lvar)
|
75
|
+
end
|
76
|
+
end
|
54
77
|
end
|
55
78
|
|
56
79
|
def eligible_arguments?(node)
|