rubocop 0.67.2 → 0.68.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +86 -233
  4. data/exe/rubocop +0 -12
  5. data/lib/rubocop.rb +13 -30
  6. data/lib/rubocop/ast/builder.rb +4 -0
  7. data/lib/rubocop/ast/node/alias_node.rb +24 -0
  8. data/lib/rubocop/ast/node/class_node.rb +31 -0
  9. data/lib/rubocop/ast/node/module_node.rb +24 -0
  10. data/lib/rubocop/ast/node/range_node.rb +7 -0
  11. data/lib/rubocop/ast/node/resbody_node.rb +12 -0
  12. data/lib/rubocop/ast/node/self_class_node.rb +24 -0
  13. data/lib/rubocop/cli.rb +40 -4
  14. data/lib/rubocop/config.rb +9 -7
  15. data/lib/rubocop/config_loader.rb +48 -7
  16. data/lib/rubocop/config_loader_resolver.rb +5 -4
  17. data/lib/rubocop/cop/commissioner.rb +24 -0
  18. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +18 -6
  19. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +12 -14
  20. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +9 -20
  21. data/lib/rubocop/cop/layout/align_arguments.rb +93 -0
  22. data/lib/rubocop/cop/layout/align_parameters.rb +57 -33
  23. data/lib/rubocop/cop/layout/class_structure.rb +5 -5
  24. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +6 -8
  25. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +3 -6
  26. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +1 -2
  27. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -0
  28. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +292 -0
  29. data/lib/rubocop/cop/layout/{first_parameter_indentation.rb → indent_first_argument.rb} +11 -12
  30. data/lib/rubocop/cop/layout/{indent_array.rb → indent_first_array_element.rb} +2 -2
  31. data/lib/rubocop/cop/layout/{indent_hash.rb → indent_first_hash_element.rb} +2 -2
  32. data/lib/rubocop/cop/layout/indent_first_parameter.rb +96 -0
  33. data/lib/rubocop/cop/layout/indentation_width.rb +4 -16
  34. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +2 -4
  35. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -16
  36. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -2
  37. data/lib/rubocop/cop/lint/duplicate_methods.rb +6 -8
  38. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +4 -8
  39. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +157 -0
  40. data/lib/rubocop/cop/lint/inherit_exception.rb +3 -4
  41. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +18 -1
  42. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -5
  43. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +25 -5
  44. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -6
  45. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -2
  46. data/lib/rubocop/cop/message_annotator.rb +1 -0
  47. data/lib/rubocop/cop/metrics/line_length.rb +139 -28
  48. data/lib/rubocop/cop/metrics/perceived_complexity.rb +3 -4
  49. data/lib/rubocop/cop/mixin/check_line_breakable.rb +190 -0
  50. data/lib/rubocop/cop/mixin/{array_hash_indentation.rb → multiline_element_indentation.rb} +3 -2
  51. data/lib/rubocop/cop/mixin/too_many_lines.rb +3 -7
  52. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +33 -4
  53. data/lib/rubocop/cop/rails/active_record_override.rb +23 -8
  54. data/lib/rubocop/cop/rails/delegate.rb +5 -8
  55. data/lib/rubocop/cop/rails/environment_comparison.rb +5 -3
  56. data/lib/rubocop/cop/rails/find_each.rb +1 -1
  57. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +3 -3
  58. data/lib/rubocop/cop/rails/reflection_class_name.rb +1 -1
  59. data/lib/rubocop/cop/rails/skips_model_validations.rb +6 -7
  60. data/lib/rubocop/cop/rails/time_zone.rb +3 -10
  61. data/lib/rubocop/cop/rails/validation.rb +3 -0
  62. data/lib/rubocop/cop/registry.rb +3 -3
  63. data/lib/rubocop/cop/style/alias.rb +13 -7
  64. data/lib/rubocop/cop/style/block_delimiters.rb +20 -0
  65. data/lib/rubocop/cop/style/class_and_module_children.rb +19 -21
  66. data/lib/rubocop/cop/style/class_methods.rb +16 -24
  67. data/lib/rubocop/cop/style/conditional_assignment.rb +20 -49
  68. data/lib/rubocop/cop/style/documentation.rb +3 -7
  69. data/lib/rubocop/cop/style/format_string.rb +18 -21
  70. data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
  71. data/lib/rubocop/cop/style/inverse_methods.rb +4 -0
  72. data/lib/rubocop/cop/style/lambda.rb +12 -8
  73. data/lib/rubocop/cop/style/mixin_grouping.rb +8 -10
  74. data/lib/rubocop/cop/style/module_function.rb +2 -3
  75. data/lib/rubocop/cop/style/next.rb +10 -14
  76. data/lib/rubocop/cop/style/one_line_conditional.rb +5 -3
  77. data/lib/rubocop/cop/style/optional_arguments.rb +1 -4
  78. data/lib/rubocop/cop/style/random_with_offset.rb +44 -47
  79. data/lib/rubocop/cop/style/redundant_return.rb +6 -14
  80. data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -1
  81. data/lib/rubocop/cop/style/safe_navigation.rb +3 -0
  82. data/lib/rubocop/cop/style/struct_inheritance.rb +2 -3
  83. data/lib/rubocop/cop/style/symbol_proc.rb +20 -40
  84. data/lib/rubocop/cop/style/unless_else.rb +1 -2
  85. data/lib/rubocop/cop/style/yoda_condition.rb +8 -7
  86. data/lib/rubocop/cop/util.rb +2 -4
  87. data/lib/rubocop/file_finder.rb +5 -10
  88. data/lib/rubocop/formatter/disabled_config_formatter.rb +5 -0
  89. data/lib/rubocop/node_pattern.rb +304 -170
  90. data/lib/rubocop/options.rb +4 -1
  91. data/lib/rubocop/rspec/shared_contexts.rb +3 -0
  92. data/lib/rubocop/version.rb +1 -1
  93. data/lib/rubocop/yaml_duplication_checker.rb +1 -1
  94. metadata +26 -50
  95. data/lib/rubocop/cop/performance/caller.rb +0 -69
  96. data/lib/rubocop/cop/performance/case_when_splat.rb +0 -177
  97. data/lib/rubocop/cop/performance/casecmp.rb +0 -108
  98. data/lib/rubocop/cop/performance/chain_array_allocation.rb +0 -78
  99. data/lib/rubocop/cop/performance/compare_with_block.rb +0 -122
  100. data/lib/rubocop/cop/performance/count.rb +0 -102
  101. data/lib/rubocop/cop/performance/detect.rb +0 -110
  102. data/lib/rubocop/cop/performance/double_start_end_with.rb +0 -94
  103. data/lib/rubocop/cop/performance/end_with.rb +0 -56
  104. data/lib/rubocop/cop/performance/fixed_size.rb +0 -97
  105. data/lib/rubocop/cop/performance/flat_map.rb +0 -78
  106. data/lib/rubocop/cop/performance/inefficient_hash_search.rb +0 -99
  107. data/lib/rubocop/cop/performance/open_struct.rb +0 -46
  108. data/lib/rubocop/cop/performance/range_include.rb +0 -50
  109. data/lib/rubocop/cop/performance/redundant_block_call.rb +0 -93
  110. data/lib/rubocop/cop/performance/redundant_match.rb +0 -56
  111. data/lib/rubocop/cop/performance/redundant_merge.rb +0 -183
  112. data/lib/rubocop/cop/performance/regexp_match.rb +0 -265
  113. data/lib/rubocop/cop/performance/reverse_each.rb +0 -42
  114. data/lib/rubocop/cop/performance/size.rb +0 -77
  115. data/lib/rubocop/cop/performance/start_with.rb +0 -59
  116. data/lib/rubocop/cop/performance/string_replacement.rb +0 -173
  117. data/lib/rubocop/cop/performance/times_map.rb +0 -71
  118. data/lib/rubocop/cop/performance/unfreeze_string.rb +0 -50
  119. data/lib/rubocop/cop/performance/uri_default_parser.rb +0 -47
