All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tech.picnic.errorprone.refasterrules.ClassRules Maven / Gradle / Ivy

There is a newer version: 0.19.1
Show newest version
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.Function;
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 lambda expressions that require
   * naming a variable.
   */
  // XXX: Once the `ClassReferenceIsInstancePredicate` rule is dropped, rename this rule to just
  // `ClassIsInstancePredicate`.
  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 lambda expressions that require
   * naming a variable.
   */
  // XXX: Drop this rule once the `MethodReferenceUsage` rule is enabled by default.
  static final class ClassReferenceIsInstancePredicate {
    @BeforeTemplate
    Predicate before(Class clazz) {
      return o -> clazz.isInstance(o);
    }

    @AfterTemplate
    Predicate after(Class 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 {
    @BeforeTemplate
    @SuppressWarnings("unchecked")
    Function before() {
      return t -> (S) t;
    }

    @AfterTemplate
    Function after() {
      return Refaster.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 {
    @BeforeTemplate
    Function before(Class clazz) {
      return o -> clazz.cast(o);
    }

    @AfterTemplate
    Function after(Class clazz) {
      return clazz::cast;
    }
  }
}