rubocop 0.72.0 → 0.76.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -1
- data/bin/console +1 -0
- data/config/default.yml +93 -56
- data/lib/rubocop.rb +21 -10
- data/lib/rubocop/ast/builder.rb +1 -0
- data/lib/rubocop/ast/node.rb +12 -14
- data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +4 -4
- data/lib/rubocop/ast/node/return_node.rb +24 -0
- data/lib/rubocop/ast/traversal.rb +3 -3
- data/lib/rubocop/cli.rb +7 -4
- data/lib/rubocop/comment_config.rb +5 -4
- data/lib/rubocop/config.rb +28 -537
- data/lib/rubocop/config_loader.rb +21 -3
- data/lib/rubocop/config_loader_resolver.rb +4 -3
- data/lib/rubocop/config_obsoletion.rb +222 -0
- data/lib/rubocop/config_validator.rb +248 -0
- data/lib/rubocop/cop/autocorrect_logic.rb +71 -1
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +1 -1
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/commissioner.rb +18 -16
- data/lib/rubocop/cop/cop.rb +49 -14
- data/lib/rubocop/cop/corrector.rb +10 -10
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +43 -17
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +1 -1
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +1 -1
- data/lib/rubocop/cop/generator.rb +4 -4
- data/lib/rubocop/cop/generator/configuration_injector.rb +9 -4
- data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -2
- data/lib/rubocop/cop/layout/align_hash.rb +6 -2
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -3
- data/lib/rubocop/cop/layout/class_structure.rb +1 -1
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/comment_indentation.rb +10 -13
- data/lib/rubocop/cop/layout/empty_comment.rb +7 -16
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +22 -7
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +2 -2
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +2 -2
- data/lib/rubocop/cop/layout/end_of_line.rb +8 -3
- data/lib/rubocop/cop/layout/extra_spacing.rb +14 -59
- data/lib/rubocop/cop/layout/indent_assignment.rb +10 -1
- data/lib/rubocop/cop/layout/indent_first_argument.rb +10 -8
- data/lib/rubocop/cop/layout/indent_first_hash_element.rb +1 -1
- data/lib/rubocop/cop/layout/indent_heredoc.rb +4 -3
- data/lib/rubocop/cop/layout/indentation_width.rb +20 -6
- data/lib/rubocop/cop/layout/leading_comment_space.rb +28 -0
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +24 -2
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +20 -4
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +5 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +42 -23
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -7
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +8 -5
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +21 -2
- data/lib/rubocop/cop/layout/space_inside_parens.rb +6 -6
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +24 -40
- data/lib/rubocop/cop/layout/tab.rb +10 -22
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +18 -2
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +17 -4
- data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -1
- data/lib/rubocop/cop/lint/debugger.rb +4 -6
- data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -3
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
- data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -4
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +62 -5
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +11 -37
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
- data/lib/rubocop/cop/lint/inherit_exception.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -8
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +2 -2
- data/lib/rubocop/cop/lint/multiple_compare.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +3 -3
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +3 -3
- data/lib/rubocop/cop/lint/rand_one.rb +1 -1
- data/lib/rubocop/cop/lint/{unneeded_cop_disable_directive.rb → redundant_cop_disable_directive.rb} +24 -24
- data/lib/rubocop/cop/lint/{unneeded_cop_enable_directive.rb → redundant_cop_enable_directive.rb} +6 -8
- data/lib/rubocop/cop/lint/{unneeded_require_statement.rb → redundant_require_statement.rb} +2 -2
- data/lib/rubocop/cop/lint/{unneeded_splat_expansion.rb → redundant_splat_expansion.rb} +12 -7
- data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +10 -11
- data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +91 -0
- data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +6 -6
- data/lib/rubocop/cop/lint/unified_integer.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
- data/lib/rubocop/cop/lint/unused_block_argument.rb +22 -6
- data/lib/rubocop/cop/lint/unused_method_argument.rb +23 -5
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -1
- data/lib/rubocop/cop/lint/uri_regexp.rb +2 -2
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +6 -6
- data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +7 -26
- data/lib/rubocop/cop/message_annotator.rb +16 -7
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +1 -1
- data/lib/rubocop/cop/metrics/line_length.rb +7 -4
- data/lib/rubocop/cop/metrics/module_length.rb +1 -1
- data/lib/rubocop/cop/metrics/parameter_lists.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +23 -6
- data/lib/rubocop/cop/migration/department_name.rb +44 -0
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/documentation_comment.rb +0 -2
- data/lib/rubocop/cop/mixin/empty_parameter.rb +1 -1
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +4 -4
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
- data/lib/rubocop/cop/mixin/method_complexity.rb +3 -2
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -3
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +87 -0
- data/lib/rubocop/cop/mixin/safe_mode.rb +2 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +5 -2
- data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -5
- data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -6
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +2 -2
- data/lib/rubocop/cop/naming/file_name.rb +12 -5
- data/lib/rubocop/cop/naming/method_name.rb +12 -1
- data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
- data/lib/rubocop/cop/naming/variable_name.rb +1 -0
- data/lib/rubocop/cop/offense.rb +18 -7
- data/lib/rubocop/cop/registry.rb +22 -1
- data/lib/rubocop/cop/security/eval.rb +1 -1
- data/lib/rubocop/cop/security/json_load.rb +1 -1
- data/lib/rubocop/cop/security/marshal_load.rb +1 -1
- data/lib/rubocop/cop/security/open.rb +1 -1
- data/lib/rubocop/cop/security/yaml_load.rb +1 -1
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -0
- data/lib/rubocop/cop/style/alias.rb +1 -1
- data/lib/rubocop/cop/style/attr.rb +2 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +35 -16
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
- data/lib/rubocop/cop/style/colon_method_call.rb +1 -1
- data/lib/rubocop/cop/style/comment_annotation.rb +5 -5
- data/lib/rubocop/cop/style/commented_keyword.rb +16 -30
- data/lib/rubocop/cop/style/conditional_assignment.rb +6 -8
- data/lib/rubocop/cop/style/constant_visibility.rb +14 -3
- data/lib/rubocop/cop/style/copyright.rb +11 -7
- data/lib/rubocop/cop/style/date_time.rb +3 -3
- data/lib/rubocop/cop/style/dir.rb +1 -1
- data/lib/rubocop/cop/style/documentation_method.rb +45 -1
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +55 -0
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/each_with_object.rb +1 -1
- data/lib/rubocop/cop/style/empty_case_condition.rb +2 -2
- data/lib/rubocop/cop/style/empty_literal.rb +2 -2
- data/lib/rubocop/cop/style/empty_method.rb +5 -5
- data/lib/rubocop/cop/style/eval_with_location.rb +2 -2
- data/lib/rubocop/cop/style/even_odd.rb +1 -1
- data/lib/rubocop/cop/style/expand_path_arguments.rb +4 -4
- data/lib/rubocop/cop/style/float_division.rb +4 -4
- data/lib/rubocop/cop/style/format_string.rb +17 -14
- data/lib/rubocop/cop/style/format_string_token.rb +19 -68
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +28 -33
- data/lib/rubocop/cop/style/guard_clause.rb +39 -10
- data/lib/rubocop/cop/style/hash_syntax.rb +4 -4
- data/lib/rubocop/cop/style/if_unless_modifier.rb +58 -15
- data/lib/rubocop/cop/style/infinite_loop.rb +5 -4
- data/lib/rubocop/cop/style/inverse_methods.rb +21 -15
- data/lib/rubocop/cop/style/lambda.rb +0 -2
- data/lib/rubocop/cop/style/line_end_concatenation.rb +14 -10
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +25 -25
- data/lib/rubocop/cop/style/method_def_parentheses.rb +17 -9
- data/lib/rubocop/cop/style/min_max.rb +1 -1
- data/lib/rubocop/cop/style/mixin_usage.rb +12 -2
- data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +55 -0
- data/lib/rubocop/cop/style/multiple_comparison.rb +1 -1
- data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
- data/lib/rubocop/cop/style/nested_modifier.rb +22 -4
- data/lib/rubocop/cop/style/non_nil_check.rb +21 -9
- data/lib/rubocop/cop/style/numeric_predicate.rb +3 -3
- data/lib/rubocop/cop/style/option_hash.rb +1 -1
- data/lib/rubocop/cop/style/or_assignment.rb +8 -3
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +15 -1
- data/lib/rubocop/cop/style/random_with_offset.rb +6 -6
- data/lib/rubocop/cop/style/{unneeded_capital_w.rb → redundant_capital_w.rb} +1 -1
- data/lib/rubocop/cop/style/{unneeded_condition.rb → redundant_condition.rb} +3 -3
- data/lib/rubocop/cop/style/redundant_conditional.rb +2 -2
- data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
- data/lib/rubocop/cop/style/{unneeded_interpolation.rb → redundant_interpolation.rb} +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +15 -6
- data/lib/rubocop/cop/style/{unneeded_percent_q.rb → redundant_percent_q.rb} +1 -1
- data/lib/rubocop/cop/style/redundant_return.rb +37 -21
- data/lib/rubocop/cop/style/redundant_self.rb +18 -1
- data/lib/rubocop/cop/style/{unneeded_sort.rb → redundant_sort.rb} +4 -4
- data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +24 -0
- data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
- data/lib/rubocop/cop/style/return_nil.rb +1 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +24 -4
- data/lib/rubocop/cop/style/sample.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +13 -2
- data/lib/rubocop/cop/style/single_line_methods.rb +8 -1
- data/lib/rubocop/cop/style/special_global_vars.rb +5 -7
- data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
- data/lib/rubocop/cop/style/string_hash_keys.rb +2 -2
- data/lib/rubocop/cop/style/strip.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +3 -3
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
- data/lib/rubocop/cop/style/ternary_parentheses.rb +20 -1
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +4 -6
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/unpack_first.rb +1 -1
- data/lib/rubocop/cop/style/variable_interpolation.rb +6 -16
- data/lib/rubocop/cop/style/zero_length_predicate.rb +5 -5
- data/lib/rubocop/cop/team.rb +15 -14
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/utils/format_string.rb +120 -0
- data/lib/rubocop/cop/variable_force.rb +7 -5
- data/lib/rubocop/cop/variable_force/variable.rb +15 -2
- data/lib/rubocop/core_ext/string.rb +0 -24
- data/lib/rubocop/error.rb +23 -0
- data/lib/rubocop/formatter/clang_style_formatter.rb +8 -3
- data/lib/rubocop/formatter/emacs_style_formatter.rb +22 -9
- data/lib/rubocop/formatter/file_list_formatter.rb +1 -1
- data/lib/rubocop/formatter/formatter_set.rb +16 -15
- data/lib/rubocop/formatter/pacman_formatter.rb +80 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +16 -4
- data/lib/rubocop/formatter/tap_formatter.rb +17 -4
- data/lib/rubocop/magic_comment.rb +4 -0
- data/lib/rubocop/node_pattern.rb +5 -3
- data/lib/rubocop/options.rb +33 -21
- data/lib/rubocop/path_util.rb +1 -1
- data/lib/rubocop/processed_source.rb +4 -0
- data/lib/rubocop/result_cache.rb +1 -1
- data/lib/rubocop/rspec/expect_offense.rb +4 -1
- data/lib/rubocop/rspec/shared_contexts.rb +12 -0
- data/lib/rubocop/runner.rb +42 -31
- data/lib/rubocop/target_finder.rb +12 -4
- data/lib/rubocop/version.rb +1 -1
- metadata +21 -12
- data/lib/rubocop/cop/mixin/ignored_method_patterns.rb +0 -19
@@ -3,11 +3,16 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# This cop is designed to help
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
6
|
+
# This cop is designed to help you transition from mutable string literals
|
7
|
+
# to frozen string literals.
|
8
|
+
# It will add the comment `# frozen_string_literal: true` to the top of
|
9
|
+
# files to enable frozen string literals. Frozen string literals may be
|
10
|
+
# default in future Ruby. The comment will be added below a shebang and
|
11
|
+
# encoding comment. The frozen string literal comment is only valid in
|
12
|
+
# Ruby 2.3+.
|
13
|
+
#
|
14
|
+
# Note that the cop will ignore files where the comment exists but is set
|
15
|
+
# to `false` instead of `true`.
|
11
16
|
#
|
12
17
|
# @example EnforcedStyle: always (default)
|
13
18
|
# # The `always` style will always add the frozen string literal comment
|
@@ -25,6 +30,13 @@ module RuboCop
|
|
25
30
|
# # ...
|
26
31
|
# end
|
27
32
|
#
|
33
|
+
# # good
|
34
|
+
# # frozen_string_literal: false
|
35
|
+
#
|
36
|
+
# module Bar
|
37
|
+
# # ...
|
38
|
+
# end
|
39
|
+
#
|
28
40
|
# @example EnforcedStyle: never
|
29
41
|
# # The `never` will enforce that the frozen string literal comment does
|
30
42
|
# # not exist in a file.
|
@@ -121,42 +133,25 @@ module RuboCop
|
|
121
133
|
end
|
122
134
|
|
123
135
|
def insert_comment(corrector)
|
124
|
-
|
125
|
-
if last_special_comment.nil?
|
126
|
-
corrector.insert_before(correction_range, preceding_comment)
|
127
|
-
else
|
128
|
-
corrector.insert_after(correction_range, proceeding_comment)
|
129
|
-
end
|
130
|
-
end
|
136
|
+
comment = last_special_comment(processed_source)
|
131
137
|
|
132
|
-
|
133
|
-
|
134
|
-
"#{FROZEN_STRING_LITERAL_ENABLED}\n"
|
138
|
+
if comment
|
139
|
+
corrector.insert_after(line_range(comment.line), following_comment)
|
135
140
|
else
|
136
|
-
|
141
|
+
corrector.insert_before(line_range(1), preceding_comment)
|
137
142
|
end
|
138
143
|
end
|
139
144
|
|
140
|
-
def
|
141
|
-
|
142
|
-
following_line = processed_source.following_line(last_special_comment)
|
143
|
-
|
144
|
-
if following_line&.empty?
|
145
|
-
"\n#{FROZEN_STRING_LITERAL_ENABLED}"
|
146
|
-
else
|
147
|
-
"\n#{FROZEN_STRING_LITERAL_ENABLED}\n"
|
148
|
-
end
|
145
|
+
def line_range(line)
|
146
|
+
processed_source.buffer.line_range(line)
|
149
147
|
end
|
150
148
|
|
151
|
-
def
|
152
|
-
|
149
|
+
def preceding_comment
|
150
|
+
"#{FROZEN_STRING_LITERAL_ENABLED}\n"
|
151
|
+
end
|
153
152
|
|
154
|
-
|
155
|
-
|
156
|
-
side: :left)
|
157
|
-
else
|
158
|
-
last_special_comment.pos
|
159
|
-
end
|
153
|
+
def following_comment
|
154
|
+
"\n#{FROZEN_STRING_LITERAL_ENABLED}"
|
160
155
|
end
|
161
156
|
end
|
162
157
|
end
|
@@ -37,9 +37,10 @@ module RuboCop
|
|
37
37
|
# ok
|
38
38
|
class GuardClause < Cop
|
39
39
|
include MinBodyLength
|
40
|
+
include StatementModifier
|
40
41
|
|
41
|
-
MSG = 'Use a guard clause instead of wrapping the
|
42
|
-
'conditional expression.'
|
42
|
+
MSG = 'Use a guard clause (`%<example>s`) instead of wrapping the ' \
|
43
|
+
'code inside a conditional expression.'
|
43
44
|
|
44
45
|
def on_def(node)
|
45
46
|
body = node.body
|
@@ -55,9 +56,19 @@ module RuboCop
|
|
55
56
|
alias on_defs on_def
|
56
57
|
|
57
58
|
def on_if(node)
|
58
|
-
return if accepted_form?(node)
|
59
|
+
return if accepted_form?(node)
|
59
60
|
|
60
|
-
|
61
|
+
guard_clause_in_if = node.if_branch&.guard_clause?
|
62
|
+
guard_clause_in_else = node.else_branch&.guard_clause?
|
63
|
+
guard_clause = guard_clause_in_if || guard_clause_in_else
|
64
|
+
return unless guard_clause
|
65
|
+
|
66
|
+
kw = if guard_clause_in_if
|
67
|
+
node.loc.keyword.source
|
68
|
+
else
|
69
|
+
opposite_keyword(node)
|
70
|
+
end
|
71
|
+
register_offense(node, guard_clause.source, kw)
|
61
72
|
end
|
62
73
|
|
63
74
|
private
|
@@ -65,7 +76,30 @@ module RuboCop
|
|
65
76
|
def check_ending_if(node)
|
66
77
|
return if accepted_form?(node, true) || !min_body_length?(node)
|
67
78
|
|
68
|
-
|
79
|
+
register_offense(node, 'return', opposite_keyword(node))
|
80
|
+
end
|
81
|
+
|
82
|
+
def opposite_keyword(node)
|
83
|
+
node.if? ? 'unless' : 'if'
|
84
|
+
end
|
85
|
+
|
86
|
+
def register_offense(node, scope_exiting_keyword, conditional_keyword)
|
87
|
+
condition, = node.node_parts
|
88
|
+
example = [scope_exiting_keyword,
|
89
|
+
conditional_keyword,
|
90
|
+
condition.source].join(' ')
|
91
|
+
if too_long_for_single_line?(node, example)
|
92
|
+
example = "#{conditional_keyword} #{condition.source}; " \
|
93
|
+
"#{scope_exiting_keyword}; end"
|
94
|
+
end
|
95
|
+
add_offense(node,
|
96
|
+
location: :keyword,
|
97
|
+
message: format(MSG, example: example))
|
98
|
+
end
|
99
|
+
|
100
|
+
def too_long_for_single_line?(node, example)
|
101
|
+
max = max_line_length
|
102
|
+
max && node.source_range.column + example.length > max
|
69
103
|
end
|
70
104
|
|
71
105
|
def accepted_form?(node, ending = false)
|
@@ -81,11 +115,6 @@ module RuboCop
|
|
81
115
|
!node.else? || node.elsif?
|
82
116
|
end
|
83
117
|
end
|
84
|
-
|
85
|
-
def contains_guard_clause?(node)
|
86
|
-
node.if_branch&.guard_clause? ||
|
87
|
-
node.else_branch&.guard_clause?
|
88
|
-
end
|
89
118
|
end
|
90
119
|
end
|
91
120
|
end
|
@@ -118,9 +118,9 @@ module RuboCop
|
|
118
118
|
|
119
119
|
def alternative_style
|
120
120
|
case style
|
121
|
-
when :hash_rockets
|
121
|
+
when :hash_rockets
|
122
122
|
:ruby19
|
123
|
-
when :ruby19, :ruby19_no_mixed_keys
|
123
|
+
when :ruby19, :ruby19_no_mixed_keys
|
124
124
|
:hash_rockets
|
125
125
|
end
|
126
126
|
end
|
@@ -168,10 +168,10 @@ module RuboCop
|
|
168
168
|
end
|
169
169
|
|
170
170
|
def autocorrect_ruby19(corrector, pair_node)
|
171
|
-
key = pair_node.key
|
171
|
+
key = pair_node.key.source_range
|
172
172
|
op = pair_node.loc.operator
|
173
173
|
|
174
|
-
range =
|
174
|
+
range = key.join(op)
|
175
175
|
range = range_with_surrounding_space(range: range, side: :right)
|
176
176
|
|
177
177
|
space = argument_without_space?(pair_node.parent) ? ' ' : ''
|
@@ -3,10 +3,13 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Checks for if and unless statements that would fit on one line
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
6
|
+
# Checks for `if` and `unless` statements that would fit on one line if
|
7
|
+
# written as modifier `if`/`unless`. The cop also checks for modifier
|
8
|
+
# `if`/`unless` lines that exceed the maximum line length.
|
9
|
+
#
|
10
|
+
# The maximum line length is configured in the `Metrics/LineLength`
|
11
|
+
# cop. The tab size is configured in the `IndentationWidth` of the
|
12
|
+
# `Layout/Tab` cop.
|
10
13
|
#
|
11
14
|
# @example
|
12
15
|
# # bad
|
@@ -18,35 +21,66 @@ module RuboCop
|
|
18
21
|
# Foo.do_something
|
19
22
|
# end
|
20
23
|
#
|
24
|
+
# do_something_in_a_method_with_a_long_name(arg) if long_condition
|
25
|
+
#
|
21
26
|
# # good
|
22
27
|
# do_stuff(bar) if condition
|
23
28
|
# Foo.do_something unless qux.empty?
|
29
|
+
#
|
30
|
+
# if long_condition
|
31
|
+
# do_something_in_a_method_with_a_long_name(arg)
|
32
|
+
# end
|
24
33
|
class IfUnlessModifier < Cop
|
25
34
|
include StatementModifier
|
26
35
|
|
27
|
-
|
28
|
-
|
29
|
-
|
36
|
+
MSG_USE_MODIFIER = 'Favor modifier `%<keyword>s` usage when having a ' \
|
37
|
+
'single-line body. Another good alternative is ' \
|
38
|
+
'the usage of control flow `&&`/`||`.'
|
39
|
+
MSG_USE_NORMAL =
|
40
|
+
'Modifier form of `%<keyword>s` makes the line too long.'
|
30
41
|
|
31
42
|
ASSIGNMENT_TYPES = %i[lvasgn casgn cvasgn
|
32
43
|
gvasgn ivasgn masgn].freeze
|
33
44
|
|
34
45
|
def on_if(node)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
46
|
+
msg = if eligible_node?(node)
|
47
|
+
MSG_USE_MODIFIER unless named_capture_in_condition?(node)
|
48
|
+
elsif node.modifier_form? && too_long_single_line?(node)
|
49
|
+
MSG_USE_NORMAL
|
50
|
+
end
|
51
|
+
return unless msg
|
52
|
+
|
53
|
+
add_offense(node,
|
54
|
+
location: :keyword,
|
55
|
+
message: format(msg, keyword: node.keyword))
|
40
56
|
end
|
41
57
|
|
42
58
|
def autocorrect(node)
|
43
|
-
|
44
|
-
|
45
|
-
|
59
|
+
replacement = if node.modifier_form?
|
60
|
+
to_normal_form(node)
|
61
|
+
else
|
62
|
+
to_modifier_form(node)
|
63
|
+
end
|
64
|
+
->(corrector) { corrector.replace(node.source_range, replacement) }
|
46
65
|
end
|
47
66
|
|
48
67
|
private
|
49
68
|
|
69
|
+
def too_long_single_line?(node)
|
70
|
+
return false unless max_line_length
|
71
|
+
|
72
|
+
range = node.source_range
|
73
|
+
return false unless range.first_line == range.last_line
|
74
|
+
return false unless line_length_enabled_at_line?(range.first_line)
|
75
|
+
|
76
|
+
range.last_column > max_line_length
|
77
|
+
end
|
78
|
+
|
79
|
+
def line_length_enabled_at_line?(line)
|
80
|
+
processed_source.comment_config
|
81
|
+
.cop_enabled_at_line?('Metrics/LineLength', line)
|
82
|
+
end
|
83
|
+
|
50
84
|
def named_capture_in_condition?(node)
|
51
85
|
node.condition.match_with_lvasgn_type?
|
52
86
|
end
|
@@ -79,6 +113,15 @@ module RuboCop
|
|
79
113
|
parenthesize?(node) ? "(#{expression})" : expression
|
80
114
|
end
|
81
115
|
|
116
|
+
def to_normal_form(node)
|
117
|
+
indentation = ' ' * node.source_range.column
|
118
|
+
<<~RUBY.chomp
|
119
|
+
#{node.keyword} #{node.condition.source}
|
120
|
+
#{indentation} #{node.body.source}
|
121
|
+
#{indentation}end
|
122
|
+
RUBY
|
123
|
+
end
|
124
|
+
|
82
125
|
def first_line_comment(node)
|
83
126
|
comment =
|
84
127
|
processed_source.find_comment { |c| c.loc.line == node.loc.line }
|
@@ -97,12 +97,13 @@ module RuboCop
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def modifier_replacement(node)
|
100
|
+
body = node.body
|
100
101
|
if node.single_line?
|
101
|
-
'loop { ' +
|
102
|
+
'loop { ' + body.source + ' }'
|
102
103
|
else
|
103
|
-
indentation =
|
104
|
+
indentation = body.source_range.source_line[LEADING_SPACE]
|
104
105
|
|
105
|
-
['loop do',
|
106
|
+
['loop do', body.source.gsub(/^/, configured_indent),
|
106
107
|
'end'].join("\n#{indentation}")
|
107
108
|
end
|
108
109
|
end
|
@@ -119,7 +120,7 @@ module RuboCop
|
|
119
120
|
end
|
120
121
|
|
121
122
|
def configured_indent
|
122
|
-
' ' * config.for_cop('IndentationWidth')['Width']
|
123
|
+
' ' * config.for_cop('Layout/IndentationWidth')['Width']
|
123
124
|
end
|
124
125
|
end
|
125
126
|
end
|
@@ -47,7 +47,7 @@ module RuboCop
|
|
47
47
|
[Style::Not]
|
48
48
|
end
|
49
49
|
|
50
|
-
def_node_matcher :inverse_candidate?,
|
50
|
+
def_node_matcher :inverse_candidate?, <<~PATTERN
|
51
51
|
{
|
52
52
|
(send $(send $(...) $_ $...) :!)
|
53
53
|
(send (block $(send $(...) $_) $...) :!)
|
@@ -55,7 +55,7 @@ module RuboCop
|
|
55
55
|
}
|
56
56
|
PATTERN
|
57
57
|
|
58
|
-
def_node_matcher :inverse_block?,
|
58
|
+
def_node_matcher :inverse_block?, <<~PATTERN
|
59
59
|
(block $(send (...) $_) ... { $(send ... :!)
|
60
60
|
$(send (...) {:!= :!~} ...)
|
61
61
|
(begin ... $(send ... :!))
|
@@ -94,20 +94,25 @@ module RuboCop
|
|
94
94
|
end
|
95
95
|
|
96
96
|
def autocorrect(node)
|
97
|
+
if node.block_type?
|
98
|
+
correct_inverse_block(node)
|
99
|
+
elsif node.send_type?
|
100
|
+
correct_inverse_method(node)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def correct_inverse_method(node)
|
97
105
|
method_call, _lhs, method, _rhs = inverse_candidate?(node)
|
106
|
+
return unless method_call && method
|
98
107
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
inverse_methods[method].to_s)
|
108
|
+
lambda do |corrector|
|
109
|
+
corrector.remove(not_to_receiver(node, method_call))
|
110
|
+
corrector.replace(method_call.loc.selector,
|
111
|
+
inverse_methods[method].to_s)
|
104
112
|
|
105
|
-
|
106
|
-
|
107
|
-
end
|
113
|
+
if EQUALITY_METHODS.include?(method)
|
114
|
+
corrector.remove(end_parentheses(node, method_call))
|
108
115
|
end
|
109
|
-
else
|
110
|
-
correct_inverse_block(node)
|
111
116
|
end
|
112
117
|
end
|
113
118
|
|
@@ -122,18 +127,19 @@ module RuboCop
|
|
122
127
|
end
|
123
128
|
|
124
129
|
def correct_inverse_selector(block, corrector)
|
125
|
-
|
130
|
+
selector_loc = block.loc.selector
|
131
|
+
selector = selector_loc.source
|
126
132
|
|
127
133
|
if NEGATED_EQUALITY_METHODS.include?(selector.to_sym)
|
128
134
|
selector[0] = '='
|
129
|
-
corrector.replace(
|
135
|
+
corrector.replace(selector_loc, selector)
|
130
136
|
else
|
131
137
|
if block.loc.dot
|
132
138
|
range = dot_range(block.loc)
|
133
139
|
corrector.remove(range)
|
134
140
|
end
|
135
141
|
|
136
|
-
corrector.remove(
|
142
|
+
corrector.remove(selector_loc)
|
137
143
|
end
|
138
144
|
end
|
139
145
|
|
@@ -26,13 +26,14 @@ module RuboCop
|
|
26
26
|
'those strings.'
|
27
27
|
CONCAT_TOKEN_TYPES = %i[tPLUS tLSHFT].freeze
|
28
28
|
SIMPLE_STRING_TOKEN_TYPE = :tSTRING
|
29
|
-
|
29
|
+
COMPLEX_STRING_BEGIN_TOKEN = :tSTRING_BEG
|
30
|
+
COMPLEX_STRING_END_TOKEN = :tSTRING_END
|
30
31
|
HIGH_PRECEDENCE_OP_TOKEN_TYPES = %i[tSTAR2 tPERCENT tDOT
|
31
32
|
tLBRACK2].freeze
|
32
33
|
QUOTE_DELIMITERS = %w[' "].freeze
|
33
34
|
|
34
35
|
def self.autocorrect_incompatible_with
|
35
|
-
[Style::
|
36
|
+
[Style::RedundantInterpolation]
|
36
37
|
end
|
37
38
|
|
38
39
|
def investigate(processed_source)
|
@@ -59,9 +60,7 @@ module RuboCop
|
|
59
60
|
def check_token_set(index)
|
60
61
|
predecessor, operator, successor = processed_source.tokens[index, 3]
|
61
62
|
|
62
|
-
return unless
|
63
|
-
eligible_operator?(operator) &&
|
64
|
-
eligible_predecessor?(predecessor)
|
63
|
+
return unless eligible_token_set?(predecessor, operator, successor)
|
65
64
|
|
66
65
|
return if operator.line == successor.line
|
67
66
|
|
@@ -72,6 +71,12 @@ module RuboCop
|
|
72
71
|
add_offense(operator.pos, location: operator.pos)
|
73
72
|
end
|
74
73
|
|
74
|
+
def eligible_token_set?(predecessor, operator, successor)
|
75
|
+
eligible_successor?(successor) &&
|
76
|
+
eligible_operator?(operator) &&
|
77
|
+
eligible_predecessor?(predecessor)
|
78
|
+
end
|
79
|
+
|
75
80
|
def eligible_successor?(successor)
|
76
81
|
successor && standard_string_literal?(successor)
|
77
82
|
end
|
@@ -91,13 +96,12 @@ module RuboCop
|
|
91
96
|
|
92
97
|
def token_after_last_string(successor, base_index)
|
93
98
|
index = base_index + 3
|
94
|
-
|
95
|
-
if successor.type == begin_token
|
99
|
+
if successor.type == COMPLEX_STRING_BEGIN_TOKEN
|
96
100
|
ends_to_find = 1
|
97
101
|
while ends_to_find.positive?
|
98
102
|
case processed_source.tokens[index].type
|
99
|
-
when
|
100
|
-
when
|
103
|
+
when COMPLEX_STRING_BEGIN_TOKEN then ends_to_find += 1
|
104
|
+
when COMPLEX_STRING_END_TOKEN then ends_to_find -= 1
|
101
105
|
end
|
102
106
|
index += 1
|
103
107
|
end
|
@@ -109,7 +113,7 @@ module RuboCop
|
|
109
113
|
case token.type
|
110
114
|
when SIMPLE_STRING_TOKEN_TYPE
|
111
115
|
true
|
112
|
-
when
|
116
|
+
when COMPLEX_STRING_BEGIN_TOKEN, COMPLEX_STRING_END_TOKEN
|
113
117
|
QUOTE_DELIMITERS.include?(token.text)
|
114
118
|
else
|
115
119
|
false
|