rubocop 1.11.0 → 1.12.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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/config/default.yml +16 -1
  4. data/lib/rubocop.rb +1 -0
  5. data/lib/rubocop/cli/command/suggest_extensions.rb +3 -2
  6. data/lib/rubocop/comment_config.rb +43 -94
  7. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -6
  8. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +11 -8
  9. data/lib/rubocop/cop/layout/argument_alignment.rb +6 -5
  10. data/lib/rubocop/cop/layout/array_alignment.rb +7 -6
  11. data/lib/rubocop/cop/layout/assignment_indentation.rb +6 -3
  12. data/lib/rubocop/cop/layout/block_end_newline.rb +4 -8
  13. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +14 -15
  14. data/lib/rubocop/cop/layout/comment_indentation.rb +16 -16
  15. data/lib/rubocop/cop/layout/else_alignment.rb +9 -6
  16. data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -5
  17. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +9 -6
  18. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +22 -15
  19. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +6 -5
  20. data/lib/rubocop/cop/layout/indentation_consistency.rb +9 -6
  21. data/lib/rubocop/cop/layout/indentation_style.rb +27 -30
  22. data/lib/rubocop/cop/layout/indentation_width.rb +19 -9
  23. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +6 -5
  24. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +6 -5
  25. data/lib/rubocop/cop/layout/parameter_alignment.rb +6 -5
  26. data/lib/rubocop/cop/lint/number_conversion.rb +7 -0
  27. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +1 -2
  28. data/lib/rubocop/cop/lint/suppressed_exception.rb +44 -1
  29. data/lib/rubocop/cop/lint/symbol_conversion.rb +89 -2
  30. data/lib/rubocop/cop/mixin/alignment.rb +10 -3
  31. data/lib/rubocop/cop/mixin/comments_help.rb +5 -1
  32. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  33. data/lib/rubocop/cop/mixin/line_length_help.rb +11 -6
  34. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +3 -1
  35. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +4 -3
  36. data/lib/rubocop/cop/mixin/preferred_delimiters.rb +1 -1
  37. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +4 -6
  38. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +4 -0
  39. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -0
  40. data/lib/rubocop/cop/registry.rb +9 -0
  41. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -1
  42. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +59 -71
  43. data/lib/rubocop/cop/style/bisected_attr_accessor/macro.rb +62 -0
  44. data/lib/rubocop/cop/style/case_like_if.rb +15 -4
  45. data/lib/rubocop/cop/style/class_equality_comparison.rb +2 -0
  46. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  47. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  48. data/lib/rubocop/cop/style/documentation.rb +25 -3
  49. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  50. data/lib/rubocop/cop/style/hash_syntax.rb +16 -15
  51. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +40 -0
  52. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +20 -2
  53. data/lib/rubocop/cop/style/negated_if_else_condition.rb +15 -2
  54. data/lib/rubocop/cop/style/redundant_begin.rb +26 -3
  55. data/lib/rubocop/cop/style/redundant_return.rb +4 -0
  56. data/lib/rubocop/cop/style/redundant_self.rb +7 -3
  57. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  58. data/lib/rubocop/cop/style/rescue_modifier.rb +17 -14
  59. data/lib/rubocop/cop/style/sole_nested_conditional.rb +16 -0
  60. data/lib/rubocop/cop/style/string_chars.rb +38 -0
  61. data/lib/rubocop/cop/style/struct_inheritance.rb +2 -0
  62. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +5 -1
  63. data/lib/rubocop/cop/style/unless_logical_operators.rb +8 -2
  64. data/lib/rubocop/directive_comment.rb +64 -9
  65. data/lib/rubocop/ext/regexp_parser.rb +3 -6
  66. data/lib/rubocop/magic_comment.rb +1 -1
  67. data/lib/rubocop/target_finder.rb +1 -0
  68. data/lib/rubocop/version.rb +1 -1
  69. metadata +5 -3
