rubocop 1.32.0 → 1.34.1
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 +2 -2
- data/config/default.yml +51 -16
- data/config/obsoletion.yml +23 -1
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +2 -2
- data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
- data/lib/rubocop/cli/command/suggest_extensions.rb +53 -15
- data/lib/rubocop/config_finder.rb +68 -0
- data/lib/rubocop/config_loader.rb +12 -40
- data/lib/rubocop/config_loader_resolver.rb +1 -5
- data/lib/rubocop/config_obsoletion/changed_parameter.rb +5 -0
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +4 -0
- data/lib/rubocop/config_obsoletion.rb +7 -2
- data/lib/rubocop/cop/cop.rb +1 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +28 -0
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +61 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/block_end_newline.rb +33 -5
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -1
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
- data/lib/rubocop/cop/legacy/corrections_proxy.rb +1 -1
- data/lib/rubocop/cop/legacy/corrector.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +21 -8
- data/lib/rubocop/cop/lint/debugger.rb +26 -16
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +65 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +24 -8
- data/lib/rubocop/cop/lint/shadowed_exception.rb +15 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +9 -1
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -1
- data/lib/rubocop/cop/metrics/block_length.rb +6 -7
- data/lib/rubocop/cop/metrics/method_length.rb +8 -8
- data/lib/rubocop/cop/mixin/allowed_methods.rb +15 -1
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +5 -1
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +4 -9
- data/lib/rubocop/cop/mixin/range_help.rb +2 -2
- data/lib/rubocop/cop/naming/predicate_name.rb +24 -3
- data/lib/rubocop/cop/style/block_delimiters.rb +26 -7
- data/lib/rubocop/cop/style/class_and_module_children.rb +4 -4
- data/lib/rubocop/cop/style/class_equality_comparison.rb +32 -7
- data/lib/rubocop/cop/style/double_negation.rb +2 -0
- data/lib/rubocop/cop/style/empty_heredoc.rb +15 -1
- data/lib/rubocop/cop/style/format_string_token.rb +21 -8
- data/lib/rubocop/cop/style/hash_except.rb +0 -4
- data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -7
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -6
- data/lib/rubocop/cop/style/numeric_literals.rb +16 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +28 -8
- data/lib/rubocop/cop/style/redundant_condition.rb +19 -4
- data/lib/rubocop/cop/style/redundant_parentheses.rb +15 -22
- data/lib/rubocop/cop/style/redundant_sort.rb +21 -6
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +14 -3
- data/lib/rubocop/cop/style/symbol_proc.rb +34 -9
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -13
- data/lib/rubocop/ext/range.rb +15 -0
- data/lib/rubocop/feature_loader.rb +90 -0
- data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +1 -1
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -1
- data/lib/rubocop/formatter/tap_formatter.rb +1 -1
- data/lib/rubocop/result_cache.rb +22 -20
- data/lib/rubocop/server/cache.rb +33 -1
- data/lib/rubocop/server/cli.rb +19 -2
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +2 -1
- metadata +13 -9
- data/lib/rubocop/cop/mixin/ignored_methods.rb +0 -52
@@ -12,10 +12,24 @@ module RuboCop
|
|
12
12
|
allowed_methods.include?(name.to_s)
|
13
13
|
end
|
14
14
|
|
15
|
+
# @deprecated Use allowed_method? instead
|
16
|
+
alias ignored_method? allowed_method?
|
17
|
+
|
15
18
|
# @api public
|
16
19
|
def allowed_methods
|
17
|
-
|
20
|
+
deprecated_values = cop_config_deprecated_values
|
21
|
+
if deprecated_values.any?(Regexp)
|
22
|
+
cop_config.fetch('AllowedMethods', [])
|
23
|
+
else
|
24
|
+
Array(cop_config['AllowedMethods']).concat(deprecated_values)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def cop_config_deprecated_values
|
29
|
+
Array(cop_config['IgnoredMethods']).concat(Array(cop_config['ExcludedMethods']))
|
18
30
|
end
|
19
31
|
end
|
32
|
+
# @deprecated IgnoredMethods class has been replaced with AllowedMethods.
|
33
|
+
IgnoredMethods = AllowedMethods
|
20
34
|
end
|
21
35
|
end
|
@@ -30,7 +30,15 @@ module RuboCop
|
|
30
30
|
def allowed_patterns
|
31
31
|
# Since there could be a pattern specified in the default config, merge the two
|
32
32
|
# arrays together.
|
33
|
-
Array(cop_config['AllowedPatterns']).concat(Array(cop_config['IgnoredPatterns']))
|
33
|
+
patterns = Array(cop_config['AllowedPatterns']).concat(Array(cop_config['IgnoredPatterns']))
|
34
|
+
deprecated_values = cop_config_deprecated_methods_values
|
35
|
+
return patterns unless deprecated_values.any?(Regexp)
|
36
|
+
|
37
|
+
Array(patterns.concat(deprecated_values))
|
38
|
+
end
|
39
|
+
|
40
|
+
def cop_config_deprecated_methods_values
|
41
|
+
Array(cop_config['IgnoredMethods']).concat(Array(cop_config['ExcludedMethods']))
|
34
42
|
end
|
35
43
|
end
|
36
44
|
|
@@ -12,10 +12,14 @@ module RuboCop
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def contains_comments?(node)
|
15
|
+
comments_in_range(node).any?
|
16
|
+
end
|
17
|
+
|
18
|
+
def comments_in_range(node)
|
15
19
|
start_line = node.source_range.line
|
16
20
|
end_line = find_end_line(node)
|
17
21
|
|
18
|
-
processed_source.each_comment_in_lines(start_line...end_line)
|
22
|
+
processed_source.each_comment_in_lines(start_line...end_line)
|
19
23
|
end
|
20
24
|
|
21
25
|
private
|
@@ -6,7 +6,8 @@ module RuboCop
|
|
6
6
|
#
|
7
7
|
# IMPORTANT: RuboCop core depended on this module when it supported Rails department.
|
8
8
|
# Rails department has been extracted to RuboCop Rails gem.
|
9
|
-
#
|
9
|
+
#
|
10
|
+
# @deprecated This module is deprecated and will be removed by RuboCop 2.0.
|
10
11
|
# It will not be updated to `RuboCop::Cop::Base` v1 API to maintain compatibility
|
11
12
|
# with existing RuboCop Rails 2.8 or lower.
|
12
13
|
#
|
@@ -6,21 +6,16 @@ module RuboCop
|
|
6
6
|
#
|
7
7
|
# This module handles measurement and reporting of complexity in methods.
|
8
8
|
module MethodComplexity
|
9
|
-
include
|
9
|
+
include AllowedMethods
|
10
|
+
include AllowedPattern
|
10
11
|
include Metrics::Utils::RepeatedCsendDiscount
|
11
12
|
extend NodePattern::Macros
|
12
13
|
extend ExcludeLimit
|
13
14
|
|
14
15
|
exclude_limit 'Max'
|
15
16
|
|
16
|
-
# Ensure cops that include `MethodComplexity` have the config
|
17
|
-
# `attr_accessor`s that `ignored_method?` needs.
|
18
|
-
def self.included(base)
|
19
|
-
base.extend(IgnoredMethods::Config)
|
20
|
-
end
|
21
|
-
|
22
17
|
def on_def(node)
|
23
|
-
return if
|
18
|
+
return if allowed_method?(node.method_name) || matches_allowed_pattern?(node.method_name)
|
24
19
|
|
25
20
|
check_complexity(node, node.method_name)
|
26
21
|
end
|
@@ -28,7 +23,7 @@ module RuboCop
|
|
28
23
|
|
29
24
|
def on_block(node)
|
30
25
|
define_method?(node) do |name|
|
31
|
-
return if
|
26
|
+
return if allowed_method?(name) || matches_allowed_pattern?(name)
|
32
27
|
|
33
28
|
check_complexity(node, name)
|
34
29
|
end
|
@@ -54,11 +54,11 @@ module RuboCop
|
|
54
54
|
NOT_GIVEN = Module.new
|
55
55
|
def range_with_surrounding_space(range_positional = NOT_GIVEN, # rubocop:disable Metrics/ParameterLists
|
56
56
|
range: NOT_GIVEN, side: :both, newlines: true,
|
57
|
-
whitespace: false, continuations: false
|
57
|
+
whitespace: false, continuations: false,
|
58
|
+
buffer: @processed_source.buffer)
|
58
59
|
|
59
60
|
range = range_positional unless range_positional == NOT_GIVEN
|
60
61
|
|
61
|
-
buffer = @processed_source.buffer
|
62
62
|
src = buffer.source
|
63
63
|
|
64
64
|
go_left, go_right = directions(side)
|
@@ -3,9 +3,30 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Naming
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# Checks that predicate methods names end with a question mark and
|
7
|
+
# do not start with a forbidden prefix.
|
8
|
+
#
|
9
|
+
# A method is determined to be a predicate method if its name starts
|
10
|
+
# with one of the prefixes defined in the `NamePrefix` configuration.
|
11
|
+
# You can change what prefixes are considered by changing this option.
|
12
|
+
# Any method name that starts with one of these prefixes is required by
|
13
|
+
# the cop to end with a `?`. Other methods can be allowed by adding to
|
14
|
+
# the `AllowedMethods` configuration.
|
15
|
+
#
|
16
|
+
# NOTE: The `is_a?` method is allowed by default.
|
17
|
+
#
|
18
|
+
# If `ForbiddenPrefixes` is set, methods that start with the configured
|
19
|
+
# prefixes will not be allowed and will be removed by autocorrection.
|
20
|
+
#
|
21
|
+
# In other words, if `ForbiddenPrefixes` is empty, a method named `is_foo`
|
22
|
+
# will register an offense only due to the lack of question mark (and will be
|
23
|
+
# autocorrected to `is_foo?`). If `ForbiddenPrefixes` contains `is_`,
|
24
|
+
# `is_foo` will register an offense both because the ? is missing and because of
|
25
|
+
# the `is_` prefix, and will be corrected to `foo?`.
|
26
|
+
#
|
27
|
+
# NOTE: `ForbiddenPrefixes` is only applied to prefixes in `NamePrefix`;
|
28
|
+
# a prefix in the former but not the latter will not be considered by
|
29
|
+
# this cop.
|
9
30
|
#
|
10
31
|
# @example
|
11
32
|
# # bad
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
# Methods that can be either procedural or functional and cannot be
|
11
11
|
# categorised from their usage alone is ignored.
|
12
12
|
# `lambda`, `proc`, and `it` are their defaults.
|
13
|
-
# Additional methods can be added to the `
|
13
|
+
# Additional methods can be added to the `AllowedMethods`.
|
14
14
|
#
|
15
15
|
# @example EnforcedStyle: line_count_based (default)
|
16
16
|
# # bad - single line block
|
@@ -66,7 +66,7 @@ module RuboCop
|
|
66
66
|
# x
|
67
67
|
# }.inspect
|
68
68
|
#
|
69
|
-
# # The AllowBracesOnProceduralOneLiners option is
|
69
|
+
# # The AllowBracesOnProceduralOneLiners option is allowed unless the
|
70
70
|
# # EnforcedStyle is set to `semantic`. If so:
|
71
71
|
#
|
72
72
|
# # If the AllowBracesOnProceduralOneLiners option is unspecified, or
|
@@ -116,7 +116,7 @@ module RuboCop
|
|
116
116
|
#
|
117
117
|
# # Methods listed in the BracesRequiredMethods list, such as 'sig'
|
118
118
|
# # in this example, will require `{...}` braces. This option takes
|
119
|
-
# # precedence over all other configurations except
|
119
|
+
# # precedence over all other configurations except AllowedMethods.
|
120
120
|
#
|
121
121
|
# # bad
|
122
122
|
# sig do
|
@@ -138,7 +138,7 @@ module RuboCop
|
|
138
138
|
# puts foo
|
139
139
|
# end
|
140
140
|
#
|
141
|
-
# @example
|
141
|
+
# @example AllowedMethods: ['lambda', 'proc', 'it' ] (default)
|
142
142
|
#
|
143
143
|
# # good
|
144
144
|
# foo = lambda do |x|
|
@@ -149,9 +149,26 @@ module RuboCop
|
|
149
149
|
# x * 100
|
150
150
|
# end
|
151
151
|
#
|
152
|
+
# @example AllowedPatterns: [] (default)
|
153
|
+
#
|
154
|
+
# # bad
|
155
|
+
# things.map { |thing|
|
156
|
+
# something = thing.some_method
|
157
|
+
# process(something)
|
158
|
+
# }
|
159
|
+
#
|
160
|
+
# @example AllowedPatterns: [/map/]
|
161
|
+
#
|
162
|
+
# # good
|
163
|
+
# things.map { |thing|
|
164
|
+
# something = thing.some_method
|
165
|
+
# process(something)
|
166
|
+
# }
|
167
|
+
#
|
152
168
|
class BlockDelimiters < Base
|
153
169
|
include ConfigurableEnforcedStyle
|
154
|
-
include
|
170
|
+
include AllowedMethods
|
171
|
+
include AllowedPattern
|
155
172
|
include RangeHelp
|
156
173
|
extend AutoCorrector
|
157
174
|
|
@@ -330,12 +347,14 @@ module RuboCop
|
|
330
347
|
end
|
331
348
|
|
332
349
|
def special_method?(method_name)
|
333
|
-
|
350
|
+
allowed_method?(method_name) ||
|
351
|
+
matches_allowed_pattern?(method_name) ||
|
352
|
+
braces_required_method?(method_name)
|
334
353
|
end
|
335
354
|
|
336
355
|
def special_method_proper_block_style?(node)
|
337
356
|
method_name = node.method_name
|
338
|
-
return true if
|
357
|
+
return true if allowed_method?(method_name) || matches_allowed_pattern?(method_name)
|
339
358
|
return node.braces? if braces_required_method?(method_name)
|
340
359
|
end
|
341
360
|
|
@@ -117,10 +117,10 @@ module RuboCop
|
|
117
117
|
end
|
118
118
|
|
119
119
|
def remove_end(corrector, body)
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
120
|
+
remove_begin_pos = body.loc.end.begin_pos - leading_spaces(body).size
|
121
|
+
adjustment = processed_source.raw_source[remove_begin_pos] == ';' ? 0 : 1
|
122
|
+
range = range_between(remove_begin_pos, body.loc.end.end_pos + adjustment)
|
123
|
+
|
124
124
|
corrector.remove(range)
|
125
125
|
end
|
126
126
|
|
@@ -5,8 +5,8 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Enforces the use of `Object#instance_of?` instead of class comparison
|
7
7
|
# for equality.
|
8
|
-
# `==`, `equal?`, and `eql?` methods are
|
9
|
-
# These are customizable with `
|
8
|
+
# `==`, `equal?`, and `eql?` methods are allowed by default.
|
9
|
+
# These are customizable with `AllowedMethods` option.
|
10
10
|
#
|
11
11
|
# @example
|
12
12
|
# # bad
|
@@ -18,7 +18,7 @@ module RuboCop
|
|
18
18
|
# # good
|
19
19
|
# var.instance_of?(Date)
|
20
20
|
#
|
21
|
-
# @example
|
21
|
+
# @example AllowedMethods: [] (default)
|
22
22
|
# # good
|
23
23
|
# var.instance_of?(Date)
|
24
24
|
#
|
@@ -28,7 +28,7 @@ module RuboCop
|
|
28
28
|
# var.class.eql?(Date)
|
29
29
|
# var.class.name == 'Date'
|
30
30
|
#
|
31
|
-
# @example
|
31
|
+
# @example AllowedMethods: [`==`]
|
32
32
|
# # good
|
33
33
|
# var.instance_of?(Date)
|
34
34
|
# var.class == Date
|
@@ -38,9 +38,30 @@ module RuboCop
|
|
38
38
|
# var.class.equal?(Date)
|
39
39
|
# var.class.eql?(Date)
|
40
40
|
#
|
41
|
+
# @example AllowedPatterns: [] (default)
|
42
|
+
# # good
|
43
|
+
# var.instance_of?(Date)
|
44
|
+
#
|
45
|
+
# # bad
|
46
|
+
# var.class == Date
|
47
|
+
# var.class.equal?(Date)
|
48
|
+
# var.class.eql?(Date)
|
49
|
+
# var.class.name == 'Date'
|
50
|
+
#
|
51
|
+
# @example AllowedPatterns: [`/eq/`]
|
52
|
+
# # good
|
53
|
+
# var.instance_of?(Date)
|
54
|
+
# var.class.equal?(Date)
|
55
|
+
# var.class.eql?(Date)
|
56
|
+
#
|
57
|
+
# # bad
|
58
|
+
# var.class == Date
|
59
|
+
# var.class.name == 'Date'
|
60
|
+
#
|
41
61
|
class ClassEqualityComparison < Base
|
42
62
|
include RangeHelp
|
43
|
-
include
|
63
|
+
include AllowedMethods
|
64
|
+
include AllowedPattern
|
44
65
|
extend AutoCorrector
|
45
66
|
|
46
67
|
MSG = 'Use `instance_of?(%<class_name>s)` instead of comparing classes.'
|
@@ -56,7 +77,9 @@ module RuboCop
|
|
56
77
|
|
57
78
|
def on_send(node)
|
58
79
|
def_node = node.each_ancestor(:def, :defs).first
|
59
|
-
return if def_node &&
|
80
|
+
return if def_node &&
|
81
|
+
(allowed_method?(def_node.method_name) ||
|
82
|
+
matches_allowed_pattern?(def_node.method_name))
|
60
83
|
|
61
84
|
class_comparison_candidate?(node) do |receiver_node, class_node|
|
62
85
|
range = offense_range(receiver_node, node)
|
@@ -74,7 +97,9 @@ module RuboCop
|
|
74
97
|
if node.children.first.method?(:name)
|
75
98
|
return class_node.receiver.source if class_node.receiver
|
76
99
|
|
77
|
-
class_node.source.delete('"').delete("'")
|
100
|
+
value = class_node.source.delete('"').delete("'")
|
101
|
+
value.prepend('::') if class_node.each_ancestor(:class, :module).any?
|
102
|
+
value
|
78
103
|
else
|
79
104
|
class_node.source
|
80
105
|
end
|
@@ -93,6 +93,8 @@ module RuboCop
|
|
93
93
|
|
94
94
|
if conditional_node
|
95
95
|
double_negative_condition_return_value?(node, last_child, conditional_node)
|
96
|
+
elsif last_child.pair_type? || last_child.hash_type? || last_child.parent.array_type?
|
97
|
+
false
|
96
98
|
else
|
97
99
|
last_child.last_line <= node.last_line
|
98
100
|
end
|
@@ -48,11 +48,25 @@ module RuboCop
|
|
48
48
|
add_offense(node) do |corrector|
|
49
49
|
heredoc_end = node.loc.heredoc_end
|
50
50
|
|
51
|
-
corrector.replace(node,
|
51
|
+
corrector.replace(node, preferred_string_literal)
|
52
52
|
corrector.remove(range_by_whole_lines(heredoc_body, include_final_newline: true))
|
53
53
|
corrector.remove(range_by_whole_lines(heredoc_end, include_final_newline: true))
|
54
54
|
end
|
55
55
|
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def preferred_string_literal
|
60
|
+
enforce_double_quotes? ? '""' : "''"
|
61
|
+
end
|
62
|
+
|
63
|
+
def enforce_double_quotes?
|
64
|
+
string_literals_config['EnforcedStyle'] == 'double_quotes'
|
65
|
+
end
|
66
|
+
|
67
|
+
def string_literals_config
|
68
|
+
config.for_cop('Style/StringLiterals')
|
69
|
+
end
|
56
70
|
end
|
57
71
|
end
|
58
72
|
end
|
@@ -11,8 +11,8 @@ module RuboCop
|
|
11
11
|
# The reason is that _unannotated_ format is very similar
|
12
12
|
# to encoded URLs or Date/Time formatting strings.
|
13
13
|
#
|
14
|
-
# This cop can be customized
|
15
|
-
# By default, there are no methods to
|
14
|
+
# This cop can be customized allowed methods with `AllowedMethods`.
|
15
|
+
# By default, there are no methods to allowed.
|
16
16
|
#
|
17
17
|
# @example EnforcedStyle: annotated (default)
|
18
18
|
#
|
@@ -62,23 +62,34 @@ module RuboCop
|
|
62
62
|
# # good
|
63
63
|
# format('%06d', 10)
|
64
64
|
#
|
65
|
-
# @example
|
65
|
+
# @example AllowedMethods: [] (default)
|
66
66
|
#
|
67
67
|
# # bad
|
68
68
|
# redirect('foo/%{bar_id}')
|
69
69
|
#
|
70
|
-
# @example
|
70
|
+
# @example AllowedMethods: [redirect]
|
71
|
+
#
|
72
|
+
# # good
|
73
|
+
# redirect('foo/%{bar_id}')
|
74
|
+
#
|
75
|
+
# @example AllowedPatterns: [] (default)
|
76
|
+
#
|
77
|
+
# # bad
|
78
|
+
# redirect('foo/%{bar_id}')
|
79
|
+
#
|
80
|
+
# @example AllowedPatterns: [/redirect/]
|
71
81
|
#
|
72
82
|
# # good
|
73
83
|
# redirect('foo/%{bar_id}')
|
74
84
|
#
|
75
85
|
class FormatStringToken < Base
|
76
86
|
include ConfigurableEnforcedStyle
|
77
|
-
include
|
87
|
+
include AllowedMethods
|
88
|
+
include AllowedPattern
|
78
89
|
extend AutoCorrector
|
79
90
|
|
80
91
|
def on_str(node)
|
81
|
-
return if format_string_token?(node) ||
|
92
|
+
return if format_string_token?(node) || use_allowed_method?(node)
|
82
93
|
|
83
94
|
detections = collect_detections(node)
|
84
95
|
return if detections.empty?
|
@@ -103,9 +114,11 @@ module RuboCop
|
|
103
114
|
!node.value.include?('%') || node.each_ancestor(:xstr, :regexp).any?
|
104
115
|
end
|
105
116
|
|
106
|
-
def
|
117
|
+
def use_allowed_method?(node)
|
107
118
|
send_parent = node.each_ancestor(:send).first
|
108
|
-
send_parent &&
|
119
|
+
send_parent &&
|
120
|
+
(allowed_method?(send_parent.method_name) ||
|
121
|
+
matches_allowed_pattern?(send_parent.method_name))
|
109
122
|
end
|
110
123
|
|
111
124
|
def check_sequence(detected_sequence, token_range)
|
@@ -159,10 +159,6 @@ module RuboCop
|
|
159
159
|
key_argument = node.argument_list.first.source
|
160
160
|
body = extract_body_if_nagated(node.body)
|
161
161
|
lhs, _method_name, rhs = *body
|
162
|
-
|
163
|
-
return lhs if body.method?('include?')
|
164
|
-
return lhs if body.method?('exclude?')
|
165
|
-
return rhs if body.method?('in?')
|
166
162
|
return if [lhs, rhs].map(&:source).none?(key_argument)
|
167
163
|
|
168
164
|
[lhs, rhs].find { |operand| operand.source != key_argument }
|
@@ -96,7 +96,7 @@ module RuboCop
|
|
96
96
|
return false unless max_line_length
|
97
97
|
|
98
98
|
range = node.source_range
|
99
|
-
return false unless range.
|
99
|
+
return false unless range.single_line?
|
100
100
|
return false unless line_length_enabled_at_line?(range.first_line)
|
101
101
|
|
102
102
|
line = range.source_line
|
@@ -12,7 +12,7 @@ module RuboCop
|
|
12
12
|
private
|
13
13
|
|
14
14
|
def require_parentheses(node)
|
15
|
-
return if
|
15
|
+
return if allowed_method_name?(node.method_name)
|
16
16
|
return if matches_allowed_pattern?(node.method_name)
|
17
17
|
return if eligible_for_parentheses_omission?(node)
|
18
18
|
return unless node.arguments? && !node.parenthesized?
|
@@ -24,6 +24,10 @@ module RuboCop
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
def allowed_method_name?(name)
|
28
|
+
allowed_method?(name) || matches_allowed_pattern?(name)
|
29
|
+
end
|
30
|
+
|
27
31
|
def eligible_for_parentheses_omission?(node)
|
28
32
|
node.operator_method? || node.setter_method? || ignored_macro?(node)
|
29
33
|
end
|
@@ -6,8 +6,8 @@ module RuboCop
|
|
6
6
|
# Enforces the presence (default) or absence of parentheses in
|
7
7
|
# method calls containing parameters.
|
8
8
|
#
|
9
|
-
# In the default style (require_parentheses), macro methods are
|
10
|
-
# Additional methods can be added to the `
|
9
|
+
# In the default style (require_parentheses), macro methods are allowed.
|
10
|
+
# Additional methods can be added to the `AllowedMethods`
|
11
11
|
# or `AllowedPatterns` list. These options are
|
12
12
|
# valid only in the default style. Macros can be included by
|
13
13
|
# either setting `IgnoreMacros` to false or adding specific macros to
|
@@ -15,13 +15,13 @@ module RuboCop
|
|
15
15
|
#
|
16
16
|
# Precedence of options is all follows:
|
17
17
|
#
|
18
|
-
# 1. `
|
18
|
+
# 1. `AllowedMethods`
|
19
19
|
# 2. `AllowedPatterns`
|
20
20
|
# 3. `IncludedMacros`
|
21
21
|
#
|
22
22
|
# eg. If a method is listed in both
|
23
|
-
# `IncludedMacros` and `
|
24
|
-
# precedence (that is, the method is
|
23
|
+
# `IncludedMacros` and `AllowedMethods`, then the latter takes
|
24
|
+
# precedence (that is, the method is allowed).
|
25
25
|
#
|
26
26
|
# In the alternative style (omit_parentheses), there are three additional
|
27
27
|
# options.
|
@@ -65,7 +65,7 @@ module RuboCop
|
|
65
65
|
# # Setter methods don't need parens
|
66
66
|
# foo.bar = baz
|
67
67
|
#
|
68
|
-
# # okay with `puts` listed in `
|
68
|
+
# # okay with `puts` listed in `AllowedMethods`
|
69
69
|
# puts 'test'
|
70
70
|
#
|
71
71
|
# # okay with `^assert` listed in `AllowedPatterns`
|
@@ -197,7 +197,7 @@ module RuboCop
|
|
197
197
|
require_relative 'method_call_with_args_parentheses/require_parentheses'
|
198
198
|
|
199
199
|
include ConfigurableEnforcedStyle
|
200
|
-
include
|
200
|
+
include AllowedMethods
|
201
201
|
include AllowedPattern
|
202
202
|
include RequireParentheses
|
203
203
|
include OmitParentheses
|
@@ -5,8 +5,8 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Checks for unwanted parentheses in parameterless method calls.
|
7
7
|
#
|
8
|
-
# This cop can be customized
|
9
|
-
# By default, there are no methods to
|
8
|
+
# This cop can be customized allowed methods with `AllowedMethods`.
|
9
|
+
# By default, there are no methods to allowed.
|
10
10
|
#
|
11
11
|
# @example
|
12
12
|
# # bad
|
@@ -15,16 +15,17 @@ module RuboCop
|
|
15
15
|
# # good
|
16
16
|
# object.some_method
|
17
17
|
#
|
18
|
-
# @example
|
18
|
+
# @example AllowedMethods: [] (default)
|
19
19
|
# # bad
|
20
20
|
# object.foo()
|
21
21
|
#
|
22
|
-
# @example
|
22
|
+
# @example AllowedMethods: [foo]
|
23
23
|
# # good
|
24
24
|
# object.foo()
|
25
25
|
#
|
26
26
|
class MethodCallWithoutArgsParentheses < Base
|
27
|
-
include
|
27
|
+
include AllowedMethods
|
28
|
+
include AllowedPattern
|
28
29
|
extend AutoCorrector
|
29
30
|
|
30
31
|
MSG = 'Do not use parentheses for method calls with no arguments.'
|
@@ -33,7 +34,7 @@ module RuboCop
|
|
33
34
|
return unless !node.arguments? && node.parenthesized?
|
34
35
|
return if ineligible_node?(node)
|
35
36
|
return if default_argument?(node)
|
36
|
-
return if
|
37
|
+
return if allowed_method_name?(node.method_name)
|
37
38
|
return if same_name_assignment?(node)
|
38
39
|
|
39
40
|
register_offense(node)
|
@@ -56,6 +57,10 @@ module RuboCop
|
|
56
57
|
node.parent&.optarg_type?
|
57
58
|
end
|
58
59
|
|
60
|
+
def allowed_method_name?(name)
|
61
|
+
allowed_method?(name) || matches_allowed_pattern?(name)
|
62
|
+
end
|
63
|
+
|
59
64
|
def same_name_assignment?(node)
|
60
65
|
any_assignment?(node) do |asgn_node|
|
61
66
|
next variable_in_mass_assignment?(node.method_name, asgn_node) if asgn_node.masgn_type?
|
@@ -3,9 +3,17 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Checks for big numeric literals without _ between groups
|
6
|
+
# Checks for big numeric literals without `_` between groups
|
7
7
|
# of digits in them.
|
8
8
|
#
|
9
|
+
# Additional allowed patterns can be added by adding regexps to
|
10
|
+
# the `AllowedPatterns` configuration. All regexps are treated
|
11
|
+
# as anchored even if the patterns do not contain anchors (so
|
12
|
+
# `\d{4}_\d{4}` will allow `1234_5678` but not `1234_5678_9012`).
|
13
|
+
#
|
14
|
+
# NOTE: Even if `AllowedPatterns` are given, autocorrection will
|
15
|
+
# only correct to the standard pattern of an `_` every 3 digits.
|
16
|
+
#
|
9
17
|
# @example
|
10
18
|
#
|
11
19
|
# # bad
|
@@ -34,6 +42,7 @@ module RuboCop
|
|
34
42
|
#
|
35
43
|
class NumericLiterals < Base
|
36
44
|
include IntegerNode
|
45
|
+
include AllowedPattern
|
37
46
|
extend AutoCorrector
|
38
47
|
|
39
48
|
MSG = 'Use underscores(_) as thousands separator and separate every 3 digits with them.'
|
@@ -59,6 +68,7 @@ module RuboCop
|
|
59
68
|
# TODO: handle non-decimal literals as well
|
60
69
|
return if int.start_with?('0')
|
61
70
|
return if allowed_numbers.include?(int)
|
71
|
+
return if matches_allowed_pattern?(int)
|
62
72
|
return unless int.size >= min_digits
|
63
73
|
|
64
74
|
case int
|
@@ -108,6 +118,11 @@ module RuboCop
|
|
108
118
|
def allowed_numbers
|
109
119
|
cop_config.fetch('AllowedNumbers', []).map(&:to_s)
|
110
120
|
end
|
121
|
+
|
122
|
+
def allowed_patterns
|
123
|
+
# Convert the patterns to be anchored
|
124
|
+
super.map { |regexp| Regexp.new(/\A#{regexp}\z/) }
|
125
|
+
end
|
111
126
|
end
|
112
127
|
end
|
113
128
|
end
|