@@ -24,14 +24,17 @@ module RuboCop
24
24
  MSG = 'Use `self.%<method>s` instead of `%<class>s.%<method>s`.'.freeze
25
25
 
26
26
  def on_class(node)
27
- name, _superclass, body = *node
28
- check(name, body)
29
- end
30
-
31
- def on_module(node)
32
- name, body = *node
33
- check(name, body)
27
+ return unless node.body
28
+
29
+ if node.body.defs_type?
30
+ check_defs(node.identifier, node.body)
31
+ elsif node.body.begin_type?
32
+ node.body.each_child_node(:defs) do |def_node|
33
+ check_defs(node.identifier, def_node)
34
+ end
35
+ end
34
36
  end
37
+ alias on_module on_class
35
38
 
36
39
  def autocorrect(node)
37
40
  ->(corrector) { corrector.replace(node.loc.name, 'self') }
@@ -39,28 +42,17 @@ module RuboCop
39
42
 
40
43
  private
41
44
 
42
- def check(name, node)
43
- return unless node
44
-
45
- if node.defs_type?
46
- check_defs(name, node)
47
- elsif node.begin_type?
48
- node.each_child_node(:defs) { |n| check_defs(name, n) }
49
- end
50
- end
51
-
52
45
  def check_defs(name, node)
