rubocop 1.88.2 → 1.90.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/config/default.yml +139 -16
- data/exe/rubocop +1 -1
- data/lib/rubocop/cached_data.rb +7 -2
- data/lib/rubocop/cli/command/execute_runner.rb +31 -0
- data/lib/rubocop/cli.rb +2 -4
- data/lib/rubocop/comment_config/directive_range.rb +32 -0
- data/lib/rubocop/comment_config/disable_next.rb +97 -0
- data/lib/rubocop/comment_config.rb +81 -49
- data/lib/rubocop/config.rb +76 -5
- data/lib/rubocop/config_loader.rb +1 -2
- data/lib/rubocop/config_loader_resolver.rb +1 -2
- data/lib/rubocop/config_validator.rb +39 -3
- data/lib/rubocop/cop/autocorrect_logic.rb +8 -0
- data/lib/rubocop/cop/badge.rb +8 -0
- data/lib/rubocop/cop/base.rb +40 -6
- data/lib/rubocop/cop/bundler.rb +19 -0
- data/lib/rubocop/cop/corrector.rb +4 -4
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +55 -5
- data/lib/rubocop/cop/gemspec.rb +22 -0
- data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
- data/lib/rubocop/cop/generator.rb +4 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -2
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
- data/lib/rubocop/cop/layout/block_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/class_structure.rb +108 -26
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -2
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
- data/lib/rubocop/cop/layout/end_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/extra_spacing.rb +105 -3
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +21 -1
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +3 -1
- data/lib/rubocop/cop/layout/leading_comment_space.rb +27 -0
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -2
- data/lib/rubocop/cop/layout/line_length.rb +84 -12
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -2
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +12 -2
- data/lib/rubocop/cop/layout/redundant_line_break.rb +77 -0
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/space_around_operators.rb +7 -0
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +31 -34
- data/lib/rubocop/cop/layout.rb +114 -0
- data/lib/rubocop/cop/lazy_loader.rb +41 -0
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -7
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +71 -0
- data/lib/rubocop/cop/lint/ambiguous_range.rb +1 -2
- data/lib/rubocop/cop/lint/argument_mismatch.rb +89 -0
- data/lib/rubocop/cop/lint/constant_reassignment.rb +18 -21
- data/lib/rubocop/cop/lint/constant_resolution.rb +25 -0
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -8
- data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +300 -22
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
- data/lib/rubocop/cop/lint/interpolation_check.rb +1 -2
- data/lib/rubocop/cop/lint/literal_as_condition.rb +8 -6
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +4 -7
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +25 -12
- data/lib/rubocop/cop/lint/missing_super.rb +31 -1
- data/lib/rubocop/cop/lint/name_typo.rb +270 -0
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +15 -4
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +98 -19
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +47 -7
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -2
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -2
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +2 -4
- data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +1 -2
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +38 -3
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -2
- data/lib/rubocop/cop/lint/unused_private_method.rb +234 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -2
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +36 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -0
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +61 -7
- data/lib/rubocop/cop/lint/void.rb +18 -8
- data/lib/rubocop/cop/lint.rb +178 -0
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -2
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics.rb +31 -0
- data/lib/rubocop/cop/migration/department_name.rb +1 -6
- data/lib/rubocop/cop/migration.rb +13 -0
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +23 -5
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -2
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +13 -5
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +23 -6
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +1 -2
- data/lib/rubocop/cop/mixin/hash_subset.rb +1 -2
- data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +7 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +51 -6
- data/lib/rubocop/cop/mixin/project_index_help.rb +140 -0
- data/lib/rubocop/cop/mixin/range_help.rb +1 -2
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +171 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +46 -4
- data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -4
- data/lib/rubocop/cop/mixin.rb +82 -77
- data/lib/rubocop/cop/naming/accessor_method_name.rb +24 -0
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +16 -0
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +2 -4
- data/lib/rubocop/cop/naming/method_name.rb +5 -2
- data/lib/rubocop/cop/naming/predicate_prefix.rb +33 -5
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -2
- data/lib/rubocop/cop/naming/variable_number.rb +3 -1
- data/lib/rubocop/cop/naming.rb +31 -0
- data/lib/rubocop/cop/offense.rb +37 -10
- data/lib/rubocop/cop/registry.rb +180 -46
- data/lib/rubocop/cop/security.rb +19 -0
- data/lib/rubocop/cop/style/accessor_grouping.rb +1 -2
- data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -6
- data/lib/rubocop/cop/style/array_first_last.rb +1 -2
- data/lib/rubocop/cop/style/array_intersect.rb +24 -5
- data/lib/rubocop/cop/style/bitwise_predicate.rb +1 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +3 -6
- data/lib/rubocop/cop/style/case_like_if.rb +2 -4
- data/lib/rubocop/cop/style/class_and_module_children.rb +79 -20
- data/lib/rubocop/cop/style/combinable_loops.rb +1 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +23 -2
- data/lib/rubocop/cop/style/constant_visibility.rb +1 -2
- data/lib/rubocop/cop/style/copyright.rb +5 -1
- data/lib/rubocop/cop/style/directive_scope.rb +171 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +76 -12
- data/lib/rubocop/cop/style/documentation.rb +47 -0
- data/lib/rubocop/cop/style/empty_case_condition.rb +1 -2
- data/lib/rubocop/cop/style/endless_method.rb +0 -10
- data/lib/rubocop/cop/style/format_string_token.rb +1 -2
- data/lib/rubocop/cop/style/guard_clause.rb +1 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -2
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +2 -4
- data/lib/rubocop/cop/style/if_inside_else.rb +1 -2
- data/lib/rubocop/cop/style/if_unless_modifier.rb +8 -50
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +1 -2
- data/lib/rubocop/cop/style/lambda.rb +4 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +22 -7
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +1 -2
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +30 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +7 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -2
- data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
- data/lib/rubocop/cop/style/mutable_constant.rb +5 -0
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -2
- data/lib/rubocop/cop/style/negative_array_index.rb +3 -3
- data/lib/rubocop/cop/style/nil_comparison.rb +1 -2
- data/lib/rubocop/cop/style/operator_method_call.rb +1 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -2
- data/lib/rubocop/cop/style/redundant_assignment.rb +12 -2
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -4
- data/lib/rubocop/cop/style/redundant_constant_base.rb +37 -1
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +1 -2
- data/lib/rubocop/cop/style/redundant_each.rb +1 -2
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -0
- data/lib/rubocop/cop/style/redundant_format.rb +14 -7
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +78 -135
- data/lib/rubocop/cop/style/redundant_parentheses.rb +65 -67
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +1 -2
- data/lib/rubocop/cop/style/redundant_return.rb +1 -2
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -2
- data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +11 -2
- data/lib/rubocop/cop/style/sample.rb +11 -6
- data/lib/rubocop/cop/style/select_by_regexp.rb +1 -2
- data/lib/rubocop/cop/style/semicolon.rb +2 -4
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -2
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +21 -5
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/static_class.rb +21 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +18 -5
- data/lib/rubocop/cop/style/super_arguments.rb +1 -2
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -2
- data/lib/rubocop/cop/style/time_now.rb +41 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +1 -2
- data/lib/rubocop/cop/style.rb +312 -0
- data/lib/rubocop/cop/team.rb +59 -6
- data/lib/rubocop/cop/util.rb +2 -4
- data/lib/rubocop/cop/variable_force/variable.rb +19 -8
- data/lib/rubocop/cops_documentation_generator.rb +4 -7
- data/lib/rubocop/directive_comment.rb +39 -3
- data/lib/rubocop/feature_loader.rb +0 -6
- data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
- data/lib/rubocop/formatter/html_formatter.rb +2 -4
- data/lib/rubocop/formatter/json_formatter.rb +11 -6
- data/lib/rubocop/formatter/junit_formatter.rb +26 -9
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -2
- data/lib/rubocop/formatter/simple_text_formatter.rb +4 -3
- data/lib/rubocop/formatter/tap_formatter.rb +3 -1
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -2
- data/lib/rubocop/lockfile.rb +18 -0
- data/lib/rubocop/lsp/diagnostic.rb +4 -8
- data/lib/rubocop/lsp/routes.rb +89 -22
- data/lib/rubocop/lsp/runtime.rb +4 -0
- data/lib/rubocop/lsp/server.rb +4 -0
- data/lib/rubocop/lsp/stdin_runner.rb +20 -0
- data/lib/rubocop/mcp/server.rb +1 -2
- data/lib/rubocop/options.rb +10 -6
- data/lib/rubocop/path_util.rb +1 -2
- data/lib/rubocop/pending_cops_reporter.rb +1 -6
- data/lib/rubocop/plugin/configuration_integrator.rb +6 -3
- data/lib/rubocop/project_index_loader.rb +16 -0
- data/lib/rubocop/rake_task.rb +1 -2
- data/lib/rubocop/result_cache.rb +6 -4
- data/lib/rubocop/rspec/expect_offense.rb +2 -4
- data/lib/rubocop/rspec/shared_contexts.rb +16 -2
- data/lib/rubocop/runner.rb +71 -43
- data/lib/rubocop/server/cache.rb +11 -7
- data/lib/rubocop/server/cli.rb +2 -4
- data/lib/rubocop/server.rb +14 -0
- data/lib/rubocop/target_finder.rb +4 -1
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/todo_audit.rb +111 -0
- data/lib/rubocop/version.rb +3 -5
- data/lib/rubocop.rb +20 -626
- data/lib/ruby_lsp/rubocop/addon.rb +1 -2
- metadata +28 -5
|
@@ -13,6 +13,11 @@ module RuboCop
|
|
|
13
13
|
# a `#:nodoc:` comment next to it. Likewise, `#:nodoc: all` does the
|
|
14
14
|
# same for all its children.
|
|
15
15
|
#
|
|
16
|
+
# When `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is
|
|
17
|
+
# installed, a reopened class or module is not reported when any of its
|
|
18
|
+
# other definition sites (in the same or another file) carries a
|
|
19
|
+
# documentation comment.
|
|
20
|
+
#
|
|
16
21
|
# @example
|
|
17
22
|
# # bad
|
|
18
23
|
# class Person
|
|
@@ -71,10 +76,15 @@ module RuboCop
|
|
|
71
76
|
#
|
|
72
77
|
class Documentation < Base
|
|
73
78
|
include DocumentationComment
|
|
79
|
+
include ProjectIndexHelp
|
|
74
80
|
include RangeHelp
|
|
75
81
|
|
|
76
82
|
MSG = 'Missing top-level documentation comment for `%<type>s %<identifier>s`.'
|
|
77
83
|
|
|
84
|
+
# Comments that configure tooling rather than document the code.
|
|
85
|
+
DIRECTIVE_COMMENT_REGEXP = /\A\#\s*(rubocop:|frozen_string_literal:|encoding:|
|
|
86
|
+
shareable_constant_value:|typed:|-\*-)/x.freeze
|
|
87
|
+
|
|
78
88
|
# @!method constant_definition?(node)
|
|
79
89
|
def_node_matcher :constant_definition?, '{class module casgn}'
|
|
80
90
|
|
|
@@ -109,12 +119,49 @@ module RuboCop
|
|
|
109
119
|
return if constant_allowed?(node)
|
|
110
120
|
return if nodoc_self_or_outer_module?(node)
|
|
111
121
|
return if include_statement_only?(body)
|
|
122
|
+
return if documented_elsewhere?(node)
|
|
123
|
+
|
|
124
|
+
add_documentation_offense(node)
|
|
125
|
+
end
|
|
112
126
|
|
|
127
|
+
def add_documentation_offense(node)
|
|
113
128
|
range = range_between(node.source_range.begin_pos, node.loc.name.end_pos)
|
|
114
129
|
message = format(MSG, type: node.type, identifier: identifier(node))
|
|
115
130
|
add_offense(range, message: message)
|
|
116
131
|
end
|
|
117
132
|
|
|
133
|
+
# A reopened class or module is typically documented at a single
|
|
134
|
+
# definition site. When `AllCops/UseProjectIndex` is enabled, the
|
|
135
|
+
# documentation requirement is satisfied by a comment on any other
|
|
136
|
+
# definition of the same class or module.
|
|
137
|
+
def documented_elsewhere?(node)
|
|
138
|
+
return false unless project_index
|
|
139
|
+
|
|
140
|
+
declaration = resolve_constant_in_index(node.identifier)
|
|
141
|
+
return false unless declaration.is_a?(Rubydex::Namespace)
|
|
142
|
+
|
|
143
|
+
declaration.definitions.any? do |definition|
|
|
144
|
+
other_definition?(definition, node) && documenting_comments?(definition)
|
|
145
|
+
end
|
|
146
|
+
rescue StandardError
|
|
147
|
+
false
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def other_definition?(definition, node)
|
|
151
|
+
location = definition.location
|
|
152
|
+
return false unless location.uri.start_with?(FILE_URI_PREFIX)
|
|
153
|
+
|
|
154
|
+
!same_file?(location.to_file_path, processed_source.file_path) ||
|
|
155
|
+
location.to_display.start_line != node.first_line
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def documenting_comments?(definition)
|
|
159
|
+
definition.comments.to_a.any? do |comment|
|
|
160
|
+
text = comment.string.strip
|
|
161
|
+
!text.empty? && !DIRECTIVE_COMMENT_REGEXP.match?(text)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
118
165
|
def nodoc_self_or_outer_module?(node)
|
|
119
166
|
nodoc_comment?(node) ||
|
|
120
167
|
(compact_namespace?(node) && nodoc_comment?(outer_module(node).first))
|
|
@@ -42,7 +42,7 @@ module RuboCop
|
|
|
42
42
|
MSG = 'Do not use empty `case` condition, instead use an `if` expression.'
|
|
43
43
|
NOT_SUPPORTED_PARENT_TYPES = %i[return break next send csend yield super].freeze
|
|
44
44
|
|
|
45
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
45
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
46
46
|
def on_case(case_node)
|
|
47
47
|
if case_node.condition || NOT_SUPPORTED_PARENT_TYPES.include?(case_node.parent&.type)
|
|
48
48
|
return
|
|
@@ -56,7 +56,6 @@ module RuboCop
|
|
|
56
56
|
|
|
57
57
|
add_offense(case_node.loc.keyword) { |corrector| autocorrect(corrector, case_node) }
|
|
58
58
|
end
|
|
59
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
60
59
|
|
|
61
60
|
private
|
|
62
61
|
|
|
@@ -206,16 +206,6 @@ module RuboCop
|
|
|
206
206
|
body.each_descendant(:str).any?(&:heredoc?)
|
|
207
207
|
end
|
|
208
208
|
|
|
209
|
-
def correct_to_multiline(corrector, node)
|
|
210
|
-
replacement = <<~RUBY.strip
|
|
211
|
-
def #{receiver(node)}#{node.method_name}#{arguments(node)}
|
|
212
|
-
#{node.body.source}
|
|
213
|
-
end
|
|
214
|
-
RUBY
|
|
215
|
-
|
|
216
|
-
corrector.replace(node, replacement)
|
|
217
|
-
end
|
|
218
|
-
|
|
219
209
|
def endless_replacement(node)
|
|
220
210
|
<<~RUBY.strip
|
|
221
211
|
def #{receiver(node)}#{node.method_name}#{arguments(node)} = #{node.body.source}
|
|
@@ -228,7 +228,7 @@ module RuboCop
|
|
|
228
228
|
"Prefer #{message_text(style)} over #{message_text(detected_style)}."
|
|
229
229
|
end
|
|
230
230
|
|
|
231
|
-
# rubocop:disable Style/FormatStringToken
|
|
231
|
+
# rubocop:disable-next Style/FormatStringToken
|
|
232
232
|
def message_text(style)
|
|
233
233
|
{
|
|
234
234
|
annotated: 'annotated tokens (like `%<foo>s`)',
|
|
@@ -236,7 +236,6 @@ module RuboCop
|
|
|
236
236
|
unannotated: 'unannotated tokens (like `%s`)'
|
|
237
237
|
}[style]
|
|
238
238
|
end
|
|
239
|
-
# rubocop:enable Style/FormatStringToken
|
|
240
239
|
|
|
241
240
|
def tokens(str_node, &block)
|
|
242
241
|
return if str_node.source == '__FILE__'
|
|
@@ -196,7 +196,7 @@ module RuboCop
|
|
|
196
196
|
end
|
|
197
197
|
end
|
|
198
198
|
|
|
199
|
-
# rubocop:disable Metrics/AbcSize
|
|
199
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
200
200
|
def autocorrect(corrector, node, condition, replacement, guard)
|
|
201
201
|
corrector.replace(node.loc.keyword.join(condition.source_range), replacement)
|
|
202
202
|
|
|
@@ -217,7 +217,6 @@ module RuboCop
|
|
|
217
217
|
corrector.remove(range_of_branch_to_remove(node, guard))
|
|
218
218
|
end
|
|
219
219
|
end
|
|
220
|
-
# rubocop:enable Metrics/AbcSize
|
|
221
220
|
|
|
222
221
|
def heredoc?(argument)
|
|
223
222
|
argument.respond_to?(:heredoc?) && argument.heredoc?
|
|
@@ -76,7 +76,7 @@ module RuboCop
|
|
|
76
76
|
alias on_numblock on_block
|
|
77
77
|
alias on_itblock on_block
|
|
78
78
|
|
|
79
|
-
# rubocop:disable Metrics/AbcSize
|
|
79
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
80
80
|
def check_unused_block_args(node, key, value)
|
|
81
81
|
return if node.body.nil?
|
|
82
82
|
|
|
@@ -96,7 +96,6 @@ module RuboCop
|
|
|
96
96
|
register_each_args_offense(node, message, 'each_value', unused_range)
|
|
97
97
|
end
|
|
98
98
|
end
|
|
99
|
-
# rubocop:enable Metrics/AbcSize
|
|
100
99
|
|
|
101
100
|
def on_block_pass(node)
|
|
102
101
|
kv_each_with_block_pass(node.parent) do |target, method|
|
|
@@ -217,7 +217,7 @@ module RuboCop
|
|
|
217
217
|
acceptable_19_syntax_symbol?(pair.key.source)
|
|
218
218
|
end
|
|
219
219
|
|
|
220
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
220
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
221
221
|
def acceptable_19_syntax_symbol?(sym_name)
|
|
222
222
|
sym_name.delete_prefix!(':')
|
|
223
223
|
|
|
@@ -237,7 +237,6 @@ module RuboCop
|
|
|
237
237
|
(sym_name.start_with?("'") && sym_name.end_with?("'")) ||
|
|
238
238
|
(sym_name.start_with?('"') && sym_name.end_with?('"'))
|
|
239
239
|
end
|
|
240
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
241
240
|
|
|
242
241
|
def check(pairs, delim, msg)
|
|
243
242
|
pairs.each do |pair|
|
|
@@ -136,7 +136,7 @@ module RuboCop
|
|
|
136
136
|
|
|
137
137
|
private
|
|
138
138
|
|
|
139
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
139
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
140
140
|
def check_branches(node, branches)
|
|
141
141
|
# return if any branch is empty. An empty branch can be an `if`
|
|
142
142
|
# without an `else` or a branch that contains only comments.
|
|
@@ -168,7 +168,6 @@ module RuboCop
|
|
|
168
168
|
|
|
169
169
|
check_expressions(node, heads, :before_condition)
|
|
170
170
|
end
|
|
171
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
172
171
|
|
|
173
172
|
def duplicated_expressions?(node, expressions)
|
|
174
173
|
unique_expressions = expressions.uniq
|
|
@@ -189,7 +188,7 @@ module RuboCop
|
|
|
189
188
|
end
|
|
190
189
|
end
|
|
191
190
|
|
|
192
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
191
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
193
192
|
def check_expressions(node, expressions, insert_position)
|
|
194
193
|
return if expressions.any?(&:nil?)
|
|
195
194
|
|
|
@@ -213,7 +212,6 @@ module RuboCop
|
|
|
213
212
|
end
|
|
214
213
|
end
|
|
215
214
|
end
|
|
216
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
217
215
|
|
|
218
216
|
def correct_assignment(corrector, node, expression, insert_position)
|
|
219
217
|
indentation = indentation_of(node.parent)
|
|
@@ -64,7 +64,7 @@ module RuboCop
|
|
|
64
64
|
|
|
65
65
|
MSG = 'Convert `if` nested inside `else` to `elsif`.'
|
|
66
66
|
|
|
67
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
67
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
68
68
|
def on_if(node)
|
|
69
69
|
return if node.ternary? || node.unless?
|
|
70
70
|
|
|
@@ -81,7 +81,6 @@ module RuboCop
|
|
|
81
81
|
ignore_node(node)
|
|
82
82
|
end
|
|
83
83
|
end
|
|
84
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
85
84
|
|
|
86
85
|
private
|
|
87
86
|
|
|
@@ -72,10 +72,8 @@ module RuboCop
|
|
|
72
72
|
# do_something
|
|
73
73
|
# end
|
|
74
74
|
#
|
|
75
|
-
class IfUnlessModifier < Base
|
|
75
|
+
class IfUnlessModifier < Base
|
|
76
76
|
include StatementModifier
|
|
77
|
-
include LineLengthHelp
|
|
78
|
-
include AllowedPattern
|
|
79
77
|
include RangeHelp
|
|
80
78
|
include CommentsHelp
|
|
81
79
|
extend AutoCorrector
|
|
@@ -83,13 +81,17 @@ module RuboCop
|
|
|
83
81
|
MSG_USE_MODIFIER = 'Favor modifier `%<keyword>s` usage when having a ' \
|
|
84
82
|
'single-line body. Another good alternative is ' \
|
|
85
83
|
'the usage of control flow `&&`/`||`.'
|
|
84
|
+
MSG_USE_MODIFIER_PARENS = 'Favor modifier `%<keyword>s` usage when having a ' \
|
|
85
|
+
'single-line body. Wrap the expression in parentheses ' \
|
|
86
|
+
'to keep the current behavior, as it is part of a ' \
|
|
87
|
+
'larger expression.'
|
|
86
88
|
MSG_USE_NORMAL = 'Modifier form of `%<keyword>s` makes the line too long.'
|
|
87
89
|
|
|
88
90
|
def self.autocorrect_incompatible_with
|
|
89
91
|
[Style::Next, Style::SoleNestedConditional]
|
|
90
92
|
end
|
|
91
93
|
|
|
92
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
94
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
93
95
|
def on_if(node)
|
|
94
96
|
return if endless_method?(node.body) || node.each_ancestor(:dstr).any?
|
|
95
97
|
|
|
@@ -107,7 +109,6 @@ module RuboCop
|
|
|
107
109
|
ignore_node(node)
|
|
108
110
|
end
|
|
109
111
|
end
|
|
110
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
111
112
|
|
|
112
113
|
private
|
|
113
114
|
|
|
@@ -143,7 +144,7 @@ module RuboCop
|
|
|
143
144
|
|
|
144
145
|
def message(node)
|
|
145
146
|
if single_line_as_modifier?(node) && !named_capture_in_condition?(node)
|
|
146
|
-
MSG_USE_MODIFIER
|
|
147
|
+
parenthesize?(node) ? MSG_USE_MODIFIER_PARENS : MSG_USE_MODIFIER
|
|
147
148
|
elsif too_long_due_to_modifier?(node)
|
|
148
149
|
MSG_USE_NORMAL
|
|
149
150
|
end
|
|
@@ -188,52 +189,9 @@ module RuboCop
|
|
|
188
189
|
max_line_length.between?(source_length - comment.source_range.length, source_length)
|
|
189
190
|
end
|
|
190
191
|
|
|
191
|
-
def allowed_patterns
|
|
192
|
-
line_length_config = config.for_cop('Layout/LineLength')
|
|
193
|
-
line_length_config['AllowedPatterns'] || line_length_config['IgnoredPatterns'] || []
|
|
194
|
-
end
|
|
195
|
-
|
|
196
192
|
def too_long_single_line?(node)
|
|
197
|
-
return false unless max_line_length
|
|
198
|
-
|
|
199
193
|
range = node.source_range
|
|
200
|
-
|
|
201
|
-
return false unless line_length_enabled_at_line?(range.first_line)
|
|
202
|
-
|
|
203
|
-
line = range.source_line
|
|
204
|
-
return false if line_length(line) <= max_line_length
|
|
205
|
-
|
|
206
|
-
too_long_line_based_on_config?(range, line)
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
def too_long_line_based_on_config?(range, line)
|
|
210
|
-
return false if matches_allowed_pattern?(line)
|
|
211
|
-
|
|
212
|
-
too_long = too_long_line_based_on_allow_cop_directives?(range, line)
|
|
213
|
-
return too_long unless too_long == :undetermined
|
|
214
|
-
|
|
215
|
-
too_long_line_based_on_allow_uri?(line)
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
def too_long_line_based_on_allow_cop_directives?(range, line)
|
|
219
|
-
if allow_cop_directives? && directive_on_source_line?(range.line - 1)
|
|
220
|
-
return line_length_without_directive(line) > max_line_length
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
:undetermined
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
def too_long_line_based_on_allow_uri?(line)
|
|
227
|
-
if allow_uri?
|
|
228
|
-
uri_range = find_excessive_range(line, :uri)
|
|
229
|
-
return false if uri_range && allowed_position?(line, uri_range)
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
true
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
def line_length_enabled_at_line?(line)
|
|
236
|
-
processed_source.comment_config.cop_enabled_at_line?('Layout/LineLength', line)
|
|
194
|
+
range.single_line? && !acceptable_line_length?(range.source_line, range.first_line)
|
|
237
195
|
end
|
|
238
196
|
|
|
239
197
|
def named_capture_in_condition?(node)
|
|
@@ -28,7 +28,7 @@ module RuboCop
|
|
|
28
28
|
|
|
29
29
|
MSG = 'Avoid modifier `%<keyword>s` after another conditional.'
|
|
30
30
|
|
|
31
|
-
# rubocop:disable Metrics/AbcSize
|
|
31
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
32
32
|
def on_if(node)
|
|
33
33
|
return unless node.modifier_form? && node.body.if_type?
|
|
34
34
|
|
|
@@ -37,7 +37,6 @@ module RuboCop
|
|
|
37
37
|
corrector.remove(node.if_branch.source_range.end.join(node.condition.source_range.end))
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
|
-
# rubocop:enable Metrics/AbcSize
|
|
41
40
|
end
|
|
42
41
|
end
|
|
43
42
|
end
|
|
@@ -67,7 +67,7 @@ module RuboCop
|
|
|
67
67
|
|
|
68
68
|
private
|
|
69
69
|
|
|
70
|
-
# rubocop:disable Metrics/AbcSize
|
|
70
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
71
71
|
def autocorrect(corrector, to_h, map)
|
|
72
72
|
removal_range = range_between(to_h.loc.dot.begin_pos, to_h.loc.selector.end_pos)
|
|
73
73
|
|
|
@@ -83,7 +83,6 @@ module RuboCop
|
|
|
83
83
|
corrector.replace(argument, argument.source[1..-2])
|
|
84
84
|
end
|
|
85
85
|
end
|
|
86
|
-
# rubocop:enable Metrics/AbcSize
|
|
87
86
|
end
|
|
88
87
|
end
|
|
89
88
|
end
|
|
@@ -5,14 +5,29 @@ module RuboCop
|
|
|
5
5
|
module Style
|
|
6
6
|
class MethodCallWithArgsParentheses
|
|
7
7
|
# Style omit_parentheses
|
|
8
|
-
# rubocop:disable Metrics/ModuleLength, Metrics/CyclomaticComplexity
|
|
8
|
+
# rubocop:disable-next Metrics/ModuleLength, Metrics/CyclomaticComplexity
|
|
9
9
|
module OmitParentheses
|
|
10
10
|
include RangeHelp
|
|
11
|
+
include ReparsedEquivalence
|
|
11
12
|
|
|
12
13
|
TRAILING_WHITESPACE_REGEX = /\s+\Z/.freeze
|
|
13
14
|
OMIT_MSG = 'Omit parentheses for method calls with arguments.'
|
|
14
15
|
private_constant :OMIT_MSG
|
|
15
16
|
|
|
17
|
+
def on_investigation_end
|
|
18
|
+
# Each candidate's exact correction is verified by reparsing before
|
|
19
|
+
# the offense is registered, so an omission that would change how
|
|
20
|
+
# the code parses is never reported or offered.
|
|
21
|
+
verified_by_reparse(@pending_omit_offenses || []).each do |node|
|
|
22
|
+
add_offense(offense_range(node), message: OMIT_MSG) do |corrector|
|
|
23
|
+
autocorrect(corrector, node)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
@pending_omit_offenses = []
|
|
27
|
+
|
|
28
|
+
super
|
|
29
|
+
end
|
|
30
|
+
|
|
16
31
|
private
|
|
17
32
|
|
|
18
33
|
def omit_parentheses(node) # rubocop:disable Metrics/PerceivedComplexity
|
|
@@ -26,9 +41,11 @@ module RuboCop
|
|
|
26
41
|
return if allowed_camel_case_method_call?(node)
|
|
27
42
|
return if allowed_string_interpolation_method_call?(node)
|
|
28
43
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
44
|
+
(@pending_omit_offenses ||= []) << node
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def apply_reparse_correction(corrector, node)
|
|
48
|
+
autocorrect(corrector, node)
|
|
32
49
|
end
|
|
33
50
|
|
|
34
51
|
def autocorrect(corrector, node)
|
|
@@ -133,7 +150,7 @@ module RuboCop
|
|
|
133
150
|
node.parent&.class_type? && node.parent.single_line?
|
|
134
151
|
end
|
|
135
152
|
|
|
136
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
153
|
+
# rubocop:disable-next Metrics/PerceivedComplexity
|
|
137
154
|
def call_with_ambiguous_arguments?(node)
|
|
138
155
|
call_with_braced_block?(node) ||
|
|
139
156
|
call_in_argument_with_block?(node) ||
|
|
@@ -146,7 +163,6 @@ module RuboCop
|
|
|
146
163
|
ambiguous_literal?(n) || logical_operator?(n)
|
|
147
164
|
end
|
|
148
165
|
end
|
|
149
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
150
166
|
|
|
151
167
|
def call_with_braced_block?(node)
|
|
152
168
|
node.type?(:call, :super) && node.block_node&.braces?
|
|
@@ -252,7 +268,6 @@ module RuboCop
|
|
|
252
268
|
last_argument.hash_type? && last_argument.children.any?(&:forwarded_kwrestarg_type?)
|
|
253
269
|
end
|
|
254
270
|
end
|
|
255
|
-
# rubocop:enable Metrics/ModuleLength, Metrics/CyclomaticComplexity
|
|
256
271
|
end
|
|
257
272
|
end
|
|
258
273
|
end
|
|
@@ -33,7 +33,7 @@ module RuboCop
|
|
|
33
33
|
|
|
34
34
|
MSG = 'Do not use parentheses for method calls with no arguments.'
|
|
35
35
|
|
|
36
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
36
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
37
37
|
def on_send(node)
|
|
38
38
|
return unless !node.arguments? && node.parenthesized?
|
|
39
39
|
return if ineligible_node?(node)
|
|
@@ -44,7 +44,6 @@ module RuboCop
|
|
|
44
44
|
|
|
45
45
|
register_offense(node)
|
|
46
46
|
end
|
|
47
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
48
47
|
alias on_csend on_send
|
|
49
48
|
|
|
50
49
|
private
|
|
@@ -28,6 +28,11 @@ module RuboCop
|
|
|
28
28
|
# delegator.upcase # => FOO
|
|
29
29
|
# ----
|
|
30
30
|
#
|
|
31
|
+
# When `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is
|
|
32
|
+
# installed, `respond_to_missing?` defined in another definition of the
|
|
33
|
+
# same class or module (e.g. a reopening in another file) also
|
|
34
|
+
# satisfies the check.
|
|
35
|
+
#
|
|
31
36
|
# @example
|
|
32
37
|
# # bad
|
|
33
38
|
# def method_missing(name, *args)
|
|
@@ -52,11 +57,14 @@ module RuboCop
|
|
|
52
57
|
# end
|
|
53
58
|
#
|
|
54
59
|
class MissingRespondToMissing < Base
|
|
60
|
+
include ProjectIndexHelp
|
|
61
|
+
|
|
55
62
|
MSG = 'When using `method_missing`, define `respond_to_missing?`.'
|
|
56
63
|
|
|
57
64
|
def on_def(node)
|
|
58
65
|
return unless node.method?(:method_missing)
|
|
59
66
|
return if implements_respond_to_missing?(node)
|
|
67
|
+
return if respond_to_missing_elsewhere?(node)
|
|
60
68
|
|
|
61
69
|
add_offense(node)
|
|
62
70
|
end
|
|
@@ -64,6 +72,28 @@ module RuboCop
|
|
|
64
72
|
|
|
65
73
|
private
|
|
66
74
|
|
|
75
|
+
# When `AllCops/UseProjectIndex` is enabled, `respond_to_missing?`
|
|
76
|
+
# defined in another definition of the same class or module (e.g. a
|
|
77
|
+
# reopening in another file) also satisfies the check. Ancestors are
|
|
78
|
+
# not consulted: overriding `method_missing` warrants a matching
|
|
79
|
+
# `respond_to_missing?` for the same class.
|
|
80
|
+
def respond_to_missing_elsewhere?(node)
|
|
81
|
+
return false unless project_index
|
|
82
|
+
return false unless (namespace_node = node.each_ancestor(:class, :module).first)
|
|
83
|
+
|
|
84
|
+
declaration = resolve_constant_in_index(namespace_node.identifier)
|
|
85
|
+
return false unless declaration.is_a?(Rubydex::Namespace)
|
|
86
|
+
|
|
87
|
+
scope = singleton_definition?(node) ? indexed_singleton_of(declaration) : declaration
|
|
88
|
+
!scope&.member('respond_to_missing?()').nil?
|
|
89
|
+
rescue StandardError
|
|
90
|
+
false
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def singleton_definition?(node)
|
|
94
|
+
node.defs_type? || node.each_ancestor(:sclass, :class, :module).first&.sclass_type?
|
|
95
|
+
end
|
|
96
|
+
|
|
67
97
|
def implements_respond_to_missing?(node)
|
|
68
98
|
scope = enclosing_scope(node)
|
|
69
99
|
search_root = scope || node.parent
|
|
@@ -36,7 +36,13 @@ module RuboCop
|
|
|
36
36
|
private
|
|
37
37
|
|
|
38
38
|
def non_modifier_then?(node)
|
|
39
|
-
node.multiline? && node
|
|
39
|
+
node.multiline? && own_then?(node) && node.loc.begin.line != node.if_branch&.loc&.line
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Prism gives an `elsif` with no `then` of its own the previous branch's `then` location,
|
|
43
|
+
# which lies outside the node.
|
|
44
|
+
def own_then?(node)
|
|
45
|
+
node.then? && node.source_range.contains?(node.loc.begin)
|
|
40
46
|
end
|
|
41
47
|
end
|
|
42
48
|
end
|
|
@@ -38,7 +38,7 @@ module RuboCop
|
|
|
38
38
|
|
|
39
39
|
private
|
|
40
40
|
|
|
41
|
-
# rubocop:disable Metrics/AbcSize
|
|
41
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
42
42
|
def autocorrect(corrector, node, begin_of_arguments)
|
|
43
43
|
arguments = node.arguments
|
|
44
44
|
joined_arguments = arguments.map(&:source).join(', ')
|
|
@@ -62,7 +62,6 @@ module RuboCop
|
|
|
62
62
|
corrector.remove(arguments_range)
|
|
63
63
|
corrector.insert_after(begin_of_arguments, joined_arguments)
|
|
64
64
|
end
|
|
65
|
-
# rubocop:enable Metrics/AbcSize
|
|
66
65
|
|
|
67
66
|
def last_line_source_of_arguments(arguments)
|
|
68
67
|
processed_source[arguments.last_line - 1].strip
|
|
@@ -70,48 +70,59 @@ module RuboCop
|
|
|
70
70
|
(send $_ :== ${lvar call})
|
|
71
71
|
PATTERN
|
|
72
72
|
|
|
73
|
-
# rubocop:disable Metrics/AbcSize
|
|
74
73
|
def on_or(node)
|
|
75
|
-
|
|
76
|
-
return unless node == root_of_or_node
|
|
74
|
+
return unless node == root_of_or_node(node)
|
|
77
75
|
return unless nested_comparison?(node)
|
|
78
|
-
|
|
79
|
-
return unless (variable, values = find_offending_var(node))
|
|
76
|
+
return unless (variable, values, skipped = find_offending_var(node))
|
|
80
77
|
return if values.size < comparisons_threshold
|
|
81
78
|
|
|
82
79
|
range = offense_range(values)
|
|
80
|
+
# Bail when an allowed method comparison sits between the collected
|
|
81
|
+
# values: collapsing them into a single `include?` would drop it.
|
|
82
|
+
return if skipped_within_range?(skipped, range)
|
|
83
83
|
|
|
84
84
|
add_offense(range) do |corrector|
|
|
85
|
-
|
|
86
|
-
argument = variable.lvar_type? ? variable_name(variable) : variable.source
|
|
87
|
-
prefer_method = "[#{elements}].include?(#{argument})"
|
|
88
|
-
|
|
89
|
-
corrector.replace(range, prefer_method)
|
|
85
|
+
corrector.replace(range, preferred_method(variable, values))
|
|
90
86
|
end
|
|
91
87
|
end
|
|
92
|
-
# rubocop:enable Metrics/AbcSize
|
|
93
88
|
|
|
94
89
|
private
|
|
95
90
|
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
def skipped_within_range?(skipped, range)
|
|
92
|
+
skipped.any? { |node_part| range.contains?(node_part.source_range) }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def preferred_method(variable, values)
|
|
96
|
+
elements = values.map(&:source).join(', ')
|
|
97
|
+
argument = variable.lvar_type? ? variable_name(variable) : variable.source
|
|
98
|
+
"[#{elements}].include?(#{argument})"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def find_offending_var(node, variables = Set.new, values = [], skipped = [])
|
|
98
102
|
if node.or_type?
|
|
99
|
-
find_offending_var(node.lhs, variables, values)
|
|
100
|
-
find_offending_var(node.rhs, variables, values)
|
|
103
|
+
find_offending_var(node.lhs, variables, values, skipped)
|
|
104
|
+
find_offending_var(node.rhs, variables, values, skipped)
|
|
101
105
|
elsif simple_double_comparison?(node)
|
|
102
106
|
return
|
|
103
|
-
elsif (
|
|
104
|
-
|
|
107
|
+
elsif (comparison = simple_comparison(node))
|
|
108
|
+
collect_comparison(node, comparison, variables, values, skipped)
|
|
109
|
+
end
|
|
105
110
|
|
|
106
|
-
|
|
107
|
-
|
|
111
|
+
[variables.first, values, skipped] if variables.any?
|
|
112
|
+
end
|
|
108
113
|
|
|
109
|
-
|
|
114
|
+
def collect_comparison(node, comparison, variables, values, skipped)
|
|
115
|
+
var, obj = comparison
|
|
116
|
+
if allow_method_comparison? && obj.call_type?
|
|
117
|
+
skipped << node
|
|
118
|
+
return
|
|
110
119
|
end
|
|
111
120
|
|
|
112
|
-
|
|
121
|
+
variables << var
|
|
122
|
+
return if variables.size > 1
|
|
123
|
+
|
|
124
|
+
values << obj
|
|
113
125
|
end
|
|
114
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
115
126
|
|
|
116
127
|
def offense_range(values)
|
|
117
128
|
values.first.parent.source_range.begin.join(values.last.parent.source_range.end)
|
|
@@ -89,6 +89,9 @@ module RuboCop
|
|
|
89
89
|
# end
|
|
90
90
|
# end.freeze
|
|
91
91
|
#
|
|
92
|
+
# # good - `Data.define` declares an immutable value type
|
|
93
|
+
# CONST = Data.define(:foo, :bar)
|
|
94
|
+
#
|
|
92
95
|
# @example
|
|
93
96
|
# # Magic comment - shareable_constant_value: literal
|
|
94
97
|
#
|
|
@@ -319,6 +322,8 @@ module RuboCop
|
|
|
319
322
|
(const _ _)
|
|
320
323
|
(send (const {nil? cbase} :Struct) :new ...)
|
|
321
324
|
(block (send (const {nil? cbase} :Struct) :new ...) ...)
|
|
325
|
+
(send (const {nil? cbase} :Data) :define ...)
|
|
326
|
+
(block (send (const {nil? cbase} :Data) :define ...) ...)
|
|
322
327
|
(send _ :freeze)
|
|
323
328
|
(send {float int} {:+ :- :* :** :/ :% :<<} _)
|
|
324
329
|
(send _ {:+ :- :* :** :/ :%} {float int})
|