diff --git a/subprojects/core/src/main/java/org/gradle/api/internal/tasks/compile/ApiMemberSelector.java b/subprojects/core/src/main/java/org/gradle/api/internal/tasks/compile/ApiMemberSelector.java index 8a51ae272f01..a017a11769a7 100644 --- a/subprojects/core/src/main/java/org/gradle/api/internal/tasks/compile/ApiMemberSelector.java +++ b/subprojects/core/src/main/java/org/gradle/api/internal/tasks/compile/ApiMemberSelector.java @@ -83,7 +83,7 @@ public void visitEnd() { } for (FieldMember field : fields) { FieldVisitor fieldVisitor = apiMemberAdapter.visitField( - field.getAccess(), field.getName(), field.getTypeDesc(), field.getSignature(), null); + field.getAccess(), field.getName(), field.getTypeDesc(), field.getSignature(), field.getValue()); visitAnnotationMembers(fieldVisitor, field.getAnnotations()); fieldVisitor.visitEnd(); } @@ -188,7 +188,8 @@ public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, bo @Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { if (isCandidateApiMember(access, apiIncludesPackagePrivateMembers)) { - final FieldMember fieldMember = new FieldMember(access, name, signature, desc); + Object keepValue = (access & ACC_STATIC) == ACC_STATIC && ((access & ACC_FINAL) == ACC_FINAL) ? value : null; + final FieldMember fieldMember = new FieldMember(access, name, signature, desc, keepValue); fields.add(fieldMember); return new FieldVisitor(ASM5) { @Override diff --git a/subprojects/core/src/main/java/org/gradle/api/internal/tasks/compile/FieldMember.java b/subprojects/core/src/main/java/org/gradle/api/internal/tasks/compile/FieldMember.java index 635bc1b087bc..5a18ae67ffc3 100644 --- a/subprojects/core/src/main/java/org/gradle/api/internal/tasks/compile/FieldMember.java +++ b/subprojects/core/src/main/java/org/gradle/api/internal/tasks/compile/FieldMember.java @@ -16,19 +16,23 @@ package org.gradle.api.internal.tasks.compile; +import com.google.common.collect.Ordering; import org.objectweb.asm.Type; import java.lang.reflect.Modifier; public class FieldMember extends TypedMember implements Comparable { - public FieldMember(int access, String name, String signature, String typeDesc) { + private final Object value; + + public FieldMember(int access, String name, String signature, String typeDesc, Object value) { super(access, name, signature, typeDesc); + this.value = value; } @Override public int compareTo(FieldMember o) { - return super.compare(o).result(); + return super.compare(o).compare(value, o.value, Ordering.arbitrary()).result(); } @Override @@ -36,4 +40,8 @@ public String toString() { return String.format( "%s %s %s", Modifier.toString(getAccess()), Type.getType(getTypeDesc()).getClassName(), getName()); } + + public Object getValue() { + return value; + } } diff --git a/subprojects/language-java/src/integTest/groovy/org/gradle/java/compile/incremental/AbstractCrossTaskIncrementalJavaCompilationIntegrationTest.groovy b/subprojects/language-java/src/integTest/groovy/org/gradle/java/compile/incremental/AbstractCrossTaskIncrementalJavaCompilationIntegrationTest.groovy index 3e959296d2e9..1920632807af 100644 --- a/subprojects/language-java/src/integTest/groovy/org/gradle/java/compile/incremental/AbstractCrossTaskIncrementalJavaCompilationIntegrationTest.groovy +++ b/subprojects/language-java/src/integTest/groovy/org/gradle/java/compile/incremental/AbstractCrossTaskIncrementalJavaCompilationIntegrationTest.groovy @@ -20,7 +20,9 @@ package org.gradle.java.compile.incremental import groovy.transform.NotYetImplemented import org.gradle.integtests.fixtures.AbstractIntegrationSpec import org.gradle.integtests.fixtures.CompilationOutputsFixture +import org.gradle.util.TestPrecondition import spock.lang.Issue +import spock.lang.Requires import spock.lang.Unroll abstract class AbstractCrossTaskIncrementalJavaCompilationIntegrationTest extends AbstractIntegrationSpec { @@ -650,6 +652,7 @@ abstract class AbstractCrossTaskIncrementalJavaCompilationIntegrationTest extend } @Issue("gradle/gradle#1474") + @Requires({TestPrecondition.JDK8_OR_LATER}) // todo: also fix for JDK < 8 def "recompiles dependent class in case a constant is computed from another constant"() { java api: ["class A { public static final int FOO = 10; }"], impl: ['class B { public static final int BAR = 2 + A.FOO; } '] impl.snapshot { run 'compileJava' } diff --git a/subprojects/plugins/src/integTest/groovy/org/gradle/java/compile/AbstractJavaCompileAvoidanceIntegrationSpec.groovy b/subprojects/plugins/src/integTest/groovy/org/gradle/java/compile/AbstractJavaCompileAvoidanceIntegrationSpec.groovy index 62a2b37c26e3..01df1647e016 100644 --- a/subprojects/plugins/src/integTest/groovy/org/gradle/java/compile/AbstractJavaCompileAvoidanceIntegrationSpec.groovy +++ b/subprojects/plugins/src/integTest/groovy/org/gradle/java/compile/AbstractJavaCompileAvoidanceIntegrationSpec.groovy @@ -385,6 +385,42 @@ public class ToolImpl { executedAndNotSkipped ':b:compileJava' } + def "recompiles when constant value of API changes"() { + given: + buildFile << """ + project(':b') { + dependencies { + compile project(':a') + } + } + """ + def sourceFile = file("a/src/main/java/ToolImpl.java") + sourceFile << """ + public class ToolImpl { public static final int CONST = 1; } + """ + file("b/src/main/java/Main.java") << """ + public class Main { public static final int CONST2 = 1 + ToolImpl.CONST; } + """ + + when: + succeeds ':b:compileJava' + + then: + executedAndNotSkipped ':a:compileJava' + executedAndNotSkipped ':b:compileJava' + + when: + // change to constant value + sourceFile.text = """ + public class ToolImpl { public static final int CONST = 10; } +""" + + then: + succeeds ':b:compileJava' + executedAndNotSkipped ':a:compileJava' + executedAndNotSkipped ':b:compileJava' + } + def "recompiles when generic type signatures of implementation class changes"() { given: buildFile << """