53
- definee, method_name, _args, _body = *node
54
46
  # check if the class/module name matches the definee for the defs node
55
- return unless name == definee
47
+ return unless name == node.receiver
56
48
 
57
- _, class_name = *definee
58
- add_offense(definee, location: :name,
59
- message: message(class_name, method_name))
49
+ add_offense(node.receiver, location: :name)
60
50
  end
61
51
 
62
- def message(class_name, method_name)
63
- format(MSG, method: method_name, class: class_name)
52
+ def message(node)
53
+ _, class_name = *node
54
+
55
+ format(MSG, method: node.parent.method_name, class: class_name)
64
56
  end
65
57
  end
66
58
  end
@@ -70,12 +70,12 @@ module RuboCop
70
70
  def expand_elsif(node, elsif_branches = [])
71
71
  return [] if node.nil? || !node.if_type?
72
72
 
73
- _condition, elsif_branch, else_branch = *node
74
- elsif_branches << elsif_branch
75
- if else_branch && else_branch.if_type?
76
- expand_elsif(else_branch, elsif_branches)
73
+ elsif_branches << node.if_branch
74
+
75
+ if node.else_branch && node.else_branch.if_type?
76
+ expand_elsif(node.else_branch, elsif_branches)
77
77
  else
78
- elsif_branches << else_branch
78
+ elsif_branches << node.else_branch
79
79
  end
80
80
  elsif_branches
81
81
  end
@@ -326,10 +326,8 @@ module RuboCop
326
326
  CaseCorrector.correct(self, node)
327
327
  elsif node.ternary?
328
328
  TernaryCorrector.correct(node)
329
- elsif node.if?
329
+ elsif node.if? || node.unless?
330
330
  IfCorrector.correct(self, node)
331
- elsif node.unless?
332
- UnlessCorrector.correct(self, node)
333
331
  end
334
332
  end
335
333
 
@@ -519,18 +517,18 @@ module RuboCop
519
517
  private
520
518
 
521
519
  def correction(node)
522
- condition, if_branch, else_branch = *node
523
-
524
- "#{lhs(if_branch)}#{ternary(condition, if_branch, else_branch)}"
520
+ "#{lhs(node.if_branch)}#{ternary(node)}"
525
521
  end
526
522
 
527
- def ternary(condition, if_branch, else_branch)
528
- _variable, *_operator, if_rhs = *if_branch
529
- _else_variable, *_operator, else_rhs = *else_branch
523
+ def ternary(node)
524
+ _variable, *_operator, if_rhs = *node.if_branch
525
+ _else_variable, *_operator, else_rhs = *node.else_branch
530
526
 
531
- expr = "#{condition.source} ? #{if_rhs.source} : #{else_rhs.source}"
527
+ expr = "#{node.condition.source} ? " \
528
+ "#{if_rhs.source} : " \
529
+ "#{else_rhs.source}"
532
530
 
533
- element_assignment?(if_branch) ? "(#{expr})" : expr
531
+ element_assignment?(node.if_branch) ? "(#{expr})" : expr
534
532
  end
535
533
 
536
534
  def element_assignment?(node)
@@ -574,7 +572,7 @@ module RuboCop
574
572
  lambda do |corrector|
575
573
  corrector.remove(assignment)
576
574
 
