rubocop 0.70.0 → 0.71.0

Sign up to get free protection for your applications and to get access to all the features.
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