rubocop 1.8.0 → 1.11.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 +14 -13
- data/assets/output.html.erb +1 -1
- data/config/default.yml +89 -22
- data/config/obsoletion.yml +4 -0
- data/lib/rubocop.rb +9 -0
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +5 -4
- data/lib/rubocop/cli/command/execute_runner.rb +1 -1
- data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
- data/lib/rubocop/config.rb +5 -2
- data/lib/rubocop/config_loader.rb +7 -14
- data/lib/rubocop/config_store.rb +12 -1
- data/lib/rubocop/cop/base.rb +2 -1
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -1
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -0
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +1 -0
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -0
- data/lib/rubocop/cop/exclude_limit.rb +26 -0
- data/lib/rubocop/cop/gemspec/date_assignment.rb +57 -0
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -0
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -0
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +2 -0
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +2 -0
- data/lib/rubocop/cop/generator.rb +3 -5
- data/lib/rubocop/cop/internal_affairs.rb +6 -1
- data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +68 -0
- data/lib/rubocop/cop/internal_affairs/example_description.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +2 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +151 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +2 -0
- data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +62 -0
- data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +65 -0
- data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +3 -0
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +4 -0
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
- data/lib/rubocop/cop/layout/block_alignment.rb +1 -0
- data/lib/rubocop/cop/layout/class_structure.rb +8 -2
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +37 -17
- data/lib/rubocop/cop/layout/extra_spacing.rb +2 -2
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +22 -3
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -0
- data/lib/rubocop/cop/layout/line_length.rb +2 -1
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +26 -0
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_brackets.rb +9 -4
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
- data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -0
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -0
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +2 -0
- data/lib/rubocop/cop/lint/constant_resolution.rb +1 -0
- data/lib/rubocop/cop/lint/debugger.rb +60 -14
- data/lib/rubocop/cop/lint/deprecated_constants.rb +5 -0
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +14 -4
- data/lib/rubocop/cop/lint/duplicate_branch.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -0
- data/lib/rubocop/cop/lint/duplicate_require.rb +3 -2
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -0
- data/lib/rubocop/cop/lint/else_layout.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -0
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -0
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +1 -0
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -0
- data/lib/rubocop/cop/lint/inherit_exception.rb +1 -0
- data/lib/rubocop/cop/lint/multiple_comparison.rb +5 -4
- data/lib/rubocop/cop/lint/nested_method_definition.rb +3 -0
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -0
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +7 -0
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +43 -6
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +47 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +39 -0
- data/lib/rubocop/cop/lint/raise_exception.rb +2 -0
- data/lib/rubocop/cop/lint/rand_one.rb +1 -0
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +5 -3
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -0
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +1 -0
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +7 -3
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +1 -0
- data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -0
- data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -0
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +1 -0
- data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -0
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -0
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -0
- data/lib/rubocop/cop/lint/struct_new_override.rb +1 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +103 -0
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +3 -0
- data/lib/rubocop/cop/lint/triple_quotes.rb +71 -0
- data/lib/rubocop/cop/lint/unified_integer.rb +1 -0
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +5 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +1 -0
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -0
- data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -0
- data/lib/rubocop/cop/lint/useless_times.rb +3 -0
- data/lib/rubocop/cop/message_annotator.rb +4 -1
- data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
- data/lib/rubocop/cop/metrics/module_length.rb +1 -0
- data/lib/rubocop/cop/metrics/parameter_lists.rb +6 -2
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +6 -4
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +2 -0
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +5 -0
- data/lib/rubocop/cop/mixin/code_length.rb +3 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +0 -1
- data/lib/rubocop/cop/mixin/configurable_max.rb +1 -0
- data/lib/rubocop/cop/mixin/def_node.rb +1 -0
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +3 -0
- data/lib/rubocop/cop/mixin/empty_parameter.rb +1 -0
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -0
- data/lib/rubocop/cop/mixin/method_complexity.rb +4 -1
- data/lib/rubocop/cop/mixin/negative_conditional.rb +3 -0
- data/lib/rubocop/cop/mixin/preferred_delimiters.rb +3 -3
- data/lib/rubocop/cop/mixin/rational_literal.rb +1 -0
- data/lib/rubocop/cop/mixin/safe_assignment.rb +5 -0
- data/lib/rubocop/cop/mixin/uncommunicative_name.rb +5 -1
- data/lib/rubocop/cop/mixin/visibility_help.rb +1 -0
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -0
- data/lib/rubocop/cop/naming/constant_name.rb +2 -0
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +2 -0
- data/lib/rubocop/cop/naming/method_name.rb +3 -0
- data/lib/rubocop/cop/naming/predicate_name.rb +1 -0
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +38 -5
- data/lib/rubocop/cop/naming/variable_number.rb +1 -1
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/security/eval.rb +1 -0
- data/lib/rubocop/cop/security/json_load.rb +1 -0
- data/lib/rubocop/cop/security/marshal_load.rb +1 -0
- data/lib/rubocop/cop/security/open.rb +1 -0
- data/lib/rubocop/cop/security/yaml_load.rb +1 -0
- data/lib/rubocop/cop/severity.rb +3 -3
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -0
- data/lib/rubocop/cop/style/alias.rb +1 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -0
- data/lib/rubocop/cop/style/array_coercion.rb +2 -0
- data/lib/rubocop/cop/style/array_join.rb +1 -0
- data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
- data/lib/rubocop/cop/style/attr.rb +1 -0
- data/lib/rubocop/cop/style/case_equality.rb +2 -1
- data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -0
- data/lib/rubocop/cop/style/collection_compact.rb +2 -0
- data/lib/rubocop/cop/style/colon_method_call.rb +1 -0
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +2 -0
- data/lib/rubocop/cop/style/constant_visibility.rb +28 -0
- data/lib/rubocop/cop/style/date_time.rb +3 -0
- data/lib/rubocop/cop/style/dir.rb +1 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +49 -9
- data/lib/rubocop/cop/style/documentation.rb +5 -0
- data/lib/rubocop/cop/style/documentation_method.rb +1 -0
- data/lib/rubocop/cop/style/double_negation.rb +3 -2
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -0
- data/lib/rubocop/cop/style/each_with_object.rb +1 -0
- data/lib/rubocop/cop/style/empty_literal.rb +9 -0
- data/lib/rubocop/cop/style/endless_method.rb +1 -0
- data/lib/rubocop/cop/style/eval_with_location.rb +140 -49
- data/lib/rubocop/cop/style/even_odd.rb +1 -0
- data/lib/rubocop/cop/style/expand_path_arguments.rb +3 -0
- data/lib/rubocop/cop/style/explicit_block_argument.rb +12 -1
- data/lib/rubocop/cop/style/exponential_notation.rb +6 -7
- data/lib/rubocop/cop/style/float_division.rb +7 -0
- data/lib/rubocop/cop/style/format_string.rb +2 -0
- data/lib/rubocop/cop/style/format_string_token.rb +19 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +1 -0
- data/lib/rubocop/cop/style/hash_conversion.rb +105 -0
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -0
- data/lib/rubocop/cop/style/hash_except.rb +1 -0
- data/lib/rubocop/cop/style/hash_like_case.rb +1 -0
- data/lib/rubocop/cop/style/hash_transform_keys.rb +4 -0
- data/lib/rubocop/cop/style/hash_transform_values.rb +4 -0
- data/lib/rubocop/cop/style/if_inside_else.rb +14 -7
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +122 -0
- data/lib/rubocop/cop/style/implicit_runtime_error.rb +1 -0
- data/lib/rubocop/cop/style/inverse_methods.rb +2 -0
- data/lib/rubocop/cop/style/min_max.rb +1 -0
- data/lib/rubocop/cop/style/mixin_usage.rb +2 -0
- data/lib/rubocop/cop/style/module_function.rb +5 -0
- data/lib/rubocop/cop/style/multiple_comparison.rb +21 -2
- data/lib/rubocop/cop/style/mutable_constant.rb +3 -0
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +6 -0
- data/lib/rubocop/cop/style/nil_lambda.rb +1 -0
- data/lib/rubocop/cop/style/non_nil_check.rb +30 -13
- data/lib/rubocop/cop/style/numeric_literals.rb +6 -9
- data/lib/rubocop/cop/style/numeric_predicate.rb +4 -1
- data/lib/rubocop/cop/style/option_hash.rb +1 -0
- data/lib/rubocop/cop/style/or_assignment.rb +2 -0
- data/lib/rubocop/cop/style/parallel_assignment.rb +6 -0
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +1 -0
- data/lib/rubocop/cop/style/proc.rb +1 -0
- data/lib/rubocop/cop/style/random_with_offset.rb +5 -0
- data/lib/rubocop/cop/style/redundant_assignment.rb +1 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +7 -1
- data/lib/rubocop/cop/style/redundant_conditional.rb +2 -0
- data/lib/rubocop/cop/style/redundant_exception.rb +2 -0
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +2 -0
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +13 -0
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +1 -0
- data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
- data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -0
- data/lib/rubocop/cop/style/return_nil.rb +6 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +2 -0
- data/lib/rubocop/cop/style/sample.rb +1 -0
- data/lib/rubocop/cop/style/signal_exception.rb +3 -0
- data/lib/rubocop/cop/style/single_argument_dig.rb +1 -0
- data/lib/rubocop/cop/style/single_line_methods.rb +5 -2
- data/lib/rubocop/cop/style/slicing_with_range.rb +1 -0
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +28 -4
- data/lib/rubocop/cop/style/special_global_vars.rb +3 -3
- data/lib/rubocop/cop/style/stderr_puts.rb +1 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +2 -1
- data/lib/rubocop/cop/style/string_hash_keys.rb +2 -0
- data/lib/rubocop/cop/style/strip.rb +1 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +1 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +25 -1
- data/lib/rubocop/cop/style/ternary_parentheses.rb +2 -1
- data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +1 -0
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -1
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -0
- data/lib/rubocop/cop/style/unless_logical_operators.rb +99 -0
- data/lib/rubocop/cop/style/unpack_first.rb +1 -0
- data/lib/rubocop/cop/style/while_until_modifier.rb +2 -4
- data/lib/rubocop/cop/style/yoda_condition.rb +1 -0
- data/lib/rubocop/cop/style/zero_length_predicate.rb +5 -0
- data/lib/rubocop/formatter/git_hub_actions_formatter.rb +1 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +2 -1
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
- data/lib/rubocop/magic_comment.rb +30 -1
- data/lib/rubocop/name_similarity.rb +1 -1
- data/lib/rubocop/options.rb +1 -1
- data/lib/rubocop/rspec/expect_offense.rb +5 -2
- data/lib/rubocop/runner.rb +1 -0
- data/lib/rubocop/target_ruby.rb +21 -13
- data/lib/rubocop/version.rb +2 -2
- metadata +21 -7
@@ -77,6 +77,7 @@ module RuboCop
|
|
77
77
|
|
78
78
|
RESTRICT_ON_SEND = %i[private protected public module_function].freeze
|
79
79
|
|
80
|
+
# @!method access_modifier_with_symbol?(node)
|
80
81
|
def_node_matcher :access_modifier_with_symbol?, <<~PATTERN
|
81
82
|
(send nil? {:private :protected :public} (sym _))
|
82
83
|
PATTERN
|
@@ -47,14 +47,17 @@ module RuboCop
|
|
47
47
|
|
48
48
|
MSG = 'Use arguments forwarding.'
|
49
49
|
|
50
|
+
# @!method use_rest_arguments?(node)
|
50
51
|
def_node_matcher :use_rest_arguments?, <<~PATTERN
|
51
52
|
(args (restarg $_) $...)
|
52
53
|
PATTERN
|
53
54
|
|
55
|
+
# @!method only_rest_arguments?(node, name)
|
54
56
|
def_node_matcher :only_rest_arguments?, <<~PATTERN
|
55
57
|
(send _ _ (splat (lvar %1)))
|
56
58
|
PATTERN
|
57
59
|
|
60
|
+
# @!method forwarding_method_arguments?(node, rest_name, block_name, kwargs_name)
|
58
61
|
def_node_matcher :forwarding_method_arguments?, <<~PATTERN
|
59
62
|
{
|
60
63
|
(send _ _
|
@@ -26,10 +26,12 @@ module RuboCop
|
|
26
26
|
SPLAT_MSG = 'Use `Array(%<arg>s)` instead of `[*%<arg>s]`.'
|
27
27
|
CHECK_MSG = 'Use `Array(%<arg>s)` instead of explicit `Array` check.'
|
28
28
|
|
29
|
+
# @!method array_splat?(node)
|
29
30
|
def_node_matcher :array_splat?, <<~PATTERN
|
30
31
|
(array (splat $_))
|
31
32
|
PATTERN
|
32
33
|
|
34
|
+
# @!method unless_array?(node)
|
33
35
|
def_node_matcher :unless_array?, <<~PATTERN
|
34
36
|
(if
|
35
37
|
(send
|
@@ -7,7 +7,7 @@ module RuboCop
|
|
7
7
|
module Style
|
8
8
|
# This cop checks for non-ascii (non-English) characters
|
9
9
|
# in comments. You could set an array of allowed non-ascii chars in
|
10
|
-
# AllowedChars attribute (
|
10
|
+
# `AllowedChars` attribute (copyright notice "©" by default).
|
11
11
|
#
|
12
12
|
# @example
|
13
13
|
# # bad
|
@@ -35,6 +35,7 @@ module RuboCop
|
|
35
35
|
MSG = 'Avoid the use of the case equality operator `===`.'
|
36
36
|
RESTRICT_ON_SEND = %i[===].freeze
|
37
37
|
|
38
|
+
# @!method case_equality?(node)
|
38
39
|
def_node_matcher :case_equality?, '(send $#const? :=== $_)'
|
39
40
|
|
40
41
|
def on_send(node)
|
@@ -64,7 +65,7 @@ module RuboCop
|
|
64
65
|
# The automatic correction from `a === b` to `a.match?(b)` needs to
|
65
66
|
# consider `Regexp.last_match?`, `$~`, `$1`, and etc.
|
66
67
|
# This correction is expected to be supported by `Performance/Regexp` cop.
|
67
|
-
# See: https://github.com/rubocop
|
68
|
+
# See: https://github.com/rubocop/rubocop-performance/issues/152
|
68
69
|
#
|
69
70
|
# So here is noop.
|
70
71
|
when :begin
|
@@ -35,6 +35,7 @@ module RuboCop
|
|
35
35
|
|
36
36
|
RESTRICT_ON_SEND = %i[reject reject! select select!].freeze
|
37
37
|
|
38
|
+
# @!method reject_method?(node)
|
38
39
|
def_node_matcher :reject_method?, <<~PATTERN
|
39
40
|
(block
|
40
41
|
(send
|
@@ -44,6 +45,7 @@ module RuboCop
|
|
44
45
|
$(lvar _) :nil?))
|
45
46
|
PATTERN
|
46
47
|
|
48
|
+
# @!method select_method?(node)
|
47
49
|
def_node_matcher :select_method?, <<~PATTERN
|
48
50
|
(block
|
49
51
|
(send
|
@@ -231,6 +231,7 @@ module RuboCop
|
|
231
231
|
|
232
232
|
# The shovel operator `<<` does not have its own type. It is a `send`
|
233
233
|
# type.
|
234
|
+
# @!method assignment_type?(node)
|
234
235
|
def_node_matcher :assignment_type?, <<~PATTERN
|
235
236
|
{
|
236
237
|
#{ASSIGNMENT_TYPES.join(' ')}
|
@@ -300,6 +301,7 @@ module RuboCop
|
|
300
301
|
style == :assign_inside_condition && assignment_rhs_exist?(node)
|
301
302
|
end
|
302
303
|
|
304
|
+
# @!method candidate_condition?(node)
|
303
305
|
def_node_matcher :candidate_condition?, '[{if case} !#allowed_ternary?]'
|
304
306
|
|
305
307
|
def allowed_ternary?(assignment)
|
@@ -26,6 +26,24 @@ module RuboCop
|
|
26
26
|
# public_constant :BAZ
|
27
27
|
# end
|
28
28
|
#
|
29
|
+
# @example IgnoreModules: false (default)
|
30
|
+
# # bad
|
31
|
+
# class Foo
|
32
|
+
# MyClass = Struct.new()
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# # good
|
36
|
+
# class Foo
|
37
|
+
# MyClass = Struct.new()
|
38
|
+
# public_constant :MyClass
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# @example IgnoreModules: true
|
42
|
+
# # good
|
43
|
+
# class Foo
|
44
|
+
# MyClass = Struct.new()
|
45
|
+
# end
|
46
|
+
#
|
29
47
|
class ConstantVisibility < Base
|
30
48
|
MSG = 'Explicitly make `%<constant_name>s` public or private using ' \
|
31
49
|
'either `#public_constant` or `#private_constant`.'
|
@@ -33,6 +51,7 @@ module RuboCop
|
|
33
51
|
def on_casgn(node)
|
34
52
|
return unless class_or_module_scope?(node)
|
35
53
|
return if visibility_declaration?(node)
|
54
|
+
return if ignore_modules? && module?(node)
|
36
55
|
|
37
56
|
message = message(node)
|
38
57
|
add_offense(node, message: message)
|
@@ -40,6 +59,14 @@ module RuboCop
|
|
40
59
|
|
41
60
|
private
|
42
61
|
|
62
|
+
def ignore_modules?
|
63
|
+
cop_config.fetch('IgnoreModules', false)
|
64
|
+
end
|
65
|
+
|
66
|
+
def module?(node)
|
67
|
+
node.children.last.class_constructor?
|
68
|
+
end
|
69
|
+
|
43
70
|
def message(node)
|
44
71
|
_namespace, constant_name, _value = *node
|
45
72
|
|
@@ -65,6 +92,7 @@ module RuboCop
|
|
65
92
|
end
|
66
93
|
end
|
67
94
|
|
95
|
+
# @!method visibility_declaration_for?(node, const_name)
|
68
96
|
def_node_matcher :visibility_declaration_for?, <<~PATTERN
|
69
97
|
(send nil? {:public_constant :private_constant} ({sym str} #match_name?(%1)))
|
70
98
|
PATTERN
|
@@ -47,14 +47,17 @@ module RuboCop
|
|
47
47
|
CLASS_MSG = 'Prefer Time over DateTime.'
|
48
48
|
COERCION_MSG = 'Do not use #to_datetime.'
|
49
49
|
|
50
|
+
# @!method date_time?(node)
|
50
51
|
def_node_matcher :date_time?, <<~PATTERN
|
51
52
|
(send (const {nil? (cbase)} :DateTime) ...)
|
52
53
|
PATTERN
|
53
54
|
|
55
|
+
# @!method historic_date?(node)
|
54
56
|
def_node_matcher :historic_date?, <<~PATTERN
|
55
57
|
(send _ _ _ (const (const {nil? (cbase)} :Date) _))
|
56
58
|
PATTERN
|
57
59
|
|
60
|
+
# @!method to_datetime?(node)
|
58
61
|
def_node_matcher :to_datetime?, <<~PATTERN
|
59
62
|
(send _ :to_datetime)
|
60
63
|
PATTERN
|
@@ -22,6 +22,7 @@ module RuboCop
|
|
22
22
|
MSG = "Use `__dir__` to get an absolute path to the current file's directory."
|
23
23
|
RESTRICT_ON_SEND = %i[expand_path dirname].freeze
|
24
24
|
|
25
|
+
# @!method dir_replacement?(node)
|
25
26
|
def_node_matcher :dir_replacement?, <<~PATTERN
|
26
27
|
{(send (const {nil? cbase} :File) :expand_path (send (const {nil? cbase} :File) :dirname #file_keyword?))
|
27
28
|
(send (const {nil? cbase} :File) :dirname (send (const {nil? cbase} :File) :realpath #file_keyword?))}
|
@@ -9,37 +9,77 @@ module RuboCop
|
|
9
9
|
# This is useful if want to make sure that every RuboCop error gets fixed
|
10
10
|
# and not quickly disabled with a comment.
|
11
11
|
#
|
12
|
+
# Specific cops can be allowed with the `AllowedCops` configuration. Note that
|
13
|
+
# if this configuration is set, `rubocop:disable all` is still disallowed.
|
14
|
+
#
|
12
15
|
# @example
|
13
16
|
# # bad
|
14
17
|
# # rubocop:disable Metrics/AbcSize
|
15
|
-
# def
|
18
|
+
# def foo
|
16
19
|
# end
|
17
20
|
# # rubocop:enable Metrics/AbcSize
|
18
21
|
#
|
19
22
|
# # good
|
20
|
-
# def
|
23
|
+
# def foo
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# @example AllowedCops: [Metrics/AbcSize]
|
27
|
+
# # good
|
28
|
+
# # rubocop:disable Metrics/AbcSize
|
29
|
+
# def foo
|
21
30
|
# end
|
31
|
+
# # rubocop:enable Metrics/AbcSize
|
22
32
|
#
|
23
33
|
class DisableCopsWithinSourceCodeDirective < Base
|
24
34
|
extend AutoCorrector
|
25
35
|
|
26
36
|
# rubocop:enable Lint/RedundantCopDisableDirective
|
27
|
-
MSG = '
|
37
|
+
MSG = 'Rubocop disable/enable directives are not permitted.'
|
38
|
+
MSG_FOR_COPS = 'Rubocop disable/enable directives for %<cops>s are not permitted.'
|
28
39
|
|
29
40
|
def on_new_investigation
|
30
41
|
processed_source.comments.each do |comment|
|
31
|
-
|
42
|
+
directive_cops = directive_cops(comment)
|
43
|
+
disallowed_cops = directive_cops - allowed_cops
|
32
44
|
|
33
|
-
|
34
|
-
|
35
|
-
|
45
|
+
next unless disallowed_cops.any?
|
46
|
+
|
47
|
+
register_offense(comment, directive_cops, disallowed_cops)
|
36
48
|
end
|
37
49
|
end
|
38
50
|
|
39
51
|
private
|
40
52
|
|
41
|
-
def
|
42
|
-
|
53
|
+
def register_offense(comment, directive_cops, disallowed_cops)
|
54
|
+
message = if any_cops_allowed?
|
55
|
+
format(MSG_FOR_COPS, cops: "`#{disallowed_cops.join('`, `')}`")
|
56
|
+
else
|
57
|
+
MSG
|
58
|
+
end
|
59
|
+
|
60
|
+
add_offense(comment, message: message) do |corrector|
|
61
|
+
replacement = ''
|
62
|
+
|
63
|
+
if directive_cops.length != disallowed_cops.length
|
64
|
+
replacement = comment.text.sub(/#{Regexp.union(disallowed_cops)},?\s*/, '')
|
65
|
+
.sub(/,\s*$/, '')
|
66
|
+
end
|
67
|
+
|
68
|
+
corrector.replace(comment, replacement)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def directive_cops(comment)
|
73
|
+
match = CommentConfig::COMMENT_DIRECTIVE_REGEXP.match(comment.text)
|
74
|
+
match && match[2] ? match[2].split(',').map(&:strip) : []
|
75
|
+
end
|
76
|
+
|
77
|
+
def allowed_cops
|
78
|
+
Array(cop_config['AllowedCops'])
|
79
|
+
end
|
80
|
+
|
81
|
+
def any_cops_allowed?
|
82
|
+
allowed_cops.any?
|
43
83
|
end
|
44
84
|
end
|
45
85
|
end
|
@@ -65,8 +65,13 @@ module RuboCop
|
|
65
65
|
|
66
66
|
MSG = 'Missing top-level %<type>s documentation comment.'
|
67
67
|
|
68
|
+
# @!method constant_definition?(node)
|
68
69
|
def_node_matcher :constant_definition?, '{class module casgn}'
|
70
|
+
|
71
|
+
# @!method outer_module(node)
|
69
72
|
def_node_search :outer_module, '(const (const nil? _) _)'
|
73
|
+
|
74
|
+
# @!method constant_visibility_declaration?(node)
|
70
75
|
def_node_matcher :constant_visibility_declaration?, <<~PATTERN
|
71
76
|
(send nil? {:public_constant :private_constant} ({sym str} _))
|
72
77
|
PATTERN
|
@@ -5,8 +5,8 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# This cop checks for uses of double negation (`!!`) to convert something to a boolean value.
|
7
7
|
#
|
8
|
-
# When using `EnforcedStyle: allowed_in_returns`, allow double
|
9
|
-
# that use boolean as a return value. When using `EnforcedStyle: forbidden`, double
|
8
|
+
# When using `EnforcedStyle: allowed_in_returns`, allow double negation in contexts
|
9
|
+
# that use boolean as a return value. When using `EnforcedStyle: forbidden`, double negation
|
10
10
|
# should be forbidden always.
|
11
11
|
#
|
12
12
|
# @example
|
@@ -39,6 +39,7 @@ module RuboCop
|
|
39
39
|
MSG = 'Avoid the use of double negation (`!!`).'
|
40
40
|
RESTRICT_ON_SEND = %i[!].freeze
|
41
41
|
|
42
|
+
# @!method double_negative?(node)
|
42
43
|
def_node_matcher :double_negative?, '(send (send _ :!) :!)'
|
43
44
|
|
44
45
|
def on_send(node)
|
@@ -23,6 +23,7 @@ module RuboCop
|
|
23
23
|
MSG = 'Use `each_with_object` instead of `%<method>s`.'
|
24
24
|
METHODS = %i[inject reduce].freeze
|
25
25
|
|
26
|
+
# @!method each_with_object_candidate?(node)
|
26
27
|
def_node_matcher :each_with_object_candidate?, <<~PATTERN
|
27
28
|
(block $(send _ {:inject :reduce} _) $_ $_)
|
28
29
|
PATTERN
|
@@ -27,11 +27,20 @@ module RuboCop
|
|
27
27
|
|
28
28
|
RESTRICT_ON_SEND = %i[new].freeze
|
29
29
|
|
30
|
+
# @!method array_node(node)
|
30
31
|
def_node_matcher :array_node, '(send (const {nil? cbase} :Array) :new)'
|
32
|
+
|
33
|
+
# @!method hash_node(node)
|
31
34
|
def_node_matcher :hash_node, '(send (const {nil? cbase} :Hash) :new)'
|
35
|
+
|
36
|
+
# @!method str_node(node)
|
32
37
|
def_node_matcher :str_node, '(send (const {nil? cbase} :String) :new)'
|
38
|
+
|
39
|
+
# @!method array_with_block(node)
|
33
40
|
def_node_matcher :array_with_block,
|
34
41
|
'(block (send (const {nil? cbase} :Array) :new) args _)'
|
42
|
+
|
43
|
+
# @!method hash_with_block(node)
|
35
44
|
def_node_matcher :hash_with_block, <<~PATTERN
|
36
45
|
{
|
37
46
|
(block (send (const {nil? cbase} :Hash) :new) args _)
|
@@ -11,6 +11,7 @@ module RuboCop
|
|
11
11
|
# Other method definition types are not considered by this cop.
|
12
12
|
#
|
13
13
|
# The supported styles are:
|
14
|
+
#
|
14
15
|
# * allow_single_line (default) - only single line endless method definitions are allowed.
|
15
16
|
# * allow_always - all endless method definitions are allowed.
|
16
17
|
# * disallow - all endless method definitions are disallowed.
|
@@ -3,9 +3,19 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# This cop
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# This cop ensures that eval methods (`eval`, `instance_eval`, `class_eval`
|
7
|
+
# and `module_eval`) are given filename and line number values (`__FILE__`
|
8
|
+
# and `__LINE__`). This data is used to ensure that any errors raised
|
9
|
+
# within the evaluated code will be given the correct identification
|
10
|
+
# in a backtrace.
|
11
|
+
#
|
12
|
+
# The cop also checks that the line number given relative to `__LINE__` is
|
13
|
+
# correct.
|
14
|
+
#
|
15
|
+
# This cop will autocorrect incorrect or missing filename and line number
|
16
|
+
# values. However, if `eval` is called without a binding argument, the cop
|
17
|
+
# will not attempt to automatically add a binding, or add filename and
|
18
|
+
# line values.
|
9
19
|
#
|
10
20
|
# @example
|
11
21
|
# # bad
|
@@ -31,30 +41,36 @@ module RuboCop
|
|
31
41
|
# def do_something
|
32
42
|
# end
|
33
43
|
# RUBY
|
44
|
+
#
|
45
|
+
# This cop works only when a string literal is given as a code string.
|
46
|
+
# No offence is reported if a string variable is given as below:
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
# # not checked
|
50
|
+
# code = <<-RUBY
|
51
|
+
# def do_something
|
52
|
+
# end
|
53
|
+
# RUBY
|
54
|
+
# eval code
|
55
|
+
#
|
34
56
|
class EvalWithLocation < Base
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
57
|
+
extend AutoCorrector
|
58
|
+
|
59
|
+
MSG = 'Pass `__FILE__` and `__LINE__` to `%<method_name>s`.'
|
60
|
+
MSG_EVAL = 'Pass a binding, `__FILE__` and `__LINE__` to `eval`.'
|
61
|
+
MSG_INCORRECT_FILE = 'Incorrect file for `%<method_name>s`; ' \
|
62
|
+
'use `%<expected>s` instead of `%<actual>s`.'
|
63
|
+
MSG_INCORRECT_LINE = 'Incorrect line number for `%<method_name>s`; ' \
|
64
|
+
'use `%<expected>s` instead of `%<actual>s`.'
|
39
65
|
|
40
66
|
RESTRICT_ON_SEND = %i[eval class_eval module_eval instance_eval].freeze
|
41
67
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
(send nil? :eval ${str dstr} _)
|
46
|
-
(send nil? :eval ${str dstr} _ #special_file_keyword?)
|
47
|
-
(send nil? :eval ${str dstr} _ #special_file_keyword? _)
|
48
|
-
|
49
|
-
(send _ {:class_eval :module_eval :instance_eval}
|
50
|
-
${str dstr})
|
51
|
-
(send _ {:class_eval :module_eval :instance_eval}
|
52
|
-
${str dstr} #special_file_keyword?)
|
53
|
-
(send _ {:class_eval :module_eval :instance_eval}
|
54
|
-
${str dstr} #special_file_keyword? _)
|
55
|
-
}
|
68
|
+
# @!method valid_eval_receiver?(node)
|
69
|
+
def_node_matcher :valid_eval_receiver?, <<~PATTERN
|
70
|
+
{ nil? (const {nil? cbase} :Kernel) }
|
56
71
|
PATTERN
|
57
72
|
|
73
|
+
# @!method line_with_offset?(node, sign, num)
|
58
74
|
def_node_matcher :line_with_offset?, <<~PATTERN
|
59
75
|
{
|
60
76
|
(send #special_line_keyword? %1 (int %2))
|
@@ -63,17 +79,38 @@ module RuboCop
|
|
63
79
|
PATTERN
|
64
80
|
|
65
81
|
def on_send(node)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
82
|
+
# Classes should not redefine eval, but in case one does, it shouldn't
|
83
|
+
# register an offense. Only `eval` without a receiver and `Kernel.eval`
|
84
|
+
# are considered.
|
85
|
+
return if node.method?(:eval) && !valid_eval_receiver?(node.receiver)
|
86
|
+
|
87
|
+
code = node.arguments.first
|
88
|
+
return unless code && (code.str_type? || code.dstr_type?)
|
89
|
+
|
90
|
+
check_location(node, code)
|
73
91
|
end
|
74
92
|
|
75
93
|
private
|
76
94
|
|
95
|
+
def check_location(node, code)
|
96
|
+
file, line = file_and_line(node)
|
97
|
+
|
98
|
+
if line
|
99
|
+
check_file(node, file)
|
100
|
+
check_line(node, code)
|
101
|
+
elsif file
|
102
|
+
check_file(node, file)
|
103
|
+
add_offense_for_missing_line(node, code)
|
104
|
+
else
|
105
|
+
add_offense_for_missing_location(node, code)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def register_offense(node, &block)
|
110
|
+
msg = node.method?(:eval) ? MSG_EVAL : format(MSG, method_name: node.method_name)
|
111
|
+
add_offense(node, message: msg, &block)
|
112
|
+
end
|
113
|
+
|
77
114
|
def special_file_keyword?(node)
|
78
115
|
node.str_type? &&
|
79
116
|
node.source == '__FILE__'
|
@@ -84,6 +121,15 @@ module RuboCop
|
|
84
121
|
node.source == '__LINE__'
|
85
122
|
end
|
86
123
|
|
124
|
+
def file_and_line(node)
|
125
|
+
base = node.method?(:eval) ? 2 : 1
|
126
|
+
[node.arguments[base], node.arguments[base + 1]]
|
127
|
+
end
|
128
|
+
|
129
|
+
def with_binding?(node)
|
130
|
+
node.method?(:eval) ? node.arguments.size >= 2 : true
|
131
|
+
end
|
132
|
+
|
87
133
|
# FIXME: It's a Style/ConditionalAssignment's false positive.
|
88
134
|
# rubocop:disable Style/ConditionalAssignment
|
89
135
|
def with_lineno?(node)
|
@@ -95,20 +141,34 @@ module RuboCop
|
|
95
141
|
end
|
96
142
|
# rubocop:enable Style/ConditionalAssignment
|
97
143
|
|
98
|
-
def
|
99
|
-
expected =
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
144
|
+
def add_offense_for_incorrect_line(method_name, line_node, sign, line_diff)
|
145
|
+
expected = expected_line(sign, line_diff)
|
146
|
+
message = format(MSG_INCORRECT_LINE,
|
147
|
+
method_name: method_name,
|
148
|
+
actual: line_node.source,
|
149
|
+
expected: expected)
|
150
|
+
|
151
|
+
add_offense(line_node.loc.expression, message: message) do |corrector|
|
152
|
+
corrector.replace(line_node, expected)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def check_file(node, file_node)
|
157
|
+
return true if special_file_keyword?(file_node)
|
158
|
+
|
159
|
+
message = format(MSG_INCORRECT_FILE,
|
160
|
+
method_name: node.method_name,
|
161
|
+
expected: '__FILE__',
|
162
|
+
actual: file_node.source)
|
163
|
+
|
164
|
+
add_offense(file_node, message: message) do |corrector|
|
165
|
+
corrector.replace(file_node, '__FILE__')
|
166
|
+
end
|
106
167
|
end
|
107
168
|
|
108
|
-
def
|
169
|
+
def check_line(node, code)
|
109
170
|
line_node = node.arguments.last
|
110
|
-
|
111
|
-
line_diff = string_first_line(code) - lineno_range.first_line
|
171
|
+
line_diff = line_difference(line_node, code)
|
112
172
|
if line_diff.zero?
|
113
173
|
add_offense_for_same_line(node, line_node)
|
114
174
|
else
|
@@ -116,6 +176,10 @@ module RuboCop
|
|
116
176
|
end
|
117
177
|
end
|
118
178
|
|
179
|
+
def line_difference(line_node, code)
|
180
|
+
string_first_line(code) - line_node.loc.expression.first_line
|
181
|
+
end
|
182
|
+
|
119
183
|
def string_first_line(str_node)
|
120
184
|
if str_node.heredoc?
|
121
185
|
str_node.loc.heredoc_body.first_line
|
@@ -124,23 +188,50 @@ module RuboCop
|
|
124
188
|
end
|
125
189
|
end
|
126
190
|
|
127
|
-
def add_offense_for_same_line(
|
191
|
+
def add_offense_for_same_line(node, line_node)
|
128
192
|
return if special_line_keyword?(line_node)
|
129
193
|
|
130
|
-
|
131
|
-
line_node.loc.expression,
|
132
|
-
message: message_incorrect_line(line_node, nil, 0)
|
133
|
-
)
|
194
|
+
add_offense_for_incorrect_line(node.method_name, line_node, nil, 0)
|
134
195
|
end
|
135
196
|
|
136
|
-
def add_offense_for_different_line(
|
197
|
+
def add_offense_for_different_line(node, line_node, line_diff)
|
137
198
|
sign = line_diff.positive? ? :+ : :-
|
138
199
|
return if line_with_offset?(line_node, sign, line_diff.abs)
|
139
200
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
201
|
+
add_offense_for_incorrect_line(node.method_name, line_node, sign, line_diff.abs)
|
202
|
+
end
|
203
|
+
|
204
|
+
def expected_line(sign, line_diff)
|
205
|
+
if line_diff.zero?
|
206
|
+
'__LINE__'
|
207
|
+
else
|
208
|
+
"__LINE__ #{sign} #{line_diff.abs}"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def add_offense_for_missing_line(node, code)
|
213
|
+
register_offense(node) do |corrector|
|
214
|
+
line_str = missing_line(node, code)
|
215
|
+
corrector.insert_after(node.loc.expression.end, ", #{line_str}")
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def add_offense_for_missing_location(node, code)
|
220
|
+
if node.method?(:eval) && !with_binding?(node)
|
221
|
+
register_offense(node)
|
222
|
+
return
|
223
|
+
end
|
224
|
+
|
225
|
+
register_offense(node) do |corrector|
|
226
|
+
line_str = missing_line(node, code)
|
227
|
+
corrector.insert_after(node.loc.expression.end, ", __FILE__, #{line_str}")
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def missing_line(node, code)
|
232
|
+
line_diff = line_difference(node.arguments.last, code)
|
233
|
+
sign = line_diff.positive? ? :+ : :-
|
234
|
+
expected_line(sign, line_diff)
|
144
235
|
end
|
145
236
|
end
|
146
237
|
end
|