package net.ltgt.gradle.errorprone; import static java.util.Objects.requireNonNull; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.annotation.Nullable; import org.gradle.api.Action; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.artifacts.Configuration; import org.gradle.api.tasks.TaskInputs; import org.gradle.api.tasks.compile.JavaCompile; import org.gradle.util.GradleVersion; public class ErrorPronePlugin implements Plugin<Project> { @Override public void apply(final Project project) { project.getPluginManager().apply(ErrorProneBasePlugin.class); final ErrorProneToolChain toolChain = ErrorProneToolChain.create(project); Action<JavaCompile> action = task -> { task.setToolChain(toolChain); taskGetInputsFiles(task, toolChain.getConfiguration()); }; if (GradleVersion.current().compareTo(GradleVersion.version("4.9")) >= 0) { project.getTasks().withType(JavaCompile.class).configureEach(action); } else { project.getTasks().withType(JavaCompile.class, action); } } private void taskGetInputsFiles(JavaCompile task, Configuration configuration) { try { // task.getInputs().files(configuration)… Object inputs = taskInputsFiles.invoke(taskGetInputs.invoke(task), (Object) new Object[] {configuration}); if (withNormalizer != null) { // ….withNormalizer(ClasspathNormalizer.class) withNormalizer.invoke(inputs, classpathNormalizer); } } catch (IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } } private static final Method taskGetInputs; private static final Method taskInputsFiles; private static final @Nullable Method withNormalizer; private static final @Nullable Class<?> classpathNormalizer; static { // Changed return type in Gradle 3.0 taskGetInputs = getMethod(Task.class, "getInputs"); taskInputsFiles = getMethod(TaskInputs.class, "files", Object[].class); // Only exists since Gradle 4.3 classpathNormalizer = classForName("org.gradle.api.tasks.ClasspathNormalizer"); if (classpathNormalizer != null) { // Exists since Gradle 3.1 Class<?> taskInputFilePropertyBuilder = requireNonNull(classForName("org.gradle.api.tasks.TaskInputFilePropertyBuilder")); withNormalizer = getMethod(taskInputFilePropertyBuilder, "withNormalizer", Class.class); } else { withNormalizer = null; } } private static @Nullable Class<?> classForName(String className) { try { return Class.forName(className); } catch (ClassNotFoundException e) { return null; } } private static Method getMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) { try { return clazz.getMethod(methodName, parameterTypes); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } }