rubocop 0.70.0 → 0.71.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f98c70ae4897b3f4c793fa73cb716986f9d63815928c278accf6879a0190e97e
4
- data.tar.gz: 89111e2312bdf926aab76ca58bfb90a414ff3b5f58ba48257e5d1949763d4776
3
+ metadata.gz: cbaa6a7da185f890ae7fbe520da9e4a7c701526c6b59128434a7a4a305706aa5
4
+ data.tar.gz: 3f040c8c4f0e0325f79327767e254b4367488740ceeb42e7ed11a837f12b7dee
5
5
  SHA512:
6
- metadata.gz: 83462908a6383ab72503c4af338d395a118e435d8f4f73e7cdda54b6d8d1cc05f40a5ebdb6a3197bf9a2734046665c7c2d6616e0bb0847f198d11b410ae4b7f8
7
- data.tar.gz: 39c1a0fca5a9251e3a60f9ca3958d228d79f5797de21da608f69cb133611c683913673bbdc426a537c9578bc4394607a20617d394d1abc3454878373589a0fdd
6
+ metadata.gz: 604bb0adb5459672c490398a4599274f02ec7fa5669ab2caadee7f6178c53b3d3622114fb9faffd767ddf4ec2c8e62023069657f1acd42c587aa1e1d5cd8431e
7
+ data.tar.gz: 6a9413fd59a1e9d2ce3f016c54a481ef758fb441bb16af29e6d86b43a18e7daa39f1306618bdd7168552af91064c065e70c381813c8489670d1137151944eaef
data/README.md CHANGED
@@ -7,7 +7,6 @@
7
7
  [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=rubocop&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=rubocop&package-manager=bundler&version-scheme=semver)
8
8
 
9
9
  [![Patreon](https://img.shields.io/badge/patreon-donate-orange.svg)](https://www.patreon.com/bbatsov)
10
- [![Liberapay](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/bbatsov/donate)
11
10
  [![OpenCollective](https://opencollective.com/rubocop/backers/badge.svg)](#open-collective-backers)
12
11
  [![OpenCollective](https://opencollective.com/rubocop/sponsors/badge.svg)](#open-collective-sponsors)
13
12
 
@@ -53,7 +52,7 @@ haven't reached version 1.0 yet). To prevent an unwanted RuboCop update you
53
52
  might want to use a conservative version lock in your `Gemfile`:
54
53
 
55
54
  ```rb
56
- gem 'rubocop', '~> 0.70.0', require: false
55
+ gem 'rubocop', '~> 0.71.0', require: false
57
56
  ```
58
57
 
59
58
  ## Quickstart
@@ -138,7 +137,7 @@ to become a RuboCop sponsor.
138
137
  You can support the development of RuboCop via
139
138
  [Salt](https://salt.bountysource.com/teams/rubocop),
140
139
  [Patreon](https://www.patreon.com/bbatsov),
141
- [Liberapay](https://liberapay.com/bbatsov/donate),
140
+ [PayPal](https://paypal.me/bbatsov)
142
141
  and [Open Collective](https://opencollective.com/rubocop).
143
142
 
144
143
  ### Open Collective Backers
@@ -1495,6 +1495,7 @@ Lint/PercentStringArray:
1495
1495
  Description: >-
1496
1496
  Checks for unwanted commas and quotes in %w/%W literals.
1497
1497
  Enabled: true
1498
+ Safe: false
1498
1499
  VersionAdded: '0.41'
1499
1500
 
1500
1501
  Lint/PercentSymbolArray:
@@ -2939,6 +2940,13 @@ Style/ConditionalAssignment:
2939
2940
  SingleLineConditionsOnly: true
2940
2941
  IncludeTernaryExpressions: true
2941
2942
 
2943
+ Style/ConstantVisibility:
2944
+ Description: >-
2945
+ Check that class- and module constants have
2946
+ visibility declarations.
2947
+ Enabled: false
2948
+ VersionAdded: '0.66'
2949
+
2942
2950
  # Checks that you have put a copyright in a comment before any code.
2943
2951
  #
2944
2952
  # You can override the default Notice in your .rubocop.yml file.
@@ -2957,13 +2965,6 @@ Style/ConditionalAssignment:
2957
2965
  # Notice: 'Copyright (\(c\) )?2015 Yahoo! Inc'
2958
2966
  # AutocorrectNotice: '# Copyright (c) 2015 Yahoo! Inc.'
2959
2967
  #
2960
- Style/ConstantVisibility:
2961
- Description: >-
2962
- Check that class- and module constants have
2963
- visibility declarations.
2964
- Enabled: false
2965
- VersionAdded: '0.66'
2966
-
2967
2968
  Style/Copyright:
2968
2969
  Description: 'Include a copyright notice in each file before any code.'
2969
2970
  Enabled: false
@@ -21,7 +21,7 @@ module RuboCop
21
21
 
22
22
  # 2.3 is the oldest officially supported Ruby version.
23
23
  DEFAULT_RUBY_VERSION = 2.3
24
- KNOWN_RUBIES = [2.3, 2.4, 2.5, 2.6].freeze
24
+ KNOWN_RUBIES = [2.3, 2.4, 2.5, 2.6, 2.7].freeze
25
25
  OBSOLETE_RUBIES = {
26
26
  1.9 => '0.50', 2.0 => '0.50', 2.1 => '0.58', 2.2 => '0.69'
27
27
  }.freeze
@@ -144,6 +144,10 @@ module RuboCop
144
144
  puts "Added inheritance from `#{AUTO_GENERATED_FILE}` in `#{DOTFILE}`."
145
145
  end
146
146
 
147
+ def required_features
148
+ resolver.required_features
149
+ end
150
+
147
151
  private
148
152
 
149
153
  def find_project_dotfile(target_dir)
@@ -6,9 +6,17 @@ require 'pathname'
6
6
  module RuboCop
7
7
  # A help class for ConfigLoader that handles configuration resolution.
8
8
  class ConfigLoaderResolver
9
+ attr_reader :required_features
10
+
11
+ def initialize
12
+ @required_features = []
13
+ end
14
+
9
15
  def resolve_requires(path, hash)
10
16
  config_dir = File.dirname(path)
11
17
  Array(hash.delete('require')).each do |r|
18
+ @required_features << r
19
+
12
20
  if r.start_with?('.')
13
21
  require(File.join(config_dir, r))
14
22
  else
@@ -27,7 +27,9 @@ module RuboCop
27
27
  KIND = 'block'
28
28
 
29
29
  def on_block(node)
30
- check(node, node.body)
30
+ first_line = node.send_node.last_line
31
+
32
+ check(node, node.body, adjusted_first_line: first_line)
31
33
  end
32
34
 
33
35
  def autocorrect(node)
@@ -108,6 +108,10 @@ module RuboCop
108
108
  end
109
109
  end
110
110
 
111
+ def self.autocorrect_incompatible_with
112
+ [Style::TrailingCommaInArguments]
113
+ end
114
+
111
115
  private
112
116
 
113
117
  def outermost_send_on_same_line(heredoc)
@@ -26,6 +26,8 @@ module RuboCop
26
26
  'on a separate line.'
27
27
 
28
28
  def on_send(node)
29
+ return if node.method_name == :[]=
30
+
29
31
  args = node.arguments
30
32
 
31
33
  # If there is a trailing hash arg without explicit braces, like this:
@@ -83,6 +83,10 @@ module RuboCop
83
83
  class TableAlignment
84
84
  include ValueAlignment
85
85
 
86
+ def initialize
87
+ self.max_key_width = 0
88
+ end
89
+
86
90
  def deltas_for_first_pair(first_pair, node)
87
91
  self.max_key_width = node.keys.map { |key| key.source.length }.max
88
92
 
@@ -90,11 +90,8 @@ module RuboCop
90
90
  end
91
91
 
92
92
  def preferred_name
93
- @preferred_name ||= begin
94
- name = cop_config.fetch('PreferredName', 'e')
95
- name = "_#{name}" if variable_name.to_s.start_with?('_')
96
- name
97
- end
93
+ name = cop_config.fetch('PreferredName', 'e')
94
+ variable_name.to_s.start_with?('_') ? "_#{name}" : name
98
95
  end
99
96
 
100
97
  def variable_name
@@ -65,6 +65,10 @@ module RuboCop
65
65
  PunctuationCorrector.swap_comma(range)
66
66
  end
67
67
 
68
+ def self.autocorrect_incompatible_with
69
+ [Layout::HeredocArgumentClosingParenthesis]
70
+ end
71
+
68
72
  private
69
73
 
70
74
  def avoid_autocorrect?(args)
@@ -47,6 +47,11 @@ module RuboCop
47
47
  # # a `sym` node, but can have more.
48
48
  # '(array <$str $_>)' # captures are in the order of the pattern,
49
49
  # # irrespective of the actual order of the children
50
+ # '(array int*)' # will match an array of 0 or more integers
51
+ # '(array int ?)' # will match 0 or 1 integer.
52
+ # # Note: Space needed to distinguish from int?
53
+ # '(array int+)' # will match an array of 1 or more integers
54
+ # '(array (int $_)+)' # as above and will capture the numbers in an array
50
55
  # '(send $...)' # capture all the children as an array
51
56
  # '(send $... int)' # capture all children but the last as an array
52
57
  # '(send _x :+ _x)' # unification is performed on named wildcards
@@ -106,7 +111,9 @@ module RuboCop
106
111
  class Compiler
107
112
  SYMBOL = %r{:(?:[\w+@*/?!<>=~|%^-]+|\[\]=?)}.freeze
108
113
  IDENTIFIER = /[a-zA-Z_][a-zA-Z0-9_-]*/.freeze
109
- META = Regexp.union(%w"( ) { } [ ] $< < > $... $ ! ^ ...").freeze
114
+ META = Regexp.union(
115
+ %w"( ) { } [ ] $< < > $... $ ! ^ ... + * ?"
116
+ ).freeze
110
117
  NUMBER = /-?\d+(?:\.\d+)?/.freeze
111
118
  STRING = /".+?"/.freeze
112
119
  METHOD_NAME = /\#?#{IDENTIFIER}[\!\?]?\(?/.freeze
@@ -160,6 +167,21 @@ module RuboCop
160
167
  RUBY
161
168
  ANY_ORDER_TEMPLATE.location = [__FILE__, line + 1]
162
169
 
170
+ line = __LINE__
171
+ REPEATED_TEMPLATE = ERB.new <<~RUBY.gsub("-%>\n", '%>')
172
+ <% if captured %>(<%= accumulate %> = Array.new) && <% end %>
173
+ <%= CUR_NODE %>.children[<%= range %>].all? do |<%= child %>|
174
+ <%= with_context(expr, child, use_temp_node: false) %><% if captured %>&&
175
+ <%= accumulate %>.push(<%= captured %>)<% end %>
176
+ end <% if captured %>&&
177
+ (<%= captured %> = if <%= accumulate %>.empty?
178
+ <%= captured %>.map{[]} # Transpose hack won't work for empty case
179
+ else
180
+ <%= accumulate %>.transpose
181
+ end) <% end -%>
182
+ RUBY
183
+ REPEATED_TEMPLATE.location = [__FILE__, line + 1]
184
+
163
185
  def initialize(str, node_var = 'node0')
164
186
  @string = str
165
187
  @root = node_var
@@ -238,10 +260,48 @@ module RuboCop
238
260
  when REST then compile_ellipsis
239
261
  when '$<' then compile_any_order(next_capture)
240
262
  when '<' then compile_any_order
241
- else [1, compile_expr(token)]
263
+ else compile_repeated_expr(token)
264
+ end
265
+ end
266
+
267
+ def compile_repeated_expr(token)
268
+ before = @captures
269
+ expr = compile_expr(token)
270
+ min, max = parse_repetition_token
271
+ return [1, expr] if min.nil?
272
+
273
+ if @captures != before
274
+ captured = "captures[#{before}...#{@captures}]"
275
+ accumulate = next_temp_variable(:accumulate)
276
+ end
277
+ arity = min..max || Float::INFINITY
278
+
279
+ [arity, repeated_generator(expr, captured, accumulate)]
280
+ end
281
+
282
+ def repeated_generator(expr, captured, accumulate)
283
+ with_temp_variables do |child|
284
+ lambda do |range|
285
+ if range.begin == SEQ_HEAD_INDEX
286
+ fail_due_to 'repeated pattern at beginning of sequence'
287
+ end
288
+ REPEATED_TEMPLATE.result(binding)
289
+ end
242
290
  end
243
291
  end
244
292
 
293
+ def parse_repetition_token
294
+ case tokens.first
295
+ when '*' then min = 0
296
+ when '+' then min = 1
297
+ when '?' then min = 0
298
+ max = 1
299
+ else return
300
+ end
301
+ tokens.shift
302
+ [min, max]
303
+ end
304
+
245
305
  # @private
246
306
  # Builds Ruby code for a sequence
247
307
  # (head *first_terms variadic_term *last_terms)
@@ -276,6 +336,10 @@ module RuboCop
276
336
  last_terms_range { |r| @arities[r].inject(0, :+) } || 0
277
337
  end
278
338
 
339
+ def variadic_term_min_arity
340
+ @variadic_index ? @arities[@variadic_index].begin : 0
341
+ end
342
+
279
343
  def first_terms_range
280
344
  yield 1..(@variadic_index || @terms.size) - 1 if seq_head?
281
345
  end
@@ -289,8 +353,19 @@ module RuboCop
289
353
  end
290
354
 
291
355
  def compile_child_nb_guard
292
- min = first_terms_arity + last_terms_arity
293
- "#{CUR_NODE}.children.size #{@variadic_index ? '>' : '='}= #{min}"
356
+ fixed = first_terms_arity + last_terms_arity
357
+ min = fixed + variadic_term_min_arity
358
+ op = if @variadic_index
359
+ max_variadic = @arities[@variadic_index].end
360
+ if max_variadic != Float::INFINITY
361
+ range = min..fixed + max_variadic
362
+ return "(#{range}).cover?(#{CUR_NODE}.children.size)"
363
+ end
364
+ '>='
365
+ else
366
+ '=='
367
+ end
368
+ "#{CUR_NODE}.children.size #{op} #{min}"
294
369
  end
295
370
 
296
371
  def term(index, range)
@@ -555,10 +630,14 @@ module RuboCop
555
630
  end
556
631
 
557
632
  def with_temp_variables(&block)
558
- names = block.parameters.map { |_, name| "#{name}#{next_temp_value}" }
633
+ names = block.parameters.map { |_, name| next_temp_variable(name) }
559
634
  yield(*names)
560
635
  end
561
636
 
637
+ def next_temp_variable(name)
638
+ "#{name}#{next_temp_value}"
639
+ end
640
+
562
641
  def next_temp_value
563
642
  @temps += 1
564
643
  end
@@ -183,6 +183,9 @@ module RuboCop
183
183
  when 2.6
184
184
  require 'parser/ruby26'
185
185
  Parser::Ruby26
186
+ when 2.7
187
+ require 'parser/ruby27'
188
+ Parser::Ruby27
186
189
  else
187
190
  raise ArgumentError, "Unknown Ruby version: #{ruby_version.inspect}"
188
191
  end
@@ -24,6 +24,14 @@ module RuboCop
24
24
 
25
25
  def initialize(options, config_store)
26
26
  @options = options
27
+
28
+ if @options.key?(:rails)
29
+ warn <<~MESSAGE
30
+ `-R/--rails` option and Rails cops will be removed from RuboCop 0.72. Use the `rubocop-rails` gem instead.
31
+ https://github.com/rubocop-hq/rubocop/blob/master/manual/migrate_rails_cops.md
32
+ MESSAGE
33
+ end
34
+
27
35
  @config_store = config_store
28
36
  @errors = []
29
37
  @warnings = []
@@ -72,7 +80,12 @@ module RuboCop
72
80
 
73
81
  each_inspected_file(files) { |file| inspected_files << file }
74
82
  ensure
75
- ResultCache.cleanup(@config_store, @options[:debug]) if cached_run?
83
+ # OPTIMIZE: Calling `ResultCache.cleanup` takes time. This optimization
84
+ # mainly targets editors that integrates RuboCop. When RuboCop is run
85
+ # by an editor, it should be inspecting only one file.
86
+ if files.size > 1 && cached_run?
87
+ ResultCache.cleanup(@config_store, @options[:debug])
88
+ end
76
89
  formatter_set.finished(inspected_files.freeze)
77
90
  formatter_set.close_output_files
78
91
  end
@@ -268,7 +281,10 @@ module RuboCop
268
281
 
269
282
  def inspect_file(processed_source)
270
283
  config = @config_store.for(processed_source.path)
271
- enable_rails_cops(config) if @options[:rails]
284
+ if @options[:rails] ||
285
+ ConfigLoader.required_features.include?('rubocop-rails')
286
+ enable_rails_cops(config)
287
+ end
272
288
  team = Cop::Team.new(mobilized_cop_classes(config), config, @options)
273
289
  offenses = team.inspect_file(processed_source)
274
290
  @errors.concat(team.errors)
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '0.70.0'
6
+ STRING = '0.71.0'
7
7
 
8
8
  MSG = '%<version>s (using Parser %<parser_version>s, running on ' \
9
9
  '%<ruby_engine>s %<ruby_version>s %<ruby_platform>s)'
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: 0.70.0
4
+ version: 0.71.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: 2019-05-21 00:00:00.000000000 Z
13
+ date: 2019-05-30 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: jaro_winkler
@@ -802,7 +802,28 @@ metadata:
802
802
  source_code_uri: https://github.com/rubocop-hq/rubocop/
803
803
  documentation_uri: https://docs.rubocop.org/
804
804
  bug_tracker_uri: https://github.com/rubocop-hq/rubocop/issues
805
- post_install_message:
805
+ post_install_message: |
806
+ Rails cops will be removed from RuboCop 0.72. Use the `rubocop-rails` gem instead.
807
+
808
+ Put this in your `Gemfile`.
809
+
810
+ ```rb
811
+ gem 'rubocop-rails'
812
+ ```
813
+
814
+ And then execute:
815
+
816
+ ```sh
817
+ $ bundle install
818
+ ```
819
+
820
+ Put this into your `.rubocop.yml`.
821
+
822
+ ```yaml
823
+ require: rubocop-rails
824
+ ```
825
+
826
+ More information: https://github.com/rubocop-hq/rubocop-rails
806
827
  rdoc_options: []
807
828
  require_paths:
808
829
  - lib