Kapt: Fix compatibility with Java 9
1. Move option set up to one place, before using any of Java context components; 2. Set Javac file manager options (new to Java 9)
This commit is contained in:
@@ -59,14 +59,21 @@ import java.util.*
|
|||||||
import javax.annotation.processing.Processor
|
import javax.annotation.processing.Processor
|
||||||
import com.sun.tools.javac.util.List as JavacList
|
import com.sun.tools.javac.util.List as JavacList
|
||||||
|
|
||||||
|
class KaptPaths(
|
||||||
|
compileClasspath: List<File>,
|
||||||
|
annotationProcessingClasspath: List<File>,
|
||||||
|
val javaSourceRoots: List<File>,
|
||||||
|
val sourcesOutputDir: File,
|
||||||
|
val classFilesOutputDir: File,
|
||||||
|
val stubsOutputDir: File,
|
||||||
|
val incrementalDataOutputDir: File?
|
||||||
|
) {
|
||||||
|
val compileClasspath = compileClasspath.distinct()
|
||||||
|
val annotationProcessingClasspath = annotationProcessingClasspath.distinct()
|
||||||
|
}
|
||||||
|
|
||||||
class ClasspathBasedKapt3Extension(
|
class ClasspathBasedKapt3Extension(
|
||||||
compileClasspath: List<File>,
|
paths: KaptPaths,
|
||||||
annotationProcessingClasspath: List<File>,
|
|
||||||
javaSourceRoots: List<File>,
|
|
||||||
sourcesOutputDir: File,
|
|
||||||
classFilesOutputDir: File,
|
|
||||||
stubsOutputDir: File,
|
|
||||||
incrementalDataOutputDir: File?,
|
|
||||||
options: Map<String, String>,
|
options: Map<String, String>,
|
||||||
javacOptions: Map<String, String>,
|
javacOptions: Map<String, String>,
|
||||||
annotationProcessorFqNames: List<String>,
|
annotationProcessorFqNames: List<String>,
|
||||||
@@ -77,8 +84,7 @@ class ClasspathBasedKapt3Extension(
|
|||||||
pluginInitializedTime: Long,
|
pluginInitializedTime: Long,
|
||||||
logger: KaptLogger,
|
logger: KaptLogger,
|
||||||
compilerConfiguration: CompilerConfiguration
|
compilerConfiguration: CompilerConfiguration
|
||||||
) : AbstractKapt3Extension(compileClasspath, annotationProcessingClasspath, javaSourceRoots, sourcesOutputDir,
|
) : AbstractKapt3Extension(paths, options, javacOptions, annotationProcessorFqNames,
|
||||||
classFilesOutputDir, stubsOutputDir, incrementalDataOutputDir, options, javacOptions, annotationProcessorFqNames,
|
|
||||||
aptMode, pluginInitializedTime, logger, correctErrorTypes, mapDiagnosticLocations, compilerConfiguration) {
|
aptMode, pluginInitializedTime, logger, correctErrorTypes, mapDiagnosticLocations, compilerConfiguration) {
|
||||||
override val analyzePartially: Boolean
|
override val analyzePartially: Boolean
|
||||||
get() = useLightAnalysis
|
get() = useLightAnalysis
|
||||||
@@ -102,7 +108,7 @@ class ClasspathBasedKapt3Extension(
|
|||||||
override fun loadProcessors(): List<Processor> {
|
override fun loadProcessors(): List<Processor> {
|
||||||
ClassUtilCore.clearJarURLCache()
|
ClassUtilCore.clearJarURLCache()
|
||||||
|
|
||||||
val classpath = (annotationProcessingClasspath + compileClasspath).distinct()
|
val classpath = (paths.annotationProcessingClasspath + paths.compileClasspath).distinct()
|
||||||
val classLoader = URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray())
|
val classLoader = URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray())
|
||||||
this.annotationProcessingClassLoader = classLoader
|
this.annotationProcessingClassLoader = classLoader
|
||||||
|
|
||||||
@@ -147,13 +153,7 @@ class ClasspathBasedKapt3Extension(
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class AbstractKapt3Extension(
|
abstract class AbstractKapt3Extension(
|
||||||
compileClasspath: List<File>,
|
val paths: KaptPaths,
|
||||||
annotationProcessingClasspath: List<File>,
|
|
||||||
val javaSourceRoots: List<File>,
|
|
||||||
val sourcesOutputDir: File,
|
|
||||||
val classFilesOutputDir: File,
|
|
||||||
val stubsOutputDir: File,
|
|
||||||
val incrementalDataOutputDir: File?,
|
|
||||||
val options: Map<String, String>,
|
val options: Map<String, String>,
|
||||||
val javacOptions: Map<String, String>,
|
val javacOptions: Map<String, String>,
|
||||||
val annotationProcessorFqNames: List<String>,
|
val annotationProcessorFqNames: List<String>,
|
||||||
@@ -164,9 +164,6 @@ abstract class AbstractKapt3Extension(
|
|||||||
val mapDiagnosticLocations: Boolean,
|
val mapDiagnosticLocations: Boolean,
|
||||||
val compilerConfiguration: CompilerConfiguration
|
val compilerConfiguration: CompilerConfiguration
|
||||||
) : PartialAnalysisHandlerExtension() {
|
) : PartialAnalysisHandlerExtension() {
|
||||||
val compileClasspath = compileClasspath.distinct()
|
|
||||||
val annotationProcessingClasspath = annotationProcessingClasspath.distinct()
|
|
||||||
|
|
||||||
private var annotationProcessingComplete = false
|
private var annotationProcessingComplete = false
|
||||||
|
|
||||||
private fun setAnnotationProcessingComplete(): Boolean {
|
private fun setAnnotationProcessingComplete(): Boolean {
|
||||||
@@ -230,14 +227,14 @@ abstract class AbstractKapt3Extension(
|
|||||||
AnalysisResult.RetryWithAdditionalJavaRoots(
|
AnalysisResult.RetryWithAdditionalJavaRoots(
|
||||||
bindingTrace.bindingContext,
|
bindingTrace.bindingContext,
|
||||||
module,
|
module,
|
||||||
listOf(sourcesOutputDir),
|
listOf(paths.sourcesOutputDir),
|
||||||
addToEnvironment = true)
|
addToEnvironment = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateStubs(project: Project, module: ModuleDescriptor, context: BindingContext, files: Collection<KtFile>): KaptContext<*> {
|
private fun generateStubs(project: Project, module: ModuleDescriptor, context: BindingContext, files: Collection<KtFile>): KaptContext<*> {
|
||||||
if (!aptMode.generateStubs) {
|
if (!aptMode.generateStubs) {
|
||||||
return KaptContext(logger, project, BindingContext.EMPTY, emptyList(), emptyMap(), null,
|
return KaptContext(paths, false, aptMode, logger, project, BindingContext.EMPTY, emptyList(), emptyMap(), null,
|
||||||
mapDiagnosticLocations, options, javacOptions)
|
mapDiagnosticLocations, options, javacOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,8 +251,7 @@ abstract class AbstractKapt3Extension(
|
|||||||
val javaSourceFiles = collectJavaSourceFiles()
|
val javaSourceFiles = collectJavaSourceFiles()
|
||||||
|
|
||||||
val (annotationProcessingTime) = measureTimeMillis {
|
val (annotationProcessingTime) = measureTimeMillis {
|
||||||
kaptContext.doAnnotationProcessing(
|
kaptContext.doAnnotationProcessing(javaSourceFiles, processors)
|
||||||
javaSourceFiles, processors, compileClasspath, annotationProcessingClasspath, sourcesOutputDir, classFilesOutputDir)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info { "Annotation processing took $annotationProcessingTime ms" }
|
logger.info { "Annotation processing took $annotationProcessingTime ms" }
|
||||||
@@ -292,7 +288,7 @@ abstract class AbstractKapt3Extension(
|
|||||||
logger.info { "Stubs compilation took $classFilesCompilationTime ms" }
|
logger.info { "Stubs compilation took $classFilesCompilationTime ms" }
|
||||||
logger.info { "Compiled classes: " + compiledClasses.joinToString { it.name } }
|
logger.info { "Compiled classes: " + compiledClasses.joinToString { it.name } }
|
||||||
|
|
||||||
return KaptContext(logger, project, bindingContext, compiledClasses, origins, generationState,
|
return KaptContext(paths, false, aptMode, logger, project, bindingContext, compiledClasses, origins, generationState,
|
||||||
mapDiagnosticLocations, options, javacOptions)
|
mapDiagnosticLocations, options, javacOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,7 +307,7 @@ abstract class AbstractKapt3Extension(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun collectJavaSourceFiles(): List<File> {
|
private fun collectJavaSourceFiles(): List<File> {
|
||||||
val javaFilesFromJavaSourceRoots = (javaSourceRoots + stubsOutputDir).flatMap {
|
val javaFilesFromJavaSourceRoots = (paths.javaSourceRoots + paths.stubsOutputDir).flatMap {
|
||||||
root -> root.walk().filter { it.isFile && it.extension == "java" }.toList()
|
root -> root.walk().filter { it.isFile && it.extension == "java" }.toList()
|
||||||
}
|
}
|
||||||
logger.info { "Java source files: " + javaFilesFromJavaSourceRoots.joinToString { it.canonicalPath } }
|
logger.info { "Java source files: " + javaFilesFromJavaSourceRoots.joinToString { it.canonicalPath } }
|
||||||
@@ -325,10 +321,10 @@ abstract class AbstractKapt3Extension(
|
|||||||
val className = (stub.defs.first { it is JCTree.JCClassDecl } as JCTree.JCClassDecl).simpleName.toString()
|
val className = (stub.defs.first { it is JCTree.JCClassDecl } as JCTree.JCClassDecl).simpleName.toString()
|
||||||
|
|
||||||
val packageName = stub.getPackageNameJava9Aware()?.toString() ?: ""
|
val packageName = stub.getPackageNameJava9Aware()?.toString() ?: ""
|
||||||
val packageDir = if (packageName.isEmpty()) stubsOutputDir else File(stubsOutputDir, packageName.replace('.', '/'))
|
val packageDir = if (packageName.isEmpty()) paths.stubsOutputDir else File(paths.stubsOutputDir, packageName.replace('.', '/'))
|
||||||
packageDir.mkdirs()
|
packageDir.mkdirs()
|
||||||
|
|
||||||
val sourceFile = File(packageDir, className + ".java")
|
val sourceFile = File(packageDir, "$className.java")
|
||||||
sourceFile.writeText(stub.prettyPrint(kaptContext.context))
|
sourceFile.writeText(stub.prettyPrint(kaptContext.context))
|
||||||
|
|
||||||
kaptStub.writeMetadataIfNeeded(forSource = sourceFile)
|
kaptStub.writeMetadataIfNeeded(forSource = sourceFile)
|
||||||
@@ -339,7 +335,7 @@ abstract class AbstractKapt3Extension(
|
|||||||
kaptContext: KaptContext<GenerationState>,
|
kaptContext: KaptContext<GenerationState>,
|
||||||
messageCollector: MessageCollector,
|
messageCollector: MessageCollector,
|
||||||
converter: ClassFileToSourceStubConverter) {
|
converter: ClassFileToSourceStubConverter) {
|
||||||
val incrementalDataOutputDir = this.incrementalDataOutputDir ?: return
|
val incrementalDataOutputDir = paths.incrementalDataOutputDir ?: return
|
||||||
|
|
||||||
val reportOutputFiles = kaptContext.generationState.configuration.getBoolean(CommonConfigurationKeys.REPORT_OUTPUT_FILES)
|
val reportOutputFiles = kaptContext.generationState.configuration.getBoolean(CommonConfigurationKeys.REPORT_OUTPUT_FILES)
|
||||||
kaptContext.generationState.factory.writeAll(
|
kaptContext.generationState.factory.writeAll(
|
||||||
@@ -347,7 +343,7 @@ abstract class AbstractKapt3Extension(
|
|||||||
if (!reportOutputFiles) null else fun(file: OutputFile, sources: List<File>, output: File) {
|
if (!reportOutputFiles) null else fun(file: OutputFile, sources: List<File>, output: File) {
|
||||||
val stubFileObject = converter.bindings[file.relativePath.substringBeforeLast(".class", missingDelimiterValue = "")]
|
val stubFileObject = converter.bindings[file.relativePath.substringBeforeLast(".class", missingDelimiterValue = "")]
|
||||||
if (stubFileObject != null) {
|
if (stubFileObject != null) {
|
||||||
val stubFile = File(stubsOutputDir, stubFileObject.name)
|
val stubFile = File(paths.stubsOutputDir, stubFileObject.name)
|
||||||
val lineMappingsFile = File(stubFile.parentFile, stubFile.nameWithoutExtension + KAPT_METADATA_EXTENSION)
|
val lineMappingsFile = File(stubFile.parentFile, stubFile.nameWithoutExtension + KAPT_METADATA_EXTENSION)
|
||||||
|
|
||||||
for (file in listOf(stubFile, lineMappingsFile)) {
|
for (file in listOf(stubFile, lineMappingsFile)) {
|
||||||
|
|||||||
@@ -301,10 +301,16 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
|
|||||||
logger.info("Options: $apOptions")
|
logger.info("Options: $apOptions")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val paths = KaptPaths(
|
||||||
|
compileClasspath, apClasspath, javaSourceRoots, sourcesOutputDir, classFilesOutputDir,
|
||||||
|
stubsOutputDir, incrementalDataOutputDir
|
||||||
|
)
|
||||||
|
|
||||||
val kapt3AnalysisCompletedHandlerExtension = ClasspathBasedKapt3Extension(
|
val kapt3AnalysisCompletedHandlerExtension = ClasspathBasedKapt3Extension(
|
||||||
compileClasspath, apClasspath, javaSourceRoots, sourcesOutputDir, classFilesOutputDir,
|
paths, apOptions, javacCliOptions, annotationProcessors,
|
||||||
stubsOutputDir, incrementalDataOutputDir, apOptions, javacCliOptions, annotationProcessors,
|
aptMode, useLightAnalysis, correctErrorTypes, mapDiagnosticLocations, System.currentTimeMillis(), logger, configuration
|
||||||
aptMode, useLightAnalysis, correctErrorTypes, mapDiagnosticLocations, System.currentTimeMillis(), logger, configuration)
|
)
|
||||||
|
|
||||||
AnalysisHandlerExtension.registerExtension(project, kapt3AnalysisCompletedHandlerExtension)
|
AnalysisHandlerExtension.registerExtension(project, kapt3AnalysisCompletedHandlerExtension)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,24 +17,31 @@
|
|||||||
package org.jetbrains.kotlin.kapt3
|
package org.jetbrains.kotlin.kapt3
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.sun.tools.javac.file.JavacFileManager
|
|
||||||
import com.sun.tools.javac.jvm.ClassReader
|
import com.sun.tools.javac.jvm.ClassReader
|
||||||
import com.sun.tools.javac.main.JavaCompiler
|
import com.sun.tools.javac.main.JavaCompiler
|
||||||
import com.sun.tools.javac.tree.TreeMaker
|
import com.sun.tools.javac.tree.TreeMaker
|
||||||
|
import com.sun.tools.javac.main.Option
|
||||||
import com.sun.tools.javac.util.Context
|
import com.sun.tools.javac.util.Context
|
||||||
import com.sun.tools.javac.util.Options
|
import com.sun.tools.javac.util.Options
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.kapt3.javac.KaptJavaCompiler
|
import org.jetbrains.kotlin.kapt3.javac.KaptJavaCompiler
|
||||||
|
import org.jetbrains.kotlin.kapt3.javac.KaptJavaFileManager
|
||||||
import org.jetbrains.kotlin.kapt3.javac.KaptJavaLog
|
import org.jetbrains.kotlin.kapt3.javac.KaptJavaLog
|
||||||
import org.jetbrains.kotlin.kapt3.javac.KaptTreeMaker
|
import org.jetbrains.kotlin.kapt3.javac.KaptTreeMaker
|
||||||
import org.jetbrains.kotlin.kapt3.util.KaptLogger
|
import org.jetbrains.kotlin.kapt3.util.KaptLogger
|
||||||
|
import org.jetbrains.kotlin.kapt3.util.isJava9OrLater
|
||||||
|
import org.jetbrains.kotlin.kapt3.util.putJavacOption
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.utils.keysToMap
|
import org.jetbrains.kotlin.utils.keysToMap
|
||||||
import org.jetbrains.org.objectweb.asm.tree.ClassNode
|
import org.jetbrains.org.objectweb.asm.tree.ClassNode
|
||||||
|
import java.io.File
|
||||||
import javax.tools.JavaFileManager
|
import javax.tools.JavaFileManager
|
||||||
|
|
||||||
class KaptContext<out GState : GenerationState?>(
|
class KaptContext<out GState : GenerationState?>(
|
||||||
|
val paths: KaptPaths,
|
||||||
|
private val withJdk: Boolean,
|
||||||
|
aptMode: AptMode,
|
||||||
val logger: KaptLogger,
|
val logger: KaptLogger,
|
||||||
val project: Project,
|
val project: Project,
|
||||||
val bindingContext: BindingContext,
|
val bindingContext: BindingContext,
|
||||||
@@ -47,47 +54,77 @@ class KaptContext<out GState : GenerationState?>(
|
|||||||
) : AutoCloseable {
|
) : AutoCloseable {
|
||||||
val context = Context()
|
val context = Context()
|
||||||
val compiler: KaptJavaCompiler
|
val compiler: KaptJavaCompiler
|
||||||
val fileManager: JavacFileManager
|
val fileManager: KaptJavaFileManager
|
||||||
val options: Options
|
val options: Options
|
||||||
val javaLog: KaptJavaLog
|
val javaLog: KaptJavaLog
|
||||||
val treeMaker: KaptTreeMaker
|
private val treeMaker: TreeMaker
|
||||||
|
|
||||||
init {
|
init {
|
||||||
KaptJavaLog.preRegister(this, logger.messageCollector, mapDiagnosticLocations)
|
KaptJavaLog.preRegister(this, logger.messageCollector, mapDiagnosticLocations)
|
||||||
JavacFileManager.preRegister(context)
|
KaptJavaFileManager.preRegister(context)
|
||||||
KaptTreeMaker.preRegister(context, this)
|
if (aptMode != AptMode.APT_ONLY) {
|
||||||
|
KaptTreeMaker.preRegister(context, this)
|
||||||
|
}
|
||||||
KaptJavaCompiler.preRegister(context)
|
KaptJavaCompiler.preRegister(context)
|
||||||
|
|
||||||
options = Options.instance(context)
|
options = Options.instance(context).apply {
|
||||||
for ((key, value) in processorOptions) {
|
for ((key, value) in processorOptions) {
|
||||||
val option = if (value.isEmpty()) "-A$key" else "-A$key=$value"
|
val option = if (value.isEmpty()) "-A$key" else "-A$key=$value"
|
||||||
options.put(option, option) // key == value: it's intentional
|
put(option, option) // key == value: it's intentional
|
||||||
}
|
|
||||||
|
|
||||||
for ((key, value) in javacOptions) {
|
|
||||||
if (value.isNotEmpty()) {
|
|
||||||
options.put(key, value)
|
|
||||||
} else {
|
|
||||||
options.put(key, key)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for ((key, value) in javacOptions) {
|
||||||
|
if (value.isNotEmpty()) {
|
||||||
|
put(key, value)
|
||||||
|
} else {
|
||||||
|
put(key, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
put(Option.PROC, "only") // Only process annotations
|
||||||
|
|
||||||
|
if (!withJdk) {
|
||||||
|
putJavacOption("BOOTCLASSPATH", "BOOT_CLASS_PATH", "") // No boot classpath
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isJava9OrLater) {
|
||||||
|
put("accessInternalAPI", "true")
|
||||||
|
}
|
||||||
|
|
||||||
|
putJavacOption("CLASSPATH", "CLASS_PATH",
|
||||||
|
paths.compileClasspath.joinToString(File.pathSeparator) { it.canonicalPath })
|
||||||
|
putJavacOption("PROCESSORPATH", "PROCESSOR_PATH",
|
||||||
|
paths.annotationProcessingClasspath.joinToString(File.pathSeparator) { it.canonicalPath })
|
||||||
|
|
||||||
|
put(Option.S, paths.sourcesOutputDir.canonicalPath)
|
||||||
|
put(Option.D, paths.classFilesOutputDir.canonicalPath)
|
||||||
|
put(Option.ENCODING, "UTF-8")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logger.isVerbose) {
|
if (logger.isVerbose) {
|
||||||
logger.info("Javac options: " + options.keySet().keysToMap { key -> options[key] ?: "" })
|
logger.info("Javac options: " + options.keySet().keysToMap { key -> options[key] ?: "" })
|
||||||
}
|
}
|
||||||
|
|
||||||
fileManager = context.get(JavaFileManager::class.java) as JavacFileManager
|
fileManager = context.get(JavaFileManager::class.java) as KaptJavaFileManager
|
||||||
|
|
||||||
|
if (isJava9OrLater) {
|
||||||
|
for (option in Option.getJavacFileManagerOptions()) {
|
||||||
|
val value = options.get(option) ?: continue
|
||||||
|
fileManager.handleOptionJavac9(option, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
compiler = JavaCompiler.instance(context) as KaptJavaCompiler
|
compiler = JavaCompiler.instance(context) as KaptJavaCompiler
|
||||||
compiler.keepComments = true
|
compiler.keepComments = true
|
||||||
|
|
||||||
ClassReader.instance(context).saveParameterNames = true
|
ClassReader.instance(context).saveParameterNames = true
|
||||||
|
|
||||||
javaLog = compiler.log as KaptJavaLog
|
javaLog = compiler.log as KaptJavaLog
|
||||||
treeMaker = TreeMaker.instance(context) as KaptTreeMaker
|
treeMaker = TreeMaker.instance(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
treeMaker.dispose()
|
(treeMaker as? KaptTreeMaker)?.dispose()
|
||||||
compiler.close()
|
compiler.close()
|
||||||
fileManager.close()
|
fileManager.close()
|
||||||
generationState?.destroy()
|
generationState?.destroy()
|
||||||
|
|||||||
+1
-20
@@ -37,27 +37,8 @@ import com.sun.tools.javac.util.List as JavacList
|
|||||||
fun KaptContext<*>.doAnnotationProcessing(
|
fun KaptContext<*>.doAnnotationProcessing(
|
||||||
javaSourceFiles: List<File>,
|
javaSourceFiles: List<File>,
|
||||||
processors: List<Processor>,
|
processors: List<Processor>,
|
||||||
compileClasspath: List<File>,
|
additionalSources: JavacList<JCTree.JCCompilationUnit> = JavacList.nil()
|
||||||
annotationProcessingClasspath: List<File>,
|
|
||||||
sourcesOutputDir: File,
|
|
||||||
classesOutputDir: File,
|
|
||||||
additionalSources: JavacList<JCTree.JCCompilationUnit> = JavacList.nil(),
|
|
||||||
withJdk: Boolean = false
|
|
||||||
) {
|
) {
|
||||||
with (options) {
|
|
||||||
put(Option.PROC, "only") // Only process annotations
|
|
||||||
|
|
||||||
if (!withJdk) {
|
|
||||||
putJavacOption("BOOTCLASSPATH", "BOOT_CLASS_PATH", "") // No boot classpath
|
|
||||||
}
|
|
||||||
|
|
||||||
putJavacOption("CLASSPATH", "CLASS_PATH", compileClasspath.joinToString(File.pathSeparator) { it.canonicalPath })
|
|
||||||
putJavacOption("PROCESSORPATH", "PROCESSOR_PATH", annotationProcessingClasspath.joinToString(File.pathSeparator) { it.canonicalPath })
|
|
||||||
put(Option.S, sourcesOutputDir.canonicalPath)
|
|
||||||
put(Option.D, classesOutputDir.canonicalPath)
|
|
||||||
put(Option.ENCODING, "UTF-8")
|
|
||||||
}
|
|
||||||
|
|
||||||
val processingEnvironment = JavacProcessingEnvironment.instance(context)
|
val processingEnvironment = JavacProcessingEnvironment.instance(context)
|
||||||
val wrappedProcessors = processors.map { ProcessorWrapper(it) }
|
val wrappedProcessors = processors.map { ProcessorWrapper(it) }
|
||||||
|
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package org.jetbrains.kotlin.kapt3.javac
|
||||||
|
|
||||||
|
import com.sun.tools.javac.file.JavacFileManager
|
||||||
|
import com.sun.tools.javac.main.Option
|
||||||
|
import com.sun.tools.javac.util.Context
|
||||||
|
import javax.tools.JavaFileManager
|
||||||
|
|
||||||
|
class KaptJavaFileManager(context: Context) : JavacFileManager(context, true, null) {
|
||||||
|
fun handleOptionJavac9(option: Option, value: String) {
|
||||||
|
val handleOptionMethod = JavacFileManager::class.java
|
||||||
|
.getMethod("handleOption", Option::class.java, String::class.java)
|
||||||
|
|
||||||
|
handleOptionMethod.invoke(this, option, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
internal fun preRegister(context: Context) {
|
||||||
|
context.put(JavaFileManager::class.java, Context.Factory<JavaFileManager> { KaptJavaFileManager(it) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -228,7 +228,9 @@ class KaptJavaLog(
|
|||||||
"compiler.err.already.defined",
|
"compiler.err.already.defined",
|
||||||
"compiler.err.annotation.type.not.applicable",
|
"compiler.err.annotation.type.not.applicable",
|
||||||
"compiler.err.doesnt.exist",
|
"compiler.err.doesnt.exist",
|
||||||
"compiler.err.duplicate.annotation.missing.container"
|
"compiler.err.duplicate.annotation.missing.container",
|
||||||
|
"compiler.err.not.def.access.package.cant.access",
|
||||||
|
"compiler.err.package.not.visible"
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun preRegister(kaptContext: KaptContext<*>, messageCollector: MessageCollector, mapDiagnosticLocations: Boolean) {
|
internal fun preRegister(kaptContext: KaptContext<*>, messageCollector: MessageCollector, mapDiagnosticLocations: Boolean) {
|
||||||
|
|||||||
+8
-9
@@ -23,11 +23,8 @@ import org.jetbrains.kotlin.codegen.CodegenTestCase
|
|||||||
import org.jetbrains.kotlin.codegen.GenerationUtils
|
import org.jetbrains.kotlin.codegen.GenerationUtils
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.kapt3.AbstractKapt3Extension
|
import org.jetbrains.kotlin.kapt3.*
|
||||||
import org.jetbrains.kotlin.kapt3.AptMode.STUBS_AND_APT
|
import org.jetbrains.kotlin.kapt3.AptMode.STUBS_AND_APT
|
||||||
import org.jetbrains.kotlin.kapt3.Kapt3BuilderFactory
|
|
||||||
import org.jetbrains.kotlin.kapt3.prettyPrint
|
|
||||||
import org.jetbrains.kotlin.kapt3.KaptContext
|
|
||||||
import org.jetbrains.kotlin.kapt3.javac.KaptJavaFileObject
|
import org.jetbrains.kotlin.kapt3.javac.KaptJavaFileObject
|
||||||
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
|
||||||
@@ -162,11 +159,13 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() {
|
|||||||
options: Map<String, String>,
|
options: Map<String, String>,
|
||||||
stubsOutputDir: File,
|
stubsOutputDir: File,
|
||||||
incrementalDataOutputDir: File
|
incrementalDataOutputDir: File
|
||||||
) : AbstractKapt3Extension(PathUtil.getJdkClassesRootsFromCurrentJre() + PathUtil.kotlinPathsForIdeaPlugin.stdlibPath,
|
) : AbstractKapt3Extension(
|
||||||
emptyList(), javaSourceRoots, outputDir, outputDir,
|
KaptPaths(
|
||||||
stubsOutputDir, incrementalDataOutputDir, options, emptyMap(), emptyList(), STUBS_AND_APT, System.currentTimeMillis(),
|
PathUtil.getJdkClassesRootsFromCurrentJre() + PathUtil.kotlinPathsForIdeaPlugin.stdlibPath,
|
||||||
KaptLogger(true), correctErrorTypes = true, mapDiagnosticLocations = true,
|
emptyList(), javaSourceRoots, outputDir, outputDir, stubsOutputDir, incrementalDataOutputDir
|
||||||
compilerConfiguration = CompilerConfiguration.EMPTY
|
), options, emptyMap(), emptyList(), STUBS_AND_APT, System.currentTimeMillis(),
|
||||||
|
KaptLogger(true), correctErrorTypes = true, mapDiagnosticLocations = true,
|
||||||
|
compilerConfiguration = CompilerConfiguration.EMPTY
|
||||||
) {
|
) {
|
||||||
internal var savedStubs: String? = null
|
internal var savedStubs: String? = null
|
||||||
internal var savedBindings: Map<String, KaptJavaFileObject>? = null
|
internal var savedBindings: Map<String, KaptJavaFileObject>? = null
|
||||||
|
|||||||
+32
-24
@@ -120,23 +120,36 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
|
|||||||
key to value
|
key to value
|
||||||
}.toMap()
|
}.toMap()
|
||||||
|
|
||||||
val kaptContext = KaptContext(logger, generationState.project, generationState.bindingContext, classBuilderFactory.compiledClasses,
|
var javaFiles: List<File>? = null
|
||||||
classBuilderFactory.origins, generationState, mapDiagnosticLocations = true,
|
var kaptContext: KaptContext<*>? = null
|
||||||
processorOptions = emptyMap(), javacOptions = javacOptions)
|
|
||||||
|
|
||||||
val javaFiles = files
|
|
||||||
.filter { it.name.toLowerCase().endsWith(".java") }
|
|
||||||
.map { createTempFile(it.name.substringBeforeLast('.'), ".java", it.content) }
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
val sourceOutputDir = Files.createTempDirectory("kaptRunner").toFile()
|
||||||
|
|
||||||
|
val paths = KaptPaths(
|
||||||
|
compileClasspath = PathUtil.getJdkClassesRootsFromCurrentJre() + PathUtil.kotlinPathsForIdeaPlugin.stdlibPath,
|
||||||
|
annotationProcessingClasspath = emptyList(), javaSourceRoots = emptyList(),
|
||||||
|
sourcesOutputDir = sourceOutputDir, classFilesOutputDir = sourceOutputDir,
|
||||||
|
stubsOutputDir = sourceOutputDir, incrementalDataOutputDir = sourceOutputDir
|
||||||
|
)
|
||||||
|
|
||||||
|
kaptContext = KaptContext(paths, true, AptMode.STUBS_AND_APT,
|
||||||
|
logger, generationState.project, generationState.bindingContext, classBuilderFactory.compiledClasses,
|
||||||
|
classBuilderFactory.origins, generationState, mapDiagnosticLocations = true,
|
||||||
|
processorOptions = emptyMap(), javacOptions = javacOptions)
|
||||||
|
|
||||||
|
javaFiles = files
|
||||||
|
.filter { it.name.toLowerCase().endsWith(".java") }
|
||||||
|
.map { createTempFile(it.name.substringBeforeLast('.'), ".java", it.content) }
|
||||||
|
|
||||||
check(kaptContext, javaFiles, txtFile, wholeFile)
|
check(kaptContext, javaFiles, txtFile, wholeFile)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
throw RuntimeException(e)
|
throw RuntimeException(e)
|
||||||
} finally {
|
} finally {
|
||||||
javaFiles.forEach { it.delete() }
|
javaFiles?.forEach { it.delete() }
|
||||||
tempFiles.forEach { if (it.isFile) it.delete() else it.deleteRecursively() }
|
tempFiles.forEach { if (it.isFile) it.delete() else it.deleteRecursively() }
|
||||||
tempFiles.clear()
|
tempFiles.clear()
|
||||||
kaptContext.close()
|
kaptContext?.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,22 +300,17 @@ open class AbstractClassFileToSourceStubConverterTest : AbstractKotlinKapt3Test(
|
|||||||
abstract class AbstractKotlinKaptContextTest : AbstractKotlinKapt3Test() {
|
abstract class AbstractKotlinKaptContextTest : AbstractKotlinKapt3Test() {
|
||||||
override fun check(kaptContext: KaptContext<GenerationState>, javaFiles: List<File>, txtFile: File, wholeFile: File) {
|
override fun check(kaptContext: KaptContext<GenerationState>, javaFiles: List<File>, txtFile: File, wholeFile: File) {
|
||||||
val compilationUnits = convert(kaptContext, javaFiles, generateNonExistentClass = false, correctErrorTypes = true)
|
val compilationUnits = convert(kaptContext, javaFiles, generateNonExistentClass = false, correctErrorTypes = true)
|
||||||
val sourceOutputDir = Files.createTempDirectory("kaptRunner").toFile()
|
|
||||||
try {
|
|
||||||
kaptContext.doAnnotationProcessing(emptyList(), listOf(JavaKaptContextTest.simpleProcessor()),
|
|
||||||
compileClasspath = PathUtil.getJdkClassesRootsFromCurrentJre() + PathUtil.kotlinPathsForIdeaPlugin.stdlibPath,
|
|
||||||
annotationProcessingClasspath = emptyList(),
|
|
||||||
sourcesOutputDir = sourceOutputDir, classesOutputDir = sourceOutputDir,
|
|
||||||
additionalSources = compilationUnits, withJdk = true
|
|
||||||
)
|
|
||||||
|
|
||||||
val javaFiles = sourceOutputDir.walkTopDown().filter { it.isFile && it.extension == "java" }
|
kaptContext.doAnnotationProcessing(
|
||||||
val actualRaw = javaFiles.sortedBy { it.name }.joinToString(FILE_SEPARATOR) { it.name + ":\n\n" + it.readText() }
|
emptyList(),
|
||||||
val actual = StringUtil.convertLineSeparators(actualRaw.trim({ it <= ' ' })).trimTrailingWhitespacesAndAddNewlineAtEOF()
|
listOf(JavaKaptContextTest.simpleProcessor()),
|
||||||
KotlinTestUtils.assertEqualsToFile(txtFile, actual)
|
additionalSources = compilationUnits
|
||||||
} finally {
|
)
|
||||||
sourceOutputDir.deleteRecursively()
|
|
||||||
}
|
val stubJavaFiles = kaptContext.paths.sourcesOutputDir.walkTopDown().filter { it.isFile && it.extension == "java" }
|
||||||
|
val actualRaw = stubJavaFiles.sortedBy { it.name }.joinToString(FILE_SEPARATOR) { it.name + ":\n\n" + it.readText() }
|
||||||
|
val actual = StringUtil.convertLineSeparators(actualRaw.trim({ it <= ' ' })).trimTrailingWhitespacesAndAddNewlineAtEOF()
|
||||||
|
KotlinTestUtils.assertEqualsToFile(txtFile, actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
-16
@@ -19,7 +19,9 @@ package org.jetbrains.kotlin.kapt3.test
|
|||||||
import com.intellij.openapi.command.impl.DummyProject
|
import com.intellij.openapi.command.impl.DummyProject
|
||||||
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
|
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
|
||||||
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
|
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
|
||||||
|
import org.jetbrains.kotlin.kapt3.AptMode
|
||||||
import org.jetbrains.kotlin.kapt3.KaptContext
|
import org.jetbrains.kotlin.kapt3.KaptContext
|
||||||
|
import org.jetbrains.kotlin.kapt3.KaptPaths
|
||||||
import org.jetbrains.kotlin.kapt3.diagnostic.KaptError
|
import org.jetbrains.kotlin.kapt3.diagnostic.KaptError
|
||||||
import org.jetbrains.kotlin.kapt3.doAnnotationProcessing
|
import org.jetbrains.kotlin.kapt3.doAnnotationProcessing
|
||||||
import org.jetbrains.kotlin.kapt3.util.KaptLogger
|
import org.jetbrains.kotlin.kapt3.util.KaptLogger
|
||||||
@@ -80,22 +82,27 @@ class JavaKaptContextTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun doAnnotationProcessing(javaSourceFile: File, processor: Processor, outputDir: File) {
|
private fun doAnnotationProcessing(javaSourceFile: File, processor: Processor, outputDir: File) {
|
||||||
KaptContext(KaptLogger(isVerbose = true, messageCollector = messageCollector),
|
KaptContext(
|
||||||
DummyProject.getInstance(),
|
KaptPaths(
|
||||||
bindingContext = BindingContext.EMPTY,
|
compileClasspath = emptyList(),
|
||||||
compiledClasses = emptyList(),
|
annotationProcessingClasspath = emptyList(),
|
||||||
origins = emptyMap(),
|
javaSourceRoots = emptyList(),
|
||||||
generationState = null,
|
sourcesOutputDir = outputDir,
|
||||||
mapDiagnosticLocations = true,
|
classFilesOutputDir = outputDir,
|
||||||
processorOptions = emptyMap()
|
stubsOutputDir = outputDir,
|
||||||
).doAnnotationProcessing(
|
incrementalDataOutputDir = outputDir
|
||||||
listOf(javaSourceFile),
|
),
|
||||||
listOf(processor),
|
withJdk = true,
|
||||||
emptyList(), // compile classpath
|
aptMode = AptMode.STUBS_AND_APT,
|
||||||
emptyList(), // annotation processing classpath
|
logger = KaptLogger(isVerbose = true, messageCollector = messageCollector),
|
||||||
outputDir,
|
project = DummyProject.getInstance(),
|
||||||
outputDir,
|
bindingContext = BindingContext.EMPTY,
|
||||||
withJdk = true)
|
compiledClasses = emptyList(),
|
||||||
|
origins = emptyMap(),
|
||||||
|
generationState = null,
|
||||||
|
mapDiagnosticLocations = true,
|
||||||
|
processorOptions = emptyMap()
|
||||||
|
).doAnnotationProcessing(listOf(javaSourceFile), listOf(processor))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+2
-2
@@ -92,8 +92,8 @@ class KotlinKapt3IntegrationTests : AbstractKotlinKapt3IntegrationTest(), Java9T
|
|||||||
test(name, "test.MyAnnotation") { _, _, _ ->
|
test(name, "test.MyAnnotation") { _, _, _ ->
|
||||||
val kaptExtension = AnalysisHandlerExtension.getInstances(myEnvironment.project).firstIsInstance<Kapt3ExtensionForTests>()
|
val kaptExtension = AnalysisHandlerExtension.getInstances(myEnvironment.project).firstIsInstance<Kapt3ExtensionForTests>()
|
||||||
|
|
||||||
val stubsOutputDir = kaptExtension.stubsOutputDir
|
val stubsOutputDir = kaptExtension.paths.stubsOutputDir
|
||||||
val incrementalDataOutputDir = kaptExtension.incrementalDataOutputDir
|
val incrementalDataOutputDir = kaptExtension.paths.incrementalDataOutputDir
|
||||||
|
|
||||||
val bindings = kaptExtension.savedBindings!!
|
val bindings = kaptExtension.savedBindings!!
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user