Skip to content

Commit

Permalink
Merge pull request #16066 from gradle/vv/jdk16/toolchains
Browse files Browse the repository at this point in the history
Fix incremental compilation with JDK16 using toolchains
  • Loading branch information
rieske committed Feb 11, 2021
2 parents d7577a3 + 03def01 commit f8f9f6f
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,6 @@ class JavaConventionPluginTest extends PluginTest {

then:
result.task(":build").outcome == TaskOutcome.SUCCESS
result.output.contains('warning: [deprecation] deprecatedMethod() in Foo has been deprecated')
result.output.contains('warning: [deprecation] deprecatedMethod()')
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,6 @@ class JavaConventionPluginTest : PluginTest() {
val result = runTask("build")

assertEquals(TaskOutcome.SUCCESS, result.task(":build")?.outcome)
assertTrue(result.output.contains("warning: [deprecation] deprecatedMethod() in Foo has been deprecated"))
assertTrue(result.output.contains("warning: [deprecation] deprecatedMethod()"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,6 @@ class JavaConventionPluginTest extends PluginTest {

then:
result.task(":build").outcome == TaskOutcome.SUCCESS
result.output.contains('warning: [deprecation] deprecatedMethod() in Foo has been deprecated')
result.output.contains('warning: [deprecation] deprecatedMethod()')
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,6 @@ class JavaConventionPluginTest : PluginTest() {
val result = runTask("build")

assertEquals(TaskOutcome.SUCCESS, result.task(":build")?.outcome)
assertTrue(result.output.contains("warning: [deprecation] deprecatedMethod() in Foo has been deprecated"))
assertTrue(result.output.contains("warning: [deprecation] deprecatedMethod()"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@

import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;
import com.sun.tools.javac.code.Symbol;

import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.tools.JavaFileObject;
import java.io.File;
import java.util.Collection;
Expand All @@ -34,9 +33,11 @@ public class ClassNameCollector implements TaskListener {
private final Map<File, Optional<String>> relativePaths = new HashMap<>();
private final Map<String, Collection<String>> mapping = new HashMap<>();
private final Function<File, Optional<String>> relativize;
private final Elements elements;

public ClassNameCollector(Function<File, Optional<String>> relativize) {
public ClassNameCollector(Function<File, Optional<String>> relativize, Elements elements) {
this.relativize = relativize;
this.elements = elements;
}

public Map<String, Collection<String>> getMapping() {
Expand Down Expand Up @@ -69,13 +70,7 @@ private void processSourceFile(TaskEvent e, File sourceFile) {
Optional<String> relativePath = findRelativePath(sourceFile);
if (relativePath.isPresent()) {
String key = relativePath.get();
TypeElement typeElement = e.getTypeElement();
Name name = typeElement.getQualifiedName();
if (typeElement instanceof Symbol.TypeSymbol) {
Symbol.TypeSymbol symbol = (Symbol.TypeSymbol) typeElement;
name = symbol.flatName();
}
String symbol = normalizeName(name);
String symbol = normalizeName(e.getTypeElement());
registerMapping(key, symbol);
}
}
Expand All @@ -93,10 +88,12 @@ private Optional<String> findRelativePath(File asSourceFile) {
return relativePaths.computeIfAbsent(asSourceFile, relativize);
}

private static String normalizeName(Name name) {
String symbol = name.toString();
private String normalizeName(TypeElement typeElement) {
String symbol = typeElement.getQualifiedName().toString();
if (symbol.endsWith("module-info")) {
symbol = "module-info";
} else if (typeElement.getNestingKind().isNested()) {
symbol = elements.getBinaryName(typeElement).toString();
}
return symbol;
}
Expand All @@ -110,11 +107,7 @@ private static boolean isClassGenerationPhase(TaskEvent e) {
}

public void registerMapping(String key, String symbol) {
Collection<String> symbols = mapping.get(key);
if (symbols == null) {
symbols = new TreeSet<String>();
mapping.put(key, symbols);
}
Collection<String> symbols = mapping.computeIfAbsent(key, k -> new TreeSet<>());
symbols.add(symbol);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,18 @@ public class IncrementalCompileTask implements JavaCompiler.CompilationTask {

private final Function<File, Optional<String>> relativize;
private final Consumer<Map<String, Collection<String>>> onComplete;
private final JavaCompiler.CompilationTask delegate;
private final JavacTask delegate;

public IncrementalCompileTask(JavaCompiler.CompilationTask delegate,
Function<File, Optional<String>> relativize,
Consumer<Map<String, Collection<String>>> onComplete) {
this.relativize = relativize;
this.onComplete = onComplete;
this.delegate = delegate;
if (delegate instanceof JavacTask) {
this.delegate = (JavacTask) delegate;
} else {
throw new UnsupportedOperationException("Unexpected Java compile task : " + delegate.getClass().getName());
}
}

@Override
Expand All @@ -67,16 +71,12 @@ public void setLocale(Locale locale) {

@Override
public Boolean call() {
if (delegate instanceof JavacTask) {
ClassNameCollector collector = new ClassNameCollector(relativize);
((JavacTask) delegate).addTaskListener(collector);
try {
return delegate.call();
} finally {
onComplete.accept(collector.getMapping());
}
} else {
throw new UnsupportedOperationException("Unexpected Java compile task : " + delegate.getClass().getName());
ClassNameCollector collector = new ClassNameCollector(relativize, delegate.getElements());
delegate.addTaskListener(collector);
try {
return delegate.call();
} finally {
onComplete.accept(collector.getMapping());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import org.gradle.util.Requires
import spock.lang.IgnoreIf
import spock.lang.Unroll

import static org.junit.Assume.assumeNotNull

class JavaCompileToolchainIntegrationTest extends AbstractPluginIntegrationTest {

@Unroll
Expand Down Expand Up @@ -337,11 +339,110 @@ public class Foo {
outputContains("task.targetCompatibility = $targetOut")
where:
source | target | sourceOut | targetOut
'9' | '10' | '1.9' | '1.10'
'9' | 'none' | '1.9' | '11'
'none' | 'none' | '11' | '11'
source | target | sourceOut | targetOut
'9' | '10' | '1.9' | '1.10'
'9' | 'none' | '1.9' | '11'
'none' | 'none' | '11' | '11'
}
def "can compile Java using different JDKs"() {
def jdk = AvailableJavaHomes.getJdk(javaVersion)
assumeNotNull(jdk)
buildFile << """
plugins {
id("java")
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(${jdk.javaVersion.majorVersion})
}
}
"""
file("src/main/java/Foo.java") << "public class Foo {}"
when:
runWithToolchainConfigured(jdk)
then:
outputDoesNotContain("Compiling with Java command line compiler")
outputContains("Compiling with toolchain '${jdk.javaHome.absolutePath}'.")
javaClassFile("Foo.class").exists()
where:
javaVersion << [
JavaVersion.VERSION_1_8,
JavaVersion.VERSION_1_9,
JavaVersion.VERSION_11,
JavaVersion.VERSION_12,
JavaVersion.VERSION_13,
JavaVersion.VERSION_14,
JavaVersion.VERSION_15,
JavaVersion.VERSION_16,
JavaVersion.VERSION_17
]
}
/*
This test covers the case where in Java8 the class name becomes fully qualified in the deprecation message which is
somehow caused by invoking javacTask.getElements() in the IncrementalCompileTask of the incremental compiler plugin.
*/
def "Java deprecation messages with different JDKs"() {
def jdk = AvailableJavaHomes.getJdk(javaVersion)
assumeNotNull(jdk)
buildFile << """
plugins {
id("java")
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(${jdk.javaVersion.majorVersion})
}
}
tasks.withType(JavaCompile).configureEach {
options.compilerArgs << "-Xlint:deprecation"
}
"""
file("src/main/java/com/example/Foo.java") << """
package com.example;
public class Foo {
@Deprecated
public void foo() {}
}
"""
def fileWithDeprecation = file("src/main/java/com/example/Bar.java") << """
package com.example;
public class Bar {
public void bar() {
new Foo().foo();
}
}
"""
executer.expectDeprecationWarning("$fileWithDeprecation:5: warning: $deprecationMessage");
when:
runWithToolchainConfigured(jdk)
then:
outputDoesNotContain("Compiling with Java command line compiler")
outputContains("Compiling with toolchain '${jdk.javaHome.absolutePath}'.")
javaClassFile("com/example/Foo.class").exists()
javaClassFile("com/example/Bar.class").exists()
where:
javaVersion | deprecationMessage
JavaVersion.VERSION_1_8 | "[deprecation] foo() in com.example.Foo has been deprecated"
JavaVersion.VERSION_11 | "[deprecation] foo() in Foo has been deprecated"
JavaVersion.VERSION_13 | "[deprecation] foo() in Foo has been deprecated"
JavaVersion.VERSION_14 | "[deprecation] foo() in Foo has been deprecated"
JavaVersion.VERSION_15 | "[deprecation] foo() in Foo has been deprecated"
JavaVersion.VERSION_16 | "[deprecation] foo() in Foo has been deprecated"
JavaVersion.VERSION_17 | "[deprecation] foo() in Foo has been deprecated"
}
def runWithToolchainConfigured(Jvm jvm) {
Expand Down

0 comments on commit f8f9f6f

Please sign in to comment.