577
- extract_branches(condition).flatten.each do |branch|
575
+ condition.branches.flatten.each do |branch|
578
576
  move_branch_inside_condition(corrector, branch, condition,
579
577
  assignment, column)
580
578
  end
@@ -584,19 +582,12 @@ module RuboCop
584
582
  private
585
583
 
586
584
  def extract_tail_branches(node)
587
- if_branch, elsif_branches, else_branch = extract_branches(node)
585
+ if_branch, *elsif_branches, else_branch = *node.branches
588
586
  elsif_branches.map! { |branch| tail(branch) }
589
587
 
590
588
  [tail(if_branch), elsif_branches, tail(else_branch)]
591
589
  end
592
590
 
593
- def extract_branches(node)
594
- _condition, if_branch, else_branch = *node
595
- elsif_branches, else_branch = expand_elses(else_branch)
596
-
597
- [if_branch, elsif_branches, else_branch]
598
- end
599
-
600
591
  def move_branch_inside_condition(corrector, branch, condition,
601
592
  assignment, column)
602
593
  branch_assignment = tail(branch)
@@ -653,10 +644,10 @@ module RuboCop
653
644
  [when_branches, tail(else_branch)]
654
645
  end
655
646
 
656
- def extract_branches(node)
657
- _condition, *when_branches, else_branch = *node
658
- when_branches = expand_when_branches(when_branches)
659
- [when_branches, else_branch]
647
+ def extract_branches(case_node)
648
+ when_branches = expand_when_branches(case_node.when_branches)
649
+
650
+ [when_branches, case_node.else_branch]
660
651
  end
661
652
 
