KT-33052: Fix KAPT stub generation for enums on JDK11

When using JDK11, generating stubs for enums is broken.
This commit handles the faulty generation by JDK11 by
fully printing enums in custom implementation of tree
printing.

Test: added JDK11 tests for KAPT stub  generation
This commit is contained in:
Ivan Gavrilovic
2019-08-29 16:59:42 +02:00
committed by Yan Zhulanow
parent 58efa34a33
commit 0cdfe89a26
6 changed files with 45 additions and 8 deletions
@@ -605,6 +605,15 @@ public class KotlinTestUtils {
return new File(jdk9);
}
@NotNull
public static File getJdk11Home() {
String jdk11 = System.getenv("JDK_11");
if (jdk11 == null) {
throw new AssertionError("Environment variable JDK_11 is not set!");
}
return new File(jdk11);
}
public static void resolveAllKotlinFiles(KotlinCoreEnvironment environment) throws IOException {
List<KotlinSourceRoot> roots = ContentRootsKt.getKotlinSourceRoots(environment.getConfiguration());
if (roots.isEmpty()) return;
@@ -24,6 +24,16 @@ import com.sun.tools.javac.util.List as JavacList
import org.jetbrains.kotlin.kapt3.base.plus
fun isJava9OrLater(): Boolean = !System.getProperty("java.version").startsWith("1.")
fun isJava11OrLater(): Boolean {
val majorVersion = System.getProperty("java.version").substringBefore(".", "")
if (majorVersion.isEmpty()) return false
return try {
majorVersion.toInt() >= 11
} catch (ignored: Throwable) {
false
}
}
fun Options.putJavacOption(jdk8Name: String, jdk9Name: String, value: String) {
val option = if (isJava9OrLater()) {
@@ -50,6 +50,7 @@ import org.jetbrains.kotlin.kapt3.base.stubs.KaptStubLineInformation.Companion.K
import org.jetbrains.kotlin.kapt3.base.util.KaptBaseError
import org.jetbrains.kotlin.kapt3.base.util.getPackageNameJava9Aware
import org.jetbrains.kotlin.kapt3.base.util.info
import org.jetbrains.kotlin.kapt3.base.util.isJava11OrLater
import org.jetbrains.kotlin.kapt3.diagnostic.KaptError
import org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter
import org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter.KaptStub
@@ -358,8 +359,15 @@ private class PrettyWithWorkarounds(private val context: Context, val out: Write
if ((tree.mods.flags and ENUM) != 0L) {
// Pretty does not print annotations for enum values for some reason
printExpr(TreeMaker.instance(context).Modifiers(0, tree.mods.annotations))
}
if (isJava11OrLater()) {
// Print enums fully, there is an issue when using Pretty in JDK 11.
// See https://youtrack.jetbrains.com/issue/KT-33052.
print("/*public static final*/ ${tree.name}")
tree.init?.let { print(" /* = $it */") }
return
}
}
super.visitVarDef(tree)
}
}
@@ -219,7 +219,7 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
wholeFile: File)
}
open class AbstractClassFileToSourceStubConverterTest : AbstractKotlinKapt3Test(), Java9TestLauncher {
open class AbstractClassFileToSourceStubConverterTest : AbstractKotlinKapt3Test(), CustomJdkTestLauncher {
companion object {
private val KOTLIN_METADATA_GROUP = "[a-z0-9]+ = (\\{.+?\\}|[0-9]+)"
private val KOTLIN_METADATA_REGEX = "@kotlin\\.Metadata\\(($KOTLIN_METADATA_GROUP)(, $KOTLIN_METADATA_GROUP)*\\)".toRegex()
@@ -261,6 +261,7 @@ open class AbstractClassFileToSourceStubConverterTest : AbstractKotlinKapt3Test(
super.doTest(filePath)
doTestWithJdk9(AbstractClassFileToSourceStubConverterTest::class.java, filePath)
doTestWithJdk11(AbstractClassFileToSourceStubConverterTest::class.java, filePath)
}
override fun check(kaptContext: KaptContextForStubGeneration, javaFiles: List<File>, txtFile: File, wholeFile: File) {
@@ -30,7 +30,7 @@ import javax.lang.model.element.ExecutableElement
import javax.lang.model.element.TypeElement
import kotlin.system.exitProcess
class KotlinKapt3IntegrationTests : AbstractKotlinKapt3IntegrationTest(), Java9TestLauncher {
class KotlinKapt3IntegrationTests : AbstractKotlinKapt3IntegrationTest(), CustomJdkTestLauncher {
override fun test(
name: String,
vararg supportedAnnotations: String,
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.kapt3.test
import com.intellij.openapi.application.PathManager
import com.intellij.openapi.util.SystemInfoRt
import org.jetbrains.kotlin.kapt3.base.util.isJava11OrLater
import org.jetbrains.kotlin.kapt3.base.util.isJava9OrLater
import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
@@ -25,17 +26,25 @@ import java.net.URL
import java.net.URLClassLoader
import java.util.concurrent.TimeUnit
interface Java9TestLauncher {
interface CustomJdkTestLauncher {
fun doTestWithJdk9(mainClass: Class<*>, arg: String) {
// Already under Java 9
if (isJava9OrLater()) return
doTestCustomJdk(mainClass, arg, KotlinTestUtils.getJdk9Home())
}
fun doTestWithJdk11(mainClass: Class<*>, arg: String) {
if (isJava9OrLater()) return
doTestCustomJdk(mainClass, arg, KotlinTestUtils.getJdk11Home())
}
private fun doTestCustomJdk(mainClass: Class<*>, arg: String, javaHome: File) {
//TODO unmute after investigation (tests are failing on TeamCity)
if (SystemInfoRt.isWindows) return
val jdk9Home = KotlinTestUtils.getJdk9Home()
val javaExe = File(jdk9Home, "bin/java.exe").takeIf { it.exists() } ?: File(jdk9Home, "bin/java")
assert(javaExe.exists()) { "Can't find 'java' executable in $jdk9Home" }
val javaExe = File(javaHome, "bin/java.exe").takeIf { it.exists() } ?: File(javaHome, "bin/java")
assert(javaExe.exists()) { "Can't find 'java' executable in $javaHome" }
val currentJavaHome = System.getProperty("java.home")
@@ -60,7 +69,7 @@ interface Java9TestLauncher {
process.waitFor(3, TimeUnit.MINUTES)
if (process.exitValue() != 0) {
throw AssertionError("Java 9 test process exited with exit code ${process.exitValue()} \n")
throw AssertionError("Java $javaHome test process exited with exit code ${process.exitValue()} \n")
}
}