@@ -43,6 +43,7 @@ module RuboCop
43
43
  return if node.ternary? || node.else? || node.elsif?
44
44
 
45
45
  if_branch = node.if_branch
46
+ return if use_variable_assignment_in_condition?(node.condition, if_branch)
46
47
  return unless offending_branch?(if_branch)
47
48
 
48
49
  message = format(MSG, conditional_type: node.keyword)
@@ -53,6 +54,21 @@ module RuboCop
53
54
 
54
55
  private
55
56
 
57
+ def use_variable_assignment_in_condition?(condition, if_branch)
58
+ assigned_variables = assigned_variables(condition)
59
+
60
+ assigned_variables && if_branch&.if_type? &&
61
+ assigned_variables.include?(if_branch.condition.source)
62
+ end
63
+
64
+ def assigned_variables(condition)
65
+ assigned_variables = condition.assignment? ? [condition.children.first.to_s] : []
66
+
67
+ assigned_variables + condition.descendants.select(&:assignment?).map do |node|
68
+ node.children.first.to_s
69
+ end
70
+ end
71
+
56
72
  def offending_branch?(branch)
57
73
  return false unless branch
58
74
 
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for uses of `String#split` with empty string or regexp literal argument.
7
+ #
8
+ # This cop is marked as unsafe. But probably it's quite unlikely that some other class would
9
+ # define a `split` method that takes exactly the same arguments.
10
+ #
11
+ # @example
12
+ # # bad
13
+ # string.split(//)
14
+ # string.split('')
15
+ #
16
+ # # good
17
+ # string.chars
18
+ #
19
+ class StringChars < Base
20
+ extend AutoCorrector
21
+
22
+ MSG = 'Use `chars` instead of `%<current>s`.'
23
+ RESTRICT_ON_SEND = %i[split].freeze
24
+ BAD_ARGUMENTS = %w[// '' ""].freeze
25
+
26
+ def on_send(node)
27
+ return unless node.arguments.one? && BAD_ARGUMENTS.include?(node.first_argument.source)
28
+
29
+ range = node.loc.selector.begin.join(node.loc.end)
30
+
31
+ add_offense(range, message: format(MSG, current: range.source)) do |corrector|
32
+ corrector.replace(range, 'chars')
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -48,6 +48,8 @@ module RuboCop
48
48
  def correct_parent(parent, corrector)
49
49
  if parent.block_type?
50
50
  corrector.remove(range_with_surrounding_space(range: parent.loc.end, newlines: false))
51
+ elsif (class_node = parent.parent).body.nil?
52
+ corrector.remove(range_by_whole_lines(class_node.loc.end, include_final_newline: true))
51
53
  else
52
54
  corrector.insert_after(parent.loc.expression, ' do')
53
55
  end
@@ -5,6 +5,8 @@ module RuboCop
5
5
  module Style
6
6
  # This cop checks for trailing code after the method definition.
7
7
  #
8
+ # NOTE: It always accepts endless method definitions that are basically on the same line.
9
+ #
8
10
  # @example
9
11
  # # bad
10
12
  # def some_method; do_stuff
@@ -24,6 +26,8 @@ module RuboCop
24
26
  # b[c: x]
25
27
  # end
26
28
  #
29
+ # def endless_method = do_stuff
30
+ #
27
31
  class TrailingBodyOnMethodDefinition < Base
28
32
  include Alignment
29
33
  include TrailingBody
@@ -34,7 +38,7 @@ module RuboCop
34
38
 
35
39
  def on_def(node)
36
40
  return unless trailing_body?(node)
37
- return if node.endless? && node.body.parenthesized_call?
41
+ return if node.endless?
38
42
 
39
43
  add_offense(first_part_of(node.body)) do |corrector|
40
44
  LineBreakCorrector.correct_trailing_body(
@@ -87,11 +87,17 @@ module RuboCop
87
87
  end
88
88
 
89
89
  def mixed_precedence_and?(node)
90
- node.source.include?('&&') && node.source.include?('and')
90
+ and_sources = node.condition.each_descendant(:and).map(&:operator)
91
+ and_sources << node.condition.operator if node.condition.and_type?
92
+
93
+ !(and_sources.all? { |s| s == '&&' } || and_sources.all? { |s| s == 'and' })
91
94
  end
92
95
 
93
96
  def mixed_precedence_or?(node)
94
- node.source.include?('||') && node.source.include?('or')
97
+ or_sources = node.condition.each_descendant(:or).map(&:operator)
98
+ or_sources << node.condition.operator if node.condition.or_type?
99
+
100
+ !(or_sources.all? { |s| s == '||' } || or_sources.all? { |s| s == 'or' })
95
101
  end
96
102
  end
97
103
  end
@@ -5,28 +5,83 @@ module RuboCop
5
5
  # special `rubocop:disable` and `rubocop:enable` comment and exposes what
6
6
  # cops it contains.
7
7
  class DirectiveComment
8
- attr_reader :comment
8
+ # @api private
9
+ REDUNDANT_COP = 'Lint/RedundantCopDisableDirective'
10
+ # @api private
11
+ COP_NAME_PATTERN = '([A-Z]\w+/)*(?:[A-Z]\w+)'
12
+ # @api private
13
+ COP_NAMES_PATTERN = "(?:#{COP_NAME_PATTERN} , )*#{COP_NAME_PATTERN}"
14
+ # @api private
15
+ COPS_PATTERN = "(all|#{COP_NAMES_PATTERN})"
16
+ # @api private
17
+ DIRECTIVE_COMMENT_REGEXP = Regexp.new(
18
+ "# rubocop : ((?:disable|enable|todo))\\b #{COPS_PATTERN}"
19
+ .gsub(' ', '\s*')
20
+ )
21
+
22
+ def self.before_comment(line)
23
+ line.split(DIRECTIVE_COMMENT_REGEXP).first
24
+ end
25
+
26
+ attr_reader :comment, :mode, :cops
9
27
 
10
28
  def initialize(comment)
11
29
  @comment = comment
30
+ @mode, @cops = match_captures
12
31
  end
13
32
 
14
- # Return all the cops specified in the directive
15
- def cops
16
- match = comment.text.match(CommentConfig::COMMENT_DIRECTIVE_REGEXP)
17
- return unless match
18
-
19
- cops_string = match.captures[1]
20
- cops_string.split(/,\s*/).uniq.sort
33
+ # Checks if this directive relates to single line
34
+ def single_line?
35
+ !self.class.before_comment(comment.text).empty?
21
36
  end
22
37
 
23
38
  # Checks if this directive contains all the given cop names
24
39
  def match?(cop_names)
25
- cops == cop_names.uniq.sort
40
+ parsed_cop_names.uniq.sort == cop_names.uniq.sort
26
41
  end
27
42
 
28
43
  def range
29
44
  comment.location.expression
30
45
  end
46
+
47
+ # Returns match captures to directive comment pattern
48
+ def match_captures
49
+ @match_captures ||= comment.text.match(DIRECTIVE_COMMENT_REGEXP)&.captures
50
+ end
51
+
52
+ # Checks if this directive disables cops
53
+ def disabled?
54
+ %w[disable todo].include?(mode)
55
+ end
56
+
57
+ # Checks if this directive enables all cops
58
+ def enabled_all?
59
+ !disabled? && all_cops?
60
+ end
61
+
62
+ # Checks if all cops specified in this directive
63
+ def all_cops?
64
+ cops == 'all'
65
+ end
66
+
67
+ # Returns array of specified in this directive cop names
68
+ def cop_names
69
+ @cop_names ||= all_cops? ? all_cop_names : parsed_cop_names
70
+ end
71
+
72
+ # Returns line number for directive
73
+ def line_number
74
+ comment.loc.expression.line
75
+ end
76
+
77
+ private
78
+
79
+ def parsed_cop_names
80
+ (cops || '').split(/,\s*/)
81
+ end
82
+
83
+ def all_cop_names
84
+ Cop::Registry.global.names - [REDUNDANT_COP]
85
+ end
31
86
  end
32
87
  end
@@ -39,9 +39,8 @@ module RuboCop
39
39
 
40
40
  # Shortcut to `loc.expression`
41
41
  def expression
42
- @expression ||= begin
43
- origin.adjust(begin_pos: start_index, end_pos: start_index + full_length)
44
- end
42
+ end_pos = start_index + full_length
43
+ @expression ||= origin.adjust(begin_pos: start_index, end_pos: end_pos)
45
44
  end
46
45
  end
47
46
 
@@ -60,9 +59,7 @@ module RuboCop
60
59
  #
61
60
  # Please open issue if you need other locations
62
61
  def loc
63
- @loc ||= begin
64
- Map.new(expression, **build_location)
65
- end
62
+ @loc ||= Map.new(expression, **build_location)
66
63
  end
67
64
 
68
65
  private
@@ -47,7 +47,7 @@ module RuboCop
47
47
  end
48
48
 
49
49
  def valid_shareable_constant_value?
50
- %w[none literal experimental_everything experimental_copy].include?(shareable_constant_values)
50
+ %w[none literal experimental_everything experimental_copy].include?(shareable_constant_value)
51
51
  end
52
52
 
53
53
  # Was a magic comment for the frozen string literal found?
@@ -96,6 +96,7 @@ module RuboCop
96
96
  end
97
97
 
98
98
  def wanted_dir_patterns(base_dir, exclude_pattern, flags)
99
+ base_dir = base_dir.gsub('/{}/', '/\{}/')
99
100
  dirs = Dir.glob(File.join(base_dir.gsub('/**/', '/\**/'), '*/'), flags)
100
101
  .reject do |dir|
101
102
  dir.end_with?('/./', '/../') || File.fnmatch?(exclude_pattern, dir, flags)
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.11.0'
6
+ STRING = '1.12.0'
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.11.0
4
+ version: 1.12.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: 2021-03-01 00:00:00.000000000 Z
13
+ date: 2021-03-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: parallel
@@ -601,6 +601,7 @@ files:
601
601
  - lib/rubocop/cop/style/bare_percent_literals.rb
602
602
  - lib/rubocop/cop/style/begin_block.rb
603
603
  - lib/rubocop/cop/style/bisected_attr_accessor.rb
604
+ - lib/rubocop/cop/style/bisected_attr_accessor/macro.rb
604
605
  - lib/rubocop/cop/style/block_comments.rb
605
606
  - lib/rubocop/cop/style/block_delimiters.rb
606
607
  - lib/rubocop/cop/style/case_equality.rb
@@ -768,6 +769,7 @@ files:
768
769
  - lib/rubocop/cop/style/stabby_lambda_parentheses.rb
769
770
  - lib/rubocop/cop/style/static_class.rb
770
771
  - lib/rubocop/cop/style/stderr_puts.rb
772
+ - lib/rubocop/cop/style/string_chars.rb
771
773
  - lib/rubocop/cop/style/string_concatenation.rb
772
774
  - lib/rubocop/cop/style/string_hash_keys.rb
773
775
  - lib/rubocop/cop/style/string_literals.rb
@@ -870,7 +872,7 @@ metadata:
870
872
  homepage_uri: https://rubocop.org/
871
873
  changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md
872
874
  source_code_uri: https://github.com/rubocop/rubocop/
873
- documentation_uri: https://docs.rubocop.org/rubocop/1.11/
875
+ documentation_uri: https://docs.rubocop.org/rubocop/1.12/
874
876
  bug_tracker_uri: https://github.com/rubocop/rubocop/issues
875
877
  post_install_message:
876
878
  rdoc_options: []