rubocop 1.32.0 → 1.35.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/config/default.yml +73 -16
- data/config/obsoletion.yml +23 -1
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cli/command/{auto_genenerate_config.rb → auto_generate_config.rb} +2 -2
- data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
- data/lib/rubocop/cli/command/suggest_extensions.rb +53 -15
- data/lib/rubocop/config.rb +1 -1
- data/lib/rubocop/config_finder.rb +68 -0
- data/lib/rubocop/config_loader.rb +12 -40
- data/lib/rubocop/config_loader_resolver.rb +1 -5
- data/lib/rubocop/config_obsoletion/changed_parameter.rb +5 -0
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +4 -0
- data/lib/rubocop/config_obsoletion.rb +7 -2
- data/lib/rubocop/cop/cop.rb +1 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +58 -0
- data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
- data/lib/rubocop/cop/generator/require_file_injector.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +69 -0
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +62 -0
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/layout/block_alignment.rb +2 -0
- data/lib/rubocop/cop/layout/block_end_newline.rb +35 -5
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +5 -2
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -0
- data/lib/rubocop/cop/layout/end_of_line.rb +4 -4
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -1
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/indentation_width.rb +2 -0
- data/lib/rubocop/cop/layout/line_length.rb +4 -1
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
- 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/layout/space_before_block_braces.rb +2 -0
- data/lib/rubocop/cop/legacy/corrections_proxy.rb +1 -1
- data/lib/rubocop/cop/legacy/corrector.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +21 -8
- data/lib/rubocop/cop/lint/debugger.rb +26 -16
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +65 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +9 -9
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +4 -0
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +25 -6
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +6 -6
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +12 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +24 -8
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +9 -3
- data/lib/rubocop/cop/lint/redundant_with_index.rb +13 -10
- data/lib/rubocop/cop/lint/redundant_with_object.rb +12 -11
- data/lib/rubocop/cop/lint/shadowed_exception.rb +15 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +10 -1
- data/lib/rubocop/cop/lint/unreachable_loop.rb +7 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +6 -4
- data/lib/rubocop/cop/lint/void.rb +2 -0
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -1
- data/lib/rubocop/cop/metrics/block_length.rb +6 -7
- data/lib/rubocop/cop/metrics/method_length.rb +8 -8
- data/lib/rubocop/cop/mixin/allowed_methods.rb +15 -1
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +5 -1
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +76 -1
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +8 -13
- data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +4 -5
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +2 -2
- data/lib/rubocop/cop/naming/predicate_name.rb +24 -3
- data/lib/rubocop/cop/style/arguments_forwarding.rb +2 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +26 -7
- data/lib/rubocop/cop/style/class_and_module_children.rb +4 -4
- data/lib/rubocop/cop/style/class_equality_comparison.rb +32 -7
- data/lib/rubocop/cop/style/class_methods_definitions.rb +2 -1
- data/lib/rubocop/cop/style/collection_methods.rb +2 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -1
- data/lib/rubocop/cop/style/double_negation.rb +2 -0
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/each_with_object.rb +39 -8
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_heredoc.rb +15 -1
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/format_string_token.rb +21 -8
- data/lib/rubocop/cop/style/guard_clause.rb +27 -16
- data/lib/rubocop/cop/style/hash_each_methods.rb +3 -1
- data/lib/rubocop/cop/style/hash_except.rb +0 -4
- data/lib/rubocop/cop/style/hash_syntax.rb +17 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +8 -6
- data/lib/rubocop/cop/style/magic_comment_format.rb +307 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -7
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -6
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
- data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -1
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
- data/lib/rubocop/cop/style/next.rb +3 -5
- data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
- data/lib/rubocop/cop/style/numeric_literals.rb +16 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +28 -8
- data/lib/rubocop/cop/style/object_then.rb +2 -0
- data/lib/rubocop/cop/style/proc.rb +4 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +2 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +19 -4
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +15 -22
- data/lib/rubocop/cop/style/redundant_self.rb +2 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +21 -6
- data/lib/rubocop/cop/style/redundant_sort_by.rb +24 -8
- data/lib/rubocop/cop/style/safe_navigation.rb +4 -2
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +14 -5
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +34 -9
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -13
- data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -1
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +1 -1
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/ext/range.rb +15 -0
- data/lib/rubocop/feature_loader.rb +94 -0
- data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +3 -3
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -1
- data/lib/rubocop/formatter/tap_formatter.rb +1 -1
- data/lib/rubocop/result_cache.rb +22 -20
- data/lib/rubocop/server/cache.rb +36 -1
- data/lib/rubocop/server/cli.rb +19 -2
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +5 -3
- metadata +15 -9
- data/lib/rubocop/cop/mixin/ignored_methods.rb +0 -52
@@ -47,10 +47,15 @@ module RuboCop
|
|
47
47
|
|
48
48
|
# Default rules for obsoletions are in config/obsoletion.yml
|
49
49
|
# Additional rules files can be added with `RuboCop::ConfigObsoletion.files << filename`
|
50
|
-
def load_rules
|
50
|
+
def load_rules # rubocop:disable Metrics/AbcSize
|
51
51
|
rules = self.class.files.each_with_object({}) do |filename, hash|
|
52
52
|
hash.merge!(YAML.safe_load(File.read(filename))) do |_key, first, second|
|
53
|
-
first
|
53
|
+
case first
|
54
|
+
when Hash
|
55
|
+
first.merge(second)
|
56
|
+
when Array
|
57
|
+
first.concat(second)
|
58
|
+
end
|
54
59
|
end
|
55
60
|
end
|
56
61
|
|
data/lib/rubocop/cop/cop.rb
CHANGED
@@ -7,7 +7,7 @@ module RuboCop
|
|
7
7
|
module Cop
|
8
8
|
# @deprecated Use Cop::Base instead
|
9
9
|
# Legacy scaffold for Cops.
|
10
|
-
# See https://docs.rubocop.org/rubocop/
|
10
|
+
# See https://docs.rubocop.org/rubocop/v1_upgrade_notes.html
|
11
11
|
class Cop < Base
|
12
12
|
attr_reader :offenses
|
13
13
|
|
@@ -5,9 +5,15 @@ module RuboCop
|
|
5
5
|
# This autocorrects parentheses
|
6
6
|
class ParenthesesCorrector
|
7
7
|
class << self
|
8
|
+
include RangeHelp
|
9
|
+
|
10
|
+
COMMA_REGEXP = /(?<=\))\s*,/.freeze
|
11
|
+
|
8
12
|
def correct(corrector, node)
|
9
13
|
corrector.remove(node.loc.begin)
|
10
14
|
corrector.remove(node.loc.end)
|
15
|
+
handle_orphaned_comma(corrector, node)
|
16
|
+
|
11
17
|
return unless ternary_condition?(node) && next_char_is_question_mark?(node)
|
12
18
|
|
13
19
|
corrector.insert_after(node.loc.end, ' ')
|
@@ -22,6 +28,58 @@ module RuboCop
|
|
22
28
|
def next_char_is_question_mark?(node)
|
23
29
|
node.loc.last_column == node.parent.loc.question.column
|
24
30
|
end
|
31
|
+
|
32
|
+
def only_closing_paren_before_comma?(node)
|
33
|
+
source_buffer = node.source_range.source_buffer
|
34
|
+
line_range = source_buffer.line_range(node.loc.end.line)
|
35
|
+
|
36
|
+
line_range.source.start_with?(/\s*\)\s*,/)
|
37
|
+
end
|
38
|
+
|
39
|
+
# If removing parentheses leaves a comma on its own line, remove all the whitespace
|
40
|
+
# preceding it to prevent a syntax error.
|
41
|
+
def handle_orphaned_comma(corrector, node)
|
42
|
+
return unless only_closing_paren_before_comma?(node)
|
43
|
+
|
44
|
+
range = extend_range_for_heredoc(node, parens_range(node))
|
45
|
+
corrector.remove(range)
|
46
|
+
|
47
|
+
add_heredoc_comma(corrector, node)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Get a range for the closing parenthesis and all whitespace to the left of it
|
51
|
+
def parens_range(node)
|
52
|
+
range_with_surrounding_space(
|
53
|
+
range: node.loc.end,
|
54
|
+
buffer: node.source_range.source_buffer,
|
55
|
+
side: :left,
|
56
|
+
newlines: true,
|
57
|
+
whitespace: true,
|
58
|
+
continuations: true
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
# If the node contains a heredoc, remove the comma too
|
63
|
+
# It'll be added back in the right place later
|
64
|
+
def extend_range_for_heredoc(node, range)
|
65
|
+
return range unless heredoc?(node)
|
66
|
+
|
67
|
+
comma_line = range_by_whole_lines(node.loc.end, buffer: node.source_range.source_buffer)
|
68
|
+
offset = comma_line.source.match(COMMA_REGEXP)[0]&.size || 0
|
69
|
+
|
70
|
+
range.adjust(end_pos: offset)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Add a comma back after the heredoc identifier
|
74
|
+
def add_heredoc_comma(corrector, node)
|
75
|
+
return unless heredoc?(node)
|
76
|
+
|
77
|
+
corrector.insert_after(node.child_nodes.last.loc.expression, ',')
|
78
|
+
end
|
79
|
+
|
80
|
+
def heredoc?(node)
|
81
|
+
node.child_nodes.last.loc.is_a?(Parser::Source::Map::Heredoc)
|
82
|
+
end
|
25
83
|
end
|
26
84
|
end
|
27
85
|
end
|
@@ -84,7 +84,7 @@ module RuboCop
|
|
84
84
|
(str "true")
|
85
85
|
PATTERN
|
86
86
|
|
87
|
-
def on_block(node) # rubocop:disable Metrics/MethodLength
|
87
|
+
def on_block(node) # rubocop:disable Metrics/MethodLength, InternalAffairs/NumblockHandler
|
88
88
|
gem_specification(node) do |block_var|
|
89
89
|
metadata_value = metadata(node)
|
90
90
|
mfa_value = mfa_value(metadata_value)
|
@@ -55,8 +55,8 @@ module RuboCop
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
def require_path_fragments(
|
59
|
-
path =
|
58
|
+
def require_path_fragments(require_directive)
|
59
|
+
path = require_directive.match(REQUIRE_PATH)
|
60
60
|
|
61
61
|
path ? path.captures.first.split('/') : []
|
62
62
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# Checks for missing `numblock handlers. The blocks with numbered
|
7
|
+
# arguments introduced in Ruby 2.7 are parsed with a node type of
|
8
|
+
# `numblock` instead of block. Cops that define `block` handlers
|
9
|
+
# need to define `numblock` handlers or disable this cope for them.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
#
|
13
|
+
# # bad
|
14
|
+
# class BlockRelatedCop < Base
|
15
|
+
# def on_block(node)
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
# class BlockRelatedCop < Base
|
21
|
+
# def on_block(node)
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# alias on_numblock on_block
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# class BlockRelatedCop < Base
|
28
|
+
# def on_block(node)
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# alias_method :on_numblock, :on_block
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# class BlockRelatedCop < Base
|
35
|
+
# def on_block(node)
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# def on_numblock(node)
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
class NumblockHandler < Base
|
42
|
+
MSG = 'Define on_numblock to handle blocks with numbered arguments.'
|
43
|
+
|
44
|
+
def on_def(node)
|
45
|
+
return unless block_handler?(node)
|
46
|
+
return unless node.parent
|
47
|
+
|
48
|
+
add_offense(node) unless numblock_handler?(node.parent)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# @!method block_handler?(node)
|
54
|
+
def_node_matcher :block_handler?, <<~PATTERN
|
55
|
+
(def :on_block (args (arg :node)) ...)
|
56
|
+
PATTERN
|
57
|
+
|
58
|
+
# @!method numblock_handler?(node)
|
59
|
+
def_node_matcher :numblock_handler?, <<~PATTERN
|
60
|
+
{
|
61
|
+
`(def :on_numblock (args (arg :node)) ...)
|
62
|
+
`(alias (sym :on_numblock) (sym :on_block))
|
63
|
+
`(send nil? :alias_method (sym :on_numblock) (sym :on_block))
|
64
|
+
}
|
65
|
+
PATTERN
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# Enforces the use of `node.single_line?` instead of
|
7
|
+
# comparing `first_line` and `last_line` for equality.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# node.loc.first_line == node.loc.last_line
|
12
|
+
#
|
13
|
+
# # bad
|
14
|
+
# node.loc.last_line == node.loc.first_line
|
15
|
+
#
|
16
|
+
# # bad
|
17
|
+
# node.loc.line == node.loc.last_line
|
18
|
+
#
|
19
|
+
# # bad
|
20
|
+
# node.loc.last_line == node.loc.line
|
21
|
+
#
|
22
|
+
# # bad
|
23
|
+
# node.first_line == node.last_line
|
24
|
+
#
|
25
|
+
# # good
|
26
|
+
# node.single_line?
|
27
|
+
#
|
28
|
+
class SingleLineComparison < Base
|
29
|
+
extend AutoCorrector
|
30
|
+
|
31
|
+
MSG = 'Use `%<preferred>s`.'
|
32
|
+
RESTRICT_ON_SEND = %i[== !=].freeze
|
33
|
+
|
34
|
+
# @!method single_line_comparison(node)
|
35
|
+
def_node_matcher :single_line_comparison, <<~PATTERN
|
36
|
+
{
|
37
|
+
(send (send $_receiver {:line :first_line}) {:== :!=} (send _receiver :last_line))
|
38
|
+
(send (send $_receiver :last_line) {:== :!=} (send _receiver {:line :first_line}))
|
39
|
+
}
|
40
|
+
PATTERN
|
41
|
+
|
42
|
+
def on_send(node)
|
43
|
+
return unless (receiver = single_line_comparison(node))
|
44
|
+
|
45
|
+
bang = node.method?(:!=) ? '!' : ''
|
46
|
+
preferred = "#{bang}#{extract_receiver(receiver)}.single_line?"
|
47
|
+
|
48
|
+
add_offense(node, message: format(MSG, preferred: preferred)) do |corrector|
|
49
|
+
corrector.replace(node, preferred)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def extract_receiver(node)
|
56
|
+
node = node.receiver if node.send_type? && %i[loc source_range].include?(node.method_name)
|
57
|
+
node.source
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -10,6 +10,7 @@ require_relative 'internal_affairs/method_name_equal'
|
|
10
10
|
require_relative 'internal_affairs/node_destructuring'
|
11
11
|
require_relative 'internal_affairs/node_matcher_directive'
|
12
12
|
require_relative 'internal_affairs/node_type_predicate'
|
13
|
+
require_relative 'internal_affairs/numblock_handler'
|
13
14
|
require_relative 'internal_affairs/offense_location_keyword'
|
14
15
|
require_relative 'internal_affairs/redundant_context_config_parameter'
|
15
16
|
require_relative 'internal_affairs/redundant_described_class_as_subject'
|
@@ -17,6 +18,7 @@ require_relative 'internal_affairs/redundant_let_rubocop_config_new'
|
|
17
18
|
require_relative 'internal_affairs/redundant_location_argument'
|
18
19
|
require_relative 'internal_affairs/redundant_message_argument'
|
19
20
|
require_relative 'internal_affairs/redundant_method_dispatch_node'
|
21
|
+
require_relative 'internal_affairs/single_line_comparison'
|
20
22
|
require_relative 'internal_affairs/style_detected_api_use'
|
21
23
|
require_relative 'internal_affairs/undefined_config'
|
22
24
|
require_relative 'internal_affairs/useless_message_assertion'
|
@@ -36,24 +36,54 @@ module RuboCop
|
|
36
36
|
# If the end is on its own line, there is no offense
|
37
37
|
return if begins_its_line?(node.loc.end)
|
38
38
|
|
39
|
-
|
40
|
-
corrector.replace(delimiter_range(node), "\n#{node.loc.end.source}#{offset(node)}")
|
41
|
-
end
|
39
|
+
register_offense(node)
|
42
40
|
end
|
43
41
|
|
42
|
+
alias on_numblock on_block
|
43
|
+
|
44
44
|
private
|
45
45
|
|
46
|
+
def register_offense(node)
|
47
|
+
add_offense(node.loc.end, message: message(node)) do |corrector|
|
48
|
+
offense_range = offense_range(node)
|
49
|
+
replacement = "\n#{offense_range.source.strip}"
|
50
|
+
|
51
|
+
if (heredoc = last_heredoc_argument(node.body))
|
52
|
+
corrector.remove(offense_range)
|
53
|
+
corrector.insert_after(heredoc.loc.heredoc_end, replacement)
|
54
|
+
else
|
55
|
+
corrector.replace(offense_range, replacement)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
46
60
|
def message(node)
|
47
61
|
format(MSG, line: node.loc.end.line, column: node.loc.end.column + 1)
|
48
62
|
end
|
49
63
|
|
50
|
-
def
|
64
|
+
def last_heredoc_argument(node)
|
65
|
+
return unless node&.call_type?
|
66
|
+
return unless (arguments = node&.arguments)
|
67
|
+
|
68
|
+
heredoc = arguments.reverse.detect { |arg| arg.str_type? && arg.heredoc? }
|
69
|
+
return heredoc if heredoc
|
70
|
+
|
71
|
+
last_heredoc_argument(node.children.first)
|
72
|
+
end
|
73
|
+
|
74
|
+
def offense_range(node)
|
51
75
|
Parser::Source::Range.new(
|
52
76
|
node.loc.expression.source_buffer,
|
53
77
|
node.children.compact.last.loc.expression.end_pos,
|
54
|
-
node.loc.expression.end_pos
|
78
|
+
end_of_method_chain(node).loc.expression.end_pos
|
55
79
|
)
|
56
80
|
end
|
81
|
+
|
82
|
+
def end_of_method_chain(node)
|
83
|
+
return node unless node.parent&.call_type?
|
84
|
+
|
85
|
+
end_of_method_chain(node.parent)
|
86
|
+
end
|
57
87
|
end
|
58
88
|
end
|
59
89
|
end
|
@@ -80,8 +80,11 @@ module RuboCop
|
|
80
80
|
@block_line = node.source_range.first_line
|
81
81
|
end
|
82
82
|
|
83
|
-
|
84
|
-
|
83
|
+
alias on_numblock on_block
|
84
|
+
|
85
|
+
def on_send(node) # rubocop:disable Metrics/CyclomaticComplexity
|
86
|
+
return unless node.bare_access_modifier? &&
|
87
|
+
!(node.parent&.block_type? || node.parent&.numblock_type?)
|
85
88
|
return if expected_empty_lines?(node)
|
86
89
|
|
87
90
|
message = message(node)
|
@@ -22,20 +22,20 @@ module RuboCop
|
|
22
22
|
# # all platforms.
|
23
23
|
#
|
24
24
|
# # bad
|
25
|
-
# puts 'Hello' # Return character is CR+LF on all
|
25
|
+
# puts 'Hello' # Return character is CR+LF on all platforms.
|
26
26
|
#
|
27
27
|
# # good
|
28
|
-
# puts 'Hello' # Return character is LF on all
|
28
|
+
# puts 'Hello' # Return character is LF on all platforms.
|
29
29
|
#
|
30
30
|
# @example EnforcedStyle: crlf
|
31
31
|
# # The `crlf` style means that CR+LF (Carriage Return + Line Feed) is
|
32
32
|
# # enforced on all platforms.
|
33
33
|
#
|
34
34
|
# # bad
|
35
|
-
# puts 'Hello' # Return character is LF on all
|
35
|
+
# puts 'Hello' # Return character is LF on all platforms.
|
36
36
|
#
|
37
37
|
# # good
|
38
|
-
# puts 'Hello' # Return character is CR+LF on all
|
38
|
+
# puts 'Hello' # Return character is CR+LF on all platforms.
|
39
39
|
#
|
40
40
|
class EndOfLine < Base
|
41
41
|
include ConfigurableEnforcedStyle
|
@@ -153,7 +153,8 @@ module RuboCop
|
|
153
153
|
MSG = 'Indent the first argument one step more than %<base>s.'
|
154
154
|
|
155
155
|
def on_send(node)
|
156
|
-
return if style != :consistent && enforce_first_argument_with_fixed_indentation?
|
156
|
+
return if style != :consistent && enforce_first_argument_with_fixed_indentation? &&
|
157
|
+
!enable_layout_first_method_argument_line_break?
|
157
158
|
return if !node.arguments? || bare_operator?(node) || node.setter_method?
|
158
159
|
|
159
160
|
indent = base_indentation(node) + configured_indentation_width
|
@@ -267,6 +268,10 @@ module RuboCop
|
|
267
268
|
argument_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
|
268
269
|
end
|
269
270
|
|
271
|
+
def enable_layout_first_method_argument_line_break?
|
272
|
+
config.for_cop('Layout/FirstMethodArgumentLineBreak')['Enabled']
|
273
|
+
end
|
274
|
+
|
270
275
|
def argument_alignment_config
|
271
276
|
config.for_cop('Layout/ArgumentAlignment')
|
272
277
|
end
|
@@ -143,7 +143,7 @@ module RuboCop
|
|
143
143
|
case indent_base_type
|
144
144
|
when :left_brace_or_bracket
|
145
145
|
'the position of the opening bracket'
|
146
|
-
when :
|
146
|
+
when :first_column_after_left_parenthesis
|
147
147
|
'the first position after the preceding left parenthesis'
|
148
148
|
when :parent_hash_key
|
149
149
|
'the parent hash key'
|
@@ -164,7 +164,7 @@ module RuboCop
|
|
164
164
|
case indent_base_type
|
165
165
|
when :left_brace_or_bracket
|
166
166
|
'Indent the right bracket the same as the left bracket.'
|
167
|
-
when :
|
167
|
+
when :first_column_after_left_parenthesis
|
168
168
|
'Indent the right bracket the same as the first position ' \
|
169
169
|
'after the preceding left parenthesis.'
|
170
170
|
when :parent_hash_key
|
@@ -192,7 +192,7 @@ module RuboCop
|
|
192
192
|
case indent_base_type
|
193
193
|
when :left_brace_or_bracket
|
194
194
|
'the position of the opening brace'
|
195
|
-
when :
|
195
|
+
when :first_column_after_left_parenthesis
|
196
196
|
'the first position after the preceding left parenthesis'
|
197
197
|
when :parent_hash_key
|
198
198
|
'the parent hash key'
|
@@ -213,7 +213,7 @@ module RuboCop
|
|
213
213
|
case indent_base_type
|
214
214
|
when :left_brace_or_bracket
|
215
215
|
'Indent the right brace the same as the left brace.'
|
216
|
-
when :
|
216
|
+
when :first_column_after_left_parenthesis
|
217
217
|
'Indent the right brace the same as the first position ' \
|
218
218
|
'after the preceding left parenthesis.'
|
219
219
|
when :parent_hash_key
|
@@ -22,6 +22,7 @@ module RuboCop
|
|
22
22
|
# (Many of these are enabled by default.)
|
23
23
|
#
|
24
24
|
# * ArgumentAlignment
|
25
|
+
# * ArrayAlignment
|
25
26
|
# * BlockAlignment
|
26
27
|
# * BlockDelimiters
|
27
28
|
# * BlockEndNewline
|
@@ -74,6 +75,8 @@ module RuboCop
|
|
74
75
|
check_for_breakable_block(node)
|
75
76
|
end
|
76
77
|
|
78
|
+
alias on_numblock on_block
|
79
|
+
|
77
80
|
def on_potential_breakable_node(node)
|
78
81
|
check_for_breakable_node(node)
|
79
82
|
end
|
@@ -131,7 +134,7 @@ module RuboCop
|
|
131
134
|
if block_node.arguments? && !block_node.lambda?
|
132
135
|
block_node.arguments.loc.end
|
133
136
|
else
|
134
|
-
block_node.loc.begin
|
137
|
+
block_node.braces? ? block_node.loc.begin : block_node.loc.begin.adjust(begin_pos: 1)
|
135
138
|
end
|
136
139
|
end
|
137
140
|
|
@@ -73,7 +73,7 @@ module RuboCop
|
|
73
73
|
return if node.send_type? && node.loc.operator&.source != '='
|
74
74
|
return unless rhs
|
75
75
|
return unless supported_types.include?(rhs.type)
|
76
|
-
return if rhs.
|
76
|
+
return if rhs.single_line?
|
77
77
|
|
78
78
|
check_by_enforced_style(node, rhs)
|
79
79
|
end
|
@@ -101,7 +101,7 @@ module RuboCop
|
|
101
101
|
!comment_within?(node) &&
|
102
102
|
node.each_descendant(:if, :case, :kwbegin, :def).none? &&
|
103
103
|
node.each_descendant(:dstr, :str).none?(&:heredoc?) &&
|
104
|
-
node.each_descendant(:begin).none? { |b| b.
|
104
|
+
node.each_descendant(:begin).none? { |b| !b.single_line? }
|
105
105
|
end
|
106
106
|
|
107
107
|
def convertible_block?(node)
|
@@ -4,7 +4,7 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Legacy
|
6
6
|
# Legacy support for Corrector#corrections
|
7
|
-
# See https://docs.rubocop.org/rubocop/
|
7
|
+
# See https://docs.rubocop.org/rubocop/v1_upgrade_notes.html
|
8
8
|
class CorrectionsProxy
|
9
9
|
def initialize(corrector)
|
10
10
|
@corrector = corrector
|
@@ -4,7 +4,7 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Legacy
|
6
6
|
# Legacy Corrector for v0 API support.
|
7
|
-
# See https://docs.rubocop.org/rubocop/
|
7
|
+
# See https://docs.rubocop.org/rubocop/v1_upgrade_notes.html
|
8
8
|
class Corrector < RuboCop::Cop::Corrector
|
9
9
|
# Support legacy second argument
|
10
10
|
def initialize(source, corr = [])
|
@@ -6,8 +6,8 @@ module RuboCop
|
|
6
6
|
# Checks for ambiguous block association with method
|
7
7
|
# when param passed without parentheses.
|
8
8
|
#
|
9
|
-
# This cop can customize
|
10
|
-
# By default, there are no methods to
|
9
|
+
# This cop can customize allowed methods with `AllowedMethods`.
|
10
|
+
# By default, there are no methods to allowed.
|
11
11
|
#
|
12
12
|
# @example
|
13
13
|
#
|
@@ -30,18 +30,30 @@ module RuboCop
|
|
30
30
|
# # Lambda arguments require no disambiguation
|
31
31
|
# foo = ->(bar) { bar.baz }
|
32
32
|
#
|
33
|
-
# @example
|
33
|
+
# @example AllowedMethods: [] (default)
|
34
34
|
#
|
35
35
|
# # bad
|
36
36
|
# expect { do_something }.to change { object.attribute }
|
37
37
|
#
|
38
|
-
# @example
|
38
|
+
# @example AllowedMethods: [change]
|
39
39
|
#
|
40
40
|
# # good
|
41
41
|
# expect { do_something }.to change { object.attribute }
|
42
42
|
#
|
43
|
+
# @example AllowedPatterns: [] (default)
|
44
|
+
#
|
45
|
+
# # bad
|
46
|
+
# expect { do_something }.to change { object.attribute }
|
47
|
+
#
|
48
|
+
# @example AllowedPatterns: [/change/]
|
49
|
+
#
|
50
|
+
# # good
|
51
|
+
# expect { do_something }.to change { object.attribute }
|
52
|
+
# expect { do_something }.to not_change { object.attribute }
|
53
|
+
#
|
43
54
|
class AmbiguousBlockAssociation < Base
|
44
|
-
include
|
55
|
+
include AllowedMethods
|
56
|
+
include AllowedPattern
|
45
57
|
|
46
58
|
MSG = 'Parenthesize the param `%<param>s` to make sure that the ' \
|
47
59
|
'block will be associated with the `%<method>s` method ' \
|
@@ -52,7 +64,7 @@ module RuboCop
|
|
52
64
|
|
53
65
|
return unless ambiguous_block_association?(node)
|
54
66
|
return if node.parenthesized? || node.last_argument.lambda? || node.last_argument.proc? ||
|
55
|
-
|
67
|
+
allowed_method_pattern?(node)
|
56
68
|
|
57
69
|
message = message(node)
|
58
70
|
|
@@ -66,9 +78,10 @@ module RuboCop
|
|
66
78
|
send_node.last_argument.block_type? && !send_node.last_argument.send_node.arguments?
|
67
79
|
end
|
68
80
|
|
69
|
-
def
|
81
|
+
def allowed_method_pattern?(node)
|
70
82
|
node.assignment? || node.operator_method? || node.method?(:[]) ||
|
71
|
-
|
83
|
+
allowed_method?(node.last_argument.method_name) ||
|
84
|
+
matches_allowed_pattern?(node.last_argument.method_name)
|
72
85
|
end
|
73
86
|
|
74
87
|
def message(send_node)
|