From 582f85f30362291e1ca802ff5b8d4f3546329aca Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Fri, 18 Nov 2016 21:58:30 +0300 Subject: [PATCH] Kapt3: Generate stub for error.NonExistentClass to make javac happy --- .../jetbrains/kotlin/kapt3/Kapt3Extension.kt | 2 +- .../kotlin/kapt3/javac/KaptJavaFileObject.kt | 4 +-- .../stubs/ClassFileToSourceStubConverter.kt | 32 ++++++++++++++++--- .../kapt3/test/AbstractKotlinKapt3Test.kt | 2 +- .../kapt3/testData/kotlinRunner/Simple.it.txt | 7 ++++ 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt index a93ada43f17..96d9dc349cc 100644 --- a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt +++ b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt @@ -187,7 +187,7 @@ abstract class AbstractKapt3Extension( private fun generateKotlinSourceStubs(kaptContext: KaptContext, typeMapper: KotlinTypeMapper): JavacList { val (stubGenerationTime, kotlinSourceStubs) = measureTimeMillis { - ClassFileToSourceStubConverter(kaptContext, typeMapper).convert() + ClassFileToSourceStubConverter(kaptContext, typeMapper, generateNonExistentClass = true).convert() } logger.info { "Java stub generation took $stubGenerationTime ms" } diff --git a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/javac/KaptJavaFileObject.kt b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/javac/KaptJavaFileObject.kt index a0afd364eb2..0f3b395dd4b 100644 --- a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/javac/KaptJavaFileObject.kt +++ b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/javac/KaptJavaFileObject.kt @@ -29,8 +29,8 @@ import javax.tools.JavaFileObject class KaptJavaFileObject( val compilationUnit: JCTree.JCCompilationUnit, val clazz: JCTree.JCClassDecl, - val timestamp: Long, - fileManager: JavacFileManager + fileManager: JavacFileManager, + val timestamp: Long = System.currentTimeMillis() ) : BaseFileObject(fileManager) { override fun getShortName() = clazz.simpleName.toString() diff --git a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt index b618c8c319a..496141e571e 100644 --- a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt +++ b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt @@ -40,7 +40,11 @@ import javax.lang.model.element.ElementKind import javax.tools.JavaFileManager import com.sun.tools.javac.util.List as JavacList -class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMapper: KotlinTypeMapper) { +class ClassFileToSourceStubConverter( + val kaptContext: KaptContext, + val typeMapper: KotlinTypeMapper, + val generateNonExistentClass: Boolean +) { private companion object { private val VISIBILITY_MODIFIERS = (Opcodes.ACC_PUBLIC or Opcodes.ACC_PRIVATE or Opcodes.ACC_PROTECTED).toLong() private val MODALITY_MODIFIERS = (Opcodes.ACC_FINAL or Opcodes.ACC_ABSTRACT).toLong() @@ -74,7 +78,28 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe fun convert(): JavacList { if (done) error(ClassFileToSourceStubConverter::class.java.simpleName + " can convert classes only once") done = true - return mapJList(kaptContext.compiledClasses) { convertTopLevelClass(it) } + + var stubs = mapJList(kaptContext.compiledClasses) { convertTopLevelClass(it) } + + if (generateNonExistentClass) { + stubs = stubs.append(generateNonExistentClass()) + } + + return stubs + } + + private fun generateNonExistentClass(): JCCompilationUnit { + val nonExistentClass = treeMaker.ClassDef( + treeMaker.Modifiers((Flags.PUBLIC or Flags.FINAL).toLong()), + treeMaker.name("NonExistentClass"), + JavacList.nil(), + null, + JavacList.nil(), + JavacList.nil()) + + val topLevel = treeMaker.TopLevel(JavacList.nil(), treeMaker.SimpleName("error"), JavacList.of(nonExistentClass)) + topLevel.sourcefile = KaptJavaFileObject(topLevel, nonExistentClass, fileManager) + return topLevel } private fun convertTopLevelClass(clazz: ClassNode): JCCompilationUnit? { @@ -95,8 +120,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe val classes = JavacList.of(classDeclaration) val topLevel = treeMaker.TopLevel(packageAnnotations, packageClause, imports + classes) - val javaFileObject = KaptJavaFileObject(topLevel, classDeclaration, System.currentTimeMillis(), fileManager) - topLevel.sourcefile = javaFileObject + topLevel.sourcefile = KaptJavaFileObject(topLevel, classDeclaration, fileManager) return topLevel } diff --git a/plugins/kapt3/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt b/plugins/kapt3/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt index b539fecfc05..479572bc47b 100644 --- a/plugins/kapt3/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt +++ b/plugins/kapt3/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt @@ -66,7 +66,7 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() { } protected fun convert(kaptRunner: KaptContext, typeMapper: KotlinTypeMapper): JavacList { - val converter = ClassFileToSourceStubConverter(kaptRunner, typeMapper) + val converter = ClassFileToSourceStubConverter(kaptRunner, typeMapper, generateNonExistentClass = false) return converter.convert() } diff --git a/plugins/kapt3/testData/kotlinRunner/Simple.it.txt b/plugins/kapt3/testData/kotlinRunner/Simple.it.txt index 703a5e4a9de..5f9bc73e07e 100644 --- a/plugins/kapt3/testData/kotlinRunner/Simple.it.txt +++ b/plugins/kapt3/testData/kotlinRunner/Simple.it.txt @@ -30,6 +30,13 @@ public enum EnumClass { //////////////////// +package error; + +public final class NonExistentClass { +} + +//////////////////// + package test; public final class Simple {