rubocop 0.77.0 → 0.81.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 (129) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +3 -3
  4. data/config/default.yml +136 -60
  5. data/lib/rubocop.rb +20 -4
  6. data/lib/rubocop/ast/builder.rb +45 -42
  7. data/lib/rubocop/ast/node.rb +11 -18
  8. data/lib/rubocop/ast/node/block_node.rb +5 -1
  9. data/lib/rubocop/ast/node/case_match_node.rb +56 -0
  10. data/lib/rubocop/ast/node/def_node.rb +11 -0
  11. data/lib/rubocop/ast/node/forward_args_node.rb +18 -0
  12. data/lib/rubocop/ast/node/regexp_node.rb +2 -4
  13. data/lib/rubocop/ast/traversal.rb +29 -10
  14. data/lib/rubocop/cli/command/auto_genenerate_config.rb +7 -7
  15. data/lib/rubocop/cli/command/show_cops.rb +11 -4
  16. data/lib/rubocop/comment_config.rb +6 -1
  17. data/lib/rubocop/config.rb +28 -10
  18. data/lib/rubocop/config_loader.rb +19 -19
  19. data/lib/rubocop/config_obsoletion.rb +6 -4
  20. data/lib/rubocop/config_validator.rb +55 -95
  21. data/lib/rubocop/cop/autocorrect_logic.rb +7 -4
  22. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -2
  23. data/lib/rubocop/cop/cop.rb +3 -1
  24. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  25. data/lib/rubocop/cop/generator.rb +3 -4
  26. data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
  27. data/lib/rubocop/cop/layout/array_alignment.rb +53 -10
  28. data/lib/rubocop/cop/layout/block_end_newline.rb +5 -3
  29. data/lib/rubocop/cop/layout/else_alignment.rb +8 -0
  30. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
  31. data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -2
  32. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -4
  33. data/lib/rubocop/cop/layout/heredoc_indentation.rb +4 -4
  34. data/lib/rubocop/cop/layout/leading_comment_space.rb +33 -2
  35. data/lib/rubocop/cop/{metrics → layout}/line_length.rb +35 -79
  36. data/lib/rubocop/cop/layout/multiline_block_layout.rb +14 -5
  37. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +0 -4
  38. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
  39. data/lib/rubocop/cop/layout/space_around_operators.rb +49 -6
  40. data/lib/rubocop/cop/layout/space_before_block_braces.rb +17 -0
  41. data/lib/rubocop/cop/layout/space_before_first_arg.rb +8 -0
  42. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -9
  43. data/lib/rubocop/cop/lint/boolean_symbol.rb +12 -0
  44. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  45. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  46. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
  47. data/lib/rubocop/cop/lint/loop.rb +6 -4
  48. data/lib/rubocop/cop/lint/nested_method_definition.rb +2 -2
  49. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +89 -0
  50. data/lib/rubocop/cop/lint/raise_exception.rb +39 -0
  51. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +3 -3
  52. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +13 -8
  53. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +1 -1
  54. data/lib/rubocop/cop/lint/struct_new_override.rb +58 -0
  55. data/lib/rubocop/cop/lint/suppressed_exception.rb +12 -22
  56. data/lib/rubocop/cop/lint/unused_method_argument.rb +32 -6
  57. data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -0
  58. data/lib/rubocop/cop/migration/department_name.rb +47 -6
  59. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  60. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +4 -0
  61. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +6 -1
  62. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +7 -7
  63. data/lib/rubocop/cop/mixin/hash_transform_method.rb +171 -0
  64. data/lib/rubocop/cop/mixin/line_length_help.rb +88 -0
  65. data/lib/rubocop/cop/mixin/method_complexity.rb +5 -0
  66. data/lib/rubocop/cop/mixin/rational_literal.rb +18 -0
  67. data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -2
  68. data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -12
  69. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  70. data/lib/rubocop/cop/naming/method_name.rb +30 -0
  71. data/lib/rubocop/cop/naming/method_parameter_name.rb +1 -1
  72. data/lib/rubocop/cop/offense.rb +11 -0
  73. data/lib/rubocop/cop/registry.rb +7 -2
  74. data/lib/rubocop/cop/style/access_modifier_declarations.rb +26 -6
  75. data/lib/rubocop/cop/style/attr.rb +8 -0
  76. data/lib/rubocop/cop/style/block_delimiters.rb +60 -1
  77. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  78. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
  79. data/lib/rubocop/cop/style/documentation.rb +43 -5
  80. data/lib/rubocop/cop/style/end_block.rb +6 -0
  81. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +89 -11
  82. data/lib/rubocop/cop/style/guard_clause.rb +3 -2
  83. data/lib/rubocop/cop/style/hash_each_methods.rb +89 -0
  84. data/lib/rubocop/cop/style/hash_transform_keys.rb +83 -0
  85. data/lib/rubocop/cop/style/hash_transform_values.rb +83 -0
  86. data/lib/rubocop/cop/style/if_unless_modifier.rb +38 -3
  87. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  88. data/lib/rubocop/cop/style/inverse_methods.rb +9 -5
  89. data/lib/rubocop/cop/style/lambda.rb +1 -0
  90. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -205
  91. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +169 -0
  92. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +54 -0
  93. data/lib/rubocop/cop/style/module_function.rb +56 -10
  94. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
  95. data/lib/rubocop/cop/style/multiline_when_then.rb +5 -1
  96. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +4 -4
  97. data/lib/rubocop/cop/style/numeric_predicate.rb +4 -3
  98. data/lib/rubocop/cop/style/one_line_conditional.rb +3 -2
  99. data/lib/rubocop/cop/style/or_assignment.rb +3 -2
  100. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +7 -7
  101. data/lib/rubocop/cop/style/redundant_condition.rb +17 -4
  102. data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
  103. data/lib/rubocop/cop/style/symbol_array.rb +2 -2
  104. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  105. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +34 -22
  106. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +41 -0
  107. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +85 -0
  108. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +44 -0
  109. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +7 -1
  110. data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
  111. data/lib/rubocop/cop/style/yoda_condition.rb +16 -1
  112. data/lib/rubocop/cop/variable_force.rb +4 -1
  113. data/lib/rubocop/formatter/base_formatter.rb +2 -2
  114. data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
  115. data/lib/rubocop/formatter/formatter_set.rb +1 -0
  116. data/lib/rubocop/formatter/json_formatter.rb +6 -5
  117. data/lib/rubocop/formatter/junit_formatter.rb +74 -0
  118. data/lib/rubocop/formatter/tap_formatter.rb +1 -1
  119. data/lib/rubocop/node_pattern.rb +97 -11
  120. data/lib/rubocop/options.rb +8 -8
  121. data/lib/rubocop/processed_source.rb +1 -1
  122. data/lib/rubocop/result_cache.rb +2 -0
  123. data/lib/rubocop/rspec/shared_contexts.rb +5 -0
  124. data/lib/rubocop/runner.rb +5 -1
  125. data/lib/rubocop/target_ruby.rb +151 -0
  126. data/lib/rubocop/version.rb +1 -1
  127. metadata +38 -10
  128. data/lib/rubocop/cop/lint/end_in_method.rb +0 -40
  129. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +0 -209
