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:
committed by
Yan Zhulanow
parent
58efa34a33
commit
0cdfe89a26
@@ -605,6 +605,15 @@ public class KotlinTestUtils {
|
|||||||
return new File(jdk9);
|
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 {
|
public static void resolveAllKotlinFiles(KotlinCoreEnvironment environment) throws IOException {
|
||||||
List<KotlinSourceRoot> roots = ContentRootsKt.getKotlinSourceRoots(environment.getConfiguration());
|
List<KotlinSourceRoot> roots = ContentRootsKt.getKotlinSourceRoots(environment.getConfiguration());
|
||||||
if (roots.isEmpty()) return;
|
if (roots.isEmpty()) return;
|
||||||
|
|||||||
@@ -24,6 +24,16 @@ import com.sun.tools.javac.util.List as JavacList
|
|||||||
import org.jetbrains.kotlin.kapt3.base.plus
|
import org.jetbrains.kotlin.kapt3.base.plus
|
||||||
|
|
||||||
fun isJava9OrLater(): Boolean = !System.getProperty("java.version").startsWith("1.")
|
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) {
|
fun Options.putJavacOption(jdk8Name: String, jdk9Name: String, value: String) {
|
||||||
val option = if (isJava9OrLater()) {
|
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.KaptBaseError
|
||||||
import org.jetbrains.kotlin.kapt3.base.util.getPackageNameJava9Aware
|
import org.jetbrains.kotlin.kapt3.base.util.getPackageNameJava9Aware
|
||||||
import org.jetbrains.kotlin.kapt3.base.util.info
|
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.diagnostic.KaptError
|
||||||
import org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter
|
import org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter
|
||||||
import org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter.KaptStub
|
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) {
|
if ((tree.mods.flags and ENUM) != 0L) {
|
||||||
// Pretty does not print annotations for enum values for some reason
|
// Pretty does not print annotations for enum values for some reason
|
||||||
printExpr(TreeMaker.instance(context).Modifiers(0, tree.mods.annotations))
|
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)
|
super.visitVarDef(tree)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -219,7 +219,7 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
|
|||||||
wholeFile: File)
|
wholeFile: File)
|
||||||
}
|
}
|
||||||
|
|
||||||
open class AbstractClassFileToSourceStubConverterTest : AbstractKotlinKapt3Test(), Java9TestLauncher {
|
open class AbstractClassFileToSourceStubConverterTest : AbstractKotlinKapt3Test(), CustomJdkTestLauncher {
|
||||||
companion object {
|
companion object {
|
||||||
private val KOTLIN_METADATA_GROUP = "[a-z0-9]+ = (\\{.+?\\}|[0-9]+)"
|
private val KOTLIN_METADATA_GROUP = "[a-z0-9]+ = (\\{.+?\\}|[0-9]+)"
|
||||||
private val KOTLIN_METADATA_REGEX = "@kotlin\\.Metadata\\(($KOTLIN_METADATA_GROUP)(, $KOTLIN_METADATA_GROUP)*\\)".toRegex()
|
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)
|
super.doTest(filePath)
|
||||||
doTestWithJdk9(AbstractClassFileToSourceStubConverterTest::class.java, filePath)
|
doTestWithJdk9(AbstractClassFileToSourceStubConverterTest::class.java, filePath)
|
||||||
|
doTestWithJdk11(AbstractClassFileToSourceStubConverterTest::class.java, filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun check(kaptContext: KaptContextForStubGeneration, javaFiles: List<File>, txtFile: File, wholeFile: File) {
|
override fun check(kaptContext: KaptContextForStubGeneration, javaFiles: List<File>, txtFile: File, wholeFile: File) {
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ import javax.lang.model.element.ExecutableElement
|
|||||||
import javax.lang.model.element.TypeElement
|
import javax.lang.model.element.TypeElement
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
class KotlinKapt3IntegrationTests : AbstractKotlinKapt3IntegrationTest(), Java9TestLauncher {
|
class KotlinKapt3IntegrationTests : AbstractKotlinKapt3IntegrationTest(), CustomJdkTestLauncher {
|
||||||
override fun test(
|
override fun test(
|
||||||
name: String,
|
name: String,
|
||||||
vararg supportedAnnotations: String,
|
vararg supportedAnnotations: String,
|
||||||
|
|||||||
+14
-5
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.kapt3.test
|
|||||||
|
|
||||||
import com.intellij.openapi.application.PathManager
|
import com.intellij.openapi.application.PathManager
|
||||||
import com.intellij.openapi.util.SystemInfoRt
|
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.kapt3.base.util.isJava9OrLater
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -25,17 +26,25 @@ import java.net.URL
|
|||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
interface Java9TestLauncher {
|
interface CustomJdkTestLauncher {
|
||||||
fun doTestWithJdk9(mainClass: Class<*>, arg: String) {
|
fun doTestWithJdk9(mainClass: Class<*>, arg: String) {
|
||||||
// Already under Java 9
|
// Already under Java 9
|
||||||
if (isJava9OrLater()) return
|
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)
|
//TODO unmute after investigation (tests are failing on TeamCity)
|
||||||
if (SystemInfoRt.isWindows) return
|
if (SystemInfoRt.isWindows) return
|
||||||
|
|
||||||
val jdk9Home = KotlinTestUtils.getJdk9Home()
|
val javaExe = File(javaHome, "bin/java.exe").takeIf { it.exists() } ?: File(javaHome, "bin/java")
|
||||||
val javaExe = File(jdk9Home, "bin/java.exe").takeIf { it.exists() } ?: File(jdk9Home, "bin/java")
|
assert(javaExe.exists()) { "Can't find 'java' executable in $javaHome" }
|
||||||
assert(javaExe.exists()) { "Can't find 'java' executable in $jdk9Home" }
|
|
||||||
|
|
||||||
val currentJavaHome = System.getProperty("java.home")
|
val currentJavaHome = System.getProperty("java.home")
|
||||||
|
|
||||||
@@ -60,7 +69,7 @@ interface Java9TestLauncher {
|
|||||||
|
|
||||||
process.waitFor(3, TimeUnit.MINUTES)
|
process.waitFor(3, TimeUnit.MINUTES)
|
||||||
if (process.exitValue() != 0) {
|
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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user