rubocop 1.14.0 → 1.15.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 +3 -1
- data/config/default.yml +11 -3
- data/lib/rubocop.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -1
- data/lib/rubocop/cop/layout/argument_alignment.rb +28 -11
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +12 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +15 -7
- data/lib/rubocop/cop/layout/indentation_width.rb +5 -2
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -0
- data/lib/rubocop/cop/lint/empty_block.rb +18 -2
- data/lib/rubocop/cop/lint/void.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +19 -3
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +6 -0
- data/lib/rubocop/cop/style/class_and_module_children.rb +14 -2
- data/lib/rubocop/cop/style/empty_literal.rb +8 -1
- data/lib/rubocop/cop/style/nil_lambda.rb +29 -12
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/top_level_method_definition.rb +75 -0
- data/lib/rubocop/cop/style/trivial_accessors.rb +65 -0
- data/lib/rubocop/formatter/junit_formatter.rb +21 -6
- data/lib/rubocop/options.rb +14 -20
- data/lib/rubocop/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1009c9da04982d8684219d15bcaaf8a09f5aa3523d8fb668fb47b885281e11ef
|
4
|
+
data.tar.gz: fac46c18283c960c698d18f5fd6206cef3d309b2d74bc5046c0c6ba30ca60431
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 292b418ad2da13f7357a6b3189128ed35a84fa662506de26d4973797e430751b158e9cb0c7a0753c0cded518ba0299cf5bcf1394abb9793aa728b4dedf36863a
|
7
|
+
data.tar.gz: cfca1c661ace6abafa34d5506c27ef48afe3ba2abc7187d3fabf41db0abce0c93d59d2f5411671d22fbadea6a09987cda71f2600cc85b5b88b18fca7f526f451
|
data/README.md
CHANGED
@@ -29,6 +29,8 @@ RuboCop is extremely flexible and most aspects of its behavior can be tweaked vi
|
|
29
29
|
[](#open-collective-sponsors)
|
30
30
|
[](https://tidelift.com/subscription/pkg/rubygems-rubocop?utm_source=rubygems-rubocop&utm_medium=referral&utm_campaign=readme)
|
31
31
|
|
32
|
+
Working on RuboCop is often fun, but it also requires a great deal of time and energy.
|
33
|
+
|
32
34
|
**Please consider [financially supporting its ongoing development](#funding).**
|
33
35
|
|
34
36
|
## Installation
|
@@ -52,7 +54,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
52
54
|
in your `Gemfile`:
|
53
55
|
|
54
56
|
```rb
|
55
|
-
gem 'rubocop', '~> 1.
|
57
|
+
gem 'rubocop', '~> 1.15', require: false
|
56
58
|
```
|
57
59
|
|
58
60
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
data/config/default.yml
CHANGED
@@ -1612,7 +1612,7 @@ Lint/EmptyBlock:
|
|
1612
1612
|
Description: 'This cop checks for blocks without a body.'
|
1613
1613
|
Enabled: pending
|
1614
1614
|
VersionAdded: '1.1'
|
1615
|
-
VersionChanged: '1.
|
1615
|
+
VersionChanged: '1.15'
|
1616
1616
|
AllowComments: true
|
1617
1617
|
AllowEmptyLambdas: true
|
1618
1618
|
|
@@ -3480,6 +3480,7 @@ Style/HashAsLastArrayItem:
|
|
3480
3480
|
|
3481
3481
|
Style/HashConversion:
|
3482
3482
|
Description: 'Avoid Hash[] in favor of ary.to_h or literal hashes.'
|
3483
|
+
StyleGuide: '#avoid-hash-constructor'
|
3483
3484
|
Enabled: pending
|
3484
3485
|
VersionAdded: '1.10'
|
3485
3486
|
VersionChanged: '1.11'
|
@@ -3998,6 +3999,7 @@ Style/NilLambda:
|
|
3998
3999
|
Description: 'Prefer `-> {}` to `-> { nil }`.'
|
3999
4000
|
Enabled: pending
|
4000
4001
|
VersionAdded: '1.3'
|
4002
|
+
VersionChanged: '1.15'
|
4001
4003
|
|
4002
4004
|
Style/NonNilCheck:
|
4003
4005
|
Description: 'Checks for redundant nil checks.'
|
@@ -4651,6 +4653,12 @@ Style/TernaryParentheses:
|
|
4651
4653
|
- require_parentheses_when_complex
|
4652
4654
|
AllowSafeAssignment: true
|
4653
4655
|
|
4656
|
+
Style/TopLevelMethodDefinition:
|
4657
|
+
Description: 'This cop looks for top-level method definitions.'
|
4658
|
+
StyleGuide: '#top-level-methods'
|
4659
|
+
Enabled: false
|
4660
|
+
VersionAdded: '1.15'
|
4661
|
+
|
4654
4662
|
Style/TrailingBodyOnClass:
|
4655
4663
|
Description: 'Class body goes below class statement.'
|
4656
4664
|
Enabled: true
|
@@ -4737,7 +4745,7 @@ Style/TrivialAccessors:
|
|
4737
4745
|
StyleGuide: '#attr_family'
|
4738
4746
|
Enabled: true
|
4739
4747
|
VersionAdded: '0.9'
|
4740
|
-
VersionChanged: '
|
4748
|
+
VersionChanged: '1.15'
|
4741
4749
|
# When set to `false` the cop will suggest the use of accessor methods
|
4742
4750
|
# in situations like:
|
4743
4751
|
#
|
@@ -4756,7 +4764,7 @@ Style/TrivialAccessors:
|
|
4756
4764
|
# on_exception :restart
|
4757
4765
|
#
|
4758
4766
|
# Commonly used in DSLs
|
4759
|
-
AllowDSLWriters:
|
4767
|
+
AllowDSLWriters: true
|
4760
4768
|
IgnoreClassMethods: false
|
4761
4769
|
AllowedMethods:
|
4762
4770
|
- to_ary
|
data/lib/rubocop.rb
CHANGED
@@ -598,6 +598,7 @@ require_relative 'rubocop/cop/style/symbol_array'
|
|
598
598
|
require_relative 'rubocop/cop/style/symbol_literal'
|
599
599
|
require_relative 'rubocop/cop/style/symbol_proc'
|
600
600
|
require_relative 'rubocop/cop/style/ternary_parentheses'
|
601
|
+
require_relative 'rubocop/cop/style/top_level_method_definition'
|
601
602
|
require_relative 'rubocop/cop/style/trailing_body_on_class'
|
602
603
|
require_relative 'rubocop/cop/style/trailing_body_on_method_definition'
|
603
604
|
require_relative 'rubocop/cop/style/trailing_body_on_module'
|
@@ -10,33 +10,39 @@ module RuboCop
|
|
10
10
|
# # good
|
11
11
|
#
|
12
12
|
# foo :bar,
|
13
|
-
# :baz
|
13
|
+
# :baz,
|
14
|
+
# key: value
|
14
15
|
#
|
15
16
|
# foo(
|
16
17
|
# :bar,
|
17
|
-
# :baz
|
18
|
+
# :baz,
|
19
|
+
# key: value
|
18
20
|
# )
|
19
21
|
#
|
20
22
|
# # bad
|
21
23
|
#
|
22
24
|
# foo :bar,
|
23
|
-
# :baz
|
25
|
+
# :baz,
|
26
|
+
# key: value
|
24
27
|
#
|
25
28
|
# foo(
|
26
29
|
# :bar,
|
27
|
-
# :baz
|
30
|
+
# :baz,
|
31
|
+
# key: value
|
28
32
|
# )
|
29
33
|
#
|
30
34
|
# @example EnforcedStyle: with_fixed_indentation
|
31
35
|
# # good
|
32
36
|
#
|
33
37
|
# foo :bar,
|
34
|
-
# :baz
|
38
|
+
# :baz,
|
39
|
+
# key: value
|
35
40
|
#
|
36
41
|
# # bad
|
37
42
|
#
|
38
43
|
# foo :bar,
|
39
|
-
# :baz
|
44
|
+
# :baz,
|
45
|
+
# key: value
|
40
46
|
class ArgumentAlignment < Base
|
41
47
|
include Alignment
|
42
48
|
extend AutoCorrector
|
@@ -47,14 +53,25 @@ module RuboCop
|
|
47
53
|
'following the first line of a multi-line method call.'
|
48
54
|
|
49
55
|
def on_send(node)
|
50
|
-
|
56
|
+
first_arg = node.first_argument
|
57
|
+
return if !multiple_arguments?(node, first_arg) || node.send_type? && node.method?(:[]=)
|
51
58
|
|
52
|
-
|
59
|
+
if first_arg.hash_type?
|
60
|
+
check_alignment(first_arg.pairs, base_column(node, first_arg.pairs.first))
|
61
|
+
else
|
62
|
+
check_alignment(node.arguments, base_column(node, first_arg))
|
63
|
+
end
|
53
64
|
end
|
54
65
|
alias on_csend on_send
|
55
66
|
|
56
67
|
private
|
57
68
|
|
69
|
+
def multiple_arguments?(node, first_argument)
|
70
|
+
return true if node.arguments.size >= 2
|
71
|
+
|
72
|
+
first_argument&.hash_type? && first_argument.pairs.count >= 2
|
73
|
+
end
|
74
|
+
|
58
75
|
def autocorrect(corrector, node)
|
59
76
|
AlignmentCorrector.correct(corrector, processed_source, node, column_delta)
|
60
77
|
end
|
@@ -67,14 +84,14 @@ module RuboCop
|
|
67
84
|
cop_config['EnforcedStyle'] == 'with_fixed_indentation'
|
68
85
|
end
|
69
86
|
|
70
|
-
def base_column(node,
|
71
|
-
if fixed_indentation?
|
87
|
+
def base_column(node, first_argument)
|
88
|
+
if fixed_indentation? || first_argument.nil?
|
72
89
|
lineno = target_method_lineno(node)
|
73
90
|
line = node.source_range.source_buffer.source_line(lineno)
|
74
91
|
indentation_of_line = /\S.*/.match(line).begin(0)
|
75
92
|
indentation_of_line + configured_indentation_width
|
76
93
|
else
|
77
|
-
display_column(
|
94
|
+
display_column(first_argument.source_range)
|
78
95
|
end
|
79
96
|
end
|
80
97
|
|
@@ -91,6 +91,8 @@ module RuboCop
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def on_send(node)
|
94
|
+
return if enforce_first_argument_with_fixed_indentation?
|
95
|
+
|
94
96
|
each_argument_node(node, :hash) do |hash_node, left_parenthesis|
|
95
97
|
check(hash_node, left_parenthesis)
|
96
98
|
end
|
@@ -182,6 +184,16 @@ module RuboCop
|
|
182
184
|
'where the left brace is.'
|
183
185
|
end
|
184
186
|
end
|
187
|
+
|
188
|
+
def enforce_first_argument_with_fixed_indentation?
|
189
|
+
return false unless argument_alignment_config['Enabled']
|
190
|
+
|
191
|
+
argument_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
|
192
|
+
end
|
193
|
+
|
194
|
+
def argument_alignment_config
|
195
|
+
config.for_cop('Layout/ArgumentAlignment')
|
196
|
+
end
|
185
197
|
end
|
186
198
|
end
|
187
199
|
end
|
@@ -200,14 +200,12 @@ module RuboCop
|
|
200
200
|
alias on_super on_send
|
201
201
|
alias on_yield on_send
|
202
202
|
|
203
|
-
def on_hash(node)
|
204
|
-
return if ignored_node?(node)
|
205
|
-
|
203
|
+
def on_hash(node)
|
204
|
+
return if enforce_first_argument_with_fixed_indentation? || ignored_node?(node) ||
|
205
|
+
node.pairs.empty? || node.single_line?
|
206
206
|
|
207
|
-
|
208
|
-
|
209
|
-
alignment_for_colons
|
210
|
-
.any? { |a| a.checkable_layout?(node) }
|
207
|
+
proc = ->(a) { a.checkable_layout?(node) }
|
208
|
+
return unless alignment_for_hash_rockets.any?(proc) && alignment_for_colons.any?(proc)
|
211
209
|
|
212
210
|
check_pairs(node)
|
213
211
|
end
|
@@ -353,6 +351,16 @@ module RuboCop
|
|
353
351
|
def good_alignment?(column_deltas)
|
354
352
|
column_deltas.values.all?(&:zero?)
|
355
353
|
end
|
354
|
+
|
355
|
+
def enforce_first_argument_with_fixed_indentation?
|
356
|
+
return false unless argument_alignment_config['Enabled']
|
357
|
+
|
358
|
+
argument_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
|
359
|
+
end
|
360
|
+
|
361
|
+
def argument_alignment_config
|
362
|
+
config.for_cop('Layout/ArgumentAlignment')
|
363
|
+
end
|
356
364
|
end
|
357
365
|
end
|
358
366
|
end
|
@@ -313,9 +313,12 @@ module RuboCop
|
|
313
313
|
check_rescue?(body_node)
|
314
314
|
elsif body_node.ensure_type?
|
315
315
|
block_body, = *body_node
|
316
|
-
return unless block_body
|
317
316
|
|
318
|
-
|
317
|
+
if block_body&.rescue_type?
|
318
|
+
check_rescue?(block_body)
|
319
|
+
else
|
320
|
+
!block_body.nil?
|
321
|
+
end
|
319
322
|
else
|
320
323
|
true
|
321
324
|
end
|
@@ -12,6 +12,8 @@ module RuboCop
|
|
12
12
|
# File.exists?(some_path)
|
13
13
|
# Dir.exists?(some_path)
|
14
14
|
# iterator?
|
15
|
+
# Socket.gethostbyname(host)
|
16
|
+
# Socket.gethostbyaddr(host)
|
15
17
|
#
|
16
18
|
# @example
|
17
19
|
#
|
@@ -20,6 +22,8 @@ module RuboCop
|
|
20
22
|
# File.exist?(some_path)
|
21
23
|
# Dir.exist?(some_path)
|
22
24
|
# block_given?
|
25
|
+
# Addrinfo.getaddrinfo(nodename, service)
|
26
|
+
# Addrinfo.tcp(host, port).getnameinfo
|
23
27
|
class DeprecatedClassMethods < Base
|
24
28
|
extend AutoCorrector
|
25
29
|
|
@@ -7,7 +7,11 @@ module RuboCop
|
|
7
7
|
# Such empty blocks are typically an oversight or we should provide a comment
|
8
8
|
# be clearer what we're aiming for.
|
9
9
|
#
|
10
|
-
# Empty lambdas are ignored by default.
|
10
|
+
# Empty lambdas and procs are ignored by default.
|
11
|
+
#
|
12
|
+
# NOTE: For backwards compatibility, the configuration that allows/disallows
|
13
|
+
# empty lambdas and procs is called `AllowEmptyLambdas`, even though it also
|
14
|
+
# applies to procs.
|
11
15
|
#
|
12
16
|
# @example
|
13
17
|
# # bad
|
@@ -40,6 +44,10 @@ module RuboCop
|
|
40
44
|
# end
|
41
45
|
# (callable || placeholder).call
|
42
46
|
#
|
47
|
+
# proc { }
|
48
|
+
#
|
49
|
+
# Proc.new { }
|
50
|
+
#
|
43
51
|
# @example AllowEmptyLambdas: false
|
44
52
|
# # bad
|
45
53
|
# allow(subject).to receive(:callable).and_return(-> {})
|
@@ -48,12 +56,16 @@ module RuboCop
|
|
48
56
|
# end
|
49
57
|
# (callable || placeholder).call
|
50
58
|
#
|
59
|
+
# proc { }
|
60
|
+
#
|
61
|
+
# Proc.new { }
|
62
|
+
#
|
51
63
|
class EmptyBlock < Base
|
52
64
|
MSG = 'Empty block detected.'
|
53
65
|
|
54
66
|
def on_block(node)
|
55
67
|
return if node.body
|
56
|
-
return if allow_empty_lambdas? && node
|
68
|
+
return if allow_empty_lambdas? && lambda_or_proc?(node)
|
57
69
|
return if cop_config['AllowComments'] && allow_comment?(node)
|
58
70
|
|
59
71
|
add_offense(node)
|
@@ -76,6 +88,10 @@ module RuboCop
|
|
76
88
|
regexp_pattern = "# rubocop : (disable|todo) ([^,],)* (all|#{cop_name})"
|
77
89
|
Regexp.new(regexp_pattern.gsub(' ', '\s*')).match?(comment)
|
78
90
|
end
|
91
|
+
|
92
|
+
def lambda_or_proc?(node)
|
93
|
+
node.lambda? || node.proc?
|
94
|
+
end
|
79
95
|
end
|
80
96
|
end
|
81
97
|
end
|
@@ -70,17 +70,33 @@ module RuboCop
|
|
70
70
|
def extract_first_element_over_column_limit(node, elements, max)
|
71
71
|
line = node.first_line
|
72
72
|
|
73
|
-
# If
|
74
|
-
#
|
75
|
-
elements.
|
73
|
+
# If a `send` node is not parenthesized, don't move the first element, because it
|
74
|
+
# can result in changed behavior or a syntax error.
|
75
|
+
elements = elements.drop(1) if node.send_type? && !node.parenthesized?
|
76
76
|
|
77
77
|
i = 0
|
78
78
|
i += 1 while within_column_limit?(elements[i], max, line)
|
79
|
+
i = shift_elements_for_heredoc_arg(node, elements, i)
|
80
|
+
|
81
|
+
return if i.nil?
|
79
82
|
return elements.first if i.zero?
|
80
83
|
|
81
84
|
elements[i - 1]
|
82
85
|
end
|
83
86
|
|
87
|
+
# @api private
|
88
|
+
# If a send node contains a heredoc argument, splitting cannot happen
|
89
|
+
# after the heredoc or else it will cause a syntax error.
|
90
|
+
def shift_elements_for_heredoc_arg(node, elements, index)
|
91
|
+
return index unless node.send_type?
|
92
|
+
|
93
|
+
heredoc_index = elements.index { |arg| (arg.str_type? || arg.dstr_type?) && arg.heredoc? }
|
94
|
+
return index unless heredoc_index
|
95
|
+
return nil if heredoc_index.zero?
|
96
|
+
|
97
|
+
heredoc_index >= index ? index : heredoc_index + 1
|
98
|
+
end
|
99
|
+
|
84
100
|
# @api private
|
85
101
|
def within_column_limit?(element, max, line)
|
86
102
|
element && element.loc.column <= max && element.loc.line == line
|
@@ -35,6 +35,12 @@ module RuboCop
|
|
35
35
|
leading_comment_lines.any? { |line| MagicComment.parse(line).frozen_string_literal? }
|
36
36
|
end
|
37
37
|
|
38
|
+
def frozen_string_literals_disabled?
|
39
|
+
leading_comment_lines.any? do |line|
|
40
|
+
MagicComment.parse(line).frozen_string_literal == false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
38
44
|
def frozen_string_literal_specified?
|
39
45
|
leading_comment_lines.any? do |line|
|
40
46
|
MagicComment.parse(line).frozen_string_literal_specified?
|
@@ -87,9 +87,18 @@ module RuboCop
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def compact_node(corrector, node)
|
90
|
-
replacement = "#{node.body.type} #{compact_identifier_name(node)}"
|
91
90
|
range = range_between(node.loc.keyword.begin_pos, node.body.loc.name.end_pos)
|
92
|
-
corrector.replace(range,
|
91
|
+
corrector.replace(range, compact_replacement(node))
|
92
|
+
end
|
93
|
+
|
94
|
+
def compact_replacement(node)
|
95
|
+
replacement = "#{node.body.type} #{compact_identifier_name(node)}"
|
96
|
+
|
97
|
+
body_comments = processed_source.ast_with_comments[node.body]
|
98
|
+
unless body_comments.empty?
|
99
|
+
replacement = body_comments.map(&:text).push(replacement).join("\n")
|
100
|
+
end
|
101
|
+
replacement
|
93
102
|
end
|
94
103
|
|
95
104
|
def compact_identifier_name(node)
|
@@ -132,6 +141,9 @@ module RuboCop
|
|
132
141
|
end
|
133
142
|
|
134
143
|
def check_compact_style(node, body)
|
144
|
+
parent = node.parent
|
145
|
+
return if parent&.class_type? || parent&.module_type?
|
146
|
+
|
135
147
|
return unless needs_compacting?(body)
|
136
148
|
|
137
149
|
add_offense(node.loc.name, message: COMPACT_MSG) do |corrector|
|
@@ -62,7 +62,7 @@ module RuboCop
|
|
62
62
|
ARR_MSG
|
63
63
|
elsif offense_hash_node?(node)
|
64
64
|
HASH_MSG
|
65
|
-
elsif str_node(node) && !
|
65
|
+
elsif str_node(node) && !frozen_strings?
|
66
66
|
format(STR_MSG, prefer: preferred_string_literal)
|
67
67
|
end
|
68
68
|
end
|
@@ -125,6 +125,13 @@ module RuboCop
|
|
125
125
|
end
|
126
126
|
end
|
127
127
|
end
|
128
|
+
|
129
|
+
def frozen_strings?
|
130
|
+
return true if frozen_string_literals_enabled?
|
131
|
+
|
132
|
+
frozen_string_cop_enabled = config.for_cop('Style/FrozenStringLiteral')['Enabled']
|
133
|
+
frozen_string_cop_enabled && !frozen_string_literals_disabled?
|
134
|
+
end
|
128
135
|
end
|
129
136
|
end
|
130
137
|
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# This cop checks for lambdas that always return nil,
|
7
|
-
# with an empty lambda instead.
|
6
|
+
# This cop checks for lambdas and procs that always return nil,
|
7
|
+
# which can be replaced with an empty lambda or proc instead.
|
8
8
|
#
|
9
9
|
# @example
|
10
10
|
# # bad
|
@@ -14,6 +14,12 @@ module RuboCop
|
|
14
14
|
# next nil
|
15
15
|
# end
|
16
16
|
#
|
17
|
+
# proc { nil }
|
18
|
+
#
|
19
|
+
# Proc.new do
|
20
|
+
# break nil
|
21
|
+
# end
|
22
|
+
#
|
17
23
|
# # good
|
18
24
|
# -> {}
|
19
25
|
#
|
@@ -22,11 +28,15 @@ module RuboCop
|
|
22
28
|
#
|
23
29
|
# -> (x) { nil if x }
|
24
30
|
#
|
31
|
+
# proc {}
|
32
|
+
#
|
33
|
+
# Proc.new { nil if x }
|
34
|
+
#
|
25
35
|
class NilLambda < Base
|
26
36
|
extend AutoCorrector
|
27
37
|
include RangeHelp
|
28
38
|
|
29
|
-
MSG = 'Use an empty
|
39
|
+
MSG = 'Use an empty %<type>s instead of always returning nil.'
|
30
40
|
|
31
41
|
# @!method nil_return?(node)
|
32
42
|
def_node_matcher :nil_return?, <<~PATTERN
|
@@ -34,19 +44,26 @@ module RuboCop
|
|
34
44
|
PATTERN
|
35
45
|
|
36
46
|
def on_block(node)
|
37
|
-
return unless node.lambda?
|
47
|
+
return unless node.lambda? || node.proc?
|
38
48
|
return unless nil_return?(node.body)
|
39
49
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
else
|
44
|
-
range_by_whole_lines(node.body.loc.expression, include_final_newline: true)
|
45
|
-
end
|
46
|
-
|
47
|
-
corrector.remove(range)
|
50
|
+
message = format(MSG, type: node.lambda? ? 'lambda' : 'proc')
|
51
|
+
add_offense(node, message: message) do |corrector|
|
52
|
+
autocorrect(corrector, node)
|
48
53
|
end
|
49
54
|
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def autocorrect(corrector, node)
|
59
|
+
range = if node.single_line?
|
60
|
+
range_with_surrounding_space(range: node.body.loc.expression)
|
61
|
+
else
|
62
|
+
range_by_whole_lines(node.body.loc.expression, include_final_newline: true)
|
63
|
+
end
|
64
|
+
|
65
|
+
corrector.remove(range)
|
66
|
+
end
|
50
67
|
end
|
51
68
|
end
|
52
69
|
end
|
@@ -110,7 +110,7 @@ module RuboCop
|
|
110
110
|
first_child = node.children.first
|
111
111
|
|
112
112
|
source = first_child.source
|
113
|
-
source = "(#{source})" if first_child.if_type?
|
113
|
+
source = "(#{source})" if first_child.if_type? && first_child.modifier_form?
|
114
114
|
|
115
115
|
corrector.replace(offense_range, source)
|
116
116
|
corrector.remove(range_between(offense_range.end_pos, first_child.source_range.end_pos))
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Newcomers to ruby applications may write top-level methods,
|
7
|
+
# when ideally they should be organized in appropriate classes or modules.
|
8
|
+
# This cop looks for definitions of top-level methods and warns about them.
|
9
|
+
#
|
10
|
+
# However for ruby scripts it is perfectly fine to use top-level methods.
|
11
|
+
# Hence this cop is disabled by default.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# # bad
|
15
|
+
# def some_method
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# # bad
|
19
|
+
# def self.some_method
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# # bad
|
23
|
+
# define_method(:foo) { puts 1 }
|
24
|
+
#
|
25
|
+
# # good
|
26
|
+
# module Foo
|
27
|
+
# def some_method
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# # good
|
32
|
+
# class Foo
|
33
|
+
# def self.some_method
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# # good
|
38
|
+
# Struct.new do
|
39
|
+
# def some_method
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# # good
|
44
|
+
# class Foo
|
45
|
+
# define_method(:foo) { puts 1 }
|
46
|
+
# end
|
47
|
+
class TopLevelMethodDefinition < Base
|
48
|
+
MSG = 'Do not define methods at the top-level.'
|
49
|
+
|
50
|
+
RESTRICT_ON_SEND = %i[define_method].freeze
|
51
|
+
|
52
|
+
def on_def(node)
|
53
|
+
return unless node.root?
|
54
|
+
|
55
|
+
add_offense(node)
|
56
|
+
end
|
57
|
+
alias on_defs on_def
|
58
|
+
alias on_send on_def
|
59
|
+
|
60
|
+
def on_block(node)
|
61
|
+
return unless define_method_block?(node) && node.root?
|
62
|
+
|
63
|
+
add_offense(node)
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# @!method define_method_block?(node)
|
69
|
+
def_node_matcher :define_method_block?, <<~PATTERN
|
70
|
+
(block (send _ {:define_method} _) ...)
|
71
|
+
PATTERN
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -27,6 +27,71 @@ module RuboCop
|
|
27
27
|
# class << self
|
28
28
|
# attr_reader :baz
|
29
29
|
# end
|
30
|
+
#
|
31
|
+
# @example ExactNameMatch: true (default)
|
32
|
+
# # good
|
33
|
+
# def name
|
34
|
+
# @other_name
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# @example ExactNameMatch: false
|
38
|
+
# # bad
|
39
|
+
# def name
|
40
|
+
# @other_name
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# @example AllowPredicates: true (default)
|
44
|
+
# # good
|
45
|
+
# def foo?
|
46
|
+
# @foo
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# @example AllowPredicates: false
|
50
|
+
# # bad
|
51
|
+
# def foo?
|
52
|
+
# @foo
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# # good
|
56
|
+
# attr_reader :foo
|
57
|
+
#
|
58
|
+
# @example AllowDSLWriters: true (default)
|
59
|
+
# # good
|
60
|
+
# def on_exception(action)
|
61
|
+
# @on_exception=action
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# @example AllowDSLWriters: false
|
65
|
+
# # bad
|
66
|
+
# def on_exception(action)
|
67
|
+
# @on_exception=action
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# # good
|
71
|
+
# attr_writer :on_exception
|
72
|
+
#
|
73
|
+
# @example IgnoreClassMethods: false (default)
|
74
|
+
# # bad
|
75
|
+
# def self.foo
|
76
|
+
# @foo
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# # good
|
80
|
+
# class << self
|
81
|
+
# attr_reader :foo
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# @example IgnoreClassMethods: true
|
85
|
+
# # good
|
86
|
+
# def self.foo
|
87
|
+
# @foo
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
# @example AllowedMethods: ['allowed_method']
|
91
|
+
# # good
|
92
|
+
# def allowed_method
|
93
|
+
# @foo
|
94
|
+
# end
|
30
95
|
class TrivialAccessors < Base
|
31
96
|
include AllowedMethods
|
32
97
|
extend AutoCorrector
|
@@ -22,9 +22,13 @@ module RuboCop
|
|
22
22
|
testsuites = REXML::Element.new('testsuites', @document)
|
23
23
|
testsuite = REXML::Element.new('testsuite', testsuites)
|
24
24
|
@testsuite = testsuite.tap { |element| element.add_attributes('name' => 'rubocop') }
|
25
|
+
|
26
|
+
reset_count
|
25
27
|
end
|
26
28
|
|
27
29
|
def file_finished(file, offenses)
|
30
|
+
@inspected_file_count += 1
|
31
|
+
|
28
32
|
# TODO: Returns all cops with the same behavior as
|
29
33
|
# the original rubocop-junit-formatter.
|
30
34
|
# https://github.com/mikian/rubocop-junit-formatter/blob/v0.1.4/lib/rubocop/formatter/junit_formatter.rb#L9
|
@@ -32,15 +36,11 @@ module RuboCop
|
|
32
36
|
# In the future, it would be preferable to return only enabled cops.
|
33
37
|
Cop::Registry.all.each do |cop|
|
34
38
|
target_offenses = offenses_for_cop(offenses, cop)
|
39
|
+
@offense_count += target_offenses.count
|
35
40
|
|
36
41
|
next unless relevant_for_output?(options, target_offenses)
|
37
42
|
|
38
|
-
|
39
|
-
testcase.attributes['classname'] = classname_attribute_value(file)
|
40
|
-
testcase.attributes['name'] = cop.cop_name
|
41
|
-
|
42
|
-
add_failure_to(testcase, target_offenses, cop.cop_name)
|
43
|
-
end
|
43
|
+
add_testcase_element_to_testsuite_element(file, target_offenses, cop)
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -52,16 +52,31 @@ module RuboCop
|
|
52
52
|
all_offenses.select { |offense| offense.cop_name == cop.cop_name }
|
53
53
|
end
|
54
54
|
|
55
|
+
def add_testcase_element_to_testsuite_element(file, target_offenses, cop)
|
56
|
+
REXML::Element.new('testcase', @testsuite).tap do |testcase|
|
57
|
+
testcase.attributes['classname'] = classname_attribute_value(file)
|
58
|
+
testcase.attributes['name'] = cop.cop_name
|
59
|
+
|
60
|
+
add_failure_to(testcase, target_offenses, cop.cop_name)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
55
64
|
def classname_attribute_value(file)
|
56
65
|
file.gsub(/\.rb\Z/, '').gsub("#{Dir.pwd}/", '').tr('/', '.')
|
57
66
|
end
|
58
67
|
|
59
68
|
def finished(_inspected_files)
|
69
|
+
@testsuite.add_attributes('tests' => @inspected_file_count, 'failures' => @offense_count)
|
60
70
|
@document.write(output, 2)
|
61
71
|
end
|
62
72
|
|
63
73
|
private
|
64
74
|
|
75
|
+
def reset_count
|
76
|
+
@inspected_file_count = 0
|
77
|
+
@offense_count = 0
|
78
|
+
end
|
79
|
+
|
65
80
|
def add_failure_to(testcase, offenses, cop_name)
|
66
81
|
# One failure per offense. Zero failures is a passing test case,
|
67
82
|
# for most surefire/nUnit parsers.
|
data/lib/rubocop/options.rb
CHANGED
@@ -297,7 +297,7 @@ module RuboCop
|
|
297
297
|
validate_auto_gen_config
|
298
298
|
validate_auto_correct
|
299
299
|
validate_display_only_failed
|
300
|
-
|
300
|
+
disable_parallel_when_invalid_option_combo
|
301
301
|
|
302
302
|
return if incompatible_options.size <= 1
|
303
303
|
|
@@ -334,33 +334,27 @@ module RuboCop
|
|
334
334
|
format('--disable-uncorrectable can only be used together with --auto-correct.')
|
335
335
|
end
|
336
336
|
|
337
|
-
def
|
337
|
+
def disable_parallel_when_invalid_option_combo
|
338
338
|
return unless @options.key?(:parallel)
|
339
339
|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
disable_parallel_when_invalid_combo
|
347
|
-
end
|
340
|
+
invalid_options = [
|
341
|
+
{ name: :auto_gen_config, value: true, flag: '--auto-gen-config' },
|
342
|
+
{ name: :fail_fast, value: true, flag: '-F/--fail-fast.' },
|
343
|
+
{ name: :auto_correct, value: true, flag: '--auto-correct.' },
|
344
|
+
{ name: :cache, value: 'false', flag: '--cache false' }
|
345
|
+
]
|
348
346
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
auto_correct: '--auto-correct.'
|
354
|
-
}
|
355
|
-
|
356
|
-
invalid_combos = combos.select { |key, _flag| @options.key?(key) }
|
347
|
+
invalid_flags = invalid_options.each_with_object([]) do |option, flags|
|
348
|
+
# `>` rather than `>=` because `@options` will also contain `parallel: true`
|
349
|
+
flags << option[:flag] if @options > { option[:name] => option[:value] }
|
350
|
+
end
|
357
351
|
|
358
|
-
return if
|
352
|
+
return if invalid_flags.empty?
|
359
353
|
|
360
354
|
@options.delete(:parallel)
|
361
355
|
|
362
356
|
puts '-P/--parallel is being ignored because ' \
|
363
|
-
"it is not compatible with #{
|
357
|
+
"it is not compatible with #{invalid_flags.join(', ')}"
|
364
358
|
end
|
365
359
|
|
366
360
|
def only_includes_redundant_disable?
|
data/lib/rubocop/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-05-
|
13
|
+
date: 2021-05-17 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: parallel
|
@@ -786,6 +786,7 @@ files:
|
|
786
786
|
- lib/rubocop/cop/style/symbol_literal.rb
|
787
787
|
- lib/rubocop/cop/style/symbol_proc.rb
|
788
788
|
- lib/rubocop/cop/style/ternary_parentheses.rb
|
789
|
+
- lib/rubocop/cop/style/top_level_method_definition.rb
|
789
790
|
- lib/rubocop/cop/style/trailing_body_on_class.rb
|
790
791
|
- lib/rubocop/cop/style/trailing_body_on_method_definition.rb
|
791
792
|
- lib/rubocop/cop/style/trailing_body_on_module.rb
|
@@ -875,7 +876,7 @@ metadata:
|
|
875
876
|
homepage_uri: https://rubocop.org/
|
876
877
|
changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md
|
877
878
|
source_code_uri: https://github.com/rubocop/rubocop/
|
878
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
879
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.15/
|
879
880
|
bug_tracker_uri: https://github.com/rubocop/rubocop/issues
|
880
881
|
post_install_message:
|
881
882
|
rdoc_options: []
|