rubocop 0.87.0 → 0.87.1

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: b4ab19d9feaaa55fc107e42860eb4fe6a6f0106350edcfee8095b689845106d1
4
- data.tar.gz: b096ab80d7f1c3e1e3ea5b4e32f74f0ce23dc5bf34c06b2fb80893c53cd058dc
3
+ metadata.gz: 766878b5fd031a287c24a96e8545398cf26adca7b6ea1a3f6b0a3bd15ee07dda
4
+ data.tar.gz: 8e33f8a7e7a15ada40bdfbba85c9568e8910c71871af11677f74499241d20c87
5
5
  SHA512:
6
- metadata.gz: d9db7c5ac245ecc290c75144ca7baf37d3f8a39911238f4d8d2866ce019c91b0c0dc2a9cc296c71e2f49d972d16773de3c077734ecef7e5b01f7d693de51a001
7
- data.tar.gz: b9a3b18f4a95be71f2518ef6a2a4946f05079f0239a41c11230e7f60ba509b9d511c160edb0fe288663d41432d1e82aba6b721f6c27604a23a64b0bac674216f
6
+ metadata.gz: dd87ec99764bc87637c84d50443a60611c87dabb23af42f5339b8911b60898b527e94bed74a1fb925d0ebe91d059041a1214dc7bb53a6d9c4e15a0bafab4c465
7
+ data.tar.gz: d747fdfd2254f1b13a332d145aef2fb205afe4aae67c9fddc41d0bdbd6eff13c6f72af18426497ac98ae68a492abcc297892a41e0f2e766ac428029b69e3b9b4
data/README.md CHANGED
@@ -49,7 +49,7 @@ haven't reached version 1.0 yet). To prevent an unwanted RuboCop update you
49
49
  might want to use a conservative version lock in your `Gemfile`:
50
50
 
51
51
  ```rb
52
- gem 'rubocop', '~> 0.87.0', require: false
52
+ gem 'rubocop', '~> 0.87.1', require: false
53
53
  ```
54
54
 
55
55
  ## Quickstart
@@ -115,6 +115,7 @@ require_relative 'rubocop/cop/mixin/trailing_body'
115
115
  require_relative 'rubocop/cop/mixin/trailing_comma'
116
116
  require_relative 'rubocop/cop/mixin/uncommunicative_name'
117
117
  require_relative 'rubocop/cop/mixin/unused_argument'
118
+ require_relative 'rubocop/cop/mixin/visibility_help'
118
119
 
119
120
  require_relative 'rubocop/cop/utils/format_string'
120
121
 
@@ -119,7 +119,6 @@ module RuboCop
119
119
 
120
120
  def add_excludes_from_files(config, config_file)
121
121
  found_files = find_files_upwards(DOTFILE, config_file)
122
- found_files = [find_user_dotfile, find_user_xdg_config].compact if found_files.empty?
123
122
 
124
123
  return if found_files.empty?
125
124
  return if PathUtil.relative_path(found_files.last) ==
@@ -134,6 +134,8 @@ module RuboCop
134
134
  #
135
135
  # @see https://rubystyle.guide#consistent-classes
136
136
  class ClassStructure < Cop
137
+ include VisibilityHelp
138
+
137
139
  HUMANIZED_NODE_TYPE = {
138
140
  casgn: :constants,
139
141
  defs: :class_methods,
@@ -141,14 +143,9 @@ module RuboCop
141
143
  sclass: :class_singleton
142
144
  }.freeze
143
145
 
144
- VISIBILITY_SCOPES = %i[private protected public].freeze
145
146
  MSG = '`%<category>s` is supposed to appear before ' \
146
147
  '`%<previous>s`.'
147
148
 
148
- def_node_matcher :visibility_block?, <<~PATTERN
149
- (send nil? { :private :protected :public })
150
- PATTERN
151
-
152
149
  # Validates code style on class declaration.
153
150
  # Add offense when find a node out of expected order.
154
151
  def on_class(class_node)
@@ -243,38 +240,6 @@ module RuboCop
243
240
  expected_order.index(classification).nil?
244
241
  end
245
242
 
