rubocop 1.12.0 → 1.12.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: c4f019dc65a23e4fdd32592747afcbee2cf60dff91484b26714f587b9f70a178
4
- data.tar.gz: 85f0e9d193e2165646764047f5422cb7942c87a147c96ff8e4a05b186eaea3c5
3
+ metadata.gz: b8e99fa7dca255059fe40cb6426a3ac3f25ca31eaa7d0bef131216ebc4f6d984
4
+ data.tar.gz: a810490713929f48307639eb0d3acf37555c529d41691e9dc6468d2443b69dc4
5
5
  SHA512:
6
- metadata.gz: 5064fb48121769e10df9fe4dd7295151f15c2a3ae5f67fbb2869302a7ad268dfd3ed20e7a3242bf59ef68c1c6cf4e92452fedab08971702d29dba06516250de8
7
- data.tar.gz: 3b01830b9394f8336bdc415d90e2805f2817eb9fa9686a11392ef8009c4a58dd4b04e40c4a8005e90204774e85b38a6885c315581d55c56bf4a847c71c570447
6
+ metadata.gz: 5e7baebccb7c9d41aa23bfcf9c0e4c930d0e383bbe5b992c67b11e7edf0e56692ff2d9855cadeaf3e9d0aef57425ba0c2412e18b76ac8248f49b985bad001006
7
+ data.tar.gz: 5a4514d8eebb852646161720437cf752b2b5b628f75f55131e71c26bc35f11a0e9aa7d576340b2123838f710c51e2bb463e639181c4eb6671a2cff04694cb957
@@ -47,14 +47,13 @@ module RuboCop
47
47
 
48
48
  if node.modifier_form? && last_argument_is_heredoc?(node)
49
49
  heredoc_node = last_heredoc_argument(node)
50
-
51
- return if next_line_empty?(heredoc_line(node, heredoc_node))
50
+ return if next_line_empty_or_enable_directive_comment?(heredoc_line(node, heredoc_node))
52
51
 
53
52
  add_offense(heredoc_node.loc.heredoc_end) do |corrector|
54
53
  autocorrect(corrector, heredoc_node)
55
54
  end
56
55
  else
57
- return if next_line_empty?(node.last_line)
56
+ return if next_line_empty_or_enable_directive_comment?(node.last_line)
58
57
 
59
58
  add_offense(offense_location(node)) do |corrector|
60
59
  autocorrect(corrector, node)
@@ -71,6 +70,11 @@ module RuboCop
71
70
  range_by_whole_lines(node.source_range)
72
71
  end
73
72
 
73
+ next_line = node_range.last_line + 1
74
+ if next_line_enable_directive_comment?(next_line)
75
+ node_range = processed_source.comment_at_line(next_line)
76
+ end
77
+
74
78
  corrector.insert_after(node_range, "\n")
75
79
  end
76
80
 
@@ -85,10 +89,23 @@ module RuboCop
85
89
  node.if_branch&.guard_clause?
86
90
  end
87
91
 
92
+ def next_line_empty_or_enable_directive_comment?(line)
93
+ return true if next_line_empty?(line)
94
+
95
+ next_line = line + 1
96
+ next_line_enable_directive_comment?(next_line) && next_line_empty?(next_line)
97
+ end
98
+
88
99
  def next_line_empty?(line)
89
100
  processed_source[line].blank?
90
101
  end
91
102
 
103
+ def next_line_enable_directive_comment?(line)
104
+ return false unless (comment = processed_source.comment_at_line(line))
105
+
106
+ DirectiveComment.new(comment).enabled?
107
+ end
108
+
92
109
  def next_line_rescue_or_ensure?(node)
93
110
  parent = node.parent
94
111
  parent.nil? || parent.rescue_type? || parent.ensure_type?
@@ -72,6 +72,18 @@ module RuboCop
72
72
  send_node.loc.dot # Only check method calls with dot operator
73
73
  end
74
74
 
75
+ def right_hand_side(send_node)
76
+ dot = send_node.loc.dot
77
+ selector = send_node.loc.selector
78
+ if send_node.dot? && selector && dot.line == selector.line
79
+ dot.join(selector)
80
+ elsif selector
81
+ selector
82
+ elsif send_node.implicit_call?
83
+ dot.join(send_node.loc.begin)
84
+ end
85
+ end
86
+
75
87
  def offending_range(node, lhs, rhs, given_style)
76
88
  return false unless begins_its_line?(rhs)
77
89
  return false if not_for_this_cop?(node)