@@ -0,0 +1,169 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ class MethodCallWithArgsParentheses
7
+ # Style omit_parentheses
8
+ module OmitParentheses
9
+ TRAILING_WHITESPACE_REGEX = /\s+\Z/.freeze
10
+
11
+ def on_send(node)
12
+ return unless node.parenthesized?
13
+ return if node.implicit_call?
14
+ return if super_call_without_arguments?(node)
15
+ return if allowed_camel_case_method_call?(node)
16
+ return if legitimate_call_with_parentheses?(node)
17
+
18
+ add_offense(node, location: node.loc.begin.join(node.loc.end))
19
+ end
20
+ alias on_csend on_send
21
+ alias on_super on_send
22
+ alias on_yield on_send
23
+
24
+ def autocorrect(node)
25
+ lambda do |corrector|
26
+ if parentheses_at_the_end_of_multiline_call?(node)
27
+ corrector.replace(args_begin(node), ' \\')
28
+ else
29
+ corrector.replace(args_begin(node), ' ')
30
+ end
31
+ corrector.remove(node.loc.end)
32
+ end
33
+ end
34
+
35
+ def message(_node = nil)
36
+ 'Omit parentheses for method calls with arguments.'
37
+ end
38
+
39
+ private
40
+
41
+ def super_call_without_arguments?(node)
42
+ node.super_type? && node.arguments.none?
43
+ end
44
+
45
+ def allowed_camel_case_method_call?(node)
46
+ node.camel_case_method? &&
47
+ (node.arguments.none? ||
48
+ cop_config['AllowParenthesesInCamelCaseMethod'])
49
+ end
50
+
51
+ def parentheses_at_the_end_of_multiline_call?(node)
52
+ node.multiline? &&
53
+ node.loc.begin.source_line
54
+ .gsub(TRAILING_WHITESPACE_REGEX, '')
55
+ .end_with?('(')
56
+ end
57
+
58
+ def legitimate_call_with_parentheses?(node)
59
+ call_in_literals?(node) ||
60
+ call_with_ambiguous_arguments?(node) ||
61
+ call_in_logical_operators?(node) ||
62
+ call_in_optional_arguments?(node) ||
63
+ allowed_multiline_call_with_parentheses?(node) ||
64
+ allowed_chained_call_with_parentheses?(node)
65
+ end
66
+
67
+ def call_in_literals?(node)
68
+ node.parent &&
69
+ (node.parent.pair_type? ||
70
+ node.parent.array_type? ||
71
+ node.parent.range_type? ||
72
+ splat?(node.parent) ||
73
+ ternary_if?(node.parent))
74
+ end
75
+
76
+ def call_in_logical_operators?(node)
77
+ parent = node.parent&.block_type? ? node.parent.parent : node.parent
78
+ parent &&
79
+ (logical_operator?(parent) ||
80
+ parent.send_type? &&
81
+ parent.arguments.any?(&method(:logical_operator?)))
82
+ end
83
+
84
+ def call_in_optional_arguments?(node)
85
+ node.parent &&
86
+ (node.parent.optarg_type? || node.parent.kwoptarg_type?)
87
+ end
88
+
89
+ def call_with_ambiguous_arguments?(node)
90
+ call_with_braced_block?(node) ||
91
+ call_as_argument_or_chain?(node) ||
92
+ hash_literal_in_arguments?(node) ||
93
+ node.descendants.any? do |n|
94
+ ambigious_literal?(n) || logical_operator?(n) ||
95
+ call_with_braced_block?(n)
96
+ end
97
+ end
98
+
99
+ def call_with_braced_block?(node)
100
+ (node.send_type? || node.super_type?) &&
101
+ node.block_node && node.block_node.braces?
102
+ end
103
+
104
+ def call_as_argument_or_chain?(node)
105
+ node.parent &&
106
+ (node.parent.send_type? && !assigned_before?(node.parent, node) ||
107
+ node.parent.csend_type? || node.parent.super_type?)
108
+ end
109
+
110
+ def hash_literal_in_arguments?(node)
111
+ node.arguments.any? do |n|
112
+ hash_literal?(n) ||
113
+ n.send_type? && node.descendants.any?(&method(:hash_literal?))
114
+ end
115
+ end
116
+
117
+ def allowed_multiline_call_with_parentheses?(node)
118
+ cop_config['AllowParenthesesInMultilineCall'] && node.multiline?
119
+ end
120
+
121
+ def allowed_chained_call_with_parentheses?(node)
122
+ return false unless cop_config['AllowParenthesesInChaining']
123
+
124
+ previous = node.descendants.first
125
+ return false unless previous&.send_type?
126
+
127
+ previous.parenthesized? ||
128
+ allowed_chained_call_with_parentheses?(previous)
129
+ end
130
+
131
+ def ambigious_literal?(node)
132
+ splat?(node) || ternary_if?(node) || regexp_slash_literal?(node) ||
133
+ unary_literal?(node)
134
+ end
135
+
136
+ def splat?(node)
137
+ node.splat_type? || node.kwsplat_type? || node.block_pass_type?
138
+ end
139
+
140
+ def ternary_if?(node)
141
+ node.if_type? && node.ternary?
142
+ end
143
+
144
+ def logical_operator?(node)
145
+ (node.and_type? || node.or_type?) && node.logical_operator?
146
+ end
147
+
148
+ def hash_literal?(node)
149
+ node.hash_type? && node.braces?
150
+ end
151
+
152
+ def regexp_slash_literal?(node)
153
+ node.regexp_type? && node.loc.begin.source == '/'
154
+ end
155
+
156
+ def unary_literal?(node)
157
+ node.numeric_type? && node.sign? ||
158
+ node.parent&.send_type? && node.parent&.unary_operation?
159
+ end
160
+
161
+ def assigned_before?(node, target)
162
+ node.assignment? &&
163
+ node.loc.operator.begin < target.loc.begin
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ class MethodCallWithArgsParentheses
7
+ # Style require_parentheses
8
+ module RequireParentheses
9
+ def on_send(node)
10
+ return if ignored_method?(node.method_name)
11
+ return if matches_ignored_pattern?(node.method_name)
12
+ return if eligible_for_parentheses_omission?(node)
13
+ return unless node.arguments? && !node.parenthesized?
14
+
15
+ add_offense(node)
16
+ end
17
+ alias on_csend on_send
18
+ alias on_super on_send
19
+ alias on_yield on_send
20
+
21
+ def autocorrect(node)
22
+ lambda do |corrector|
23
+ corrector.replace(args_begin(node), '(')
24
+
25
+ unless args_parenthesized?(node)
26
+ corrector.insert_after(args_end(node), ')')
27
+ end
28
+ end
29
+ end
30
+
31
+ def message(_node = nil)
32
+ 'Use parentheses for method calls with arguments.'
33
+ end
34
+
35
+ private
36
+
37
+ def eligible_for_parentheses_omission?(node)
38
+ node.operator_method? || node.setter_method? || ignored_macro?(node)
39
+ end
40
+
41
+ def included_macros_list
42
+ cop_config.fetch('IncludedMacros', []).map(&:to_sym)
43
+ end
44
+
45
+ def ignored_macro?(node)
46
+ cop_config['IgnoreMacros'] &&
47
+ node.macro? &&
48
+ !included_macros_list.include?(node.method_name)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -6,7 +6,7 @@ module RuboCop
6
6
  # This cop checks for use of `extend self` or `module_function` in a