246
- def node_visibility(node)
247
- scope = find_visibility_start(node)
248
- scope&.method_name || :public
249
- end
250
-
251
- def find_visibility_start(node)
252
- left_siblings_of(node)
253
- .reverse
254
- .find(&method(:visibility_block?))
255
- end
256
-
257
- # Navigate to find the last protected method
258
- def find_visibility_end(node)
259
- possible_visibilities = VISIBILITY_SCOPES - [node_visibility(node)]
260
- right = right_siblings_of(node)
261
- right.find do |child_node|
262
- possible_visibilities.include?(node_visibility(child_node))
263
- end || right.last
264
- end
265
-
266
- def siblings_of(node)
267
- node.parent.children
268
- end
269
-
270
- def right_siblings_of(node)
271
- siblings_of(node)[node.sibling_index..-1]
272
- end
273
-
274
- def left_siblings_of(node)
275
- siblings_of(node)[0, node.sibling_index]
276
- end
277
-
278
243
  def humanize_node(node)
279
244
  if node.def_type?
280
245
  return :initializer if node.method?(:initialize)
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # OpenSSL::Cipher::AES.new(128, :GCM)
16
16
  #
17
17
  # # good
18
- # OpenSSL::Cipher.new('AES-128-GCM')
18
+ # OpenSSL::Cipher.new('aes-128-gcm')
19
19
  #
20
20
  # @example
21
21
  #
@@ -127,9 +127,9 @@ module RuboCop
127
127
  end
128
128
 
129
129
  def build_cipher_arguments(node, algorithm_name)
130
- algorithm_parts = algorithm_name.split('-')
131
- size_and_mode = sanitize_arguments(node.arguments)
132
- "'#{(algorithm_parts + size_and_mode + ['CBC']).take(3).join('-')}'"
130
+ algorithm_parts = algorithm_name.downcase.split('-')
131
+ size_and_mode = sanitize_arguments(node.arguments).map(&:downcase)
132
+ "'#{(algorithm_parts + size_and_mode + ['cbc']).take(3).join('-')}'"
133
133
  end
134
134
  end
135
135
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Help methods for determining node visibility.
6
+ module VisibilityHelp
7
+ extend NodePattern::Macros
8
+
9
+ VISIBILITY_SCOPES = %i[private protected public].freeze
10
+
11
+ private
12
+
13
+ def node_visibility(node)
14
+ scope = find_visibility_start(node)
15
+ scope&.method_name || :public
16
+ end
17
+
18
+ def find_visibility_start(node)
19
+ left_siblings_of(node)
20
+ .reverse
21
+ .find(&method(:visibility_block?))
22
+ end
23
+
24
+ # Navigate to find the last protected method
25
+ def find_visibility_end(node)
26
+ possible_visibilities = VISIBILITY_SCOPES - [node_visibility(node)]
27
+ right = right_siblings_of(node)
28
+ right.find do |child_node|
29
+ possible_visibilities.include?(node_visibility(child_node))
30
+ end || right.last
31
+ end
32
+
33
+ def left_siblings_of(node)
34
+ siblings_of(node)[0, node.sibling_index]
35
+ end
36
+
37
+ def right_siblings_of(node)
38
+ siblings_of(node)[node.sibling_index..-1]
39
+ end
40
+
41
+ def siblings_of(node)
42
+ node.parent.children
43
+ end
44
+
45
+ def_node_matcher :visibility_block?, <<~PATTERN
46
+ (send nil? { :private :protected :public })
47
+ PATTERN
48
+ end
49
+ end
50
+ end
@@ -33,6 +33,7 @@ module RuboCop
33
33
  #
34
34
  class AccessorGrouping < Cop
35
35
  include ConfigurableEnforcedStyle
36
+ include VisibilityHelp
36
37
 
37
38
  GROUPED_MSG = 'Group together all `%<accessor>s` attributes.'
38
39
  SEPARATED_MSG = 'Use one attribute per `%<accessor>s`.'
@@ -46,6 +47,7 @@ module RuboCop
46
47
  check(macro)
47
48
  end
48
49
  end
50
+ alias on_sclass on_class
49
51
  alias on_module on_class
50
52
 
51
53
  def autocorrect(node)
@@ -90,7 +92,9 @@ module RuboCop
90
92
 
91
93
  def sibling_accessors(send_node)
92
94
  send_node.parent.each_child_node(:send).select do |sibling|
93
- sibling.macro? && sibling.method?(send_node.method_name)
95
+ accessor?(sibling) &&
96
+ sibling.method?(send_node.method_name) &&
97
+ node_visibility(sibling) == node_visibility(send_node)
94
98
  end
95
99
  end
96
100
 
@@ -21,15 +21,20 @@ module RuboCop
21
21
  # end
22
22
  #
23
23
  class BisectedAttrAccessor < Cop
24
- MSG = 'Combine both accessors into `attr_accessor :%<name>s`.'
24
+ include VisibilityHelp
25
+
26
+ MSG = 'Combine both accessors into `attr_accessor %<name>s`.'
25
27
 