@@ -118,6 +118,10 @@ module RuboCop
118
118
  "spaces for indenting #{what} spanning multiple lines."
119
119
  end
120
120
  end
121
+
122
+ def right_hand_side(send_node)
123
+ send_node.first_argument.source_range
124
+ end
121
125
  end
122
126
  end
123
127
  end
@@ -58,8 +58,8 @@ module RuboCop
58
58
  }.freeze
59
59
  MSG = 'Replace unsafe number conversion with number '\
60
60
  'class parsing, instead of using '\
61
- '%<current>s, use stricter '\
62
- '%<corrected_method>s.'
61
+ '`%<current>s`, use stricter '\
62
+ '`%<corrected_method>s`.'
63
63
  METHODS = CONVERSION_METHOD_CLASS_MAPPING.keys.map(&:inspect).join(' ')
64
64
 
65
65
  # @!method to_method(node)
@@ -83,7 +83,7 @@ module RuboCop
83
83
 
84
84
  # @api private
85
85
  def within_column_limit?(element, max, line)
86
- element && element.loc.column < max && element.loc.line == line
86
+ element && element.loc.column <= max && element.loc.line == line
87
87
  end
88
88
 
89
89
  # @api private
@@ -35,26 +35,6 @@ module RuboCop
35
35
  lhs
36
36
  end
37
37
 
38
- def right_hand_side(send_node)
39
- if send_node.operator_method? && send_node.arguments?
40
- send_node.first_argument.source_range # not used for method calls
41
- else
42
- regular_method_right_hand_side(send_node)
43
- end
44
- end
45
-
46
- def regular_method_right_hand_side(send_node)
47
- dot = send_node.loc.dot
48
- selector = send_node.loc.selector
49
- if send_node.dot? && selector && dot.line == selector.line
50
- dot.join(selector)
51
- elsif selector
52
- selector
53
- elsif send_node.implicit_call?
54
- dot.join(send_node.loc.begin)
55
- end
56
- end
57
-
58
38
  # The correct indentation of `node` is usually `IndentationWidth`, with
59
39
  # one exception: prefix keywords.
60
40
  #
@@ -47,7 +47,7 @@ module RuboCop
47
47
  #
48
48
  # end
49
49
  #
50
- # @example AllowModifiersOnSymbols: true
50
+ # @example AllowModifiersOnSymbols: true (default)
51
51
  # # good
52
52
  # class Foo
53
53
  #
@@ -94,7 +94,9 @@ module RuboCop
94
94
 
95
95
  return unless correctable_send?(node)
96
96
 
97
- corrector.replace(whitespace_before_arg(node), '(')
97
+ whitespace_before_arg_range = whitespace_before_arg(node)
98
+ corrector.remove(whitespace_before_arg_range)
99
+ corrector.insert_before(whitespace_before_arg_range, '(')
98
100
  corrector.insert_after(node.last_argument, ')')
99
101
  end
100
102
 
@@ -43,16 +43,6 @@ module RuboCop
43
43
  MSG = 'Do not place comments on the same line as the ' \
44
44
  '`%<keyword>s` keyword.'
45
45
 