7
7
  # module.
8
8
  #
9
- # Supported styles are: module_function, extend_self.
9
+ # Supported styles are: module_function, extend_self, forbidden.
10
10
  #
11
11
  # @example EnforcedStyle: module_function (default)
12
12
  # # bad
@@ -46,6 +46,29 @@ module RuboCop
46
46
  # # ...
47
47
  # end
48
48
  #
49
+ # The option `forbidden` prohibits the usage of both styles.
50
+ #
51
+ # @example EnforcedStyle: forbidden
52
+ # # bad
53
+ # module Test
54
+ # module_function
55
+ # # ...
56
+ # end
57
+ #
58
+ # # bad
59
+ # module Test
60
+ # extend self
61
+ # # ...
62
+ # end
63
+ #
64
+ # # bad
65
+ # module Test
66
+ # extend self
67
+ # # ...
68
+ # private
69
+ # # ...
70
+ # end
71
+ #
49
72
  # These offenses are not safe to auto-correct since there are different
50
73
  # implications to each approach.
51
74
  class ModuleFunction < Cop
@@ -55,6 +78,8 @@ module RuboCop
55
78
  'Use `module_function` instead of `extend self`.'
56
79
  EXTEND_SELF_MSG =
57
80
  'Use `extend self` instead of `module_function`.'
