rubocop 1.75.8 → 1.80.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 +20 -16
- data/config/default.yml +107 -26
- data/config/obsoletion.yml +6 -3
- data/exe/rubocop +1 -8
- data/lib/rubocop/cli.rb +17 -1
- data/lib/rubocop/config_loader.rb +1 -38
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +6 -3
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
- data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +0 -22
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +4 -4
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +26 -5
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -0
- data/lib/rubocop/cop/layout/space_around_keyword.rb +6 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +8 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +2 -9
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -2
- data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +25 -4
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
- data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +4 -4
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/literal_as_condition.rb +34 -28
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -2
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +1 -0
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +101 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +4 -4
- data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +4 -4
- data/lib/rubocop/cop/lint/self_assignment.rb +30 -4
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +5 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +29 -4
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +1 -0
- data/lib/rubocop/cop/lint/useless_or.rb +98 -0
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +3 -3
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +24 -8
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +2 -2
- data/lib/rubocop/cop/naming/method_name.rb +127 -13
- data/lib/rubocop/cop/naming/predicate_method.rb +306 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +4 -4
- data/lib/rubocop/cop/security/eval.rb +2 -1
- data/lib/rubocop/cop/security/open.rb +1 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -1
- data/lib/rubocop/cop/style/accessor_grouping.rb +13 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +11 -17
- data/lib/rubocop/cop/style/array_intersect.rb +98 -34
- data/lib/rubocop/cop/style/bitwise_predicate.rb +8 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/case_like_if.rb +1 -1
- data/lib/rubocop/cop/style/collection_querying.rb +167 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +4 -2
- data/lib/rubocop/cop/style/dig_chain.rb +1 -1
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
- data/lib/rubocop/cop/style/exponential_notation.rb +3 -2
- data/lib/rubocop/cop/style/fetch_env_var.rb +32 -6
- data/lib/rubocop/cop/style/hash_conversion.rb +16 -8
- data/lib/rubocop/cop/style/if_unless_modifier.rb +13 -6
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
- data/lib/rubocop/cop/style/it_assignment.rb +69 -12
- data/lib/rubocop/cop/style/it_block_parameter.rb +36 -15
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -3
- data/lib/rubocop/cop/style/map_to_set.rb +1 -3
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +4 -6
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +16 -0
- data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
- data/lib/rubocop/cop/style/parallel_assignment.rb +32 -20
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +34 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +1 -1
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
- data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +42 -6
- data/lib/rubocop/cop/style/redundant_self.rb +8 -5
- data/lib/rubocop/cop/style/safe_navigation.rb +38 -12
- data/lib/rubocop/cop/style/single_line_methods.rb +7 -4
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +32 -2
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +1 -1
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +1 -1
- data/lib/rubocop/cop/variable_force.rb +25 -8
- data/lib/rubocop/cops_documentation_generator.rb +1 -0
- data/lib/rubocop/formatter/disabled_config_formatter.rb +18 -5
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +1 -0
- data/lib/rubocop/lsp/diagnostic.rb +4 -4
- data/lib/rubocop/lsp/routes.rb +35 -6
- data/lib/rubocop/pending_cops_reporter.rb +56 -0
- data/lib/rubocop/result_cache.rb +14 -12
- data/lib/rubocop/rspec/expect_offense.rb +9 -3
- data/lib/rubocop/runner.rb +6 -4
- data/lib/rubocop/server/cache.rb +4 -2
- data/lib/rubocop/server/client_command/base.rb +10 -0
- data/lib/rubocop/server/client_command/exec.rb +2 -1
- data/lib/rubocop/server/client_command/start.rb +11 -1
- data/lib/rubocop/target_finder.rb +9 -9
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +11 -1
- data/lib/ruby_lsp/rubocop/addon.rb +2 -2
- metadata +17 -7
@@ -29,10 +29,13 @@ module RuboCop
|
|
29
29
|
def align_end(corrector, processed_source, node, align_to)
|
30
30
|
@processed_source = processed_source
|
31
31
|
whitespace = whitespace_range(node)
|
32
|
-
return false unless whitespace.source.strip.empty?
|
33
|
-
|
34
32
|
column = alignment_column(align_to)
|
35
|
-
|
33
|
+
|
34
|
+
if whitespace.source.strip.empty?
|
35
|
+
corrector.replace(whitespace, ' ' * column)
|
36
|
+
else
|
37
|
+
corrector.insert_after(whitespace, "\n#{' ' * column}")
|
38
|
+
end
|
36
39
|
end
|
37
40
|
|
38
41
|
private
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
class ForToEachCorrector
|
7
7
|
extend NodePattern::Macros
|
8
8
|
|
9
|
-
CORRECTION = '%<collection>s
|
9
|
+
CORRECTION = '%<collection>s%<dot>seach do |%<argument>s|'
|
10
10
|
|
11
11
|
def initialize(for_node)
|
12
12
|
@for_node = for_node
|
@@ -25,7 +25,12 @@ module RuboCop
|
|
25
25
|
attr_reader :for_node, :variable_node, :collection_node
|
26
26
|
|
27
27
|
def correction
|
28
|
-
format(
|
28
|
+
format(
|
29
|
+
CORRECTION,
|
30
|
+
collection: collection_source,
|
31
|
+
dot: collection_node.csend_type? ? '&.' : '.',
|
32
|
+
argument: variable_node.source
|
33
|
+
)
|
29
34
|
end
|
30
35
|
|
31
36
|
def collection_source
|
@@ -10,8 +10,11 @@ module RuboCop
|
|
10
10
|
COMMA_REGEXP = /(?<=\))\s*,/.freeze
|
11
11
|
|
12
12
|
def correct(corrector, node)
|
13
|
-
|
14
|
-
corrector.remove(node.loc.
|
13
|
+
buffer = node.source_range.source_buffer
|
14
|
+
corrector.remove(range_with_surrounding_space(range: node.loc.begin, buffer: buffer,
|
15
|
+
side: :right, whitespace: true))
|
16
|
+
corrector.remove(range_with_surrounding_space(range: node.loc.end, buffer: buffer,
|
17
|
+
side: :left))
|
15
18
|
handle_orphaned_comma(corrector, node)
|
16
19
|
|
17
20
|
return unless ternary_condition?(node) && next_char_is_question_mark?(node)
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Gemspec
|
6
|
+
# Use consistent style for Gemspec attributes assignment.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# # This example uses two styles for assignment of metadata attribute.
|
12
|
+
# Gem::Specification.new do |spec|
|
13
|
+
# spec.metadata = { 'key' => 'value' }
|
14
|
+
# spec.metadata['another-key'] = 'another-value'
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# Gem::Specification.new do |spec|
|
19
|
+
# spec.metadata['key'] = 'value'
|
20
|
+
# spec.metadata['another-key'] = 'another-value'
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# Gem::Specification.new do |spec|
|
25
|
+
# spec.metadata = { 'key' => 'value', 'another-key' => 'another-value' }
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# # bad
|
29
|
+
# # This example uses two styles for assignment of authors attribute.
|
30
|
+
# Gem::Specification.new do |spec|
|
31
|
+
# spec.authors = %w[author-0 author-1]
|
32
|
+
# spec.authors[2] = 'author-2'
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# # good
|
36
|
+
# Gem::Specification.new do |spec|
|
37
|
+
# spec.authors = %w[author-0 author-1 author-2]
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# # good
|
41
|
+
# Gem::Specification.new do |spec|
|
42
|
+
# spec.authors[0] = 'author-0'
|
43
|
+
# spec.authors[1] = 'author-1'
|
44
|
+
# spec.authors[2] = 'author-2'
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# # good
|
48
|
+
# # This example uses consistent assignment per attribute,
|
49
|
+
# # even though two different styles are used overall.
|
50
|
+
# Gem::Specification.new do |spec|
|
51
|
+
# spec.metadata = { 'key' => 'value' }
|
52
|
+
# spec.authors[0] = 'author-0'
|
53
|
+
# spec.authors[1] = 'author-1'
|
54
|
+
# spec.authors[2] = 'author-2'
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
class AttributeAssignment < Base
|
58
|
+
include GemspecHelp
|
59
|
+
|
60
|
+
MSG = 'Use consistent style for Gemspec attributes assignment.'
|
61
|
+
|
62
|
+
def on_new_investigation
|
63
|
+
return if processed_source.blank?
|
64
|
+
|
65
|
+
assignments = source_assignments(processed_source.ast)
|
66
|
+
indexed_assignments = source_indexed_assignments(processed_source.ast)
|
67
|
+
|
68
|
+
assignments.keys.intersection(indexed_assignments.keys).each do |attribute|
|
69
|
+
indexed_assignments[attribute].each do |node|
|
70
|
+
add_offense(node)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def source_assignments(ast)
|
78
|
+
assignment_method_declarations(ast)
|
79
|
+
.select(&:assignment_method?)
|
80
|
+
.group_by(&:method_name)
|
81
|
+
.transform_keys { |method_name| method_name.to_s.delete_suffix('=').to_sym }
|
82
|
+
end
|
83
|
+
|
84
|
+
def source_indexed_assignments(ast)
|
85
|
+
indexed_assignment_method_declarations(ast)
|
86
|
+
.group_by { |node| node.children.first.method_name }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -54,22 +54,6 @@ module RuboCop
|
|
54
54
|
MSG = '`%<assignment>s` method calls already given on line ' \
|
55
55
|
'%<line_of_first_occurrence>d of the gemspec.'
|
56
56
|
|
57
|
-
# @!method assignment_method_declarations(node)
|
58
|
-
def_node_search :assignment_method_declarations, <<~PATTERN
|
59
|
-
(send
|
60
|
-
(lvar #match_block_variable_name?) _ ...)
|
61
|
-
PATTERN
|
62
|
-
|
63
|
-
# @!method indexed_assignment_method_declarations(node)
|
64
|
-
def_node_search :indexed_assignment_method_declarations, <<~PATTERN
|
65
|
-
(send
|
66
|
-
(send (lvar #match_block_variable_name?) _)
|
67
|
-
:[]=
|
68
|
-
literal?
|
69
|
-
_
|
70
|
-
)
|
71
|
-
PATTERN
|
72
|
-
|
73
57
|
def on_new_investigation
|
74
58
|
return if processed_source.blank?
|
75
59
|
|
@@ -96,12 +80,6 @@ module RuboCop
|
|
96
80
|
end
|
97
81
|
end
|
98
82
|
|
99
|
-
def match_block_variable_name?(receiver_name)
|
100
|
-
gem_specification(processed_source.ast) do |block_variable_name|
|
101
|
-
return block_variable_name == receiver_name
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
83
|
def duplicated_assignment_method_nodes
|
106
84
|
assignment_method_declarations(processed_source.ast)
|
107
85
|
.select(&:assignment_method?)
|
@@ -71,7 +71,7 @@ module RuboCop
|
|
71
71
|
|
72
72
|
dependency_declarations(processed_source.ast)
|
73
73
|
.each_cons(2) do |previous, current|
|
74
|
-
next unless consecutive_lines(previous, current)
|
74
|
+
next unless consecutive_lines?(previous, current)
|
75
75
|
next unless case_insensitive_out_of_order?(gem_name(current), gem_name(previous))
|
76
76
|
next unless get_dependency_name(previous) == get_dependency_name(current)
|
77
77
|
|
@@ -74,6 +74,14 @@ module RuboCop
|
|
74
74
|
}
|
75
75
|
PATTERN
|
76
76
|
|
77
|
+
# @!method metadata_assignment(node)
|
78
|
+
def_node_search :metadata_assignment, <<~PATTERN
|
79
|
+
`{
|
80
|
+
(send _ :metadata= _)
|
81
|
+
(send (send _ :metadata) :[]= (str _) _)
|
82
|
+
}
|
83
|
+
PATTERN
|
84
|
+
|
77
85
|
# @!method rubygems_mfa_required(node)
|
78
86
|
def_node_search :rubygems_mfa_required, <<~PATTERN
|
79
87
|
(pair (str "rubygems_mfa_required") $_)
|
@@ -131,9 +139,15 @@ module RuboCop
|
|
131
139
|
end
|
132
140
|
|
133
141
|
def insert_mfa_required(corrector, node, block_var)
|
134
|
-
|
142
|
+
require_mfa_directive = <<~RUBY.strip
|
135
143
|
#{block_var}.metadata['rubygems_mfa_required'] = 'true'
|
136
144
|
RUBY
|
145
|
+
|
146
|
+
if (last_assignment = metadata_assignment(processed_source.ast).to_a.last)
|
147
|
+
corrector.insert_after(last_assignment, "\n#{require_mfa_directive}")
|
148
|
+
else
|
149
|
+
corrector.insert_before(node.loc.end, "#{require_mfa_directive}\n")
|
150
|
+
end
|
137
151
|
end
|
138
152
|
|
139
153
|
def change_value(corrector, value)
|
@@ -46,7 +46,7 @@ module RuboCop
|
|
46
46
|
/\A(does not|doesn't) (register|find|flag|report)/ => 'registers',
|
47
47
|
/\A(does not|doesn't) add (a|an|any )?offense/ => 'registers an offense',
|
48
48
|
/\Aregisters no offense/ => 'registers an offense',
|
49
|
-
/\A(accepts|register)\b/ => 'registers'
|
49
|
+
/\A(accepts|allows|register)\b/ => 'registers'
|
50
50
|
}.freeze
|
51
51
|
|
52
52
|
EXPECT_NO_CORRECTIONS_DESCRIPTION_MAPPING = {
|
@@ -110,8 +110,8 @@ module RuboCop
|
|
110
110
|
def directive_offense_type(directive, actual_name)
|
111
111
|
return :missing_directive unless directive
|
112
112
|
|
113
|
-
return :wrong_scope if wrong_scope(directive, actual_name)
|
114
|
-
return :no_scope if no_scope(directive, actual_name)
|
113
|
+
return :wrong_scope if wrong_scope?(directive, actual_name)
|
114
|
+
return :no_scope if no_scope?(directive, actual_name)
|
115
115
|
|
116
116
|
# The method directive being prefixed by 'self.' is always an offense.
|
117
117
|
# The matched method_name does not contain the receiver but the
|
@@ -121,11 +121,11 @@ module RuboCop
|
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
|
-
def wrong_scope(directive, actual_name)
|
124
|
+
def wrong_scope?(directive, actual_name)
|
125
125
|
!actual_name.start_with?('self.') && directive[:has_scope_directive]
|
126
126
|
end
|
127
127
|
|
128
|
-
def no_scope(directive, actual_name)
|
128
|
+
def no_scope?(directive, actual_name)
|
129
129
|
actual_name.start_with?('self.') && !directive[:has_scope_directive]
|
130
130
|
end
|
131
131
|
|
@@ -29,6 +29,7 @@ module RuboCop
|
|
29
29
|
NODE_GROUPS = {
|
30
30
|
any_block: %i[block numblock itblock],
|
31
31
|
any_def: %i[def defs],
|
32
|
+
any_match_pattern: %i[match_pattern match_pattern_p],
|
32
33
|
argument: %i[arg optarg restarg kwarg kwoptarg kwrestarg blockarg forward_arg shadowarg],
|
33
34
|
boolean: %i[true false],
|
34
35
|
call: %i[send csend],
|
@@ -66,8 +66,9 @@ module RuboCop
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def autocorrect_to_explicit_predicate(corrector, node, group_name)
|
69
|
-
|
70
|
-
|
69
|
+
range = node.loc.selector.begin.join(node.source_range.end)
|
70
|
+
|
71
|
+
corrector.replace(range, "#{group_name}_type?")
|
71
72
|
end
|
72
73
|
|
73
74
|
def autocorrect_keep_method(corrector, symbol_args, group_name, group_types)
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Layout
|
6
|
+
# Checks for an empty line after a module inclusion method (`extend`,
|
7
|
+
# `include` and `prepend`), or a group of them.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# class Foo
|
12
|
+
# include Bar
|
13
|
+
# attr_reader :baz
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# # good
|
17
|
+
# class Foo
|
18
|
+
# include Bar
|
19
|
+
#
|
20
|
+
# attr_reader :baz
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# # also good - multiple module inclusions grouped together
|
24
|
+
# class Foo
|
25
|
+
# extend Bar
|
26
|
+
# include Baz
|
27
|
+
# prepend Qux
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
class EmptyLinesAfterModuleInclusion < Base
|
31
|
+
include RangeHelp
|
32
|
+
extend AutoCorrector
|
33
|
+
|
34
|
+
MSG = 'Add an empty line after module inclusion.'
|
35
|
+
|
36
|
+
MODULE_INCLUSION_METHODS = %i[include extend prepend].freeze
|
37
|
+
|
38
|
+
RESTRICT_ON_SEND = MODULE_INCLUSION_METHODS
|
39
|
+
|
40
|
+
def on_send(node)
|
41
|
+
return if node.receiver || node.arguments.empty?
|
42
|
+
return if node.parent&.type?(:send, :any_block)
|
43
|
+
|
44
|
+
return if next_line_empty_or_enable_directive_comment?(node.last_line)
|
45
|
+
|
46
|
+
next_line_node = next_line_node(node)
|
47
|
+
return unless require_empty_line?(next_line_node)
|
48
|
+
|
49
|
+
add_offense(node) { |corrector| autocorrect(corrector, node) }
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def autocorrect(corrector, node)
|
55
|
+
node_range = range_by_whole_lines(node.source_range)
|
56
|
+
|
57
|
+
next_line = node_range.last_line + 1
|
58
|
+
if enable_directive_comment?(next_line)
|
59
|
+
node_range = processed_source.comment_at_line(next_line)
|
60
|
+
end
|
61
|
+
|
62
|
+
corrector.insert_after(node_range, "\n")
|
63
|
+
end
|
64
|
+
|
65
|
+
def next_line_empty_or_enable_directive_comment?(line)
|
66
|
+
line_empty?(line) || (enable_directive_comment?(line + 1) && line_empty?(line + 1))
|
67
|
+
end
|
68
|
+
|
69
|
+
def enable_directive_comment?(line)
|
70
|
+
return false unless (comment = processed_source.comment_at_line(line))
|
71
|
+
|
72
|
+
DirectiveComment.new(comment).enabled?
|
73
|
+
end
|
74
|
+
|
75
|
+
def line_empty?(line)
|
76
|
+
processed_source[line].nil? || processed_source[line].blank?
|
77
|
+
end
|
78
|
+
|
79
|
+
def require_empty_line?(node)
|
80
|
+
return false unless node
|
81
|
+
|
82
|
+
!allowed_method?(node)
|
83
|
+
end
|
84
|
+
|
85
|
+
def allowed_method?(node)
|
86
|
+
node = node.body if node.respond_to?(:modifier_form?) && node.modifier_form?
|
87
|
+
|
88
|
+
return false unless node.send_type?
|
89
|
+
|
90
|
+
MODULE_INCLUSION_METHODS.include?(node.method_name)
|
91
|
+
end
|
92
|
+
|
93
|
+
def next_line_node(node)
|
94
|
+
return if node.parent.if_type?
|
95
|
+
|
96
|
+
node.right_sibling
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -138,7 +138,7 @@ module RuboCop
|
|
138
138
|
end
|
139
139
|
|
140
140
|
def previous_line_ignoring_comments(processed_source, send_line)
|
141
|
-
processed_source[0..send_line - 2].reverse.find { |line| !comment_line?(line) }
|
141
|
+
processed_source[0..(send_line - 2)].reverse.find { |line| !comment_line?(line) }
|
142
142
|
end
|
143
143
|
|
144
144
|
def previous_line_empty?(send_line)
|
@@ -62,40 +62,19 @@ module RuboCop
|
|
62
62
|
node.receiver && node.receiver.loc.last_line != node.loc.selector&.line
|
63
63
|
end
|
64
64
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
68
|
-
lines.map { |_, line| line }
|
69
|
-
end
|
70
|
-
|
71
|
-
def extra_lines(node)
|
72
|
-
empty_lines(node).each do |line|
|
73
|
-
range = source_range(processed_source.buffer, line, 0)
|
74
|
-
yield(range)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def processed_lines(node)
|
79
|
-
line_numbers(node).each_with_object([]) do |num, array|
|
80
|
-
array << [processed_source.lines[num - 1], num]
|
65
|
+
def extra_lines(node, &block)
|
66
|
+
node.arguments.each do |arg|
|
67
|
+
empty_range_for_starting_point(arg.source_range.begin, &block)
|
81
68
|
end
|
82
|
-
end
|
83
69
|
|
84
|
-
|
85
|
-
inner_lines = []
|
86
|
-
line_nums = node.arguments.each_with_object([]) do |arg_node, lines|
|
87
|
-
lines << outer_lines(arg_node)
|
88
|
-
inner_lines << inner_lines(arg_node) if arg_node.multiline?
|
89
|
-
end
|
90
|
-
line_nums.flatten.uniq - inner_lines.flatten - outer_lines(node)
|
70
|
+
empty_range_for_starting_point(node.loc.end.begin, &block) if node.loc.end
|
91
71
|
end
|
92
72
|
|
93
|
-
def
|
94
|
-
|
95
|
-
|
73
|
+
def empty_range_for_starting_point(start)
|
74
|
+
range = range_with_surrounding_space(start, whitespace: true, side: :left)
|
75
|
+
return unless range.last_line - range.first_line > 1
|
96
76
|
|
97
|
-
|
98
|
-
[node.first_line - 1, node.last_line + 1]
|
77
|
+
yield range.source_buffer.line_range(range.last_line - 1).adjust(end_pos: 1)
|
99
78
|
end
|
100
79
|
end
|
101
80
|
end
|
@@ -258,7 +258,7 @@ module RuboCop
|
|
258
258
|
if ignore_cop_directives? && directive_on_source_line?(line_index)
|
259
259
|
return check_directive_line(line, line_index)
|
260
260
|
end
|
261
|
-
return
|
261
|
+
return check_line_for_exemptions(line, line_index) if allow_uri? || allow_qualified_name?
|
262
262
|
|
263
263
|
register_offense(excess_range(nil, line, line_index), line, line_index)
|
264
264
|
end
|
@@ -358,11 +358,32 @@ module RuboCop
|
|
358
358
|
)
|
359
359
|
end
|
360
360
|
|
361
|
-
def
|
362
|
-
uri_range
|
363
|
-
|
361
|
+
def check_line_for_exemptions(line, line_index)
|
362
|
+
uri_range = range_if_applicable(line, :uri)
|
363
|
+
qualified_name_range = range_if_applicable(line, :qualified_name)
|
364
364
|
|
365
|
-
|
365
|
+
return if allowed_combination?(line, uri_range, qualified_name_range)
|
366
|
+
|
367
|
+
range = uri_range || qualified_name_range
|
368
|
+
register_offense(excess_range(range, line, line_index), line, line_index)
|
369
|
+
end
|
370
|
+
|
371
|
+
def range_if_applicable(line, type)
|
372
|
+
return unless type == :uri ? allow_uri? : allow_qualified_name?
|
373
|
+
|
374
|
+
find_excessive_range(line, type)
|
375
|
+
end
|
376
|
+
|
377
|
+
def allowed_combination?(line, uri_range, qualified_name_range)
|
378
|
+
if uri_range && qualified_name_range
|
379
|
+
allowed_position?(line, uri_range) && allowed_position?(line, qualified_name_range)
|
380
|
+
elsif uri_range
|
381
|
+
allowed_position?(line, uri_range)
|
382
|
+
elsif qualified_name_range
|
383
|
+
allowed_position?(line, qualified_name_range)
|
384
|
+
else
|
385
|
+
false
|
386
|
+
end
|
366
387
|
end
|
367
388
|
|
368
389
|
def breakable_dstr?(node)
|
@@ -10,6 +10,8 @@ module RuboCop
|
|
10
10
|
# condition, an explicit `return` statement, etc. In other contexts, the second operand should
|
11
11
|
# be indented regardless of enforced style.
|
12
12
|
#
|
13
|
+
# In both styles, operators should be aligned when an assignment begins on the next line.
|
14
|
+
#
|
13
15
|
# @example EnforcedStyle: aligned (default)
|
14
16
|
# # bad
|
15
17
|
# if a +
|
@@ -16,6 +16,8 @@ module RuboCop
|
|
16
16
|
#
|
17
17
|
# something = 123if test
|
18
18
|
#
|
19
|
+
# return(foo + bar)
|
20
|
+
#
|
19
21
|
# # good
|
20
22
|
# something 'test' do |x|
|
21
23
|
# end
|
@@ -24,6 +26,9 @@ module RuboCop
|
|
24
26
|
# end
|
25
27
|
#
|
26
28
|
# something = 123 if test
|
29
|
+
#
|
30
|
+
# return (foo + bar)
|
31
|
+
#
|
27
32
|
class SpaceAroundKeyword < Base
|
28
33
|
extend AutoCorrector
|
29
34
|
|
@@ -33,7 +38,7 @@ module RuboCop
|
|
33
38
|
DO = 'do'
|
34
39
|
SAFE_NAVIGATION = '&.'
|
35
40
|
NAMESPACE_OPERATOR = '::'
|
36
|
-
ACCEPT_LEFT_PAREN = %w[break defined? next not rescue
|
41
|
+
ACCEPT_LEFT_PAREN = %w[break defined? next not rescue super yield].freeze
|
37
42
|
ACCEPT_LEFT_SQUARE_BRACKET = %w[super yield].freeze
|
38
43
|
ACCEPT_NAMESPACE_OPERATOR = 'super'
|
39
44
|
RESTRICT_ON_SEND = %i[!].freeze
|
@@ -151,6 +151,14 @@ module RuboCop
|
|
151
151
|
check_operator(:match_pattern, node.loc.operator, node)
|
152
152
|
end
|
153
153
|
|
154
|
+
def on_match_alt(node)
|
155
|
+
check_operator(:match_alt, node.loc.operator, node)
|
156
|
+
end
|
157
|
+
|
158
|
+
def on_match_as(node)
|
159
|
+
check_operator(:match_as, node.loc.operator, node)
|
160
|
+
end
|
161
|
+
|
154
162
|
alias on_or on_binary
|
155
163
|
alias on_and on_binary
|
156
164
|
alias on_lvasgn on_assignment
|
@@ -22,10 +22,11 @@ module RuboCop
|
|
22
22
|
RESTRICT_ON_SEND = %i[[] []=].freeze
|
23
23
|
|
24
24
|
def on_send(node)
|
25
|
+
return if node.loc.dot
|
26
|
+
|
25
27
|
receiver_end_pos = node.receiver.source_range.end_pos
|
26
28
|
selector_begin_pos = node.loc.selector.begin_pos
|
27
29
|
return if receiver_end_pos >= selector_begin_pos
|
28
|
-
return if dot_before_brackets?(node, receiver_end_pos, selector_begin_pos)
|
29
30
|
|
30
31
|
range = range_between(receiver_end_pos, selector_begin_pos)
|
31
32
|
|
@@ -33,14 +34,6 @@ module RuboCop
|
|
33
34
|
corrector.remove(range)
|
34
35
|
end
|
35
36
|
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def dot_before_brackets?(node, receiver_end_pos, selector_begin_pos)
|
40
|
-
return false unless node.loc.respond_to?(:dot) && (dot = node.loc.dot)
|
41
|
-
|
42
|
-
dot.begin_pos == receiver_end_pos && dot.end_pos == selector_begin_pos
|
43
|
-
end
|
44
37
|
end
|
45
38
|
end
|
46
39
|
end
|
@@ -86,6 +86,7 @@ module RuboCop
|
|
86
86
|
def on_array(node)
|
87
87
|
return if node.array_type? && !node.square_brackets?
|
88
88
|
|
89
|
+
node = find_node_with_brackets(node)
|
89
90
|
tokens, left, right = array_brackets(node)
|
90
91
|
return unless left && right
|
91
92
|
|
@@ -102,6 +103,10 @@ module RuboCop
|
|
102
103
|
|
103
104
|
private
|
104
105
|
|
106
|
+
def find_node_with_brackets(node)
|
107
|
+
node.ancestors.find(&:const_pattern_type?) || node
|
108
|
+
end
|
109
|
+
|
105
110
|
def autocorrect(corrector, node)
|
106
111
|
tokens, left, right = array_brackets(node)
|
107
112
|
|
@@ -119,7 +124,7 @@ module RuboCop
|
|
119
124
|
def array_brackets(node)
|
120
125
|
tokens = processed_source.tokens_within(node)
|
121
126
|
|
122
|
-
left = tokens.find(&:
|
127
|
+
left = tokens.find(&:left_bracket?)
|
123
128
|
right = tokens.reverse_each.find(&:right_bracket?)
|
124
129
|
|
125
130
|
[tokens, left, right]
|
@@ -192,7 +197,7 @@ module RuboCop
|
|
192
197
|
if side == :right
|
193
198
|
processed_source.tokens_within(node)[i].right_bracket?
|
194
199
|
else
|
195
|
-
processed_source.tokens_within(node)[i].
|
200
|
+
processed_source.tokens_within(node)[i].left_bracket?
|
196
201
|
end
|
197
202
|
end
|
198
203
|
|
@@ -27,7 +27,9 @@ module RuboCop
|
|
27
27
|
# @example
|
28
28
|
# # bad
|
29
29
|
# x || 1..2
|
30
|
+
# x - 1..2
|
30
31
|
# (x || 1..2)
|
32
|
+
# x || 1..y || 2
|
31
33
|
# 1..2.to_a
|
32
34
|
#
|
33
35
|
# # good, unambiguous
|
@@ -41,6 +43,7 @@ module RuboCop
|
|
41
43
|
#
|
42
44
|
# # good, ambiguity removed
|
43
45
|
# x || (1..2)
|
46
|
+
# (x - 1)..2
|
44
47
|
# (x || 1)..2
|
45
48
|
# (x || 1)..(y || 2)
|
46
49
|
# (1..2).to_a
|
@@ -96,6 +99,8 @@ module RuboCop
|
|
96
99
|
# to avoid the ambiguity of `1..2.to_a`.
|
97
100
|
return false if node.receiver&.basic_literal?
|
98
101
|
|
102
|
+
return false if node.operator_method? && !node.method?(:[])
|
103
|
+
|
99
104
|
require_parentheses_for_method_chain? || node.receiver.nil?
|
100
105
|
end
|
101
106
|
|