rubocop 1.14.0 → 1.15.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![OpenCollective](https://opencollective.com/rubocop/sponsors/badge.svg)](#open-collective-sponsors)
|
30
30
|
[![Tidelift](https://tidelift.com/badges/package/rubygems/rubocop)](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: []
|