81
+ FORBIDDEN_MSG =
82
+ 'Do not use `module_function` or `extend self`.'
58
83
 
59
84
  def_node_matcher :module_function_node?, '(send nil? :module_function)'
60
85
  def_node_matcher :extend_self_node?, '(send nil? :extend self)'
@@ -69,6 +94,8 @@ module RuboCop
69
94
  end
70
95
 
71
96
  def autocorrect(node)
97
+ return if style == :forbidden
98
+
72
99
  lambda do |corrector|
73
100
  if extend_self_node?(node)
74
101
  corrector.replace(node.source_range, 'module_function')
@@ -80,22 +107,41 @@ module RuboCop
80
107
 
81
108
  private
82
109
 
83
- def each_wrong_style(nodes)
110
+ def each_wrong_style(nodes, &block)
84
111
  case style
85
112
  when :module_function
86
- private_directive = nodes.any? { |node| private_directive?(node) }
87
-
88
- nodes.each do |node|
89
- yield node if extend_self_node?(node) && !private_directive
90
- end
113
+ check_module_function(nodes, &block)
91
114
  when :extend_self
92
- nodes.each do |node|
93
- yield node if module_function_node?(node)
94
- end
115
+ check_extend_self(nodes, &block)
116
+ when :forbidden
117
+ check_forbidden(nodes, &block)
118
+ end
119
+ end
120
+
121
+ def check_module_function(nodes)
122
+ private_directive = nodes.any? { |node| private_directive?(node) }
123
+
124
+ nodes.each do |node|
125
+ yield node if extend_self_node?(node) && !private_directive
126
+ end
127
+ end
128
+
129
+ def check_extend_self(nodes)
130
+ nodes.each do |node|
131
+ yield node if module_function_node?(node)
132
+ end
133
+ end
134
+
135
+ def check_forbidden(nodes)
136
+ nodes.each do |node|
137
+ yield node if extend_self_node?(node)
138
+ yield node if module_function_node?(node)
95
139
  end
