diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ClassRules.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ClassRules.java new file mode 100644 index 00000000000..2890dd1b9f4 --- /dev/null +++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ClassRules.java @@ -0,0 +1,65 @@ +package tech.picnic.errorprone.refasterrules; + +import com.google.errorprone.refaster.Refaster; +import com.google.errorprone.refaster.annotation.AfterTemplate; +import com.google.errorprone.refaster.annotation.BeforeTemplate; +import java.util.function.Predicate; +import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation; + +/** Refaster rules related to expressions dealing with classes. */ +@OnlineDocumentation +final class ClassRules { + private ClassRules() {} + + /** Prefer {@link Class#isInstance(Object)} over more contrived alternatives. */ + static final class ClassIsInstance { + @BeforeTemplate + boolean before(Class clazz, S object) { + return clazz.isAssignableFrom(object.getClass()); + } + + @AfterTemplate + boolean after(Class clazz, S object) { + return clazz.isInstance(object); + } + } + + /** Prefer using the {@code instanceof} keyword over less idiomatic alternatives. */ + static final class Instanceof { + @BeforeTemplate + boolean before(S object) { + return Refaster.clazz().isInstance(object); + } + + @AfterTemplate + boolean after(S object) { + return Refaster.isInstance(object); + } + } + + /** Prefer {@link Class#isInstance(Object)} method references over more verbose alternatives. */ + static final class ClassLiteralIsInstancePredicate { + @BeforeTemplate + Predicate before() { + return o -> Refaster.isInstance(o); + } + + @AfterTemplate + Predicate after() { + return Refaster.clazz()::isInstance; + } + } + + /** Prefer {@link Class#isInstance(Object)} method references over more verbose alternatives. */ + static final class ClassReferenceIsInstancePredicate { + @BeforeTemplate + Predicate before(Class clazz) { + return o -> clazz.isInstance(o); + } + + @AfterTemplate + Predicate after(Class clazz) { + return clazz::isInstance; + } + } +} diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ClassRulesTestInput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ClassRulesTestInput.java new file mode 100644 index 00000000000..d59e3e18d28 --- /dev/null +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ClassRulesTestInput.java @@ -0,0 +1,25 @@ +package tech.picnic.errorprone.refasterrules; + +import com.google.common.collect.ImmutableSet; +import java.io.IOException; +import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase; + +final class ClassRulesTest implements RefasterRuleCollectionTestCase { + boolean testClassIsInstance() throws IOException { + return CharSequence.class.isAssignableFrom("foo".getClass()); + } + + ImmutableSet testInstanceof() throws IOException { + Class clazz = CharSequence.class; + return ImmutableSet.of(CharSequence.class.isInstance("foo"), clazz.isInstance("bar")); + } + + Predicate testClassLiteralIsInstancePredicate() throws IOException { + return s -> s instanceof CharSequence; + } + + Predicate testClassReferenceIsInstancePredicate() throws IOException { + Class clazz = CharSequence.class; + return s -> clazz.isInstance(s); + } +} diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ClassRulesTestOutput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ClassRulesTestOutput.java new file mode 100644 index 00000000000..548fa314394 --- /dev/null +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ClassRulesTestOutput.java @@ -0,0 +1,25 @@ +package tech.picnic.errorprone.refasterrules; + +import com.google.common.collect.ImmutableSet; +import java.io.IOException; +import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase; + +final class ClassRulesTest implements RefasterRuleCollectionTestCase { + boolean testClassIsInstance() throws IOException { + return CharSequence.class.isInstance("foo"); + } + + ImmutableSet testInstanceof() throws IOException { + Class clazz = CharSequence.class; + return ImmutableSet.of("foo" instanceof CharSequence, clazz.isInstance("bar")); + } + + Predicate testClassLiteralIsInstancePredicate() throws IOException { + return CharSequence.class::isInstance; + } + + Predicate testClassReferenceIsInstancePredicate() throws IOException { + Class clazz = CharSequence.class; + return clazz::isInstance; + } +}