26
28
  def on_class(class_node)
27
- reader_names, writer_names = accessor_names(class_node)
29
+ VISIBILITY_SCOPES.each do |visibility|
30
+ reader_names, writer_names = accessor_names(class_node, visibility)
28
31
 
29
- accessor_macroses(class_node).each do |macro|
30
- check(macro, reader_names, writer_names)
32
+ accessor_macroses(class_node, visibility).each do |macro|
33
+ check(macro, reader_names, writer_names)
34
+ end
31
35
  end
32
36
  end
37
+ alias on_sclass on_class
33
38
  alias on_module on_class
34
39
 
35
40
  def autocorrect(node)
@@ -42,12 +47,12 @@ module RuboCop
42
47
 
43
48
  private
44
49
 
45
- def accessor_names(class_node)
50
+ def accessor_names(class_node, visibility)
46
51
  reader_names = Set.new
47
52
  writer_names = Set.new
48
53
 
49
- accessor_macroses(class_node).each do |macro|
50
- names = macro.arguments.map(&:value)
54
+ accessor_macroses(class_node, visibility).each do |macro|
55
+ names = macro.arguments.map(&:source)
51
56
 
52
57
  names.each do |name|
53
58
  if attr_reader?(macro)
@@ -61,7 +66,7 @@ module RuboCop
61
66
  [reader_names, writer_names]
62
67
  end
63
68
 
64
- def accessor_macroses(class_node)
69
+ def accessor_macroses(class_node, visibility)
65
70
  class_def = class_node.body
66
71
  return [] if !class_def || class_def.def_type?
67
72
 
@@ -72,7 +77,13 @@ module RuboCop
72
77
  class_def.each_child_node(:send)
73
78
  end
74
79
 
75
- send_nodes.select { |node| node.macro? && (attr_reader?(node) || attr_writer?(node)) }
80
+ send_nodes.select { |node| attr_within_visibility_scope?(node, visibility) }
81
+ end
82
+
83
+ def attr_within_visibility_scope?(node, visibility)
84
+ node.macro? &&
85
+ (attr_reader?(node) || attr_writer?(node)) &&
86
+ node_visibility(node) == visibility
76
87
  end
77
88
 
78
89
  def attr_reader?(send_node)
@@ -85,7 +96,7 @@ module RuboCop
85
96
 
86
97
  def check(macro, reader_names, writer_names)
87
98
  macro.arguments.each do |arg_node|
88
- name = arg_node.value
99
+ name = arg_node.source
89
100
 
90
101
  if (attr_reader?(macro) && writer_names.include?(name)) ||
91
102
  (attr_writer?(macro) && reader_names.include?(name))
@@ -95,20 +106,33 @@ module RuboCop
95
106
  end
96
107
 
97
108
  def replacement(macro, node)
98
- rest_args = macro.arguments
99
- rest_args.delete(node)
100
- args = rest_args.map(&:source).join(', ')
109
+ class_node = macro.each_ancestor(:class, :sclass, :module).first
110
+ reader_names, writer_names = accessor_names(class_node, node_visibility(macro))
111
+
112
+ rest_args = rest_args(macro.arguments, reader_names, writer_names)
101
113
 
102
114
  if attr_reader?(macro)
103
- if args.empty?
104
- "attr_accessor #{node.source}"
105
- else
106
- "attr_accessor #{node.source}\n#{indent(macro)}#{macro.method_name} #{args}"
107
- end
108
- elsif args.empty?
115
+ attr_reader_replacement(macro, node, rest_args)
116
+ elsif rest_args.empty?
109
117
  ''
110
118
  else
111
- "#{indent(macro)}#{macro.method_name} #{args}"
119
+ "#{macro.method_name} #{rest_args.map(&:source).join(', ')}"
120
+ end
121
+ end
122
+
123
+ def rest_args(args, reader_names, writer_names)
124
+ args.reject do |arg|
125
+ name = arg.source
126
+ reader_names.include?(name) && writer_names.include?(name)
127
+ end
128
+ end
129
+
130
+ def attr_reader_replacement(macro, node, rest_args)
131
+ if rest_args.empty?
132
+ "attr_accessor #{node.source}"
133
+ else
134
+ "attr_accessor #{node.source}\n"\
135
+ "#{indent(macro)}#{macro.method_name} #{rest_args.map(&:source).join(', ')}"
112
136
  end
113
137
  end
114
138
 
@@ -83,8 +83,8 @@ module RuboCop
83
83
 
