Skip to content

Commit

Permalink
Introduce Class{Literal,Reference}Cast Refaster rules (#1269)
Browse files Browse the repository at this point in the history
  • Loading branch information
mohamedsamehsalah authored Aug 11, 2024
1 parent 366cdda commit 3d9aab7
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.util.function.Function;
import java.util.function.Predicate;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;

Expand Down Expand Up @@ -37,7 +38,12 @@ boolean after(S object) {
}
}

/** Prefer {@link Class#isInstance(Object)} method references over more verbose alternatives. */
/**
* Prefer {@link Class#isInstance(Object)} method references over lambda expressions that require
* naming a variable.
*/
// XXX: Once the `ClassReferenceIsInstancePredicate` rule is dropped, rename this rule to just
// `ClassIsInstancePredicate`.
static final class ClassLiteralIsInstancePredicate<T, S> {
@BeforeTemplate
Predicate<S> before() {
Expand All @@ -50,7 +56,11 @@ Predicate<S> after() {
}
}

/** Prefer {@link Class#isInstance(Object)} method references over more verbose alternatives. */
/**
* Prefer {@link Class#isInstance(Object)} method references over lambda expressions that require
* naming a variable.
*/
// XXX: Drop this rule once the `MethodReferenceUsage` rule is enabled by default.
static final class ClassReferenceIsInstancePredicate<T, S> {
@BeforeTemplate
Predicate<S> before(Class<T> clazz) {
Expand All @@ -62,4 +72,39 @@ Predicate<S> after(Class<T> clazz) {
return clazz::isInstance;
}
}

/**
* Prefer {@link Class#cast(Object)} method references over lambda expressions that require naming
* a variable.
*/
// XXX: Once the `ClassReferenceCast` rule is dropped, rename this rule to just `ClassCast`.
static final class ClassLiteralCast<T, S> {
@BeforeTemplate
@SuppressWarnings("unchecked")
Function<T, S> before() {
return t -> (S) t;
}

@AfterTemplate
Function<T, S> after() {
return Refaster.<S>clazz()::cast;
}
}

/**
* Prefer {@link Class#cast(Object)} method references over lambda expressions that require naming
* a variable.
*/
// XXX: Drop this rule once the `MethodReferenceUsage` rule is enabled by default.
static final class ClassReferenceCast<T, S> {
@BeforeTemplate
Function<T, S> before(Class<? extends S> clazz) {
return o -> clazz.cast(o);
}

@AfterTemplate
Function<T, S> after(Class<? extends S> clazz) {
return clazz::cast;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
package tech.picnic.errorprone.refasterrules;

import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.util.function.Function;
import java.util.function.Predicate;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;

final class ClassRulesTest implements RefasterRuleCollectionTestCase {
boolean testClassIsInstance() throws IOException {
boolean testClassIsInstance() {
return CharSequence.class.isAssignableFrom("foo".getClass());
}

ImmutableSet<Boolean> testInstanceof() throws IOException {
ImmutableSet<Boolean> testInstanceof() {
Class<?> clazz = CharSequence.class;
return ImmutableSet.of(CharSequence.class.isInstance("foo"), clazz.isInstance("bar"));
}

Predicate<String> testClassLiteralIsInstancePredicate() throws IOException {
Predicate<String> testClassLiteralIsInstancePredicate() {
return s -> s instanceof CharSequence;
}

Predicate<String> testClassReferenceIsInstancePredicate() throws IOException {
Predicate<String> testClassReferenceIsInstancePredicate() {
Class<?> clazz = CharSequence.class;
return s -> clazz.isInstance(s);
}

Function<Number, Integer> testClassLiteralCast() {
return i -> (Integer) i;
}

Function<Number, Integer> testClassReferenceCast() {
return i -> Integer.class.cast(i);
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
package tech.picnic.errorprone.refasterrules;

import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.util.function.Function;
import java.util.function.Predicate;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;

final class ClassRulesTest implements RefasterRuleCollectionTestCase {
boolean testClassIsInstance() throws IOException {
boolean testClassIsInstance() {
return CharSequence.class.isInstance("foo");
}

ImmutableSet<Boolean> testInstanceof() throws IOException {
ImmutableSet<Boolean> testInstanceof() {
Class<?> clazz = CharSequence.class;
return ImmutableSet.of("foo" instanceof CharSequence, clazz.isInstance("bar"));
}

Predicate<String> testClassLiteralIsInstancePredicate() throws IOException {
Predicate<String> testClassLiteralIsInstancePredicate() {
return CharSequence.class::isInstance;
}

Predicate<String> testClassReferenceIsInstancePredicate() throws IOException {
Predicate<String> testClassReferenceIsInstancePredicate() {
Class<?> clazz = CharSequence.class;
return clazz::isInstance;
}

Function<Number, Integer> testClassLiteralCast() {
return Integer.class::cast;
}

Function<Number, Integer> testClassReferenceCast() {
return Integer.class::cast;
}
}

0 comments on commit 3d9aab7

Please sign in to comment.