96
140
  end
97
141
 
98
142
  def message(_node)
143
+ return FORBIDDEN_MSG if style == :forbidden
144
+
99
145
  style == :module_function ? MODULE_FUNCTION_MSG : EXTEND_SELF_MSG
100
146
  end
101
147
  end
@@ -53,7 +53,7 @@ module RuboCop
53
53
  end
54
54
 
55
55
  def max_line_length
56
- config.for_cop('Metrics/LineLength')['Max'] || 80
56
+ config.for_cop('Layout/LineLength')['Max'] || 80
57
57
  end
58
58
  end
59
59
  end
@@ -35,7 +35,7 @@ module RuboCop
35
35
  return if !node.children.last.nil? && !node.multiline? && node.then?
36
36
 
37
37
  # With more than one statements after then, there's not offense
38
- return if node.children.last&.begin_type?
38
+ return if accept_node_type?(node.body)
39
39
 
40
40
  add_offense(node, location: :begin)
41
41
  end
@@ -49,6 +49,10 @@ module RuboCop
49
49
  )
50
50
  end
51
51
  end
52
+
53
+ def accept_node_type?(node)
54
+ node&.begin_type? || node&.array_type? || node&.hash_type?
55
+ end
52
56
  end
53
57
  end
54
58
  end
@@ -8,10 +8,10 @@ module RuboCop
8
8
  #
9
9
  # @example
10
10
  # # good
11
- # method1(method2(arg), method3(arg))
11
+ # method1(method2(arg))
12
12
  #
13
13
  # # bad
