rubocop 0.70.0 → 0.75.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 +6 -10
- data/bin/console +1 -0
- data/config/default.yml +91 -494
- data/lib/rubocop.rb +16 -54
- data/lib/rubocop/ast/builder.rb +2 -0
- data/lib/rubocop/ast/node.rb +9 -15
- data/lib/rubocop/ast/node/float_node.rb +12 -0
- data/lib/rubocop/ast/node/int_node.rb +12 -0
- data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +4 -4
- data/lib/rubocop/ast/node/mixin/numeric_node.rb +21 -0
- data/lib/rubocop/ast/node/resbody_node.rb +1 -6
- data/lib/rubocop/ast/traversal.rb +3 -3
- data/lib/rubocop/cached_data.rb +1 -1
- data/lib/rubocop/comment_config.rb +3 -2
- data/lib/rubocop/config.rb +21 -508
- data/lib/rubocop/config_loader.rb +22 -4
- data/lib/rubocop/config_loader_resolver.rb +2 -8
- data/lib/rubocop/config_obsoletion.rb +213 -0
- data/lib/rubocop/config_validator.rb +239 -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 +3 -9
- data/lib/rubocop/cop/cop.rb +39 -12
- data/lib/rubocop/cop/corrector.rb +2 -3
- 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/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 +55 -0
- 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/block_alignment.rb +3 -3
- data/lib/rubocop/cop/layout/class_structure.rb +2 -2
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +3 -1
- data/lib/rubocop/cop/layout/extra_spacing.rb +14 -59
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +4 -0
- data/lib/rubocop/cop/layout/indent_assignment.rb +9 -1
- data/lib/rubocop/cop/layout/indent_first_argument.rb +7 -3
- data/lib/rubocop/cop/layout/indent_first_parameter.rb +7 -3
- data/lib/rubocop/cop/layout/indent_heredoc.rb +4 -4
- data/lib/rubocop/cop/layout/indentation_consistency.rb +13 -12
- data/lib/rubocop/cop/layout/indentation_width.rb +28 -10
- data/lib/rubocop/cop/layout/leading_comment_space.rb +28 -0
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +24 -2
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +2 -0
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +18 -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_inside_array_literal_brackets.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +21 -2
- 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/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 +57 -1
- 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/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 +4 -4
- data/lib/rubocop/cop/lint/rand_one.rb +1 -1
- 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 +5 -5
- 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/unneeded_cop_disable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/unneeded_require_statement.rb +1 -1
- data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +7 -2
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
- 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/message_annotator.rb +16 -7
- data/lib/rubocop/cop/metrics/class_length.rb +1 -1
- data/lib/rubocop/cop/metrics/line_length.rb +6 -0
- data/lib/rubocop/cop/metrics/module_length.rb +1 -1
- data/lib/rubocop/cop/metrics/parameter_lists.rb +1 -1
- 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/hash_alignment.rb +4 -0
- data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
- 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/surrounding_space.rb +7 -5
- 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/method_name.rb +12 -1
- data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +20 -22
- 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/block_delimiters.rb +2 -1
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +29 -10
- 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/commented_keyword.rb +16 -30
- data/lib/rubocop/cop/style/conditional_assignment.rb +8 -9
- data/lib/rubocop/cop/style/constant_visibility.rb +14 -3
- 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 +1 -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/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 +3 -3
- data/lib/rubocop/cop/style/float_division.rb +94 -0
- data/lib/rubocop/cop/style/format_string.rb +13 -9
- data/lib/rubocop/cop/style/format_string_token.rb +10 -40
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +18 -33
- data/lib/rubocop/cop/style/guard_clause.rb +39 -10
- data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
- data/lib/rubocop/cop/style/if_inside_else.rb +42 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +51 -15
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +2 -2
- data/lib/rubocop/cop/style/lambda.rb +0 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +12 -6
- 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 +18 -2
- 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/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/redundant_parentheses.rb +15 -6
- data/lib/rubocop/cop/style/redundant_self.rb +18 -1
- 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 +11 -2
- data/lib/rubocop/cop/style/sample.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +8 -1
- 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 +32 -3
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -0
- 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/unneeded_sort.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/word_array.rb +2 -2
- data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -6
- data/lib/rubocop/cop/team.rb +15 -14
- data/lib/rubocop/cop/utils/format_string.rb +128 -0
- 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/emacs_style_formatter.rb +8 -5
- data/lib/rubocop/formatter/formatter_set.rb +2 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +80 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +9 -1
- data/lib/rubocop/formatter/tap_formatter.rb +9 -1
- data/lib/rubocop/magic_comment.rb +4 -0
- data/lib/rubocop/node_pattern.rb +86 -7
- data/lib/rubocop/options.rb +18 -2
- data/lib/rubocop/path_util.rb +1 -1
- data/lib/rubocop/processed_source.rb +9 -1
- data/lib/rubocop/rspec/cop_helper.rb +0 -1
- data/lib/rubocop/rspec/expect_offense.rb +4 -1
- data/lib/rubocop/rspec/shared_contexts.rb +12 -17
- data/lib/rubocop/rspec/support.rb +0 -1
- data/lib/rubocop/runner.rb +20 -15
- data/lib/rubocop/target_finder.rb +6 -4
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop/yaml_duplication_checker.rb +8 -2
- metadata +16 -70
- data/lib/rubocop/cop/mixin/ignored_method_patterns.rb +0 -19
- data/lib/rubocop/cop/mixin/target_rails_version.rb +0 -16
- data/lib/rubocop/cop/rails/action_filter.rb +0 -117
- data/lib/rubocop/cop/rails/active_record_aliases.rb +0 -48
- data/lib/rubocop/cop/rails/active_record_override.rb +0 -82
- data/lib/rubocop/cop/rails/active_support_aliases.rb +0 -69
- data/lib/rubocop/cop/rails/application_job.rb +0 -40
- data/lib/rubocop/cop/rails/application_record.rb +0 -40
- data/lib/rubocop/cop/rails/assert_not.rb +0 -44
- data/lib/rubocop/cop/rails/belongs_to.rb +0 -102
- data/lib/rubocop/cop/rails/blank.rb +0 -164
- data/lib/rubocop/cop/rails/bulk_change_table.rb +0 -289
- data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +0 -91
- data/lib/rubocop/cop/rails/date.rb +0 -161
- data/lib/rubocop/cop/rails/delegate.rb +0 -132
- data/lib/rubocop/cop/rails/delegate_allow_blank.rb +0 -37
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +0 -91
- data/lib/rubocop/cop/rails/enum_uniqueness.rb +0 -45
- data/lib/rubocop/cop/rails/environment_comparison.rb +0 -68
- data/lib/rubocop/cop/rails/exit.rb +0 -67
- data/lib/rubocop/cop/rails/file_path.rb +0 -108
- data/lib/rubocop/cop/rails/find_by.rb +0 -55
- data/lib/rubocop/cop/rails/find_each.rb +0 -51
- data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +0 -25
- data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +0 -106
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +0 -117
- data/lib/rubocop/cop/rails/http_status.rb +0 -179
- data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +0 -94
- data/lib/rubocop/cop/rails/inverse_of.rb +0 -246
- data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +0 -175
- data/lib/rubocop/cop/rails/link_to_blank.rb +0 -98
- data/lib/rubocop/cop/rails/not_null_column.rb +0 -67
- data/lib/rubocop/cop/rails/output.rb +0 -49
- data/lib/rubocop/cop/rails/output_safety.rb +0 -99
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +0 -107
- data/lib/rubocop/cop/rails/presence.rb +0 -124
- data/lib/rubocop/cop/rails/present.rb +0 -153
- data/lib/rubocop/cop/rails/read_write_attribute.rb +0 -74
- data/lib/rubocop/cop/rails/redundant_allow_nil.rb +0 -111
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +0 -136
- data/lib/rubocop/cop/rails/reflection_class_name.rb +0 -37
- data/lib/rubocop/cop/rails/refute_methods.rb +0 -76
- data/lib/rubocop/cop/rails/relative_date_constant.rb +0 -93
- data/lib/rubocop/cop/rails/request_referer.rb +0 -56
- data/lib/rubocop/cop/rails/reversible_migration.rb +0 -286
- data/lib/rubocop/cop/rails/safe_navigation.rb +0 -87
- data/lib/rubocop/cop/rails/save_bang.rb +0 -316
- data/lib/rubocop/cop/rails/scope_args.rb +0 -29
- data/lib/rubocop/cop/rails/skips_model_validations.rb +0 -87
- data/lib/rubocop/cop/rails/time_zone.rb +0 -238
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +0 -105
- data/lib/rubocop/cop/rails/unknown_env.rb +0 -63
- data/lib/rubocop/cop/rails/validation.rb +0 -109
- data/lib/rubocop/rspec/shared_examples.rb +0 -59
@@ -29,9 +29,9 @@ module RuboCop
|
|
29
29
|
add_offense(node, location: node.parent_class.source_range)
|
30
30
|
end
|
31
31
|
|
32
|
-
def_node_matcher :struct_constructor?,
|
33
|
-
|
34
|
-
|
32
|
+
def_node_matcher :struct_constructor?, <<~PATTERN
|
33
|
+
{(send (const nil? :Struct) :new ...)
|
34
|
+
(block (send (const nil? :Struct) :new ...) ...)}
|
35
35
|
PATTERN
|
36
36
|
end
|
37
37
|
end
|
@@ -20,7 +20,7 @@ module RuboCop
|
|
20
20
|
SUPER_TYPES = %i[super zsuper].freeze
|
21
21
|
|
22
22
|
def_node_matcher :proc_node?, '(send (const nil? :Proc) :new)'
|
23
|
-
def_node_matcher :symbol_proc?,
|
23
|
+
def_node_matcher :symbol_proc?, <<~PATTERN
|
24
24
|
(block
|
25
25
|
${(send ...) (super ...) zsuper}
|
26
26
|
$(args (arg _var))
|
@@ -8,6 +8,11 @@ module RuboCop
|
|
8
8
|
# parentheses using `EnforcedStyle`. Omission is only enforced when
|
9
9
|
# removing the parentheses won't cause a different behavior.
|
10
10
|
#
|
11
|
+
# `AllowSafeAssignment` option for safe assignment.
|
12
|
+
# By safe assignment we mean putting parentheses around
|
13
|
+
# an assignment to indicate "I know I'm using an assignment
|
14
|
+
# as a condition. It's not a mistake."
|
15
|
+
#
|
11
16
|
# @example EnforcedStyle: require_no_parentheses (default)
|
12
17
|
# # bad
|
13
18
|
# foo = (bar?) ? a : b
|
@@ -40,6 +45,15 @@ module RuboCop
|
|
40
45
|
# foo = bar? ? a : b
|
41
46
|
# foo = bar.baz? ? a : b
|
42
47
|
# foo = (bar && baz) ? a : b
|
48
|
+
#
|
49
|
+
# @example AllowSafeAssignment: true (default)
|
50
|
+
# # good
|
51
|
+
# foo = (bar = baz) ? a : b
|
52
|
+
#
|
53
|
+
# @example AllowSafeAssignment: false
|
54
|
+
# # bad
|
55
|
+
# foo = (bar = baz) ? a : b
|
56
|
+
#
|
43
57
|
class TernaryParentheses < Cop
|
44
58
|
include SafeAssignment
|
45
59
|
include ConfigurableEnforcedStyle
|
@@ -53,11 +67,16 @@ module RuboCop
|
|
53
67
|
' complex conditions.'
|
54
68
|
|
55
69
|
def on_if(node)
|
70
|
+
return if only_closing_parenthesis_is_last_line?(node.condition)
|
56
71
|
return unless node.ternary? && !infinite_loop? && offense?(node)
|
57
72
|
|
58
73
|
add_offense(node, location: node.source_range)
|
59
74
|
end
|
60
75
|
|
76
|
+
def only_closing_parenthesis_is_last_line?(condition)
|
77
|
+
condition.source.split("\n").last == ')'
|
78
|
+
end
|
79
|
+
|
61
80
|
def autocorrect(node)
|
62
81
|
condition = node.condition
|
63
82
|
|
@@ -108,7 +127,7 @@ module RuboCop
|
|
108
127
|
end
|
109
128
|
|
110
129
|
def non_complex_send?(node)
|
111
|
-
return false unless node.
|
130
|
+
return false unless node.call_type?
|
112
131
|
|
113
132
|
!node.operator_method? || node.method?(:[])
|
114
133
|
end
|
@@ -149,7 +168,8 @@ module RuboCop
|
|
149
168
|
|
150
169
|
def unsafe_autocorrect?(condition)
|
151
170
|
condition.children.any? do |child|
|
152
|
-
unparenthesized_method_call?(child)
|
171
|
+
unparenthesized_method_call?(child) ||
|
172
|
+
below_ternary_precedence?(child)
|
153
173
|
end
|
154
174
|
end
|
155
175
|
|
@@ -157,7 +177,16 @@ module RuboCop
|
|
157
177
|
method_name(child) =~ /^[a-z]/i && !child.parenthesized?
|
158
178
|
end
|
159
179
|
|
160
|
-
|
180
|
+
def below_ternary_precedence?(child)
|
181
|
+
# Handle English "or", e.g. 'foo or bar ? a : b'
|
182
|
+
(child.or_type? && child.semantic_operator?) ||
|
183
|
+
# Handle English "and", e.g. 'foo and bar ? a : b'
|
184
|
+
(child.and_type? && child.semantic_operator?) ||
|
185
|
+
# Handle English "not", e.g. 'not foo ? a : b'
|
186
|
+
(child.send_type? && child.prefix_not?)
|
187
|
+
end
|
188
|
+
|
189
|
+
def_node_matcher :method_name, <<~PATTERN
|
161
190
|
{($:defined? (send nil? _) ...)
|
162
191
|
(send {_ nil?} $_ _ ...)}
|
163
192
|
PATTERN
|
@@ -42,7 +42,7 @@ module RuboCop
|
|
42
42
|
def on_def(node)
|
43
43
|
return unless trailing_end?(node)
|
44
44
|
|
45
|
-
add_offense(node
|
45
|
+
add_offense(node, location: end_token(node).pos)
|
46
46
|
end
|
47
47
|
|
48
48
|
def autocorrect(node)
|
@@ -61,7 +61,7 @@ module RuboCop
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def end_token(node)
|
64
|
-
|
64
|
+
tokens(node).reverse.find(&:end?)
|
65
65
|
end
|
66
66
|
|
67
67
|
def body_and_end_on_same_line?(node)
|
@@ -69,10 +69,8 @@ module RuboCop
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def token_before_end(node)
|
72
|
-
|
73
|
-
|
74
|
-
tokens(node)[i - 1]
|
75
|
-
end
|
72
|
+
i = tokens(node).index(end_token(node))
|
73
|
+
tokens(node)[i - 1]
|
76
74
|
end
|
77
75
|
|
78
76
|
def break_line_before_end(node, corrector)
|
@@ -118,7 +118,7 @@ module RuboCop
|
|
118
118
|
!allowed_method?(node) && !allowed_writer?(node.method_name)
|
119
119
|
end
|
120
120
|
|
121
|
-
def_node_matcher :looks_like_trivial_writer?,
|
121
|
+
def_node_matcher :looks_like_trivial_writer?, <<~PATTERN
|
122
122
|
{(def _ (args (arg ...)) (ivasgn _ (lvar _)))
|
123
123
|
(defs _ _ (args (arg ...)) (ivasgn _ (lvar _)))}
|
124
124
|
PATTERN
|
@@ -55,7 +55,7 @@ module RuboCop
|
|
55
55
|
MSG = 'Use `%<suggestion>s` instead of '\
|
56
56
|
'`%<sorter>s...%<accessor_source>s`.'
|
57
57
|
|
58
|
-
def_node_matcher :unneeded_sort?,
|
58
|
+
def_node_matcher :unneeded_sort?, <<~MATCHER
|
59
59
|
{
|
60
60
|
(send $(send _ $:sort ...) ${:last :first})
|
61
61
|
(send $(send _ $:sort ...) ${:[] :at :slice} {(int 0) (int -1)})
|
@@ -25,7 +25,7 @@ module RuboCop
|
|
25
25
|
MSG = 'Use `%<receiver>s.unpack1(%<format>s)` instead of '\
|
26
26
|
'`%<receiver>s.unpack(%<format>s)%<method>s`.'
|
27
27
|
|
28
|
-
def_node_matcher :unpack_and_first_element?,
|
28
|
+
def_node_matcher :unpack_and_first_element?, <<~PATTERN
|
29
29
|
{
|
30
30
|
(send $(send (...) :unpack $(...)) :first)
|
31
31
|
(send $(send (...) :unpack $(...)) {:[] :slice :at} (int 0))
|
@@ -16,19 +16,15 @@ module RuboCop
|
|
16
16
|
# /check #{$pattern}/
|
17
17
|
# "Let's go to the #{@store}"
|
18
18
|
class VariableInterpolation < Cop
|
19
|
+
include Interpolation
|
20
|
+
|
19
21
|
MSG = 'Replace interpolated variable `%<variable>s` ' \
|
20
22
|
'with expression `#{%<variable>s}`.'
|
21
23
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
def on_regexp(node)
|
27
|
-
check_for_interpolation(node)
|
28
|
-
end
|
29
|
-
|
30
|
-
def on_xstr(node)
|
31
|
-
check_for_interpolation(node)
|
24
|
+
def on_node_with_interpolations(node)
|
25
|
+
var_nodes(node.children).each do |var_node|
|
26
|
+
add_offense(var_node)
|
27
|
+
end
|
32
28
|
end
|
33
29
|
|
34
30
|
def autocorrect(node)
|
@@ -39,12 +35,6 @@ module RuboCop
|
|
39
35
|
|
40
36
|
private
|
41
37
|
|
42
|
-
def check_for_interpolation(node)
|
43
|
-
var_nodes(node.children).each do |var_node|
|
44
|
-
add_offense(var_node)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
38
|
def message(node)
|
49
39
|
format(MSG, variable: node.source)
|
50
40
|
end
|
@@ -71,8 +71,8 @@ module RuboCop
|
|
71
71
|
|
72
72
|
def complex_content?(strings)
|
73
73
|
strings.any? do |s|
|
74
|
-
string = s.str_content
|
75
|
-
!string.
|
74
|
+
string = s.str_content.dup.force_encoding(::Encoding::UTF_8)
|
75
|
+
!string.valid_encoding? ||
|
76
76
|
string !~ word_regex || string =~ / /
|
77
77
|
end
|
78
78
|
end
|
@@ -7,7 +7,7 @@ module RuboCop
|
|
7
7
|
# by a predicate method, such as receiver.length == 0,
|
8
8
|
# receiver.length > 0, receiver.length != 0,
|
9
9
|
# receiver.length < 1 and receiver.size == 0 that can be
|
10
|
-
# replaced by receiver.empty? and !receiver.empty
|
10
|
+
# replaced by receiver.empty? and !receiver.empty?.
|
11
11
|
#
|
12
12
|
# @example
|
13
13
|
# # bad
|
@@ -73,14 +73,14 @@ module RuboCop
|
|
73
73
|
)
|
74
74
|
end
|
75
75
|
|
76
|
-
def_node_matcher :zero_length_predicate,
|
76
|
+
def_node_matcher :zero_length_predicate, <<~PATTERN
|
77
77
|
{(send (send (...) ${:length :size}) $:== (int $0))
|
78
78
|
(send (int $0) $:== (send (...) ${:length :size}))
|
79
79
|
(send (send (...) ${:length :size}) $:< (int $1))
|
80
80
|
(send (int $1) $:> (send (...) ${:length :size}))}
|
81
81
|
PATTERN
|
82
82
|
|
83
|
-
def_node_matcher :nonzero_length_predicate,
|
83
|
+
def_node_matcher :nonzero_length_predicate, <<~PATTERN
|
84
84
|
{(send (send (...) ${:length :size}) ${:> :!=} (int $0))
|
85
85
|
(send (int $0) ${:< :!=} (send (...) ${:length :size}))}
|
86
86
|
PATTERN
|
@@ -92,14 +92,14 @@ module RuboCop
|
|
92
92
|
"!#{other_receiver(node).source}.empty?"
|
93
93
|
end
|
94
94
|
|
95
|
-
def_node_matcher :zero_length_receiver,
|
95
|
+
def_node_matcher :zero_length_receiver, <<~PATTERN
|
96
96
|
{(send (send $_ _) :== (int 0))
|
97
97
|
(send (int 0) :== (send $_ _))
|
98
98
|
(send (send $_ _) :< (int 1))
|
99
99
|
(send (int 1) :> (send $_ _))}
|
100
100
|
PATTERN
|
101
101
|
|
102
|
-
def_node_matcher :other_receiver,
|
102
|
+
def_node_matcher :other_receiver, <<~PATTERN
|
103
103
|
{(send (send $_ _) _ _)
|
104
104
|
(send _ _ (send $_ _))}
|
105
105
|
PATTERN
|
@@ -107,7 +107,7 @@ module RuboCop
|
|
107
107
|
# Some collection like objects in the Ruby standard library
|
108
108
|
# implement `#size`, but not `#empty`. We ignore those to
|
109
109
|
# reduce false positives.
|
110
|
-
def_node_matcher :non_polymorphic_collection?,
|
110
|
+
def_node_matcher :non_polymorphic_collection?, <<~PATTERN
|
111
111
|
{(send (send (send (const nil? :File) :stat _) ...) ...)
|
112
112
|
(send (send (send (const nil? {:Tempfile :StringIO}) {:new :open} ...) ...) ...)}
|
113
113
|
PATTERN
|
data/lib/rubocop/cop/team.rb
CHANGED
@@ -81,6 +81,9 @@ module RuboCop
|
|
81
81
|
File.open(filename, 'w') { |f| f.write(new_source) }
|
82
82
|
end
|
83
83
|
@updated_source_file = true
|
84
|
+
rescue RuboCop::ErrorWithAnalyzedFileLocation => e
|
85
|
+
process_errors(buffer.name, [e])
|
86
|
+
raise e.cause
|
84
87
|
end
|
85
88
|
|
86
89
|
private
|
@@ -103,8 +106,8 @@ module RuboCop
|
|
103
106
|
|
104
107
|
other = investigate(other_cops, processed_source)
|
105
108
|
|
106
|
-
errors = autocorrect.errors
|
107
|
-
|
109
|
+
errors = [*autocorrect.errors, *other.errors]
|
110
|
+
process_errors(processed_source.path, errors)
|
108
111
|
|
109
112
|
autocorrect.offenses.concat(other.offenses)
|
110
113
|
end
|
@@ -149,19 +152,17 @@ module RuboCop
|
|
149
152
|
end
|
150
153
|
end
|
151
154
|
|
152
|
-
def
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
location = "#{file}#{line}#{column}"
|
155
|
+
def process_errors(file, errors)
|
156
|
+
errors.each do |error|
|
157
|
+
line = ":#{error.line}" if error.line
|
158
|
+
column = ":#{error.column}" if error.column
|
159
|
+
location = "#{file}#{line}#{column}"
|
160
|
+
cause = error.cause
|
159
161
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
end
|
162
|
+
if cause.is_a?(Warning)
|
163
|
+
handle_warning(cause, location)
|
164
|
+
else
|
165
|
+
handle_error(cause, location, error.cop)
|
165
166
|
end
|
166
167
|
end
|
167
168
|
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Utils
|
6
|
+
# Parses {Kernel#sprintf} format strings.
|
7
|
+
class FormatString
|
8
|
+
DIGIT_DOLLAR = /(\d+)\$/.freeze
|
9
|
+
FLAG = /[ #0+-]|#{DIGIT_DOLLAR}/.freeze
|
10
|
+
NUMBER_ARG = /\*#{DIGIT_DOLLAR}?/.freeze
|
11
|
+
NUMBER = /\d+|#{NUMBER_ARG}/.freeze
|
12
|
+
WIDTH = /(?<width>#{NUMBER})/.freeze
|
13
|
+
PRECISION = /\.(?<precision>#{NUMBER})/.freeze
|
14
|
+
TYPE = /(?<type>[bBdiouxXeEfgGaAcps])/.freeze
|
15
|
+
NAME = /<(?<name>\w+)>/.freeze
|
16
|
+
TEMPLATE_NAME = /\{(?<name>\w+)\}/.freeze
|
17
|
+
|
18
|
+
SEQUENCE = /
|
19
|
+
% (?<type>%)
|
20
|
+
| % (?<flags>#{FLAG}*)
|
21
|
+
(?:
|
22
|
+
(?: #{WIDTH}? #{PRECISION}? #{NAME}?
|
23
|
+
| #{WIDTH}? #{NAME} #{PRECISION}?
|
24
|
+
| #{NAME} (?<more_flags>#{FLAG}*) #{WIDTH}? #{PRECISION}?
|
25
|
+
) #{TYPE}
|
26
|
+
| #{WIDTH}? #{PRECISION}? #{TEMPLATE_NAME}
|
27
|
+
)
|
28
|
+
/x.freeze
|
29
|
+
|
30
|
+
# The syntax of a format sequence is as follows.
|
31
|
+
#
|
32
|
+
# ```
|
33
|
+
# %[flags][width][.precision]type
|
34
|
+
# ```
|
35
|
+
#
|
36
|
+
# A format sequence consists of a percent sign, followed by optional
|
37
|
+
# flags, width, and precision indicators, then terminated with a field
|
38
|
+
# type character.
|
39
|
+
#
|
40
|
+
# For more complex formatting, Ruby supports a reference by name.
|
41
|
+
#
|
42
|
+
# @see https://ruby-doc.org/core-2.6.3/Kernel.html#method-i-format
|
43
|
+
class FormatSequence
|
44
|
+
attr_reader :begin_pos, :end_pos
|
45
|
+
attr_reader :flags, :width, :precision, :name, :type
|
46
|
+
|
47
|
+
def initialize(string, **opts)
|
48
|
+
@source = string
|
49
|
+
@begin_pos = opts[:begin_pos]
|
50
|
+
@end_pos = opts[:end_pos]
|
51
|
+
@flags = opts[:flags]
|
52
|
+
@width = opts[:width]
|
53
|
+
@precision = opts[:precision]
|
54
|
+
@name = opts[:name]
|
55
|
+
@type = opts[:type]
|
56
|
+
end
|
57
|
+
|
58
|
+
def percent?
|
59
|
+
type == '%'
|
60
|
+
end
|
61
|
+
|
62
|
+
def annotated?
|
63
|
+
name && @source.include?('<')
|
64
|
+
end
|
65
|
+
|
66
|
+
def template?
|
67
|
+
name && @source.include?('{')
|
68
|
+
end
|
69
|
+
|
70
|
+
# Number of arguments required for the format sequence
|
71
|
+
def arity
|
72
|
+
@source.scan('*').count + 1
|
73
|
+
end
|
74
|
+
|
75
|
+
def max_digit_dollar_num
|
76
|
+
@source.scan(DIGIT_DOLLAR).map do |(digit_dollar_num)|
|
77
|
+
digit_dollar_num.to_i
|
78
|
+
end.max
|
79
|
+
end
|
80
|
+
|
81
|
+
def style
|
82
|
+
if annotated?
|
83
|
+
:annotated
|
84
|
+
elsif template?
|
85
|
+
:template
|
86
|
+
else
|
87
|
+
:unannotated
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def initialize(string)
|
93
|
+
@source = string
|
94
|
+
end
|
95
|
+
|
96
|
+
def format_sequences
|
97
|
+
@format_sequences ||= parse
|
98
|
+
end
|
99
|
+
|
100
|
+
def named_interpolation?
|
101
|
+
format_sequences.any?(&:name)
|
102
|
+
end
|
103
|
+
|
104
|
+
def max_digit_dollar_num
|
105
|
+
format_sequences.map(&:max_digit_dollar_num).max
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def parse
|
111
|
+
@source.to_enum(:scan, SEQUENCE).map do
|
112
|
+
match = Regexp.last_match
|
113
|
+
FormatSequence.new(
|
114
|
+
match[0],
|
115
|
+
begin_pos: match.begin(0),
|
116
|
+
end_pos: match.end(0),
|
117
|
+
flags: match[:flags].to_s + match[:more_flags].to_s,
|
118
|
+
width: match[:width],
|
119
|
+
precision: match[:precision],
|
120
|
+
name: match[:name],
|
121
|
+
type: match[:type]
|
122
|
+
)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|