662
653
  def move_branch_inside_condition(corrector, branch, condition,
@@ -673,26 +664,6 @@ module RuboCop
673
664
  end
674
665
  end
675
666
  end
676
-
677
- # Corrector to correct conditional assignment in `unless` statements.
678
- class UnlessCorrector
679
- class << self
680
- include ConditionalAssignmentHelper
681
- include ConditionalCorrectorHelper
682
-
683
- def correct(cop, node)
684
- ->(corrector) { correct_if_branches(corrector, cop, node) }
685
- end
686
-
687
- private
688
-
689
- def extract_tail_branches(node)
690
- _condition, else_branch, if_branch = *node
691
-
692
- [tail(if_branch), [], tail(else_branch)]
693
- end
694
- end
695
- end
696
667
  end
697
668
  end
698
669
  end
@@ -33,17 +33,13 @@ module RuboCop
33
33
  def_node_search :outer_module, '(const (const nil? _) _)'
34
34
 
35
35
  def on_class(node)
36
- _, _, body = *node
36
+ return unless node.body
37
37
 
38
- return unless body
39
-
40
- check(node, body, :class)
38
+ check(node, node.body, :class)
41
39
  end
42
40
 
43
41
  def on_module(node)
44
- _, body = *node
45
-
46
- check(node, body, :module)
42
+ check(node, node.body, :module)
47
43
  end
48
44
 
49
45
  private
@@ -71,7 +71,7 @@ module RuboCop
71
71
 
72
72
  def autocorrect(node)
73
73
  lambda do |corrector|
74
- _receiver, detected_method = *node
74
+ detected_method = node.method_name
75
75
 
76
76
  case detected_method
77
77
  when :%
@@ -90,32 +90,29 @@ module RuboCop
90
90
  private
91
91
 
92
92
  def autocorrect_from_percent(corrector, node)
93
- receiver, _method, args = *node
94
- format = receiver.source
95
- args = if args.array_type? || args.hash_type?
96
- args.children.map(&:source).join(', ')
93
+ args = if %i[array hash].include?(node.first_argument.type)
94
+ node.first_argument.children.map(&:source).join(', ')
97
95
  else
98
- args.source
96
+ node.first_argument.source
99
97
  end
100
- corrected = "#{style}(#{format}, #{args})"
98
+
99
+ corrected = "#{style}(#{node.receiver.source}, #{args})"
100
+
101
101
  corrector.replace(node.loc.expression, corrected)
102
102
  end
103
103
 
104
104
  def autocorrect_to_percent(corrector, node)
105
- _nil, _method, format, *args = *node
106
- format = format.source
107
- args = if args.one?
108
- arg = args.first
109
- if arg.hash_type?
110
- "{ #{arg.source} }"
111
- else
112
- arg.source
113
- end
114
- else
115
- "[#{args.map(&:source).join(', ')}]"
116
- end
117
- corrected = "#{format} % #{args}"
118
- corrector.replace(node.loc.expression, corrected)
105
+ format = node.first_argument.source
106
+
107
+ args = if node.arguments.size == 2
108
+ arg = node.arguments.last
109
+
110
+ arg.hash_type? ? "{ #{arg.source} }" : arg.source
111
+ else
112
+ "[#{node.arguments[1..-1].map(&:source).join(', ')}]"
113
+ end
114
+
115
+ corrector.replace(node.loc.expression, "#{format} % #{args}")
119
116
  end
120
117
  end
121
118
  end
@@ -132,7 +132,7 @@ module RuboCop
132
132
  end
133
133
 
134
134
  def word_symbol_pair?(pair)
135
- return false unless pair.key.sym_type?
135
+ return false unless pair.key.sym_type? || pair.key.dsym_type?
136
136
 
137
137
  acceptable_19_syntax_symbol?(pair.key.source)
138
138
  end
@@ -37,6 +37,10 @@ module RuboCop
37
37
  NEGATED_EQUALITY_METHODS = %i[!= !~].freeze
38
38
  CAMEL_CASE = /[A-Z]+[a-z]+/.freeze
39
39
 
40
+ def self.autocorrect_incompatible_with
41
+ [Style::Not]
42
+ end
43
+
40
44
  def_node_matcher :inverse_candidate?, <<-PATTERN
41
45
  {
42
46
  (send $(send $(...) $_ $...) :!)
@@ -110,14 +110,18 @@ module RuboCop
110
110
  end
111
111
 
112
112
  def autocorrect_method_to_literal(corrector, node)
113
- block_method, args = *node
114
- corrector.replace(block_method.source_range, '->')
115
- return if args.children.empty?
116
-
117
- arg_str = "(#{lambda_arg_string(args)})"
118
- whitespace_and_old_args = node.loc.begin.end.join(args.loc.end)
119
- corrector.insert_after(block_method.source_range, arg_str)
120
- corrector.remove(whitespace_and_old_args)
113
+ corrector.replace(node.send_node.source_range, '->')
114
+
115
+ return unless node.arguments?
116
+
117
+ arg_str = "(#{lambda_arg_string(node.arguments)})"
118
+
119
+ corrector.insert_after(node.send_node.source_range, arg_str)
120
+ corrector.remove(arguments_with_whitespace(node))
121
+ end
122
+
123
+ def arguments_with_whitespace(node)
124
+ node.loc.begin.end.join(node.arguments.loc.end)
121
125
  end
122
126
 
123
127
  def lambda_arg_string(args)
@@ -123,22 +123,20 @@ module RuboCop
123
123
  end
124
124
 
125
125
  def separate_mixins(node)
126
- _receiver, mixin, *args = *node
127
- args.reverse!
128
- first_mixin = String.new("#{mixin} #{args.first.source}")
126
+ arguments = node.arguments.reverse
127
+ mixins = ["#{node.method_name} #{arguments.first.source}"]
129
128
 
130
- args[1..-1].inject(first_mixin) do |replacement, arg|
131
- replacement << "\n#{indent(node)}#{mixin} #{arg.source}"
132
- end
129
+ arguments[1..-1].inject(mixins) do |replacement, arg|
130
+ replacement << "#{indent(node)}#{node.method_name} #{arg.source}"
131
+ end.join("\n")
133
132
  end
134
133
 
135
134
  def group_mixins(node, mixins)
136
- _receiver, mixin, *_args = *node
137
- all_mixin_arguments = mixins.reverse.flat_map do |m|
138
- m.arguments.map(&:source)
135
+ mixin_names = mixins.reverse.flat_map do |mixin|
136
+ mixin.arguments.map(&:source)
139
137
  end
140
138
 
141
- "#{mixin} #{all_mixin_arguments.join(', ')}"
139
+ "#{node.method_name} #{mixin_names.join(', ')}"
142
140
  end
143
141
 
144
142
  def indent(node)
@@ -61,10 +61,9 @@ module RuboCop
61
61
  def_node_matcher :private_directive?, '(send nil? :private ...)'
62
62
 
63
63
  def on_module(node)
64
- _name, body = *node
65
- return unless body && body.begin_type?
64
+ return unless node.body && node.body.begin_type?
66
65
 
67
- each_wrong_style(body.children) do |child_node|
66
+ each_wrong_style(node.body.children) do |child_node|
68
67
  add_offense(child_node)
69
68
  end
70
69
  end
@@ -132,42 +132,38 @@ module RuboCop
132
132
 
133
133
  def offense_node(body)
134
134
  *_, condition = *body
135
+
135
136
  condition && condition.if_type? ? condition : body
136
137
  end
137
138
 
138
139
  def offense_location(offense_node)
139
- condition_expression, = *offense_node
140
140
  offense_begin_pos = offense_node.source_range.begin
141
- offense_begin_pos.join(condition_expression.source_range)
141
+ offense_begin_pos.join(offense_node.condition.source_range)
142
142
  end
143
143
 
144
144
  def autocorrect_modifier(corrector, node)
145
- cond, if_body, else_body = *node
146
- body = if_body || else_body
145
+ body = node.if_branch || node.else_branch
147
146
 
148
- replacement = "next #{opposite_kw(if_body)} #{cond.source}\n" \
149
- "#{' ' * node.source_range.column}#{body.source}"
147
+ replacement =
148
+ "next #{node.inverse_keyword} #{node.condition.source}\n" \
149
+ "#{' ' * node.source_range.column}#{body.source}"
150
150
 
151
151
  corrector.replace(node.source_range, replacement)
152
152
  end
153
153
 
154
154
  def autocorrect_block(corrector, node)
155
- cond, if_body, = *node
155
+ next_code = "next #{node.inverse_keyword} #{node.condition.source}"
156
156
 
157
- next_code = "next #{opposite_kw(if_body)} #{cond.source}"
158
157
  corrector.insert_before(node.source_range, next_code)
159
158
 
160
- corrector.remove(cond_range(node, cond))
159
+ corrector.remove(cond_range(node, node.condition))
161
160
  corrector.remove(end_range(node))
162
161
 
163
162
  lines = reindentable_lines(node)
164
- return if lines.empty?
165
163
 
166
- reindent(lines, cond, corrector)
167
- end
164
+ return if lines.empty?
168
165
 
169
- def opposite_kw(if_body)
170
- if_body.nil? ? 'if' : 'unless'
166
+ reindent(lines, node.condition, corrector)
171
167
  end
172
168
 
173
169
  def cond_range(node, cond)
@@ -61,9 +61,11 @@ module RuboCop
61
61
  end
62
62
 
63
63
  def to_ternary(node)
64
- cond, body, else_clause = *node
65
- "#{expr_replacement(cond)} ? #{expr_replacement(body)} : " \
66
- "#{expr_replacement(else_clause)}"
64
+ condition, if_branch, else_branch = *node
65
+
66
+ "#{expr_replacement(condition)} ? " \
67
+ "#{expr_replacement(if_branch)} : " \
68
+ "#{expr_replacement(else_branch)}"
67
69
  end
68
70
 
69
71
  def expr_replacement(node)
@@ -22,10 +22,7 @@ module RuboCop
22
22
  'of the argument list.'.freeze
23
23
 
24
24
  def on_def(node)
25
- _method, arguments, = *node
26
- arguments = *arguments
27
-
28
- each_misplaced_optional_arg(arguments) do |argument|
25
+ each_misplaced_optional_arg(node.arguments) do |argument|
29
26
  add_offense(argument)
30
27
  end
31
28
  end
@@ -80,81 +80,78 @@ module RuboCop
80
80
 
81
81
  private
82
82
 
83
- def corrected_integer_op_rand(node)
84
- left, operator, right = *node
85
-
86
- offset = int_from_int_node(left)
83
+ def_node_matcher :random_call, <<-PATTERN
84
+ {(send (send $_ _ $_) ...)
85
+ (send _ _ (send $_ _ $_))}
86
+ PATTERN
87
87
 
88
- prefix_node, _, random_node = *right
88
+ def corrected_integer_op_rand(node)
89
+ random_call(node) do |prefix_node, random_node|
90
+ prefix = prefix_from_prefix_node(prefix_node)
91
+ left_int, right_int = boundaries_from_random_node(random_node)
89
92
 
90
- prefix = prefix_from_prefix_node(prefix_node)
91
- left_int, right_int = boundaries_from_random_node(random_node)
93
+ offset = to_int(node.receiver)
92
94
 
93
- if operator == :+
94
- "#{prefix}(#{offset + left_int}..#{offset + right_int})"
95
- else
96
- "#{prefix}(#{offset - right_int}..#{offset - left_int})"
95
+ if node.method?(:+)
96
+ "#{prefix}(#{offset + left_int}..#{offset + right_int})"
97
+ else
98
+ "#{prefix}(#{offset - right_int}..#{offset - left_int})"
99
+ end
97
100
  end
98
101
  end
99
102
 
100
103
  def corrected_rand_op_integer(node)
101
- left, operator, right = *node
102
-
103
- prefix_node, _, random_node = *left
104
+ random_call(node) do |prefix_node, random_node|
105
+ prefix = prefix_from_prefix_node(prefix_node)
106
+ left_int, right_int = boundaries_from_random_node(random_node)
104
107
 
105
- offset = int_from_int_node(right)
108
+ offset = to_int(node.first_argument)
106
109
 
107
- prefix = prefix_from_prefix_node(prefix_node)
108
- left_int, right_int = boundaries_from_random_node(random_node)
109
-
110
- if operator == :+
111
- "#{prefix}(#{left_int + offset}..#{right_int + offset})"
112
- else
113
- "#{prefix}(#{left_int - offset}..#{right_int - offset})"
110
+ if node.method?(:+)
111
+ "#{prefix}(#{left_int + offset}..#{right_int + offset})"
112
+ else
113
+ "#{prefix}(#{left_int - offset}..#{right_int - offset})"
114
+ end
114
115
  end
115
116
  end
116
117
 
117
118
  def corrected_rand_modified(node)
118
- rand, method = *node
119
- prefix_node, _, random_node = *rand
120
-
121
- prefix = prefix_from_prefix_node(prefix_node)
122
- left_int, right_int = boundaries_from_random_node(random_node)
123
-
124
- if %i[succ next].include?(method)
125
- "#{prefix}(#{left_int + 1}..#{right_int + 1})"
126
- elsif method == :pred
127
- "#{prefix}(#{left_int - 1}..#{right_int - 1})"
119
+ random_call(node) do |prefix_node, random_node|
120
+ prefix = prefix_from_prefix_node(prefix_node)
121
+ left_int, right_int = boundaries_from_random_node(random_node)
122
+
123
+ if %i[succ next].include?(node.method_name)
124
+ "#{prefix}(#{left_int + 1}..#{right_int + 1})"
125
+ elsif node.method?(:pred)
126
+ "#{prefix}(#{left_int - 1}..#{right_int - 1})"
127
+ end
128
128
  end
129
129
  end
130
130
 
131
+ def_node_matcher :namespace, <<-PATTERN
132
+ {$nil? (const nil? $_)}
133
+ PATTERN
134
+
131
135
  def prefix_from_prefix_node(node)
132
- if node.nil?
133
- 'rand'
134
- else
135
- _, prefix = *node
136
- "#{prefix}.rand"
136
+ namespace(node) do |namespace|
137
+ [namespace, 'rand'].compact.join('.')
137
138
  end
138
139
  end
139
140
 
140
141
  def boundaries_from_random_node(random_node)
141
- children = random_node.children
142
-
143
142
  case random_node.type
144
143
  when :int
145
- [0, int_from_int_node(random_node) - 1]
144
+ [0, to_int(random_node) - 1]
146
145
  when :irange
147
- [int_from_int_node(children.first),
148
- int_from_int_node(children[1])]
146
+ [to_int(random_node.begin), to_int(random_node.end)]
149
147
  when :erange
150
- [int_from_int_node(children.first),
151
- int_from_int_node(children[1]) - 1]
148
+ [to_int(random_node.begin), to_int(random_node.end) - 1]
152
149
  end
153
150
  end
154
151
 
155
- def int_from_int_node(node)
156
- node.children.first
157
- end
152
+ def_node_matcher :to_int, <<-PATTERN
153
+ (int $_)
154
+ PATTERN
158
155
  end
159
156
  end
160
157
  end