14
- # method1(method2 arg, method3, arg)
14
+ # method1(method2 arg)
15
15
  class NestedParenthesizedCalls < Cop
16
16
  include RangeHelp
17
17
 
@@ -35,8 +35,8 @@ module RuboCop
35
35
  last_arg = nested.last_argument.source_range
36
36
 
37
37
  leading_space =
38
- range_with_surrounding_space(range: first_arg,
39
- side: :left).begin.resize(1)
38
+ range_with_surrounding_space(range: first_arg.begin,
39
+ side: :left)
40
40
 
41
41
  lambda do |corrector|
42
42
  corrector.replace(leading_space, '(')
@@ -54,9 +54,10 @@ module RuboCop
54
54
  }.freeze
55
55
 
56
56
  def on_send(node)
57
- return if node.each_ancestor(:send, :block).any? do |ancestor|
58
- ignored_method?(ancestor.method_name)
59
- end
57
+ return if ignored_method?(node.method_name) ||
58
+ node.each_ancestor(:send, :block).any? do |ancestor|
59
+ ignored_method?(ancestor.method_name)
60
+ end
60
61
 
61
62
  numeric, replacement = check(node)
62
63
 
@@ -91,9 +91,10 @@ module RuboCop
91
91
 
92
92
  def keyword_with_changed_precedence?(node)
93
93
  return false unless node.keyword?
94
- return true if node.prefix_not?
94
+ return true if node.respond_to?(:prefix_not?) && node.prefix_not?
95
95
 
96
- node.arguments? && !node.parenthesized_call?
96
+ node.respond_to?(:arguments?) && node.arguments? &&
97
+ !node.parenthesized_call?
97
98
  end
98
99
  end
99
100
  end
@@ -34,7 +34,7 @@ module RuboCop
34
34
  (if
35
35
  ({lvar ivar cvar gvar} _var)
36
36
  ({lvar ivar cvar gvar} _var)
37
- _))
37
+ $_))
38
38
  PATTERN
39
39
 
40
40
  def_node_matcher :unless_assignment?, <<~PATTERN
@@ -51,7 +51,8 @@ module RuboCop
51
51
  end
52
52
 
53
53
  def on_lvasgn(node)
54
- return unless ternary_assignment?(node)
54
+ return unless (else_branch = ternary_assignment?(node))
55
+ return if else_branch.if_type?
55
56
 
56
57
  add_offense(node)
57
58
  end
@@ -88,27 +88,27 @@ module RuboCop
88
88
  end
89
89
 
90
90
  def contains_preferred_delimiter?(node, type)
91
- preferred_delimiters = preferred_delimiters_for(type)
92
- node
93
- .children.map { |n| string_source(n) }.compact
94
- .any? { |s| preferred_delimiters.any? { |d| s.include?(d) } }
91
+ contains_delimiter?(node, preferred_delimiters_for(type))
95
92
  end
96
93
 
97
94
  def include_same_character_as_used_for_delimiter?(node, type)
98
95
  return false unless %w[%w %i].include?(type)
99
96
 
100
97
  used_delimiters = matchpairs(begin_source(node)[-1])
101
- escaped_delimiters = used_delimiters.map { |d| "\\#{d}" }.join('|')
98
+ contains_delimiter?(node, used_delimiters)
99
+ end
102
100
 
101
+ def contains_delimiter?(node, delimiters)
102
+ delimiters_regexp = Regexp.union(delimiters)
103
103
  node
104
104
  .children.map { |n| string_source(n) }.compact
105
- .any? { |s| Regexp.new(escaped_delimiters) =~ s }
105
+ .any? { |s| delimiters_regexp =~ s }
106
106
  end
107
107
 
108
108
  def string_source(node)
109
109
  if node.is_a?(String)
110
110
  node
111
- elsif node.respond_to?(:type) && node.str_type?
111
+ elsif node.respond_to?(:type) && (node.str_type? || node.sym_type?)
112
112
  node.source
113
113
  end
114
114
  end