84
84
  def delimiter?(node, char)
85
85
  delimiters = [
86
- node.loc.begin.source.chars.last,
87
- node.loc.end.source.chars.first
86
+ node.loc.begin.source[-1],
87
+ node.loc.end.source[0]
88
88
  ]
89
89
 
90
90
  delimiters.include?(char)
@@ -115,7 +115,7 @@ module RuboCop
115
115
  output_buffer.puts "# Offense count: #{offense_count}" if @show_offense_counts
116
116
 
117
117
  cop_class = Cop::Cop.registry.find_by_cop_name(cop_name)
118
- output_buffer.puts '# Cop supports --auto-correct.' if cop_class&.new&.support_autocorrect?
118
+ output_buffer.puts '# Cop supports --auto-correct.' if cop_class&.support_autocorrect?
119
119
 
120
120
  default_cfg = default_config(cop_name)
121
121
  return unless default_cfg
@@ -174,8 +174,8 @@ module RuboCop
174
174
  option(opts, '-a', '--auto-correct') do
175
175
  @options[:safe_auto_correct] = true
176
176
  end
177
- option(opts, '--safe-autocorrect') do
178
- warn '--safe-autocorrect is deprecated; use --autocorrect'
177
+ option(opts, '--safe-auto-correct') do
178
+ warn '--safe-auto-correct is deprecated; use --auto-correct'
179
179
  @options[:safe_auto_correct] = @options[:auto_correct] = true
180
180
  end
181
181
  option(opts, '-A', '--auto-correct-all') do
@@ -472,7 +472,7 @@ module RuboCop
472
472
  safe: 'Run only safe cops.',
473
473
  list_target_files: 'List all files RuboCop will inspect.',
474
474
  auto_correct: 'Auto-correct offenses (only when it\'s safe).',
475
- safe_autocorrect: '(same, deprecated)',
475
+ safe_auto_correct: '(same, deprecated)',
476
476
  auto_correct_all: 'Auto-correct offenses (safe and unsafe)',
477
477
  fix_layout: 'Run only layout cops, with auto-correct on.',
478
478
  color: 'Force color output on or off.',
@@ -89,6 +89,16 @@ module RuboCop
89
89
  # end
90
90
  # RUBY
91
91
  # end
92
+ #
93
+ # If you need to specify an offense on a blank line, use the empty `^{}` marker:
94
+ #
95
+ # @example `^{}` empty line offense
96
+ #
97
+ # expect_offense(<<~RUBY)
98
+ #
99
+ # ^{} Missing frozen string literal comment.
100
+ # puts 1
101
+ # RUBY
92
102
  module ExpectOffense
93
103
  def format_offense(source, **replacements)
94
104
  replacements.each do |keyword, value|
@@ -177,7 +187,7 @@ module RuboCop
177
187
 
178
188
  # Parsed representation of code annotated with the `^^^ Message` style
179
189
  class AnnotatedSource
180
- ANNOTATION_PATTERN = /\A\s*\^+ /.freeze
190
+ ANNOTATION_PATTERN = /\A\s*(\^+|\^{}) /.freeze
181
191
 
182
192
  # @param annotated_source [String] string passed to the matchers
183
193
  #
@@ -261,6 +271,7 @@ module RuboCop
261
271
  offenses.map do |offense|
262
272
  indent = ' ' * offense.column
263
273
  carets = '^' * offense.column_length
274
+ carets = '^{}' if offense.column_length.zero?
264
275
 
265
276
  [offense.line, "#{indent}#{carets} #{offense.message}\n"]
266
277
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '0.87.0'
6
+ STRING = '0.87.1'
7
7
 
8
8
  MSG = '%<version>s (using Parser %<parser_version>s, '\
9
9
  'rubocop-ast %<rubocop_ast_version>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.87.0
4
+ version: 0.87.1
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: 2020-07-06 00:00:00.000000000 Z
13
+ date: 2020-07-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: parallel
@@ -500,6 +500,7 @@ files:
500
500
  - lib/rubocop/cop/mixin/trailing_comma.rb
501
501
  - lib/rubocop/cop/mixin/uncommunicative_name.rb
502
502
  - lib/rubocop/cop/mixin/unused_argument.rb
503
+ - lib/rubocop/cop/mixin/visibility_help.rb
503
504
  - lib/rubocop/cop/naming/accessor_method_name.rb
504
505
  - lib/rubocop/cop/naming/ascii_identifiers.rb
505
506
  - lib/rubocop/cop/naming/binary_operator_parameter_name.rb