Skip to content

Commit a71cf6a

Browse files
committed
Import new TruffleRuby/ReplaceWithPrimitiveTrueAndFalsePredicates Rubocop cop
1 parent 9ae1528 commit a71cf6a

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

.rubocop.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ require:
33
- ./tool/rubocop-truffleruby/cop/replace_with_primitive_object_class.rb
44
- ./tool/rubocop-truffleruby/cop/replace_with_primitive_object_equal.rb
55
- ./tool/rubocop-truffleruby/cop/replace_with_primitive_object_kind_of.rb
6+
- ./tool/rubocop-truffleruby/cop/replace_with_primitive_true_and_false_predicates.rb
67

78
AllCops:
89
TargetRubyVersion: 3.1
@@ -425,3 +426,10 @@ TruffleRuby/ReplaceWithPrimitiveObjectKindOf:
425426
Include: # inspect *only* these files
426427
- lib/truffle/**/*.rb
427428
- src/main/ruby/**/*.rb
429+
430+
# Supports --auto-correct
431+
TruffleRuby/ReplaceWithPrimitiveTrueAndFalsePredicates:
432+
Enabled: true
433+
Include: # inspect *only* these files
434+
- lib/truffle/**/*.rb
435+
- src/main/ruby/**/*.rb
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# frozen_string_literal: true
2+
3+
module RuboCop
4+
module Cop
5+
module TruffleRuby
6+
# Prefer `Primitive.true?` and `Primitive.false?` to check whether object
7+
# is `true` or `false`.
8+
#
9+
# @example
10+
#
11+
# # bad
12+
# foo == true
13+
# foo == false
14+
#
15+
# # bad
16+
# foo.equal?(true)
17+
# foo.equal?(false)
18+
#
19+
# # bad
20+
# Primitive.equal?(foo, true)
21+
#
22+
# # good
23+
# Primitive.true?(foo)
24+
# Primitive.false?(foo)
25+
#
26+
class ReplaceWithPrimitiveTrueAndFalsePredicates < Base
27+
extend AutoCorrector
28+
29+
MSG = 'Use `Primitive.true?` and `Primitive.false?` instead of `==` or `#equal?`'
30+
31+
RESTRICT_ON_SEND = %i[== != equal?].freeze
32+
33+
# @!method bad_core_method?(node)
34+
def_node_matcher :bad_core_method?, <<~PATTERN
35+
(send $_ ${ :== :!= :equal? } ${ true false })
36+
PATTERN
37+
38+
# @!method bad_primitive_method?(node)
39+
def_node_matcher :bad_primitive_method?, <<~PATTERN
40+
(send
41+
(const {nil? cbase} :Primitive)
42+
:equal?
43+
{
44+
$_ ${ true false }
45+
|
46+
${ true false } $_
47+
}
48+
)
49+
PATTERN
50+
51+
def on_send(node)
52+
on_bad_core_method(node) or on_bad_primitive_method(node)
53+
end
54+
55+
private
56+
57+
def on_bad_core_method(node)
58+
captures = bad_core_method?(node)
59+
return unless captures
60+
61+
add_offense(node) do |corrector|
62+
receiver, method, true_or_false = captures
63+
64+
receiver_source = receiver&.source || 'self'
65+
optional_negation = method == :!= ? '!' : ''
66+
primitive_name = true_or_false.true_type? ? :true? : :false?
67+
68+
source_string = "#{optional_negation}Primitive.#{primitive_name}(#{receiver_source})"
69+
corrector.replace(node.loc.expression, source_string)
70+
end
71+
end
72+
73+
def on_bad_primitive_method(node)
74+
captures = bad_primitive_method?(node)
75+
return unless captures
76+
77+
add_offense(node) do |corrector|
78+
true_or_false, object = captures[0].boolean_type? ? captures : captures.reverse
79+
primitive_name = true_or_false.true_type? ? :true? : :false?
80+
81+
source_string = "Primitive.#{primitive_name}(#{object.source})"
82+
corrector.replace(node.loc.expression, source_string)
83+
end
84+
end
85+
end
86+
end
87+
end
88+
end

0 commit comments

Comments
 (0)