46
- def on_new_investigation
47
- processed_source.comments.each do |comment|
48
- next unless (match = line(comment).match(/(?<keyword>\S+).*#/)) && offensive?(comment)
49
-
50
- register_offense(comment, match[:keyword])
51
- end
52
- end
53
-
54
- private
55
-
56
46
  KEYWORDS = %w[begin class def end module].freeze
57
47
  KEYWORD_REGEXES = KEYWORDS.map { |w| /^\s*#{w}\s/ }.freeze
58
48
 
@@ -64,6 +54,16 @@ module RuboCop
64
54
  ].freeze
65
55
  ALLOWED_COMMENT_REGEXES = ALLOWED_COMMENTS.map { |c| /#\s*#{c}/ }.freeze
66
56
 
57
+ def on_new_investigation
58
+ processed_source.comments.each do |comment|
59
+ next unless (match = line(comment).match(/(?<keyword>\S+).*#/)) && offensive?(comment)
60
+
61
+ register_offense(comment, match[:keyword])
62
+ end
63
+ end
64
+
65
+ private
66
+
67
67
  def register_offense(comment, matched_keyword)
68
68
  add_offense(comment, message: format(MSG, keyword: matched_keyword)) do |corrector|
69
69
  range = range_with_surrounding_space(range: comment.loc.expression, newlines: false)
@@ -10,9 +10,6 @@ module RuboCop
10
10
  # default in future Ruby. The comment will be added below a shebang and
11
11
  # encoding comment.
12
12
  #
13
- # Note that the cop will ignore files where the comment exists but is set
14
- # to `false` instead of `true`.
15
- #
16
13
  # @example EnforcedStyle: always (default)
17
14
  # # The `always` style will always add the frozen string literal comment
18
15
  # # to a file, regardless of the Ruby version or if `freeze` or `<<` are
@@ -85,6 +85,9 @@ module RuboCop
85
85
  else
86
86
  add_offense(node, message: MSG_LITERAL_MULTI_ARG) do |corrector|
87
87
  corrector.replace(node, args_to_hash(node.arguments))
88
+
89
+ parent = node.parent
90
+ add_parentheses(parent, corrector) if parent&.send_type? && !parent.parenthesized?
88
91
  end
89
92
  end
90
93
  end
@@ -40,8 +40,12 @@ module RuboCop
40
40
  # to `true` allows the presence of parentheses in such a method call
41
41
  # even with arguments.
42
42
  #
43
- # NOTE: Parens are required around a method with arguments when inside an
44
- # endless method definition (>= Ruby 3.0).
43
+ # NOTE: Parentheses are still allowed in cases where omitting them
44
+ # results in ambiguous or syntactically incorrect code. For example,
45
+ # parentheses are required around a method with arguments when inside an
46
+ # endless method definition introduced in Ruby 3.0. Parentheses are also
47
+ # allowed when forwarding arguments with the triple-dot syntax introduced
48
+ # in Ruby 2.7 as omitting them starts an endless range.
45
49
  #
46
50
  # @example EnforcedStyle: require_parentheses (default)
47
51
  #
@@ -5,7 +5,7 @@ module RuboCop
5
5
  module Style
6
6
  class MethodCallWithArgsParentheses
7
7
  # Style omit_parentheses
8
- # rubocop:disable Metrics/ModuleLength
8
+ # rubocop:disable Metrics/ModuleLength, Metrics/CyclomaticComplexity
9
9
  module OmitParentheses
10
10
  TRAILING_WHITESPACE_REGEX = /\s+\Z/.freeze
11
11
  OMIT_MSG = 'Omit parentheses for method calls with arguments.'
@@ -13,7 +13,6 @@ module RuboCop
13
13
 
14
14
  private
15
15
 
16
- # rubocop:disable Metrics/CyclomaticComplexity
17
16
  def omit_parentheses(node)
18
17
  return unless node.parenthesized?
19
18
  return if inside_endless_method_def?(node)
@@ -27,7 +26,6 @@ module RuboCop
27
26
  auto_correct(corrector, node)
28
27
  end
29
28
  end
30
- # rubocop:enable Metrics/CyclomaticComplexity
31
29
 
32
30
  def auto_correct(corrector, node)
33
31
  if parentheses_at_the_end_of_multiline_call?(node)
@@ -114,7 +112,7 @@ module RuboCop
114
112
  call_as_argument_or_chain?(node) ||
115
113
  hash_literal_in_arguments?(node) ||
116
114
  node.descendants.any? do |n|
117
- ambigious_literal?(n) || logical_operator?(n) ||
115
+ n.forwarded_args_type? || ambigious_literal?(n) || logical_operator?(n) ||
118
116
  call_with_braced_block?(n)
119
117
  end
120
118
  end
@@ -190,7 +188,7 @@ module RuboCop
190
188
  node.ancestors.drop_while { |a| !a.begin_type? }.any?(&:dstr_type?)
191
189
  end
192
190
  end
193
- # rubocop:enable Metrics/ModuleLength
191
+ # rubocop:enable Metrics/ModuleLength, Metrics/CyclomaticComplexity
194
192
  end
195
193
  end
196
194
  end
@@ -40,7 +40,7 @@ module RuboCop
40
40
  def autocorrect(corrector, node)
41
41
  arguments = node.arguments
42
42
  joined_arguments = arguments.map(&:source).join(', ')
43
- last_line_source_of_arguments = processed_source[arguments.last_line - 1].strip
43
+ last_line_source_of_arguments = last_line_source_of_arguments(arguments)
44
44
 
45
45
  if last_line_source_of_arguments.start_with?(')')
46
46
  joined_arguments = "#{joined_arguments}#{last_line_source_of_arguments}"
@@ -48,13 +48,20 @@ module RuboCop
48
48
  corrector.remove(range_by_whole_lines(arguments.loc.end, include_final_newline: true))
49
49
  end
50
50
 
51
- corrector.replace(arguments_range(node), joined_arguments)
51
+ corrector.remove(arguments_range(node))
52
+ corrector.insert_after(arguments.loc.begin, joined_arguments)
53
+ end
54
+
55
+ def last_line_source_of_arguments(arguments)
56
+ processed_source[arguments.last_line - 1].strip
52
57
  end
53
58
 
54
59
  def arguments_range(node)
55
- range_between(
60
+ range = range_between(
56
61
  node.first_argument.source_range.begin_pos, node.last_argument.source_range.end_pos
57
62
  )
63
+
64
+ range_with_surrounding_space(range: range, side: :left)
58
65
  end
59
66
 
60
67
  def opening_line(node)
@@ -114,6 +114,17 @@ module RuboCop
114
114
 
115
115
  corrector.replace(offense_range, first_child.source)
116
116
  corrector.remove(range_between(offense_range.end_pos, first_child.source_range.end_pos))
117
+
118
+ restore_removed_comments(corrector, offense_range, node, first_child)
119
+ end
120
+
121
+ # Restore comments that occur between "begin" and "first_child".
122
+ # These comments will be moved to above the assignment line.
123
+ def restore_removed_comments(corrector, offense_range, node, first_child)
124
+ comments_range = range_between(offense_range.end_pos, first_child.source_range.begin_pos)
125
+ comments = comments_range.source
126
+
127
+ corrector.insert_before(node.parent, comments) unless comments.blank?
117
128
  end
118
129
 
119
130
  def empty_begin?(node)
@@ -91,8 +91,9 @@ module RuboCop
91
91
  end
92
92
 
93
93
  def correct_to_endless(corrector, node)
94
+ self_receiver = node.self_receiver? ? 'self.' : ''
94
95
  arguments = node.arguments.any? ? node.arguments.source : '()'
95
- replacement = "def #{node.method_name}#{arguments} = #{node.body.source}"
96
+ replacement = "def #{self_receiver}#{node.method_name}#{arguments} = #{node.body.source}"
96
97
  corrector.replace(node, replacement)
97
98
  end
98
99
 
@@ -38,7 +38,10 @@ module RuboCop
38
38
  elsif node.arguments.empty?
39
39
  corrector.insert_after(node, '()')
40
40
  else
41
- corrector.replace(args_begin(node), '(')
41
+ args_begin = args_begin(node)
42
+
43
+ corrector.remove(args_begin)
44
+ corrector.insert_before(args_begin, '(')
42
45
  corrector.insert_after(args_end(node), ')')
43
46
  end
44
47
  end
@@ -54,6 +54,11 @@ module RuboCop
54
54
  %w[disable todo].include?(mode)
55
55
  end
56
56
 
57
+ # Checks if this directive enables cops
58
+ def enabled?
59
+ mode == 'enable'
60
+ end
61
+
57
62
  # Checks if this directive enables all cops
58
63
  def enabled_all?
59
64
  !disabled? && all_cops?
@@ -49,8 +49,10 @@ module RuboCop
49
49
  end
50
50
 
51
51
  def report_highlighted_area(highlighted_area)
52
- output.puts("#{' ' * highlighted_area.begin_pos}" \
53
- "#{'^' * highlighted_area.size}")
52
+ space_area = highlighted_area.source_buffer.slice(0...highlighted_area.begin_pos)
53
+ source_area = highlighted_area.source
54
+ output.puts("#{' ' * Unicode::DisplayWidth.of(space_area)}" \
55
+ "#{'^' * Unicode::DisplayWidth.of(source_area)}")
54
56
  end
55
57
  end
56
58
  end
@@ -37,8 +37,10 @@ module RuboCop
37
37
  end
38
38
 
39
39
  def report_highlighted_area(highlighted_area)
40
- output.puts("# #{' ' * highlighted_area.begin_pos}" \
41
- "#{'^' * highlighted_area.size}")
40
+ space_area = highlighted_area.source_buffer.slice(0...highlighted_area.begin_pos)
41
+ source_area = highlighted_area.source
42
+ output.puts("# #{' ' * Unicode::DisplayWidth.of(space_area)}" \
43
+ "#{'^' * Unicode::DisplayWidth.of(source_area)}")
42
44
  end
43
45
 
44
46
  def report_offense(file, offense)
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.12.0'
6
+ STRING = '1.12.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: 1.12.0
4
+ version: 1.12.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: 2021-03-24 00:00:00.000000000 Z
13
+ date: 2021-04-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: parallel