rubocop 0.87.0 → 0.87.1

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: 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