rubocop 1.11.0 → 1.12.0

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