rubocop 1.5.2 → 1.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +3 -2
- data/config/default.yml +112 -16
- data/config/obsoletion.yml +196 -0
- data/lib/rubocop.rb +20 -1
- data/lib/rubocop/cli/command/suggest_extensions.rb +16 -44
- data/lib/rubocop/comment_config.rb +6 -6
- data/lib/rubocop/config.rb +8 -5
- data/lib/rubocop/config_loader.rb +11 -7
- data/lib/rubocop/config_loader_resolver.rb +21 -4
- data/lib/rubocop/config_obsoletion.rb +64 -262
- 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/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/empty_lines_around_attribute_accessor.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +14 -0
- data/lib/rubocop/cop/layout/line_length.rb +6 -16
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -2
- 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 +62 -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/deprecated_constants.rb +75 -0
- data/lib/rubocop/cop/lint/duplicate_branch.rb +64 -2
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +44 -0
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +10 -6
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +2 -1
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +50 -0
- 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/migration/department_name.rb +1 -1
- data/lib/rubocop/cop/mixin/allowed_identifiers.rb +18 -0
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -10
- data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -1
- data/lib/rubocop/cop/mixin/string_help.rb +4 -1
- data/lib/rubocop/cop/mixin/uncommunicative_name.rb +5 -1
- data/lib/rubocop/cop/naming/accessor_method_name.rb +15 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +59 -5
- data/lib/rubocop/cop/naming/variable_name.rb +2 -0
- data/lib/rubocop/cop/naming/variable_number.rb +1 -8
- data/lib/rubocop/cop/registry.rb +10 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +3 -1
- data/lib/rubocop/cop/style/character_literal.rb +10 -11
- 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/empty_literal.rb +6 -2
- data/lib/rubocop/cop/style/endless_method.rb +102 -0
- data/lib/rubocop/cop/style/explicit_block_argument.rb +10 -0
- data/lib/rubocop/cop/style/float_division.rb +44 -1
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/hash_except.rb +95 -0
- data/lib/rubocop/cop/style/hash_like_case.rb +2 -1
- data/lib/rubocop/cop/style/if_inside_else.rb +8 -3
- 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/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 +7 -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/nested_parenthesized_calls.rb +4 -0
- data/lib/rubocop/cop/style/perl_backrefs.rb +86 -9
- data/lib/rubocop/cop/style/raise_args.rb +5 -2
- data/lib/rubocop/cop/style/redundant_argument.rb +21 -2
- data/lib/rubocop/cop/style/redundant_freeze.rb +8 -4
- data/lib/rubocop/cop/style/redundant_return.rb +1 -1
- data/lib/rubocop/cop/style/single_line_block_params.rb +30 -7
- data/lib/rubocop/cop/style/single_line_methods.rb +34 -2
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +15 -9
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -13
- data/lib/rubocop/cop/style/string_concatenation.rb +20 -1
- 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/cop/style/symbol_proc.rb +5 -4
- data/lib/rubocop/cop/style/while_until_modifier.rb +2 -4
- data/lib/rubocop/cop/util.rb +3 -1
- 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/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/target_ruby.rb +47 -11
- data/lib/rubocop/util.rb +16 -0
- data/lib/rubocop/version.rb +8 -2
- metadata +28 -7
@@ -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
|
|
@@ -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
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This module encapsulates the ability to allow certain identifiers in a cop.
|
6
|
+
module AllowedIdentifiers
|
7
|
+
SIGILS = '@$' # if a variable starts with a sigil it will be removed
|
8
|
+
|
9
|
+
def allowed_identifier?(name)
|
10
|
+
allowed_identifiers.include?(name.to_s.delete(SIGILS))
|
11
|
+
end
|
12
|
+
|
13
|
+
def allowed_identifiers
|
14
|
+
cop_config.fetch('AllowedIdentifiers', [])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -22,16 +22,7 @@ module RuboCop
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def begin_pos_with_comment(node)
|
25
|
-
|
26
|
-
first_comment = nil
|
27
|
-
|
28
|
-
processed_source.comments_before_line(annotation_line)
|
29
|
-
.reverse_each do |comment|
|
30
|
-
if comment.location.line == annotation_line
|
31
|
-
first_comment = comment
|
32
|
-
annotation_line -= 1
|
33
|
-
end
|
34
|
-
end
|
25
|
+
first_comment = processed_source.ast_with_comments[node].first
|
35
26
|
|
36
27
|
start_line_position(first_comment || node)
|
37
28
|
end
|
@@ -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
|
@@ -24,7 +24,11 @@ module RuboCop
|
|
24
24
|
name = full_name.gsub(/\A(_+)/, '')
|
25
25
|
next if allowed_names.include?(name)
|
26
26
|
|
27
|
-
|
27
|
+
length = full_name.size
|
28
|
+
length += 1 if arg.restarg_type?
|
29
|
+
length += 2 if arg.kwrestarg_type?
|
30
|
+
|
31
|
+
range = arg_range(arg, length)
|
28
32
|
issue_offenses(node, range, name)
|
29
33
|
end
|
30
34
|
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_`.'
|
@@ -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
|
|
@@ -20,6 +20,7 @@ module RuboCop
|
|
20
20
|
# # good
|
21
21
|
# fooBar = 1
|
22
22
|
class VariableName < Base
|
23
|
+
include AllowedIdentifiers
|
23
24
|
include ConfigurableNaming
|
24
25
|
|
25
26
|
MSG = 'Use %<style>s for variable names.'
|
@@ -27,6 +28,7 @@ module RuboCop
|
|
27
28
|
def on_lvasgn(node)
|
28
29
|
name, = *node
|
29
30
|
return unless name
|
31
|
+
return if allowed_identifier?(name)
|
30
32
|
|
31
33
|
check_name(node, name, node.loc.name)
|
32
34
|
end
|
@@ -97,6 +97,7 @@ module RuboCop
|
|
97
97
|
# expect(Open3).to receive(:capture3)
|
98
98
|
#
|
99
99
|
class VariableNumber < Base
|
100
|
+
include AllowedIdentifiers
|
100
101
|
include ConfigurableNumbering
|
101
102
|
|
102
103
|
MSG = 'Use %<style>s for %<identifier_type>s numbers.'
|
@@ -139,14 +140,6 @@ module RuboCop
|
|
139
140
|
|
140
141
|
format(MSG, style: style, identifier_type: identifier_type)
|
141
142
|
end
|
142
|
-
|
143
|
-
def allowed_identifier?(name)
|
144
|
-
allowed_identifiers.include?(name.to_s.delete('@'))
|
145
|
-
end
|
146
|
-
|
147
|
-
def allowed_identifiers
|
148
|
-
cop_config.fetch('AllowedIdentifiers', [])
|
149
|
-
end
|
150
143
|
end
|
151
144
|
end
|
152
145
|
end
|
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
|
@@ -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
|
|
@@ -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
|