rubocop 1.84.2 → 1.85.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/config/default.yml +83 -4
- data/config/obsoletion.yml +5 -0
- data/lib/rubocop/cli/command/mcp.rb +19 -0
- data/lib/rubocop/cli.rb +6 -3
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -2
- data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12 -2
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16 -2
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +7 -1
- data/lib/rubocop/cop/layout/hash_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +9 -2
- data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
- data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
- data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/interpolation_check.rb +7 -2
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -1
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +0 -9
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +7 -6
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +7 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +32 -12
- data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
- data/lib/rubocop/cop/migration/department_name.rb +12 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -60
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/security/eval.rb +15 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +4 -2
- data/lib/rubocop/cop/style/alias.rb +4 -1
- data/lib/rubocop/cop/style/array_join.rb +4 -2
- data/lib/rubocop/cop/style/ascii_comments.rb +5 -2
- data/lib/rubocop/cop/style/attr.rb +5 -2
- data/lib/rubocop/cop/style/bare_percent_literals.rb +3 -1
- data/lib/rubocop/cop/style/begin_block.rb +3 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +2 -2
- data/lib/rubocop/cop/style/case_equality.rb +4 -0
- data/lib/rubocop/cop/style/class_and_module_children.rb +10 -2
- data/lib/rubocop/cop/style/colon_method_call.rb +3 -1
- data/lib/rubocop/cop/style/copyright.rb +1 -1
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/each_with_object.rb +2 -0
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_class_definition.rb +21 -20
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/encoding.rb +7 -1
- data/lib/rubocop/cop/style/end_block.rb +3 -1
- data/lib/rubocop/cop/style/endless_method.rb +8 -3
- data/lib/rubocop/cop/style/file_open.rb +63 -0
- data/lib/rubocop/cop/style/for.rb +3 -0
- data/lib/rubocop/cop/style/format_string_token.rb +29 -2
- data/lib/rubocop/cop/style/global_vars.rb +4 -1
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +21 -5
- data/lib/rubocop/cop/style/hash_transform_keys.rb +17 -7
- data/lib/rubocop/cop/style/hash_transform_values.rb +17 -7
- data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
- data/lib/rubocop/cop/style/inline_comment.rb +4 -1
- data/lib/rubocop/cop/style/map_join.rb +123 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +3 -1
- data/lib/rubocop/cop/style/nil_comparison.rb +2 -3
- data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
- data/lib/rubocop/cop/style/not.rb +2 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +2 -1
- data/lib/rubocop/cop/style/one_class_per_file.rb +95 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +4 -3
- data/lib/rubocop/cop/style/parallel_assignment.rb +4 -0
- data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -0
- data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
- data/lib/rubocop/cop/style/proc.rb +3 -2
- data/lib/rubocop/cop/style/reduce_to_hash.rb +169 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +3 -3
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
- data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +6 -3
- data/lib/rubocop/cop/style/redundant_return.rb +3 -1
- data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +104 -0
- data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
- data/lib/rubocop/cop/style/select_by_range.rb +197 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +51 -21
- data/lib/rubocop/cop/style/semicolon.rb +2 -0
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -1
- data/lib/rubocop/cop/style/special_global_vars.rb +6 -1
- data/lib/rubocop/cop/style/tally_method.rb +181 -0
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/variable_force/branch.rb +2 -2
- data/lib/rubocop/directive_comment.rb +2 -1
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/lsp/diagnostic.rb +1 -0
- data/lib/rubocop/mcp/server.rb +174 -0
- data/lib/rubocop/options.rb +10 -1
- data/lib/rubocop/server/cache.rb +5 -7
- data/lib/rubocop/target_ruby.rb +18 -12
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +14 -0
- metadata +34 -3
|
@@ -3,15 +3,28 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Security
|
|
6
|
-
# Checks for the use of `Kernel#eval` and `Binding#eval
|
|
6
|
+
# Checks for the use of `Kernel#eval` and `Binding#eval` with
|
|
7
|
+
# dynamic strings as arguments. Evaluating non-literal strings
|
|
8
|
+
# can enable code injection attacks and makes it difficult to
|
|
9
|
+
# reason about what code will actually be executed.
|
|
10
|
+
#
|
|
11
|
+
# Calls to `eval` with literal strings are not flagged by this cop,
|
|
12
|
+
# as they do not pose the same injection risk.
|
|
7
13
|
#
|
|
8
14
|
# @example
|
|
9
15
|
#
|
|
10
16
|
# # bad
|
|
11
|
-
#
|
|
12
17
|
# eval(something)
|
|
13
18
|
# binding.eval(something)
|
|
14
19
|
# Kernel.eval(something)
|
|
20
|
+
#
|
|
21
|
+
# # good - use safer alternatives
|
|
22
|
+
# obj.public_send(method_name)
|
|
23
|
+
# obj.send(method_name, *args)
|
|
24
|
+
#
|
|
25
|
+
# # good - literal strings are allowed
|
|
26
|
+
# eval("1 + 1")
|
|
27
|
+
# binding.eval("foo")
|
|
15
28
|
class Eval < Base
|
|
16
29
|
MSG = 'The use of `eval` is a serious security risk.'
|
|
17
30
|
RESTRICT_ON_SEND = %i[eval].freeze
|
|
@@ -4,8 +4,10 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Checks for grouping of accessors in `class` and `module` bodies.
|
|
7
|
-
# By default it enforces accessors to be placed in grouped
|
|
8
|
-
#
|
|
7
|
+
# By default it enforces accessors to be placed in grouped
|
|
8
|
+
# declarations, reducing boilerplate. It can also be configured
|
|
9
|
+
# to enforce separating them into individual declarations for
|
|
10
|
+
# easier diffing and per-attribute documentation.
|
|
9
11
|
#
|
|
10
12
|
# NOTE: If there is a method call before the accessor method it is always allowed
|
|
11
13
|
# as it might be intended like Sorbet.
|
|
@@ -4,7 +4,10 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Enforces the use of either `#alias` or `#alias_method`
|
|
7
|
-
# depending on configuration.
|
|
7
|
+
# depending on configuration. Consistent use of one or the
|
|
8
|
+
# other prevents confusion about their different semantics
|
|
9
|
+
# (e.g., `alias` is resolved at parse time, while `alias_method`
|
|
10
|
+
# is resolved at runtime).
|
|
8
11
|
# It also flags uses of `alias :symbol` rather than `alias bareword`.
|
|
9
12
|
#
|
|
10
13
|
# However, it will always enforce `method_alias` when used `alias`
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for uses of
|
|
6
|
+
# Checks for uses of `*` as a substitute for `Array#join`.
|
|
7
|
+
# Using `join` is clearer about intent and more readable than
|
|
8
|
+
# overloading the `*` operator for string conversion.
|
|
7
9
|
#
|
|
8
|
-
# Not all cases can reliably checked, due to Ruby's dynamic
|
|
10
|
+
# Not all cases can be reliably checked, due to Ruby's dynamic
|
|
9
11
|
# types, so we consider only cases when the first argument is an
|
|
10
12
|
# array literal or the second is a string literal.
|
|
11
13
|
#
|
|
@@ -4,8 +4,11 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Checks for non-ascii (non-English) characters
|
|
7
|
-
# in comments.
|
|
8
|
-
#
|
|
7
|
+
# in comments. Non-ascii characters can cause issues with
|
|
8
|
+
# portability and encoding across different environments
|
|
9
|
+
# and editors. You could set an array of allowed non-ascii
|
|
10
|
+
# chars in `AllowedChars` attribute (copyright notice "©"
|
|
11
|
+
# by default).
|
|
9
12
|
#
|
|
10
13
|
# @example
|
|
11
14
|
# # bad
|
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for uses of Module#attr
|
|
6
|
+
# Checks for uses of `Module#attr`. The `attr` method has confusing
|
|
7
|
+
# behavior: with a single argument it creates a reader (like `attr_reader`),
|
|
8
|
+
# but with a second boolean argument it creates an accessor (deprecated in
|
|
9
|
+
# Ruby 1.9). Use `attr_reader` or `attr_accessor` to make intent explicit.
|
|
7
10
|
#
|
|
8
11
|
# @example
|
|
9
|
-
# # bad
|
|
12
|
+
# # bad
|
|
10
13
|
# attr :something, true
|
|
11
14
|
# attr :one, :two, :three # behaves as attr_reader
|
|
12
15
|
#
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks if usage of
|
|
6
|
+
# Checks if usage of `%()` or `%Q()` matches configuration.
|
|
7
|
+
# Consistent use of one style makes the codebase easier
|
|
8
|
+
# to read.
|
|
7
9
|
#
|
|
8
10
|
# @example EnforcedStyle: bare_percent (default)
|
|
9
11
|
# # bad
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for BEGIN blocks.
|
|
6
|
+
# Checks for `BEGIN` blocks. They are Perl-style constructs that execute
|
|
7
|
+
# code before the rest of the file is parsed, making the control flow
|
|
8
|
+
# harder to follow and reason about.
|
|
7
9
|
#
|
|
8
10
|
# @example
|
|
9
11
|
# # bad
|
|
@@ -421,7 +421,7 @@ module RuboCop
|
|
|
421
421
|
|
|
422
422
|
if node.braces?
|
|
423
423
|
functional_method?(method_name) || functional_block?(node) ||
|
|
424
|
-
(procedural_oneliners_may_have_braces? &&
|
|
424
|
+
(procedural_oneliners_may_have_braces? && node.single_line?)
|
|
425
425
|
else
|
|
426
426
|
procedural_method?(method_name) || !return_value_used?(node)
|
|
427
427
|
end
|
|
@@ -489,7 +489,7 @@ module RuboCop
|
|
|
489
489
|
def begin_required?(block_node)
|
|
490
490
|
# If the block contains `rescue` or `ensure`, it needs to be wrapped in
|
|
491
491
|
# `begin`...`end` when changing `do-end` to `{}`.
|
|
492
|
-
block_node.each_child_node(:rescue, :ensure).any? &&
|
|
492
|
+
block_node.each_child_node(:rescue, :ensure).any? && block_node.multiline?
|
|
493
493
|
end
|
|
494
494
|
|
|
495
495
|
def single_argument_operator_method?(node)
|
|
@@ -4,6 +4,10 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Checks for uses of the case equality operator (`===`).
|
|
7
|
+
# The `===` operator has different behavior depending on the
|
|
8
|
+
# receiver and its use outside of `case`/`when` is confusing.
|
|
9
|
+
# Prefer more explicit alternatives like `is_a?`, `include?`,
|
|
10
|
+
# or `match?`.
|
|
7
11
|
#
|
|
8
12
|
# If `AllowOnConstant` option is enabled, the cop will ignore violations when the receiver of
|
|
9
13
|
# the case equality operator is a constant.
|
|
@@ -28,16 +28,24 @@ module RuboCop
|
|
|
28
28
|
# manual oversight.
|
|
29
29
|
#
|
|
30
30
|
# @example EnforcedStyle: nested (default)
|
|
31
|
+
# # bad
|
|
32
|
+
# class Foo::Bar
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
31
35
|
# # good
|
|
32
|
-
# # have each child on its own line
|
|
33
36
|
# class Foo
|
|
34
37
|
# class Bar
|
|
35
38
|
# end
|
|
36
39
|
# end
|
|
37
40
|
#
|
|
38
41
|
# @example EnforcedStyle: compact
|
|
42
|
+
# # bad
|
|
43
|
+
# class Foo
|
|
44
|
+
# class Bar
|
|
45
|
+
# end
|
|
46
|
+
# end
|
|
47
|
+
#
|
|
39
48
|
# # good
|
|
40
|
-
# # combine definitions as much as possible
|
|
41
49
|
# class Foo::Bar
|
|
42
50
|
# end
|
|
43
51
|
#
|
|
@@ -4,7 +4,9 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Checks for methods invoked via the `::` operator instead
|
|
7
|
-
# of the `.` operator (like `FileUtils::rmdir` instead of
|
|
7
|
+
# of the `.` operator (like `FileUtils::rmdir` instead of
|
|
8
|
+
# `FileUtils.rmdir`). The `::` operator is conventionally used to
|
|
9
|
+
# reference constants, so using it for method calls can be misleading.
|
|
8
10
|
#
|
|
9
11
|
# @example
|
|
10
12
|
# # bad
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
#
|
|
6
|
+
# Checks that a copyright notice was given in each source file.
|
|
7
7
|
#
|
|
8
8
|
# The default regexp for an acceptable copyright notice can be found in
|
|
9
9
|
# config/default.yml. The default can be changed as follows:
|
|
@@ -26,7 +26,7 @@ module RuboCop
|
|
|
26
26
|
|
|
27
27
|
MSG = 'Use `Integer#times` for a simple loop which iterates a fixed number of times.'
|
|
28
28
|
|
|
29
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
29
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
30
30
|
return unless offending?(node)
|
|
31
31
|
|
|
32
32
|
send_node = node.send_node
|
|
@@ -28,7 +28,7 @@ module RuboCop
|
|
|
28
28
|
|
|
29
29
|
MSG = 'Omit pipes for the empty block parameters.'
|
|
30
30
|
|
|
31
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
31
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
32
32
|
send_node = node.send_node
|
|
33
33
|
check(node) unless send_node.send_type? && send_node.lambda_literal?
|
|
34
34
|
end
|
|
@@ -5,15 +5,22 @@ module RuboCop
|
|
|
5
5
|
module Style
|
|
6
6
|
# Enforces consistent style for empty class definitions.
|
|
7
7
|
#
|
|
8
|
-
# This cop can enforce either a
|
|
8
|
+
# This cop can enforce either a standard class definition or `Class.new`
|
|
9
9
|
# for classes with no body.
|
|
10
10
|
#
|
|
11
11
|
# The supported styles are:
|
|
12
12
|
#
|
|
13
|
-
# * class_definition (default) - prefer
|
|
13
|
+
# * class_definition (default) - prefer standard class definition over `Class.new`
|
|
14
14
|
# * class_new - prefer `Class.new` over class definition
|
|
15
15
|
#
|
|
16
|
-
#
|
|
16
|
+
# One difference between the two styles is that the `Class.new` form does not make
|
|
17
|
+
# the subclass name available to the base class's `inherited` callback.
|
|
18
|
+
# For this reason, `EnforcedStyle: class_definition` is set as the default style.
|
|
19
|
+
# Class definitions without a superclass, which are not involved in inheritance,
|
|
20
|
+
# are not detected. This ensures safe detection regardless of the applied style.
|
|
21
|
+
# This avoids overlapping responsibilities with the `Lint/EmptyClass` cop.
|
|
22
|
+
#
|
|
23
|
+
# @example EnforcedStyle: class_keyword (default)
|
|
17
24
|
# # bad
|
|
18
25
|
# FooError = Class.new(StandardError)
|
|
19
26
|
#
|
|
@@ -37,30 +44,30 @@ module RuboCop
|
|
|
37
44
|
#
|
|
38
45
|
class EmptyClassDefinition < Base
|
|
39
46
|
include ConfigurableEnforcedStyle
|
|
40
|
-
include RangeHelp
|
|
41
47
|
extend AutoCorrector
|
|
42
48
|
|
|
43
|
-
|
|
44
|
-
'
|
|
45
|
-
MSG_CLASS_NEW = '
|
|
49
|
+
MSG_CLASS_KEYWORD =
|
|
50
|
+
'Use the `class` keyword instead of `Class.new` to define an empty class.'
|
|
51
|
+
MSG_CLASS_NEW = 'Use `Class.new` instead of the `class` keyword to define an empty class.'
|
|
46
52
|
|
|
47
53
|
# @!method class_new_assignment(node)
|
|
48
54
|
def_node_matcher :class_new_assignment, <<~PATTERN
|
|
49
|
-
(casgn _ _ $(send (const _ :Class) :new
|
|
55
|
+
(casgn _ _ $(send (const _ :Class) :new _))
|
|
50
56
|
PATTERN
|
|
51
57
|
|
|
52
58
|
def on_casgn(node)
|
|
53
|
-
return unless
|
|
59
|
+
return unless %i[class_keyword class_definition].include?(style)
|
|
54
60
|
return unless (class_new_node = class_new_assignment(node))
|
|
55
61
|
return if (arg = class_new_node.first_argument) && !arg.const_type?
|
|
56
62
|
|
|
57
|
-
add_offense(node, message:
|
|
63
|
+
add_offense(node, message: MSG_CLASS_KEYWORD) do |corrector|
|
|
58
64
|
autocorrect_class_new(corrector, node, class_new_node)
|
|
59
65
|
end
|
|
60
66
|
end
|
|
61
67
|
|
|
62
68
|
def on_class(node)
|
|
63
69
|
return unless style == :class_new
|
|
70
|
+
return unless node.parent_class
|
|
64
71
|
return if (body = node.body) && !body.children.empty?
|
|
65
72
|
|
|
66
73
|
add_offense(node, message: MSG_CLASS_NEW) do |corrector|
|
|
@@ -73,22 +80,16 @@ module RuboCop
|
|
|
73
80
|
def autocorrect_class_new(corrector, node, class_new_node)
|
|
74
81
|
indent = ' ' * node.loc.column
|
|
75
82
|
class_name = node.name
|
|
76
|
-
|
|
77
|
-
parent_class_name = " < #{parent_class.source}"
|
|
78
|
-
end
|
|
83
|
+
parent_class_name = class_new_node.first_argument.source
|
|
79
84
|
|
|
80
|
-
corrector.replace(node, "class #{class_name}#{parent_class_name}\n#{indent}end")
|
|
85
|
+
corrector.replace(node, "class #{class_name} < #{parent_class_name}\n#{indent}end")
|
|
81
86
|
end
|
|
82
87
|
|
|
83
88
|
def autocorrect_class_definition(corrector, node)
|
|
84
|
-
indent = ' ' * node.loc.column
|
|
85
89
|
class_name = node.identifier.source
|
|
86
|
-
|
|
87
|
-
parent_class_name = "(#{parent_class.source})"
|
|
88
|
-
end
|
|
89
|
-
range = range_by_whole_lines(node.source_range, include_final_newline: true)
|
|
90
|
+
parent_class_name = node.parent_class.source
|
|
90
91
|
|
|
91
|
-
corrector.replace(
|
|
92
|
+
corrector.replace(node, "#{class_name} = Class.new(#{parent_class_name})")
|
|
92
93
|
end
|
|
93
94
|
end
|
|
94
95
|
end
|
|
@@ -23,7 +23,7 @@ module RuboCop
|
|
|
23
23
|
|
|
24
24
|
MSG = 'Omit parentheses for the empty lambda parameters.'
|
|
25
25
|
|
|
26
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
26
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
27
27
|
send_node = node.send_node
|
|
28
28
|
return unless send_node.send_type?
|
|
29
29
|
|
|
@@ -3,12 +3,18 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks
|
|
6
|
+
# Checks that source files have no utf-8 encoding comments.
|
|
7
|
+
# Since Ruby 2.0, UTF-8 is the default source encoding, so
|
|
8
|
+
# these comments are no longer necessary and just add noise.
|
|
9
|
+
#
|
|
7
10
|
# @example
|
|
8
11
|
# # bad
|
|
9
12
|
# # encoding: UTF-8
|
|
10
13
|
# # coding: UTF-8
|
|
11
14
|
# # -*- coding: UTF-8 -*-
|
|
15
|
+
#
|
|
16
|
+
# # good
|
|
17
|
+
# # No encoding comment needed
|
|
12
18
|
class Encoding < Base
|
|
13
19
|
include RangeHelp
|
|
14
20
|
extend AutoCorrector
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for END blocks.
|
|
6
|
+
# Checks for `END` blocks. `END` blocks are Perl-style constructs
|
|
7
|
+
# and `Kernel#at_exit` is the idiomatic Ruby alternative, as it's
|
|
8
|
+
# explicit and can be used anywhere.
|
|
7
9
|
#
|
|
8
10
|
# @example
|
|
9
11
|
# # bad
|
|
@@ -157,6 +157,7 @@ module RuboCop
|
|
|
157
157
|
handle_require_always_style(node)
|
|
158
158
|
end
|
|
159
159
|
end
|
|
160
|
+
alias on_defs on_def
|
|
160
161
|
|
|
161
162
|
private
|
|
162
163
|
|
|
@@ -170,7 +171,7 @@ module RuboCop
|
|
|
170
171
|
end
|
|
171
172
|
|
|
172
173
|
def handle_require_single_line_style(node)
|
|
173
|
-
if node.endless? &&
|
|
174
|
+
if node.endless? && node.multiline?
|
|
174
175
|
add_offense(node, message: MSG_MULTI_LINE) do |corrector|
|
|
175
176
|
correct_to_multiline(corrector, node)
|
|
176
177
|
end
|
|
@@ -207,7 +208,7 @@ module RuboCop
|
|
|
207
208
|
|
|
208
209
|
def correct_to_multiline(corrector, node)
|
|
209
210
|
replacement = <<~RUBY.strip
|
|
210
|
-
def #{node.method_name}#{arguments(node)}
|
|
211
|
+
def #{receiver(node)}#{node.method_name}#{arguments(node)}
|
|
211
212
|
#{node.body.source}
|
|
212
213
|
end
|
|
213
214
|
RUBY
|
|
@@ -217,10 +218,14 @@ module RuboCop
|
|
|
217
218
|
|
|
218
219
|
def endless_replacement(node)
|
|
219
220
|
<<~RUBY.strip
|
|
220
|
-
def #{node.method_name}#{arguments(node)} = #{node.body.source}
|
|
221
|
+
def #{receiver(node)}#{node.method_name}#{arguments(node)} = #{node.body.source}
|
|
221
222
|
RUBY
|
|
222
223
|
end
|
|
223
224
|
|
|
225
|
+
def receiver(node)
|
|
226
|
+
node.receiver ? "#{node.receiver.source}#{node.loc.operator.source}" : ''
|
|
227
|
+
end
|
|
228
|
+
|
|
224
229
|
def arguments(node, missing = '')
|
|
225
230
|
node.arguments.any? ? node.arguments.source : missing
|
|
226
231
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Checks for `File.open` without a block, which can leak file descriptors.
|
|
7
|
+
#
|
|
8
|
+
# When `File.open` is called without a block, the caller is responsible
|
|
9
|
+
# for closing the file descriptor. If it is not explicitly closed, it
|
|
10
|
+
# will only be closed when the garbage collector runs, which may lead
|
|
11
|
+
# to resource exhaustion. Using the block form ensures the file is
|
|
12
|
+
# automatically closed when the block exits.
|
|
13
|
+
#
|
|
14
|
+
# @safety
|
|
15
|
+
# This cop is unsafe because it detects all `File.open` calls without
|
|
16
|
+
# a block, including intentional uses such as one-shot reads
|
|
17
|
+
# (`File.open("f").read`) where the file descriptor is closed by the
|
|
18
|
+
# garbage collector.
|
|
19
|
+
#
|
|
20
|
+
# @example
|
|
21
|
+
# # bad
|
|
22
|
+
# f = File.open('file')
|
|
23
|
+
#
|
|
24
|
+
# # bad
|
|
25
|
+
# File.open('file').read
|
|
26
|
+
#
|
|
27
|
+
# # good
|
|
28
|
+
# File.open('file') do |f|
|
|
29
|
+
# f.read
|
|
30
|
+
# end
|
|
31
|
+
#
|
|
32
|
+
# # good
|
|
33
|
+
# File.open('file', &:read)
|
|
34
|
+
#
|
|
35
|
+
# # good - use File.read for one-shot reads
|
|
36
|
+
# File.read('file')
|
|
37
|
+
#
|
|
38
|
+
class FileOpen < Base
|
|
39
|
+
MSG = '`File.open` without a block may leak a file descriptor; use the block form.'
|
|
40
|
+
RESTRICT_ON_SEND = %i[open].freeze
|
|
41
|
+
|
|
42
|
+
# @!method file_open?(node)
|
|
43
|
+
def_node_matcher :file_open?, <<~PATTERN
|
|
44
|
+
(send (const {nil? cbase} :File) :open ...)
|
|
45
|
+
PATTERN
|
|
46
|
+
|
|
47
|
+
def on_send(node)
|
|
48
|
+
return unless file_open?(node)
|
|
49
|
+
return if block_form?(node)
|
|
50
|
+
|
|
51
|
+
add_offense(node)
|
|
52
|
+
end
|
|
53
|
+
alias on_csend on_send
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def block_form?(node)
|
|
58
|
+
node.block_argument? || node.parent&.block_type?
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -8,6 +8,9 @@ module RuboCop
|
|
|
8
8
|
# parameter. An `each` call with a block on a single line is always
|
|
9
9
|
# allowed.
|
|
10
10
|
#
|
|
11
|
+
# NOTE: `each` is preferred in idiomatic Ruby because `for` leaks
|
|
12
|
+
# its loop variable into the surrounding scope.
|
|
13
|
+
#
|
|
11
14
|
# @example EnforcedStyle: each (default)
|
|
12
15
|
# # bad
|
|
13
16
|
# def foo
|
|
@@ -18,6 +18,11 @@ module RuboCop
|
|
|
18
18
|
# of `EnforcedStyle`) are only considered if used in the format string argument to the
|
|
19
19
|
# methods `printf`, `sprintf`, `format` and `%`.
|
|
20
20
|
#
|
|
21
|
+
# NOTE: In `aggressive` mode, offenses are registered for all strings containing tokens,
|
|
22
|
+
# but autocorrection is only applied when the string appears in a known formatting context
|
|
23
|
+
# (`format`, `sprintf`, `printf`, or `%`). This is done in order to prevent false
|
|
24
|
+
# autocorrections for strings that are not actually format strings.
|
|
25
|
+
#
|
|
21
26
|
# NOTE: Tokens in the `unannotated` style (eg. `%s`) are always treated as if
|
|
22
27
|
# configured with `Conservative: true`. This is done in order to prevent false positives,
|
|
23
28
|
# because this format is very similar to encoded URLs or Date/Time formatting strings.
|
|
@@ -90,9 +95,25 @@ module RuboCop
|
|
|
90
95
|
# # good
|
|
91
96
|
# redirect('foo/%{bar_id}')
|
|
92
97
|
#
|
|
98
|
+
# @example Mode: aggressive (default), EnforcedStyle: annotated
|
|
99
|
+
#
|
|
100
|
+
# # bad
|
|
101
|
+
# "%{greeting}"
|
|
102
|
+
# foo("%{greeting}")
|
|
103
|
+
#
|
|
104
|
+
# # bad
|
|
105
|
+
# format("%{greeting}", greeting: 'Hello')
|
|
106
|
+
# printf("%{greeting}", greeting: 'Hello')
|
|
107
|
+
# sprintf("%{greeting}", greeting: 'Hello')
|
|
108
|
+
# "%{greeting}" % { greeting: 'Hello' }
|
|
109
|
+
#
|
|
110
|
+
# # good
|
|
111
|
+
# format("%<greeting>s", greeting: 'Hello')
|
|
112
|
+
# printf("%<greeting>s", greeting: 'Hello')
|
|
113
|
+
# sprintf("%<greeting>s", greeting: 'Hello')
|
|
114
|
+
# "%<greeting>s" % { greeting: 'Hello' }
|
|
115
|
+
#
|
|
93
116
|
# @example Mode: conservative, EnforcedStyle: annotated
|
|
94
|
-
# # In `conservative` mode, offenses are only registered for strings
|
|
95
|
-
# # given to a known formatting method.
|
|
96
117
|
#
|
|
97
118
|
# # good
|
|
98
119
|
# "%{greeting}"
|
|
@@ -104,6 +125,12 @@ module RuboCop
|
|
|
104
125
|
# sprintf("%{greeting}", greeting: 'Hello')
|
|
105
126
|
# "%{greeting}" % { greeting: 'Hello' }
|
|
106
127
|
#
|
|
128
|
+
# # good
|
|
129
|
+
# format("%<greeting>s", greeting: 'Hello')
|
|
130
|
+
# printf("%<greeting>s", greeting: 'Hello')
|
|
131
|
+
# sprintf("%<greeting>s", greeting: 'Hello')
|
|
132
|
+
# "%<greeting>s" % { greeting: 'Hello' }
|
|
133
|
+
#
|
|
107
134
|
class FormatStringToken < Base
|
|
108
135
|
include ConfigurableEnforcedStyle
|
|
109
136
|
include AllowedMethods
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Looks for uses of global variables.
|
|
6
|
+
# Looks for uses of global variables. Global variables introduce
|
|
7
|
+
# shared mutable state that makes code harder to test, debug,
|
|
8
|
+
# and reason about, since any part of the program can read or modify them.
|
|
9
|
+
#
|
|
7
10
|
# It does not report offenses for built-in global variables.
|
|
8
11
|
# Built-in global variables are allowed by default. Additionally
|
|
9
12
|
# users can allow additional variables via the AllowedVariables option.
|
|
@@ -6,8 +6,13 @@ module RuboCop
|
|
|
6
6
|
# Checks for presence or absence of braces around hash literal as a last
|
|
7
7
|
# array item depending on configuration.
|
|
8
8
|
#
|
|
9
|
-
# NOTE: This cop will ignore arrays where
|
|
10
|
-
# EnforcedStyle
|
|
9
|
+
# NOTE: This cop will ignore arrays where multiple items are all hashes,
|
|
10
|
+
# regardless of `EnforcedStyle`.
|
|
11
|
+
#
|
|
12
|
+
# [source,ruby]
|
|
13
|
+
# ----
|
|
14
|
+
# [{ one: 1 }, { two: 2 }]
|
|
15
|
+
# ----
|
|
11
16
|
#
|
|
12
17
|
# @example EnforcedStyle: braces (default)
|
|
13
18
|
# # bad
|
|
@@ -16,8 +21,11 @@ module RuboCop
|
|
|
16
21
|
# # good
|
|
17
22
|
# [1, 2, { one: 1, two: 2 }]
|
|
18
23
|
#
|
|
24
|
+
# # bad
|
|
25
|
+
# [one: 1, two: 2]
|
|
26
|
+
#
|
|
19
27
|
# # good
|
|
20
|
-
# [{ one: 1
|
|
28
|
+
# [{ one: 1, two: 2 }]
|
|
21
29
|
#
|
|
22
30
|
# @example EnforcedStyle: no_braces
|
|
23
31
|
# # bad
|
|
@@ -26,8 +34,11 @@ module RuboCop
|
|
|
26
34
|
# # good
|
|
27
35
|
# [1, 2, one: 1, two: 2]
|
|
28
36
|
#
|
|
37
|
+
# # bad
|
|
38
|
+
# [{ one: 1, two: 2 }]
|
|
39
|
+
#
|
|
29
40
|
# # good
|
|
30
|
-
# [
|
|
41
|
+
# [one: 1, two: 2]
|
|
31
42
|
class HashAsLastArrayItem < Base
|
|
32
43
|
include RangeHelp
|
|
33
44
|
include ConfigurableEnforcedStyle
|
|
@@ -69,7 +80,12 @@ module RuboCop
|
|
|
69
80
|
return if node.braces?
|
|
70
81
|
|
|
71
82
|
add_offense(node, message: 'Wrap hash in `{` and `}`.') do |corrector|
|
|
72
|
-
|
|
83
|
+
if node.single_line? || same_line?(node, node.parent)
|
|
84
|
+
corrector.wrap(node, '{', '}')
|
|
85
|
+
else
|
|
86
|
+
indent = indent(node)
|
|
87
|
+
corrector.wrap(node, "{\n#{indent}", "\n#{indent}}")
|
|
88
|
+
end
|
|
73
89
|
end
|
|
74
90
|
end
|
|
75
91
|
|