rubocop 0.90.0 → 0.93.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 +79 -3
- data/lib/rubocop.rb +20 -5
- data/lib/rubocop/cached_data.rb +2 -1
- data/lib/rubocop/cli/command/execute_runner.rb +8 -0
- data/lib/rubocop/comment_config.rb +9 -5
- data/lib/rubocop/config_loader.rb +3 -3
- data/lib/rubocop/config_regeneration.rb +33 -0
- data/lib/rubocop/config_store.rb +3 -3
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +5 -1
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -0
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -0
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +10 -10
- data/lib/rubocop/cop/generator.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -0
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -0
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +77 -0
- data/lib/rubocop/cop/layout/case_indentation.rb +4 -7
- data/lib/rubocop/cop/layout/class_structure.rb +1 -1
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +6 -9
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +4 -12
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +13 -8
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -2
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +5 -10
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +26 -4
- data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +4 -13
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -7
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +0 -4
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +6 -21
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +3 -8
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +2 -2
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -0
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +2 -0
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +18 -1
- data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -2
- data/lib/rubocop/cop/lint/boolean_symbol.rb +3 -0
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +74 -0
- data/lib/rubocop/cop/lint/debugger.rb +2 -3
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -3
- data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -4
- data/lib/rubocop/cop/lint/duplicate_require.rb +7 -2
- data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +2 -4
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -0
- data/lib/rubocop/cop/lint/empty_file.rb +1 -4
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +2 -0
- data/lib/rubocop/cop/lint/float_comparison.rb +2 -2
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +37 -0
- data/lib/rubocop/cop/lint/identity_comparison.rb +51 -0
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +2 -5
- data/lib/rubocop/cop/lint/inherit_exception.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
- data/lib/rubocop/cop/lint/multiple_comparison.rb +3 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +1 -0
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -2
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
- data/lib/rubocop/cop/lint/raise_exception.rb +1 -0
- data/lib/rubocop/cop/lint/rand_one.rb +2 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +22 -12
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +14 -4
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -0
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +78 -0
- data/lib/rubocop/cop/lint/rescue_type.rb +0 -1
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +3 -1
- data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -6
- data/lib/rubocop/cop/lint/struct_new_override.rb +1 -0
- data/lib/rubocop/cop/lint/to_json.rb +16 -5
- data/lib/rubocop/cop/lint/unreachable_loop.rb +3 -6
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +3 -1
- data/lib/rubocop/cop/lint/uri_regexp.rb +2 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +3 -9
- data/lib/rubocop/cop/lint/useless_method_definition.rb +20 -27
- data/lib/rubocop/cop/lint/useless_times.rb +106 -0
- data/lib/rubocop/cop/metrics/block_length.rb +3 -1
- data/lib/rubocop/cop/metrics/class_length.rb +14 -6
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +25 -16
- data/lib/rubocop/cop/mixin/comments_help.rb +3 -9
- data/lib/rubocop/cop/mixin/configurable_naming.rb +2 -2
- data/lib/rubocop/cop/mixin/configurable_numbering.rb +3 -3
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +9 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -2
- data/lib/rubocop/cop/mixin/rescue_node.rb +1 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +9 -3
- data/lib/rubocop/cop/mixin/visibility_help.rb +4 -16
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +1 -1
- data/lib/rubocop/cop/offense.rb +15 -2
- data/lib/rubocop/cop/security/eval.rb +1 -0
- data/lib/rubocop/cop/security/json_load.rb +1 -0
- data/lib/rubocop/cop/security/marshal_load.rb +1 -0
- data/lib/rubocop/cop/security/open.rb +1 -0
- data/lib/rubocop/cop/security/yaml_load.rb +1 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +7 -11
- data/lib/rubocop/cop/style/accessor_grouping.rb +3 -0
- data/lib/rubocop/cop/style/alias.rb +2 -0
- data/lib/rubocop/cop/style/array_coercion.rb +4 -0
- data/lib/rubocop/cop/style/array_join.rb +1 -0
- data/lib/rubocop/cop/style/attr.rb +1 -0
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +2 -0
- data/lib/rubocop/cop/style/case_equality.rb +3 -0
- data/lib/rubocop/cop/style/case_like_if.rb +20 -4
- data/lib/rubocop/cop/style/class_and_module_children.rb +2 -0
- data/lib/rubocop/cop/style/class_check.rb +6 -9
- data/lib/rubocop/cop/style/class_equality_comparison.rb +64 -0
- data/lib/rubocop/cop/style/class_methods_definitions.rb +42 -16
- data/lib/rubocop/cop/style/class_vars.rb +1 -2
- data/lib/rubocop/cop/style/combinable_loops.rb +13 -11
- data/lib/rubocop/cop/style/comment_annotation.rb +6 -0
- data/lib/rubocop/cop/style/commented_keyword.rb +7 -8
- data/lib/rubocop/cop/style/conditional_assignment.rb +49 -60
- data/lib/rubocop/cop/style/date_time.rb +12 -1
- data/lib/rubocop/cop/style/dir.rb +1 -0
- data/lib/rubocop/cop/style/double_negation.rb +1 -0
- data/lib/rubocop/cop/style/empty_literal.rb +3 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +1 -3
- data/lib/rubocop/cop/style/even_odd.rb +1 -0
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -2
- data/lib/rubocop/cop/style/explicit_block_argument.rb +7 -3
- data/lib/rubocop/cop/style/float_division.rb +2 -0
- data/lib/rubocop/cop/style/for.rb +0 -4
- data/lib/rubocop/cop/style/format_string.rb +1 -4
- data/lib/rubocop/cop/style/format_string_token.rb +1 -1
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +24 -5
- data/lib/rubocop/cop/style/hash_transform_keys.rb +5 -11
- data/lib/rubocop/cop/style/hash_transform_values.rb +5 -11
- data/lib/rubocop/cop/style/if_unless_modifier.rb +0 -4
- data/lib/rubocop/cop/style/implicit_runtime_error.rb +1 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -6
- data/lib/rubocop/cop/style/lambda_call.rb +3 -1
- data/lib/rubocop/cop/style/method_def_parentheses.rb +0 -4
- data/lib/rubocop/cop/style/mixin_usage.rb +8 -27
- data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -2
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +14 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +1 -0
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +2 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
- data/lib/rubocop/cop/style/non_nil_check.rb +2 -0
- data/lib/rubocop/cop/style/not.rb +1 -0
- data/lib/rubocop/cop/style/numeric_predicate.rb +1 -3
- data/lib/rubocop/cop/style/one_line_conditional.rb +3 -1
- data/lib/rubocop/cop/style/optional_boolean_parameter.rb +12 -1
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +2 -0
- data/lib/rubocop/cop/style/raise_args.rb +2 -3
- data/lib/rubocop/cop/style/random_with_offset.rb +4 -3
- data/lib/rubocop/cop/style/redundant_assignment.rb +1 -9
- data/lib/rubocop/cop/style/redundant_begin.rb +36 -8
- data/lib/rubocop/cop/style/redundant_condition.rb +5 -1
- data/lib/rubocop/cop/style/redundant_conditional.rb +4 -5
- data/lib/rubocop/cop/style/redundant_exception.rb +1 -3
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +2 -1
- data/lib/rubocop/cop/style/redundant_interpolation.rb +6 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +14 -6
- data/lib/rubocop/cop/style/redundant_percent_q.rb +9 -11
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +39 -24
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -15
- data/lib/rubocop/cop/style/redundant_return.rb +17 -17
- data/lib/rubocop/cop/style/redundant_self.rb +7 -9
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -2
- data/lib/rubocop/cop/style/redundant_sort.rb +12 -29
- data/lib/rubocop/cop/style/redundant_sort_by.rb +5 -9
- data/lib/rubocop/cop/style/rescue_standard_error.rb +20 -16
- data/lib/rubocop/cop/style/safe_navigation.rb +5 -0
- data/lib/rubocop/cop/style/sample.rb +2 -1
- data/lib/rubocop/cop/style/send.rb +2 -3
- data/lib/rubocop/cop/style/signal_exception.rb +2 -0
- data/lib/rubocop/cop/style/single_argument_dig.rb +1 -0
- data/lib/rubocop/cop/style/slicing_with_range.rb +2 -1
- data/lib/rubocop/cop/style/stderr_puts.rb +1 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +17 -3
- data/lib/rubocop/cop/style/strip.rb +1 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +2 -3
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +4 -3
- data/lib/rubocop/cop/style/unpack_first.rb +1 -0
- data/lib/rubocop/cop/style/zero_length_predicate.rb +1 -5
- data/lib/rubocop/cop/util.rb +0 -1
- data/lib/rubocop/cop/variable_force/branch.rb +0 -4
- data/lib/rubocop/core_ext/string.rb +1 -1
- data/lib/rubocop/directive_comment.rb +32 -0
- data/lib/rubocop/ext/regexp_node.rb +23 -7
- data/lib/rubocop/formatter/disabled_config_formatter.rb +12 -5
- data/lib/rubocop/options.rb +37 -17
- data/lib/rubocop/result_cache.rb +38 -15
- data/lib/rubocop/rspec/cop_helper.rb +1 -1
- data/lib/rubocop/rspec/expect_offense.rb +5 -5
- data/lib/rubocop/runner.rb +37 -18
- data/lib/rubocop/target_finder.rb +27 -26
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/version.rb +6 -1
- metadata +19 -18
- data/lib/rubocop/cop/mixin/regexp_literal_help.rb +0 -43
- data/lib/rubocop/cop/tokens_util.rb +0 -84
@@ -40,10 +40,12 @@ module RuboCop
|
|
40
40
|
|
41
41
|
MSG = 'Use `%<method>s %<module_name>s` instead of `%<bad_method>s`.'
|
42
42
|
MIXIN_METHODS = %i[include prepend extend].freeze
|
43
|
+
SEND_METHODS = %i[send public_send __send__].freeze
|
44
|
+
RESTRICT_ON_SEND = SEND_METHODS
|
43
45
|
|
44
46
|
def_node_matcher :send_with_mixin_argument?, <<~PATTERN
|
45
47
|
(send
|
46
|
-
(const _ _) {
|
48
|
+
(const _ _) {:#{SEND_METHODS.join(' :')}}
|
47
49
|
({sym str} $#mixin_method?)
|
48
50
|
$(const _ _))
|
49
51
|
PATTERN
|
@@ -75,8 +75,7 @@ module RuboCop
|
|
75
75
|
|
76
76
|
def rescued_groups_for(rescues)
|
77
77
|
rescues.map do |group|
|
78
|
-
|
79
|
-
evaluate_exceptions(rescue_group)
|
78
|
+
evaluate_exceptions(group)
|
80
79
|
end
|
81
80
|
end
|
82
81
|
|
@@ -117,14 +116,15 @@ module RuboCop
|
|
117
116
|
$VERBOSE = old_verbose
|
118
117
|
end
|
119
118
|
|
120
|
-
def evaluate_exceptions(
|
121
|
-
|
122
|
-
|
119
|
+
def evaluate_exceptions(group)
|
120
|
+
rescued_exceptions = group.exceptions
|
121
|
+
|
122
|
+
if rescued_exceptions.any?
|
123
123
|
rescued_exceptions.each_with_object([]) do |exception, converted|
|
124
124
|
begin
|
125
125
|
silence_warnings do
|
126
126
|
# Avoid printing deprecation warnings about constants
|
127
|
-
converted << Kernel.const_get(exception)
|
127
|
+
converted << Kernel.const_get(exception.source)
|
128
128
|
end
|
129
129
|
rescue NameError
|
130
130
|
converted << nil
|
@@ -24,6 +24,7 @@ module RuboCop
|
|
24
24
|
class StructNewOverride < Base
|
25
25
|
MSG = '`%<member_name>s` member overrides `Struct#%<method_name>s`' \
|
26
26
|
' and it may be unexpected.'
|
27
|
+
RESTRICT_ON_SEND = %i[new].freeze
|
27
28
|
|
28
29
|
STRUCT_METHOD_NAMES = Struct.instance_methods
|
29
30
|
STRUCT_MEMBER_NAME_TYPES = %i[sym str].freeze
|
@@ -9,12 +9,23 @@ module RuboCop
|
|
9
9
|
# for an optional argument, your method should too.
|
10
10
|
#
|
11
11
|
# @example
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
12
|
+
# class Point
|
13
|
+
# attr_reader :x, :y
|
14
|
+
#
|
15
|
+
# # bad, incorrect arity
|
16
|
+
# def to_json
|
17
|
+
# JSON.generate([x, y])
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# # good, preserving args
|
21
|
+
# def to_json(*args)
|
22
|
+
# JSON.generate([x, y], *args)
|
23
|
+
# end
|
15
24
|
#
|
16
|
-
#
|
17
|
-
#
|
25
|
+
# # good, discarding args
|
26
|
+
# def to_json(*_args)
|
27
|
+
# JSON.generate([x, y])
|
28
|
+
# end
|
18
29
|
# end
|
19
30
|
#
|
20
31
|
class ToJSON < Base
|
@@ -130,7 +130,8 @@ module RuboCop
|
|
130
130
|
case node.type
|
131
131
|
when :begin, :kwbegin
|
132
132
|
statements = *node
|
133
|
-
statements.
|
133
|
+
break_statement = statements.find { |statement| break_statement?(statement) }
|
134
|
+
break_statement && !preceded_by_continue_statement?(break_statement)
|
134
135
|
when :if
|
135
136
|
check_if(node)
|
136
137
|
when :case
|
@@ -158,16 +159,12 @@ module RuboCop
|
|
158
159
|
end
|
159
160
|
|
160
161
|
def preceded_by_continue_statement?(break_statement)
|
161
|
-
|
162
|
+
break_statement.left_siblings.any? do |sibling|
|
162
163
|
next if sibling.loop_keyword? || loop_method?(sibling)
|
163
164
|
|
164
165
|
sibling.each_descendant(:next, :redo).any?
|
165
166
|
end
|
166
167
|
end
|
167
|
-
|
168
|
-
def left_siblings_of(node)
|
169
|
-
node.parent.children[0, node.sibling_index]
|
170
|
-
end
|
171
168
|
end
|
172
169
|
end
|
173
170
|
end
|
@@ -44,10 +44,12 @@ module RuboCop
|
|
44
44
|
MSG = '`%<uri_method>s` method is obsolete and should not be used. ' \
|
45
45
|
'Instead, use %<replacements>s depending on your specific use ' \
|
46
46
|
'case.'
|
47
|
+
METHOD_NAMES = %i[escape encode unescape decode].freeze
|
48
|
+
RESTRICT_ON_SEND = METHOD_NAMES
|
47
49
|
|
48
50
|
def_node_matcher :uri_escape_unescape?, <<~PATTERN
|
49
51
|
(send
|
50
|
-
(const ${nil? cbase} :URI) ${
|
52
|
+
(const ${nil? cbase} :URI) ${:#{METHOD_NAMES.join(' :')}}
|
51
53
|
...)
|
52
54
|
PATTERN
|
53
55
|
|
@@ -18,9 +18,10 @@ module RuboCop
|
|
18
18
|
|
19
19
|
MSG = '`%<current>s` is obsolete and should not be used. Instead, use `%<preferred>s`.'
|
20
20
|
URI_CONSTANTS = ['URI', '::URI'].freeze
|
21
|
+
RESTRICT_ON_SEND = %i[regexp].freeze
|
21
22
|
|
22
23
|
def on_send(node)
|
23
|
-
return unless node.
|
24
|
+
return unless node.receiver
|
24
25
|
return unless URI_CONSTANTS.include?(node.receiver.source)
|
25
26
|
|
26
27
|
argument = node.first_argument ? "(#{node.first_argument.source})" : ''
|
@@ -131,12 +131,10 @@ module RuboCop
|
|
131
131
|
MSG = 'Useless `%<current>s` access modifier.'
|
132
132
|
|
133
133
|
def on_class(node)
|
134
|
-
check_node(node.
|
135
|
-
end
|
136
|
-
|
137
|
-
def on_module(node)
|
138
|
-
check_node(node.children[1]) # module body
|
134
|
+
check_node(node.body)
|
139
135
|
end
|
136
|
+
alias on_module on_class
|
137
|
+
alias on_sclass on_class
|
140
138
|
|
141
139
|
def on_block(node)
|
142
140
|
return unless eval_call?(node)
|
@@ -144,10 +142,6 @@ module RuboCop
|
|
144
142
|
check_node(node.body)
|
145
143
|
end
|
146
144
|
|
147
|
-
def on_sclass(node)
|
148
|
-
check_node(node.children[1]) # singleton class body
|
149
|
-
end
|
150
|
-
|
151
145
|
private
|
152
146
|
|
153
147
|
def autocorrect(corrector, node)
|
@@ -12,32 +12,26 @@ module RuboCop
|
|
12
12
|
# @example
|
13
13
|
# # bad
|
14
14
|
# def initialize
|
15
|
+
# super
|
15
16
|
# end
|
16
17
|
#
|
17
18
|
# def method
|
18
19
|
# super
|
19
20
|
# end
|
20
21
|
#
|
21
|
-
# # good
|
22
|
-
# def initialize
|
23
|
-
# initialize_internals
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# def method
|
22
|
+
# # good - with default arguments
|
23
|
+
# def initialize(x = Object.new)
|
27
24
|
# super
|
28
|
-
# do_something_else
|
29
25
|
# end
|
30
26
|
#
|
31
|
-
# @example AllowComments: true (default)
|
32
27
|
# # good
|
33
28
|
# def initialize
|
34
|
-
#
|
29
|
+
# super
|
30
|
+
# initialize_internals
|
35
31
|
# end
|
36
32
|
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
# def initialize
|
40
|
-
# # Comment.
|
33
|
+
# def method(*args)
|
34
|
+
# super(:extra_arg, *args)
|
41
35
|
# end
|
42
36
|
#
|
43
37
|
class UselessMethodDefinition < Base
|
@@ -46,8 +40,8 @@ module RuboCop
|
|
46
40
|
MSG = 'Useless method definition detected.'
|
47
41
|
|
48
42
|
def on_def(node)
|
49
|
-
return
|
50
|
-
|
43
|
+
return if optional_args?(node)
|
44
|
+
return unless delegating?(node.body, node)
|
51
45
|
|
52
46
|
add_offense(node) { |corrector| corrector.remove(node) }
|
53
47
|
end
|
@@ -55,21 +49,20 @@ module RuboCop
|
|
55
49
|
|
56
50
|
private
|
57
51
|
|
58
|
-
def
|
59
|
-
|
60
|
-
return false if cop_config['AllowComments'] && comment_lines?(node)
|
61
|
-
|
62
|
-
true
|
63
|
-
end
|
64
|
-
|
65
|
-
def constructor?(node)
|
66
|
-
node.def_type? && node.method?(:initialize)
|
52
|
+
def optional_args?(node)
|
53
|
+
node.arguments.any? { |arg| arg.optarg_type? || arg.kwoptarg_type? }
|
67
54
|
end
|
68
55
|
|
69
56
|
def delegating?(node, def_node)
|
70
|
-
|
71
|
-
|
72
|
-
|
57
|
+
if node.nil?
|
58
|
+
false
|
59
|
+
elsif node.zsuper_type?
|
60
|
+
true
|
61
|
+
elsif node.super_type?
|
62
|
+
node.arguments.map(&:source) == def_node.arguments.map(&:source)
|
63
|
+
else
|
64
|
+
false
|
65
|
+
end
|
73
66
|
end
|
74
67
|
end
|
75
68
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks for uses of `Integer#times` that will never yield
|
7
|
+
# (when the integer <= 0) or that will only ever yield once
|
8
|
+
# (`1.times`).
|
9
|
+
#
|
10
|
+
# This cop is marked as unsafe as `times` returns its receiver, which
|
11
|
+
# is *usually* OK, but might change behavior.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# # bad
|
15
|
+
# -5.times { do_something }
|
16
|
+
# 0.times { do_something }
|
17
|
+
# 1.times { do_something }
|
18
|
+
# 1.times { |i| do_something(i) }
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# do_something
|
22
|
+
# do_something(1)
|
23
|
+
class UselessTimes < Base
|
24
|
+
include RangeHelp
|
25
|
+
extend AutoCorrector
|
26
|
+
|
27
|
+
MSG = 'Useless call to `%<count>i.times` detected.'
|
28
|
+
RESTRICT_ON_SEND = %i[times].freeze
|
29
|
+
|
30
|
+
def_node_matcher :times_call?, <<~PATTERN
|
31
|
+
(send (int $_) :times (block-pass (sym $_))?)
|
32
|
+
PATTERN
|
33
|
+
|
34
|
+
def_node_matcher :block_arg, <<~PATTERN
|
35
|
+
(block _ (args (arg $_)) ...)
|
36
|
+
PATTERN
|
37
|
+
|
38
|
+
def_node_search :block_reassigns_arg?, <<~PATTERN
|
39
|
+
(lvasgn %)
|
40
|
+
PATTERN
|
41
|
+
|
42
|
+
def on_send(node)
|
43
|
+
return unless (count, proc_name = times_call?(node))
|
44
|
+
return if count > 1
|
45
|
+
|
46
|
+
# Get the block node if applicable
|
47
|
+
node = node.block_node if node.block_literal?
|
48
|
+
|
49
|
+
add_offense(node, message: format(MSG, count: count)) do |corrector|
|
50
|
+
next unless own_line?(node)
|
51
|
+
|
52
|
+
if never_process?(count, node)
|
53
|
+
remove_node(corrector, node)
|
54
|
+
elsif !proc_name.empty?
|
55
|
+
autocorrect_block_pass(corrector, node, proc_name)
|
56
|
+
else
|
57
|
+
autocorrect_block(corrector, node)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def never_process?(count, node)
|
65
|
+
count < 1 || node.block_type? && node.body.nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
def remove_node(corrector, node)
|
69
|
+
corrector.remove(range_by_whole_lines(node.loc.expression, include_final_newline: true))
|
70
|
+
end
|
71
|
+
|
72
|
+
def autocorrect_block_pass(corrector, node, proc_name)
|
73
|
+
corrector.replace(node, proc_name)
|
74
|
+
end
|
75
|
+
|
76
|
+
def autocorrect_block(corrector, node)
|
77
|
+
block_arg = block_arg(node)
|
78
|
+
return if block_reassigns_arg?(node, block_arg)
|
79
|
+
|
80
|
+
source = node.body.source
|
81
|
+
source.gsub!(/\b#{block_arg}\b/, '1') if block_arg
|
82
|
+
|
83
|
+
corrector.replace(node, fix_indentation(source, node.loc.column...node.body.loc.column))
|
84
|
+
end
|
85
|
+
|
86
|
+
def fix_indentation(source, range)
|
87
|
+
# Cleanup indentation in a multiline block
|
88
|
+
source_lines = source.split("\n")
|
89
|
+
|
90
|
+
source_lines[1..-1].each do |line|
|
91
|
+
next if line.empty?
|
92
|
+
|
93
|
+
line[range] = ''
|
94
|
+
end
|
95
|
+
source_lines.join("\n")
|
96
|
+
end
|
97
|
+
|
98
|
+
def own_line?(node)
|
99
|
+
# If there is anything else on the line other than whitespace,
|
100
|
+
# don't try to autocorrect
|
101
|
+
processed_source.buffer.source_line(node.loc.line)[0...node.loc.column] !~ /\S/
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -29,6 +29,8 @@ module RuboCop
|
|
29
29
|
# content.
|
30
30
|
# HEREDOC
|
31
31
|
# end # 5 points
|
32
|
+
#
|
33
|
+
# NOTE: This cop does not apply for `Struct` definitions.
|
32
34
|
class BlockLength < Base
|
33
35
|
include CodeLength
|
34
36
|
|
@@ -36,7 +38,7 @@ module RuboCop
|
|
36
38
|
|
37
39
|
def on_block(node)
|
38
40
|
return if excluded_method?(node)
|
39
|
-
return if node.class_constructor?
|
41
|
+
return if node.class_constructor? || node.struct_constructor?
|
40
42
|
|
41
43
|
check_code_length(node)
|
42
44
|
end
|
@@ -29,6 +29,8 @@ module RuboCop
|
|
29
29
|
# HEREDOC
|
30
30
|
# end # 5 points
|
31
31
|
#
|
32
|
+
#
|
33
|
+
# NOTE: This cop also applies for `Struct` definitions.
|
32
34
|
class ClassLength < Base
|
33
35
|
include CodeLength
|
34
36
|
|
@@ -37,17 +39,23 @@ module RuboCop
|
|
37
39
|
end
|
38
40
|
|
39
41
|
def on_casgn(node)
|
40
|
-
|
41
|
-
|
42
|
+
parent = node.parent
|
43
|
+
|
44
|
+
if parent&.assignment?
|
45
|
+
block_node = parent.children[1]
|
46
|
+
elsif parent&.parent&.masgn_type?
|
47
|
+
block_node = parent.parent.children[1]
|
48
|
+
else
|
49
|
+
_scope, _name, block_node = *node
|
42
50
|
end
|
51
|
+
|
52
|
+
return unless block_node.respond_to?(:class_definition?) && block_node.class_definition?
|
53
|
+
|
54
|
+
check_code_length(block_node)
|
43
55
|
end
|
44
56
|
|
45
57
|
private
|
46
58
|
|
47
|
-
def_node_matcher :class_definition?, <<~PATTERN
|
48
|
-
(casgn nil? _ (block (send (const {nil? cbase} :Class) :new) ...))
|
49
|
-
PATTERN
|
50
|
-
|
51
59
|
def message(length, max_length)
|
52
60
|
format('Class has too many lines. [%<length>d/%<max>d]',
|
53
61
|
length: length,
|
@@ -81,40 +81,49 @@ module RuboCop
|
|
81
81
|
private
|
82
82
|
|
83
83
|
def assignment?(node)
|
84
|
+
return compound_assignment(node) if node.masgn_type? || node.shorthand_asgn?
|
85
|
+
|
84
86
|
node.for_type? ||
|
85
|
-
node.op_asgn_type? ||
|
86
87
|
(node.respond_to?(:setter_method?) && node.setter_method?) ||
|
87
|
-
|
88
|
+
simple_assignment?(node) ||
|
89
|
+
argument?(node)
|
88
90
|
end
|
89
91
|
|
90
|
-
def
|
91
|
-
|
92
|
+
def compound_assignment(node)
|
93
|
+
# Methods setter can not be detected for multiple assignments
|
94
|
+
# and shorthand assigns, so we'll count them here instead
|
95
|
+
children = node.masgn_type? ? node.children[0].children : node.children
|
92
96
|
|
93
|
-
|
94
|
-
|
95
|
-
|
97
|
+
will_be_miscounted = children.count do |child|
|
98
|
+
child.respond_to?(:setter_method?) &&
|
99
|
+
!child.setter_method?
|
96
100
|
end
|
101
|
+
@assignment += will_be_miscounted
|
97
102
|
|
98
|
-
|
103
|
+
false
|
99
104
|
end
|
100
105
|
|
101
|
-
def
|
102
|
-
|
106
|
+
def simple_assignment?(node)
|
107
|
+
if !node.equals_asgn?
|
108
|
+
false
|
109
|
+
elsif node.lvasgn_type?
|
110
|
+
reset_on_lvasgn(node)
|
111
|
+
capturing_variable?(node.children.first)
|
112
|
+
else
|
113
|
+
true
|
114
|
+
end
|
103
115
|
end
|
104
116
|
|
105
|
-
|
106
|
-
|
107
|
-
def assignment_doubled_in_ast?(node)
|
108
|
-
node.masgn_type? || node.or_asgn_type? || node.and_asgn_type?
|
117
|
+
def capturing_variable?(name)
|
118
|
+
name && !/^_/.match?(name)
|
109
119
|
end
|
110
120
|
|
111
121
|
def branch?(node)
|
112
122
|
BRANCH_NODES.include?(node.type)
|
113
123
|
end
|
114
124
|
|
115
|
-
# TODO: move to rubocop-ast
|
116
125
|
def argument?(node)
|
117
|
-
ARGUMENT_TYPES.include?(node.type)
|
126
|
+
ARGUMENT_TYPES.include?(node.type) && capturing_variable?(node.children.first)
|
118
127
|
end
|
119
128
|
|
120
129
|
def condition?(node)
|