Kapt: Extract annotation processing running logic from the compiler plugin
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
<properties>
|
||||
<maven.version>3.0.4</maven.version>
|
||||
<annotation-processing.src>${basedir}/../../../plugins/kapt3/kapt3-compiler/src</annotation-processing.src>
|
||||
<annotation-processing.base.src>${basedir}/../../../plugins/kapt3/kapt3-base/src</annotation-processing.base.src>
|
||||
<annotation-processing.runtime.src>${basedir}/../../../plugins/kapt3/kapt3-runtime/src</annotation-processing.runtime.src>
|
||||
<annotation-processing.target-src>${basedir}/target/src/main/kotlin</annotation-processing.target-src>
|
||||
<annotation-processing.target-src-test>${basedir}/target/src/test/kotlin</annotation-processing.target-src-test>
|
||||
@@ -69,6 +70,7 @@
|
||||
<outputDirectory>${annotation-processing.target-src}</outputDirectory>
|
||||
<resources>
|
||||
<resource><directory>${annotation-processing.src}</directory></resource>
|
||||
<resource><directory>${annotation-processing.base.src}</directory></resource>
|
||||
<resource><directory>${annotation-processing.runtime.src}</directory></resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
|
||||
+18
-18
@@ -120,24 +120,6 @@ open class Kapt3IT : Kapt3BaseIT() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testArguments() {
|
||||
Project("arguments", directoryPrefix = "kapt2").build("build") {
|
||||
assertSuccessful()
|
||||
assertKaptSuccessful()
|
||||
assertContains(
|
||||
"Options: {suffix=Customized, justColon=:, justEquals==, containsColon=a:b, " +
|
||||
"containsEquals=a=b, startsWithColon=:a, startsWithEquals==a, endsWithColon=a:, " +
|
||||
"endsWithEquals=a:, withSpace=a b c,"
|
||||
)
|
||||
assertContains("-Xmaxerrs=500, -Xlint:all=-Xlint:all") // Javac options test
|
||||
assertFileExists("build/generated/source/kapt/main/example/TestClassCustomized.java")
|
||||
assertFileExists(kotlinClassesDir() + "example/TestClass.class")
|
||||
assertFileExists(javaClassesDir() + "example/TestClassCustomized.class")
|
||||
assertContains("Annotation processor class names are set, skip AP discovery")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInheritedAnnotations() {
|
||||
Project("inheritedAnnotations", directoryPrefix = "kapt2").build("build") {
|
||||
@@ -150,6 +132,24 @@ open class Kapt3IT : Kapt3BaseIT() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testArguments() {
|
||||
Project("arguments", directoryPrefix = "kapt2").build("build") {
|
||||
assertSuccessful()
|
||||
assertKaptSuccessful()
|
||||
assertContains(
|
||||
"AP options: {suffix=Customized, justColon=:, justEquals==, containsColon=a:b, " +
|
||||
"containsEquals=a=b, startsWithColon=:a, startsWithEquals==a, endsWithColon=a:, " +
|
||||
"endsWithEquals=a:, withSpace=a b c,"
|
||||
)
|
||||
assertContains("-Xmaxerrs=500, -Xlint:all=-Xlint:all") // Javac options test
|
||||
assertFileExists("build/generated/source/kapt/main/example/TestClassCustomized.java")
|
||||
assertFileExists(kotlinClassesDir() + "example/TestClass.class")
|
||||
assertFileExists(javaClassesDir() + "example/TestClassCustomized.class")
|
||||
assertContains("Annotation processor class names are set, skip AP discovery")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGeneratedDirectoryIsUpToDate() {
|
||||
val project = Project("generatedDirUpToDate", directoryPrefix = "kapt2")
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(projectDist(":kotlin-stdlib"))
|
||||
compile(files("${System.getProperty("java.home")}/../lib/tools.jar"))
|
||||
testCompile(commonDep("junit:junit"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
testsJar {}
|
||||
|
||||
projectTest {
|
||||
workingDir = rootDir
|
||||
dependsOn(":dist")
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.base
|
||||
|
||||
import com.sun.tools.javac.util.Context
|
||||
import org.jetbrains.kotlin.kapt3.base.util.KaptLogger
|
||||
import org.jetbrains.kotlin.kapt3.base.util.WriterBackedKaptLogger
|
||||
import org.jetbrains.kotlin.kapt3.base.util.info
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
object Kapt {
|
||||
private const val JAVAC_CONTEXT_CLASS = "com.sun.tools.javac.util.Context"
|
||||
|
||||
@JvmStatic
|
||||
@Suppress("unused")
|
||||
fun kapt(
|
||||
paths: KaptPaths,
|
||||
isVerbose: Boolean,
|
||||
mapDiagnosticLocations: Boolean,
|
||||
annotationProcessorFqNames: List<String>,
|
||||
processorOptions: Map<String, String>,
|
||||
javacOptions: Map<String, String>
|
||||
): Boolean {
|
||||
val logger = WriterBackedKaptLogger(isVerbose)
|
||||
|
||||
if (!Kapt.checkJavacComponentsAccess(logger)) {
|
||||
return false
|
||||
}
|
||||
|
||||
val kaptContext = KaptContext(paths, false, logger, mapDiagnosticLocations, processorOptions, javacOptions)
|
||||
|
||||
logger.info { "Kapt3 is enabled (stand-alone mode)." }
|
||||
logger.info { "Map diagnostic locations: $mapDiagnosticLocations" }
|
||||
paths.log(logger)
|
||||
logger.info { "Javac options: $javacOptions" }
|
||||
logger.info { "AP options: $processorOptions" }
|
||||
|
||||
val javaSourceFiles = paths.collectJavaSourceFiles()
|
||||
logger.info { "Java source files: " + javaSourceFiles.joinToString { it.canonicalPath } }
|
||||
|
||||
val processorLoader = ProcessorLoader(paths, annotationProcessorFqNames, logger)
|
||||
|
||||
processorLoader.use {
|
||||
val processors = processorLoader.loadProcessors(findClassLoaderWithJavac())
|
||||
|
||||
val annotationProcessingTime = measureTimeMillis {
|
||||
kaptContext.doAnnotationProcessing(javaSourceFiles, processors)
|
||||
}
|
||||
|
||||
logger.info { "Annotation processing took $annotationProcessingTime ms" }
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun checkJavacComponentsAccess(logger: KaptLogger): Boolean {
|
||||
try {
|
||||
Class.forName(JAVAC_CONTEXT_CLASS)
|
||||
return true
|
||||
} catch (e: ClassNotFoundException) {
|
||||
logger.error("'$JAVAC_CONTEXT_CLASS' class can't be found ('tools.jar' is absent in the plugin classpath). Kapt won't work.")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private fun findClassLoaderWithJavac(): ClassLoader {
|
||||
fun Class<*>.toClassFilePath() = name.replace('.', '/') + ".class"
|
||||
|
||||
// find topmost class loader with javac
|
||||
val javacContextPath = Context::class.java.toClassFilePath()
|
||||
val kaptPath = Kapt::class.java.toClassFilePath()
|
||||
|
||||
fun findRightClassLoader(current: ClassLoader): ClassLoader? {
|
||||
if (current.getResource(javacContextPath) != null && current.getResource(kaptPath) == null) {
|
||||
return current
|
||||
}
|
||||
|
||||
val parent = current.parent ?: return null
|
||||
return findRightClassLoader(parent)
|
||||
}
|
||||
|
||||
val kaptClassLoader = Kapt::class.java.classLoader
|
||||
return findRightClassLoader(kaptClassLoader) ?: kaptClassLoader
|
||||
}
|
||||
}
|
||||
+33
-48
@@ -1,54 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3
|
||||
package org.jetbrains.kotlin.kapt3.base
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.sun.tools.javac.jvm.ClassReader
|
||||
import com.sun.tools.javac.main.JavaCompiler
|
||||
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.Log
|
||||
import com.sun.tools.javac.util.Options
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
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.KaptTreeMaker
|
||||
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.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
import org.jetbrains.org.objectweb.asm.tree.ClassNode
|
||||
import org.jetbrains.kotlin.kapt3.base.javac.KaptJavaCompiler
|
||||
import org.jetbrains.kotlin.kapt3.base.javac.KaptJavaFileManager
|
||||
import org.jetbrains.kotlin.kapt3.base.javac.KaptJavaLog
|
||||
import org.jetbrains.kotlin.kapt3.base.util.KaptLogger
|
||||
import org.jetbrains.kotlin.kapt3.base.util.isJava9OrLater
|
||||
import org.jetbrains.kotlin.kapt3.base.util.putJavacOption
|
||||
import java.io.File
|
||||
import javax.tools.JavaFileManager
|
||||
|
||||
class KaptContext<out GState : GenerationState?>(
|
||||
open class KaptContext(
|
||||
val paths: KaptPaths,
|
||||
private val withJdk: Boolean,
|
||||
aptMode: AptMode,
|
||||
val withJdk: Boolean,
|
||||
val logger: KaptLogger,
|
||||
val project: Project,
|
||||
val bindingContext: BindingContext,
|
||||
val compiledClasses: List<ClassNode>,
|
||||
val origins: Map<Any, JvmDeclarationOrigin>,
|
||||
val generationState: GState,
|
||||
mapDiagnosticLocations: Boolean,
|
||||
private val mapDiagnosticLocations: Boolean,
|
||||
processorOptions: Map<String, String>,
|
||||
javacOptions: Map<String, String> = emptyMap()
|
||||
) : AutoCloseable {
|
||||
@@ -57,14 +33,26 @@ class KaptContext<out GState : GenerationState?>(
|
||||
val fileManager: KaptJavaFileManager
|
||||
val options: Options
|
||||
val javaLog: KaptJavaLog
|
||||
private val treeMaker: TreeMaker
|
||||
|
||||
protected open fun preregisterTreeMaker(context: Context) {}
|
||||
|
||||
private fun preregisterLog(context: Context) {
|
||||
val interceptorData = KaptJavaLog.DiagnosticInterceptorData()
|
||||
context.put(Log.logKey, Context.Factory<Log> { newContext ->
|
||||
KaptJavaLog(
|
||||
paths.projectBaseDir, newContext, logger.errorWriter, logger.warnWriter, logger.infoWriter,
|
||||
interceptorData, mapDiagnosticLocations
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
init {
|
||||
KaptJavaLog.preRegister(this, logger.messageCollector, mapDiagnosticLocations)
|
||||
preregisterLog(context)
|
||||
KaptJavaFileManager.preRegister(context)
|
||||
if (aptMode != AptMode.APT_ONLY) {
|
||||
KaptTreeMaker.preRegister(context, this)
|
||||
}
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
preregisterTreeMaker(context)
|
||||
|
||||
KaptJavaCompiler.preRegister(context)
|
||||
|
||||
options = Options.instance(context).apply {
|
||||
@@ -87,7 +75,7 @@ class KaptContext<out GState : GenerationState?>(
|
||||
putJavacOption("BOOTCLASSPATH", "BOOT_CLASS_PATH", "") // No boot classpath
|
||||
}
|
||||
|
||||
if (isJava9OrLater) {
|
||||
if (isJava9OrLater()) {
|
||||
put("accessInternalAPI", "true")
|
||||
}
|
||||
|
||||
@@ -102,12 +90,12 @@ class KaptContext<out GState : GenerationState?>(
|
||||
}
|
||||
|
||||
if (logger.isVerbose) {
|
||||
logger.info("Javac options: " + options.keySet().keysToMap { key -> options[key] ?: "" })
|
||||
logger.info("All Javac options: " + options.keySet().associateBy({ it }) { key -> options[key] ?: "" })
|
||||
}
|
||||
|
||||
fileManager = context.get(JavaFileManager::class.java) as KaptJavaFileManager
|
||||
|
||||
if (isJava9OrLater) {
|
||||
if (isJava9OrLater()) {
|
||||
for (option in Option.getJavacFileManagerOptions()) {
|
||||
val value = options.get(option) ?: continue
|
||||
fileManager.handleOptionJavac9(option, value)
|
||||
@@ -120,13 +108,10 @@ class KaptContext<out GState : GenerationState?>(
|
||||
ClassReader.instance(context).saveParameterNames = true
|
||||
|
||||
javaLog = compiler.log as KaptJavaLog
|
||||
treeMaker = TreeMaker.instance(context)
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
(treeMaker as? KaptTreeMaker)?.dispose()
|
||||
compiler.close()
|
||||
fileManager.close()
|
||||
generationState?.destroy()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.base
|
||||
|
||||
import org.jetbrains.kotlin.kapt3.base.util.KaptLogger
|
||||
import java.io.File
|
||||
|
||||
class KaptPaths(
|
||||
val projectBaseDir: File?,
|
||||
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()
|
||||
|
||||
fun collectJavaSourceFiles(): List<File> {
|
||||
return (javaSourceRoots + stubsOutputDir).flatMap { root ->
|
||||
root.walk().filter { it.isFile && it.extension == "java" }.toList()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun KaptPaths.log(logger: KaptLogger) {
|
||||
if (!logger.isVerbose) return
|
||||
|
||||
logger.info("Project base dir: $projectBaseDir")
|
||||
logger.info("Compile classpath: ${compileClasspath.joinToString()}")
|
||||
logger.info("Annotation processing classpath: ${annotationProcessingClasspath.joinToString()}")
|
||||
logger.info("Java source roots: ${javaSourceRoots.joinToString()}")
|
||||
logger.info("Sources output directory: $sourcesOutputDir")
|
||||
logger.info("Class files output directory: $classFilesOutputDir")
|
||||
logger.info("Stubs output directory: $stubsOutputDir")
|
||||
logger.info("Incremental data output directory: $incrementalDataOutputDir")
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.base
|
||||
|
||||
import org.jetbrains.kotlin.kapt3.base.util.KaptLogger
|
||||
import org.jetbrains.kotlin.kapt3.base.util.info
|
||||
import java.io.Closeable
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Modifier
|
||||
import java.net.URLClassLoader
|
||||
import java.util.*
|
||||
import javax.annotation.processing.Processor
|
||||
|
||||
class ProcessorLoader(
|
||||
private val paths: KaptPaths,
|
||||
private val annotationProcessorFqNames: List<String>,
|
||||
private val logger: KaptLogger
|
||||
) : Closeable {
|
||||
private var annotationProcessingClassLoader: URLClassLoader? = null
|
||||
|
||||
fun loadProcessors(parentClassLoader: ClassLoader = ClassLoader.getSystemClassLoader()): List<Processor> {
|
||||
clearJarURLCache()
|
||||
|
||||
val classpath = (paths.annotationProcessingClasspath + paths.compileClasspath).distinct()
|
||||
val classLoader = URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray(), parentClassLoader)
|
||||
this.annotationProcessingClassLoader = classLoader
|
||||
|
||||
val processors = if (annotationProcessorFqNames.isNotEmpty()) {
|
||||
logger.info("Annotation processor class names are set, skip AP discovery")
|
||||
annotationProcessorFqNames.mapNotNull { tryLoadProcessor(it, classLoader) }
|
||||
} else {
|
||||
logger.info("Need to discovery annotation processors in the AP classpath")
|
||||
ServiceLoader.load(Processor::class.java, classLoader).toList()
|
||||
}
|
||||
|
||||
if (processors.isEmpty()) {
|
||||
logger.info("No annotation processors available, aborting")
|
||||
} else {
|
||||
logger.info { "Annotation processors: " + processors.joinToString { it::class.java.canonicalName } }
|
||||
}
|
||||
|
||||
return processors
|
||||
}
|
||||
|
||||
|
||||
private fun tryLoadProcessor(fqName: String, classLoader: ClassLoader): Processor? {
|
||||
val annotationProcessorClass = try {
|
||||
Class.forName(fqName, true, classLoader)
|
||||
} catch (e: Throwable) {
|
||||
logger.warn("Can't find annotation processor class $fqName: ${e.message}")
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
val annotationProcessorInstance = annotationProcessorClass.newInstance()
|
||||
if (annotationProcessorInstance !is Processor) {
|
||||
logger.warn("$fqName is not an instance of 'Processor'")
|
||||
return null
|
||||
}
|
||||
|
||||
return annotationProcessorInstance
|
||||
} catch (e: Throwable) {
|
||||
logger.warn("Can't load annotation processor class $fqName: ${e.message}")
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
annotationProcessingClassLoader?.close()
|
||||
clearJarURLCache()
|
||||
}
|
||||
}
|
||||
|
||||
// Copied from com.intellij.ide.ClassUtilCore
|
||||
private fun clearJarURLCache() {
|
||||
fun clearMap(cache: Field) {
|
||||
cache.isAccessible = true
|
||||
|
||||
if (!Modifier.isFinal(cache.modifiers)) {
|
||||
cache.set(null, hashMapOf<Any, Any>())
|
||||
} else {
|
||||
val map = cache.get(null) as MutableMap<*, *>
|
||||
map.clear()
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
val jarFileFactory = Class.forName("sun.net.www.protocol.jar.JarFileFactory")
|
||||
|
||||
clearMap(jarFileFactory.getDeclaredField("fileCache"))
|
||||
clearMap(jarFileFactory.getDeclaredField("urlCache"))
|
||||
} catch (ignore: Exception) {}
|
||||
}
|
||||
+14
-27
@@ -1,32 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3
|
||||
package org.jetbrains.kotlin.kapt3.base
|
||||
|
||||
import com.sun.tools.javac.comp.CompileStates.*
|
||||
import com.sun.tools.javac.main.JavaCompiler
|
||||
import com.sun.tools.javac.main.Option
|
||||
import com.sun.tools.javac.processing.AnnotationProcessingError
|
||||
import com.sun.tools.javac.processing.JavacFiler
|
||||
import com.sun.tools.javac.processing.JavacProcessingEnvironment
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import org.jetbrains.kotlin.kapt3.diagnostic.KaptError
|
||||
import org.jetbrains.kotlin.kapt3.util.isJava9OrLater
|
||||
import org.jetbrains.kotlin.kapt3.util.putJavacOption
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.measureTimeMillisWithResult
|
||||
import org.jetbrains.kotlin.kapt3.base.util.KaptBaseError
|
||||
import org.jetbrains.kotlin.kapt3.base.util.isJava9OrLater
|
||||
import org.jetbrains.kotlin.kapt3.base.util.measureTimeMillisWithResult
|
||||
import java.io.File
|
||||
import javax.annotation.processing.Processor
|
||||
import javax.annotation.processing.RoundEnvironment
|
||||
@@ -34,7 +21,7 @@ import javax.lang.model.element.TypeElement
|
||||
import javax.tools.JavaFileObject
|
||||
import com.sun.tools.javac.util.List as JavacList
|
||||
|
||||
fun KaptContext<*>.doAnnotationProcessing(
|
||||
fun KaptContext.doAnnotationProcessing(
|
||||
javaSourceFiles: List<File>,
|
||||
processors: List<Processor>,
|
||||
additionalSources: JavacList<JCTree.JCCompilationUnit> = JavacList.nil()
|
||||
@@ -44,7 +31,7 @@ fun KaptContext<*>.doAnnotationProcessing(
|
||||
|
||||
val compilerAfterAP: JavaCompiler
|
||||
try {
|
||||
if (isJava9OrLater) {
|
||||
if (isJava9OrLater()) {
|
||||
val initProcessAnnotationsMethod = JavaCompiler::class.java.declaredMethods.single { it.name == "initProcessAnnotations" }
|
||||
initProcessAnnotationsMethod.invoke(compiler, wrappedProcessors, emptyList<JavaFileObject>(), emptyList<String>())
|
||||
}
|
||||
@@ -59,7 +46,7 @@ fun KaptContext<*>.doAnnotationProcessing(
|
||||
val analyzedFiles = compiler.stopIfErrorOccurred(
|
||||
CompileState.PARSE, compiler.enterTrees(parsedJavaFiles + additionalSources))
|
||||
|
||||
if (isJava9OrLater) {
|
||||
if (isJava9OrLater()) {
|
||||
val processAnnotationsMethod = compiler.javaClass.getMethod("processAnnotations", JavacList::class.java)
|
||||
processAnnotationsMethod.invoke(compiler, analyzedFiles)
|
||||
compiler
|
||||
@@ -68,7 +55,7 @@ fun KaptContext<*>.doAnnotationProcessing(
|
||||
compiler.processAnnotations(analyzedFiles)
|
||||
}
|
||||
} catch (e: AnnotationProcessingError) {
|
||||
throw KaptError(KaptError.Kind.EXCEPTION, e.cause ?: e)
|
||||
throw KaptBaseError(KaptBaseError.Kind.EXCEPTION, e.cause ?: e)
|
||||
}
|
||||
|
||||
val log = compilerAfterAP.log
|
||||
@@ -93,7 +80,7 @@ fun KaptContext<*>.doAnnotationProcessing(
|
||||
}
|
||||
|
||||
if (log.nerrors > 0) {
|
||||
throw KaptError(KaptError.Kind.ERROR_RAISED)
|
||||
throw KaptBaseError(KaptBaseError.Kind.ERROR_RAISED)
|
||||
}
|
||||
} finally {
|
||||
processingEnvironment.close()
|
||||
@@ -117,7 +104,7 @@ private class ProcessorWrapper(private val delegate: Processor) : Processor by d
|
||||
}
|
||||
}
|
||||
|
||||
internal fun KaptContext<*>.parseJavaFiles(javaSourceFiles: List<File>): JavacList<JCTree.JCCompilationUnit> {
|
||||
fun KaptContext.parseJavaFiles(javaSourceFiles: List<File>): JavacList<JCTree.JCCompilationUnit> {
|
||||
val javaFileObjects = fileManager.getJavaFileObjectsFromFiles(javaSourceFiles)
|
||||
|
||||
return compiler.stopIfErrorOccurred(CompileState.PARSE,
|
||||
@@ -126,8 +113,8 @@ internal fun KaptContext<*>.parseJavaFiles(javaSourceFiles: List<File>): JavacLi
|
||||
compiler.parseFiles(javaFileObjects))))
|
||||
}
|
||||
|
||||
private fun KaptContext<*>.initModulesIfNeeded(files: JavacList<JCTree.JCCompilationUnit>): JavacList<JCTree.JCCompilationUnit> {
|
||||
if (isJava9OrLater) {
|
||||
private fun KaptContext.initModulesIfNeeded(files: JavacList<JCTree.JCCompilationUnit>): JavacList<JCTree.JCCompilationUnit> {
|
||||
if (isJava9OrLater()) {
|
||||
val initModulesMethod = compiler.javaClass.getMethod("initModules", JavacList::class.java)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
+3
-14
@@ -1,20 +1,9 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.javac
|
||||
package org.jetbrains.kotlin.kapt3.base.javac
|
||||
|
||||
import com.sun.tools.javac.comp.CompileStates
|
||||
import com.sun.tools.javac.main.JavaCompiler
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
package org.jetbrains.kotlin.kapt3.javac
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.base.javac
|
||||
|
||||
import com.sun.tools.javac.file.JavacFileManager
|
||||
import com.sun.tools.javac.main.Option
|
||||
+18
-48
@@ -1,32 +1,17 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.javac
|
||||
package org.jetbrains.kotlin.kapt3.base.javac
|
||||
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import com.sun.tools.javac.util.*
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.kapt3.KaptContext
|
||||
import org.jetbrains.kotlin.kapt3.stubs.KaptStubLineInformation
|
||||
import org.jetbrains.kotlin.kapt3.stubs.KotlinPosition
|
||||
import org.jetbrains.kotlin.kapt3.util.MessageCollectorBackedWriter
|
||||
import org.jetbrains.kotlin.kapt3.util.isJava9OrLater
|
||||
import org.jetbrains.kotlin.kapt3.base.KaptContext
|
||||
import org.jetbrains.kotlin.kapt3.base.stubs.KaptStubLineInformation
|
||||
import org.jetbrains.kotlin.kapt3.base.stubs.KotlinPosition
|
||||
import org.jetbrains.kotlin.kapt3.base.util.isJava9OrLater
|
||||
import java.io.*
|
||||
import javax.tools.Diagnostic
|
||||
import javax.tools.JavaFileObject
|
||||
@@ -35,14 +20,14 @@ import javax.tools.SimpleJavaFileObject
|
||||
import com.sun.tools.javac.util.List as JavacList
|
||||
|
||||
class KaptJavaLog(
|
||||
private val projectBasePath: String?,
|
||||
context: Context,
|
||||
errWriter: PrintWriter,
|
||||
warnWriter: PrintWriter,
|
||||
noticeWriter: PrintWriter,
|
||||
val interceptorData: DiagnosticInterceptorData,
|
||||
val mapDiagnosticLocations: Boolean
|
||||
) : Log(context, errWriter, warnWriter, noticeWriter) {
|
||||
private val projectBaseDir: File?,
|
||||
context: Context,
|
||||
errWriter: PrintWriter,
|
||||
warnWriter: PrintWriter,
|
||||
noticeWriter: PrintWriter,
|
||||
val interceptorData: DiagnosticInterceptorData,
|
||||
private val mapDiagnosticLocations: Boolean
|
||||
) : Log(context, errWriter, warnWriter, noticeWriter) {
|
||||
private val stubLineInfo = KaptStubLineInformation()
|
||||
private val javacMessages = JavacMessages.instance(context)
|
||||
|
||||
@@ -183,7 +168,7 @@ class KaptJavaLog(
|
||||
|
||||
private fun getKotlinSourceFile(pos: KotlinPosition): File? {
|
||||
return if (pos.isRelativePath) {
|
||||
val basePath = this.projectBasePath
|
||||
val basePath = this.projectBaseDir
|
||||
if (basePath != null) File(basePath, pos.path) else null
|
||||
}
|
||||
else {
|
||||
@@ -232,21 +217,6 @@ class KaptJavaLog(
|
||||
"compiler.err.not.def.access.package.cant.access",
|
||||
"compiler.err.package.not.visible"
|
||||
)
|
||||
|
||||
internal fun preRegister(kaptContext: KaptContext<*>, messageCollector: MessageCollector, mapDiagnosticLocations: Boolean) {
|
||||
val interceptorData = DiagnosticInterceptorData()
|
||||
kaptContext.context.put(Log.logKey, Context.Factory<Log> { newContext ->
|
||||
fun makeWriter(severity: CompilerMessageSeverity) = PrintWriter(MessageCollectorBackedWriter(messageCollector, severity))
|
||||
|
||||
val errWriter = makeWriter(ERROR)
|
||||
val warnWriter = makeWriter(STRONG_WARNING)
|
||||
val noticeWriter = makeWriter(WARNING)
|
||||
|
||||
KaptJavaLog(
|
||||
kaptContext.project.basePath, newContext, errWriter, warnWriter, noticeWriter,
|
||||
interceptorData, mapDiagnosticLocations)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
class DiagnosticInterceptorData {
|
||||
@@ -254,7 +224,7 @@ class KaptJavaLog(
|
||||
}
|
||||
}
|
||||
|
||||
fun KaptContext<*>.kaptError(text: String): JCDiagnostic {
|
||||
fun KaptContext.kaptError(text: String): JCDiagnostic {
|
||||
return JCDiagnostic.Factory.instance(context).errorJava9Aware(null, null, "proc.messager", text)
|
||||
}
|
||||
|
||||
@@ -264,7 +234,7 @@ private fun JCDiagnostic.Factory.errorJava9Aware(
|
||||
key: String,
|
||||
vararg args: String
|
||||
): JCDiagnostic {
|
||||
return if (isJava9OrLater) {
|
||||
return if (isJava9OrLater()) {
|
||||
val errorMethod = this::class.java.getDeclaredMethod(
|
||||
"error",
|
||||
JCDiagnostic.DiagnosticFlag::class.java,
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.base.stubs
|
||||
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
|
||||
fun JCTree.JCMethodDecl.getJavacSignature(): String {
|
||||
val name = name.toString()
|
||||
val params = parameters.joinToString { it.getType().toString() }
|
||||
return "$name($params)"
|
||||
}
|
||||
|
||||
typealias LineInfoMap = MutableMap<String, KotlinPosition>
|
||||
|
||||
class FileInfo(private val lineInfo: LineInfoMap, private val signatureInfo: Map<String, String>) {
|
||||
companion object {
|
||||
val EMPTY = FileInfo(mutableMapOf(), emptyMap())
|
||||
}
|
||||
|
||||
fun getPositionFor(fqName: String) = lineInfo[fqName]
|
||||
fun getMethodDescriptor(decl: JCTree.JCMethodDecl) = signatureInfo[decl.getJavacSignature()]
|
||||
}
|
||||
+60
-17
@@ -1,34 +1,77 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.stubs
|
||||
package org.jetbrains.kotlin.kapt3.base.stubs
|
||||
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import com.sun.tools.javac.tree.TreeScanner
|
||||
import org.jetbrains.kotlin.kapt3.stubs.KaptLineMappingCollector.FileInfo
|
||||
import org.jetbrains.kotlin.kapt3.util.getPackageNameJava9Aware
|
||||
import org.jetbrains.kotlin.kapt3.base.util.getPackageNameJava9Aware
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.File
|
||||
import java.io.ObjectInputStream
|
||||
|
||||
class KaptStubLineInformation {
|
||||
private val offsets = mutableMapOf<JCTree.JCCompilationUnit, FileInfo>()
|
||||
private val declarations = mutableMapOf<JCTree.JCCompilationUnit, List<JCTree>>()
|
||||
|
||||
companion object {
|
||||
const val KAPT_METADATA_EXTENSION = ".kapt_metadata"
|
||||
const val METADATA_VERSION = 1
|
||||
|
||||
fun parseFileInfo(file: JCTree.JCCompilationUnit): FileInfo {
|
||||
val sourceUri = file.sourcefile
|
||||
?.toUri()
|
||||
?.takeIf { it.isAbsolute && !it.isOpaque && it.path != null && it.scheme?.toLowerCase() == "file" } ?: return FileInfo.EMPTY
|
||||
|
||||
val sourceFile = File(sourceUri).takeIf { it.exists() } ?: return FileInfo.EMPTY
|
||||
val kaptMetadataFile = File(sourceFile.parentFile, sourceFile.nameWithoutExtension + KAPT_METADATA_EXTENSION)
|
||||
|
||||
if (!kaptMetadataFile.isFile) {
|
||||
return FileInfo.EMPTY
|
||||
}
|
||||
|
||||
return deserialize(kaptMetadataFile.readBytes())
|
||||
}
|
||||
|
||||
private fun deserialize(data: ByteArray): FileInfo {
|
||||
val lineInfo: LineInfoMap = mutableMapOf()
|
||||
val signatureInfo = mutableMapOf<String, String>()
|
||||
|
||||
val ois = ObjectInputStream(ByteArrayInputStream(data))
|
||||
|
||||
val version = ois.readInt()
|
||||
if (version != METADATA_VERSION) {
|
||||
return FileInfo.EMPTY
|
||||
}
|
||||
|
||||
val lineInfoCount = ois.readInt()
|
||||
repeat(lineInfoCount) {
|
||||
val fqName = ois.readUTF()
|
||||
val path = ois.readUTF()
|
||||
val isRelative = ois.readBoolean()
|
||||
val pos = ois.readInt()
|
||||
|
||||
lineInfo[fqName] = KotlinPosition(path, isRelative, pos)
|
||||
}
|
||||
|
||||
val signatureCount = ois.readInt()
|
||||
repeat(signatureCount) {
|
||||
val javacSignature = ois.readUTF()
|
||||
val methodDesc = ois.readUTF()
|
||||
|
||||
signatureInfo[javacSignature] = methodDesc
|
||||
}
|
||||
|
||||
return FileInfo(lineInfo, signatureInfo)
|
||||
}
|
||||
}
|
||||
|
||||
fun getPositionInKotlinFile(file: JCTree.JCCompilationUnit, element: JCTree): KotlinPosition? {
|
||||
val declaration = findDeclarationFor(element, file) ?: return null
|
||||
|
||||
val fileInfo = offsets.getOrPut(file) { KaptLineMappingCollector.parseFileInfo(file) }
|
||||
val fileInfo = offsets.getOrPut(file) { parseFileInfo(file) }
|
||||
val elementDescriptor = getKaptDescriptor(declaration, file, fileInfo) ?: return null
|
||||
|
||||
return fileInfo.getPositionFor(elementDescriptor)
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.base.stubs
|
||||
|
||||
data class KotlinPosition(val path: String, val isRelativePath: Boolean, val pos: Int)
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.base.util
|
||||
|
||||
class KaptBaseError : RuntimeException {
|
||||
val kind: Kind
|
||||
|
||||
enum class Kind(val message: String) {
|
||||
EXCEPTION("Exception while annotation processing"),
|
||||
ERROR_RAISED("Error while annotation processing"),
|
||||
}
|
||||
|
||||
constructor(kind: Kind) : super(kind.message) {
|
||||
this.kind = kind
|
||||
}
|
||||
|
||||
constructor(kind: Kind, cause: Throwable) : super(kind.message, cause) {
|
||||
this.kind = kind
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.base.util
|
||||
|
||||
import java.io.PrintWriter
|
||||
|
||||
interface KaptLogger {
|
||||
val isVerbose: Boolean
|
||||
|
||||
val infoWriter: PrintWriter
|
||||
val warnWriter: PrintWriter
|
||||
val errorWriter: PrintWriter
|
||||
|
||||
fun info(message: String)
|
||||
fun warn(message: String)
|
||||
fun error(message: String)
|
||||
|
||||
fun exception(e: Throwable)
|
||||
}
|
||||
|
||||
inline fun KaptLogger.info(message: () -> String) {
|
||||
if (isVerbose) {
|
||||
info(message())
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.base.util
|
||||
|
||||
import java.io.PrintWriter
|
||||
|
||||
class WriterBackedKaptLogger(
|
||||
override val isVerbose: Boolean,
|
||||
override val infoWriter: PrintWriter = PrintWriter(System.out),
|
||||
override val warnWriter: PrintWriter = PrintWriter(System.out),
|
||||
override val errorWriter: PrintWriter = PrintWriter(System.err)
|
||||
) : KaptLogger {
|
||||
override fun info(message: String) {
|
||||
if (isVerbose) {
|
||||
report("INFO", message, infoWriter)
|
||||
}
|
||||
}
|
||||
|
||||
override fun warn(message: String) {
|
||||
report("WARN", message, warnWriter)
|
||||
}
|
||||
|
||||
override fun error(message: String) {
|
||||
report("ERROR", message, errorWriter)
|
||||
}
|
||||
|
||||
override fun exception(e: Throwable) {
|
||||
errorWriter.println("An error occurred:")
|
||||
e.printStackTrace(errorWriter)
|
||||
errorWriter.flush()
|
||||
}
|
||||
|
||||
private fun report(prefix: String, message: String, writer: PrintWriter) {
|
||||
writer.println("[$prefix] $message")
|
||||
writer.flush()
|
||||
}
|
||||
}
|
||||
+12
-17
@@ -14,32 +14,29 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.util
|
||||
package org.jetbrains.kotlin.kapt3.base.util
|
||||
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.sun.tools.javac.main.Option
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import com.sun.tools.javac.tree.TreeMaker
|
||||
import com.sun.tools.javac.util.Options
|
||||
import com.sun.tools.javac.util.List as JavacList
|
||||
import org.jetbrains.kotlin.kapt3.plus
|
||||
import org.jetbrains.kotlin.kapt3.base.plus
|
||||
|
||||
internal val isJava9OrLater: Boolean
|
||||
get() = SystemInfo.isJavaVersionAtLeast("9")
|
||||
fun isJava9OrLater(): Boolean = !System.getProperty("java.version").startsWith("1.")
|
||||
|
||||
internal fun Options.putJavacOption(jdk8Name: String, jdk9Name: String, value: String) {
|
||||
val option = if (isJava9OrLater) {
|
||||
fun Options.putJavacOption(jdk8Name: String, jdk9Name: String, value: String) {
|
||||
val option = if (isJava9OrLater()) {
|
||||
Option.valueOf(jdk9Name)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Option.valueOf(jdk8Name)
|
||||
}
|
||||
|
||||
put(option, value)
|
||||
}
|
||||
|
||||
internal fun TreeMaker.TopLevelJava9Aware(packageClause: JCTree.JCExpression?, declarations: JavacList<JCTree>): JCTree.JCCompilationUnit {
|
||||
return if (isJava9OrLater) {
|
||||
fun TreeMaker.TopLevelJava9Aware(packageClause: JCTree.JCExpression?, declarations: JavacList<JCTree>): JCTree.JCCompilationUnit {
|
||||
return if (isJava9OrLater()) {
|
||||
val topLevelMethod = TreeMaker::class.java.declaredMethods.single { it.name == "TopLevel" }
|
||||
val packageDecl: JCTree? = packageClause?.let {
|
||||
val packageDeclMethod = TreeMaker::class.java.methods.single { it.name == "PackageDecl" }
|
||||
@@ -47,17 +44,15 @@ internal fun TreeMaker.TopLevelJava9Aware(packageClause: JCTree.JCExpression?, d
|
||||
}
|
||||
val allDeclarations = if (packageDecl != null) JavacList.of(packageDecl) + declarations else declarations
|
||||
topLevelMethod.invoke(this, allDeclarations) as JCTree.JCCompilationUnit
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
TopLevel(JavacList.nil(), packageClause, declarations)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun JCTree.JCCompilationUnit.getPackageNameJava9Aware(): JCTree? {
|
||||
return if (isJava9OrLater) {
|
||||
fun JCTree.JCCompilationUnit.getPackageNameJava9Aware(): JCTree? {
|
||||
return if (isJava9OrLater()) {
|
||||
JCTree.JCCompilationUnit::class.java.getDeclaredMethod("getPackageName").invoke(this) as JCTree?
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.packageName
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.base
|
||||
|
||||
import com.sun.tools.javac.util.List as JavacList
|
||||
|
||||
inline fun <T, R> mapJList(values: Iterable<T>?, f: (T) -> R?): JavacList<R> {
|
||||
if (values == null) return JavacList.nil()
|
||||
|
||||
var result = JavacList.nil<R>()
|
||||
for (item in values) {
|
||||
f(item)?.let { result = result.append(it) }
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
inline fun <T, R> mapJListIndexed(values: Iterable<T>?, f: (Int, T) -> R?): JavacList<R> {
|
||||
if (values == null) return JavacList.nil()
|
||||
|
||||
var result = JavacList.nil<R>()
|
||||
values.forEachIndexed { index, item ->
|
||||
f(index, item)?.let { result = result.append(it) }
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
inline fun <T> mapPairedValuesJList(valuePairs: List<Any>?, f: (String, Any) -> T?): JavacList<T> {
|
||||
if (valuePairs == null || valuePairs.isEmpty()) return JavacList.nil()
|
||||
|
||||
val size = valuePairs.size
|
||||
var result = JavacList.nil<T>()
|
||||
assert(size % 2 == 0)
|
||||
var index = 0
|
||||
while (index < size) {
|
||||
val key = valuePairs[index] as String
|
||||
val value = valuePairs[index + 1]
|
||||
f(key, value)?.let { result = result.prepend(it) }
|
||||
index += 2
|
||||
}
|
||||
return result.reverse()
|
||||
}
|
||||
|
||||
fun pairedListToMap(valuePairs: List<Any>?): Map<String, Any?> {
|
||||
val map = mutableMapOf<String, Any?>()
|
||||
|
||||
mapPairedValuesJList(valuePairs) { key, value ->
|
||||
map.put(key, value)
|
||||
}
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
operator fun <T : Any> JavacList<T>.plus(other: JavacList<T>): JavacList<T> {
|
||||
return this.appendList(other)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.base.util
|
||||
|
||||
inline fun <T> measureTimeMillisWithResult(block: () -> T) : Pair<Long, T> {
|
||||
val start = System.currentTimeMillis()
|
||||
val result = block()
|
||||
return Pair(System.currentTimeMillis() - start, result)
|
||||
}
|
||||
+18
-57
@@ -1,32 +1,15 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.test
|
||||
|
||||
import com.intellij.openapi.command.impl.DummyProject
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
|
||||
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.KaptPaths
|
||||
import org.jetbrains.kotlin.kapt3.diagnostic.KaptError
|
||||
import org.jetbrains.kotlin.kapt3.doAnnotationProcessing
|
||||
import org.jetbrains.kotlin.kapt3.util.KaptLogger
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.junit.Assert.*
|
||||
import org.jetbrains.kotlin.kapt3.base.KaptContext
|
||||
import org.jetbrains.kotlin.kapt3.base.KaptPaths
|
||||
import org.jetbrains.kotlin.kapt3.base.doAnnotationProcessing
|
||||
import org.jetbrains.kotlin.kapt3.base.util.KaptBaseError
|
||||
import org.jetbrains.kotlin.kapt3.base.util.WriterBackedKaptLogger
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
@@ -35,26 +18,9 @@ import javax.annotation.processing.Processor
|
||||
import javax.annotation.processing.RoundEnvironment
|
||||
import javax.lang.model.element.TypeElement
|
||||
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
class JavaKaptContextTest {
|
||||
companion object {
|
||||
private val TEST_DATA_DIR = File("plugins/kapt3/kapt3-compiler/testData/runner")
|
||||
val messageCollector = PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, false)
|
||||
private val TEST_DATA_DIR = File("plugins/kapt3/kapt3-base/testData/runner")
|
||||
|
||||
fun simpleProcessor() = object : AbstractProcessor() {
|
||||
override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
|
||||
@@ -84,6 +50,7 @@ class JavaKaptContextTest {
|
||||
private fun doAnnotationProcessing(javaSourceFile: File, processor: Processor, outputDir: File) {
|
||||
KaptContext(
|
||||
KaptPaths(
|
||||
projectBaseDir = javaSourceFile.parentFile,
|
||||
compileClasspath = emptyList(),
|
||||
annotationProcessingClasspath = emptyList(),
|
||||
javaSourceRoots = emptyList(),
|
||||
@@ -93,13 +60,7 @@ class JavaKaptContextTest {
|
||||
incrementalDataOutputDir = outputDir
|
||||
),
|
||||
withJdk = true,
|
||||
aptMode = AptMode.STUBS_AND_APT,
|
||||
logger = KaptLogger(isVerbose = true, messageCollector = messageCollector),
|
||||
project = DummyProject.getInstance(),
|
||||
bindingContext = BindingContext.EMPTY,
|
||||
compiledClasses = emptyList(),
|
||||
origins = emptyMap(),
|
||||
generationState = null,
|
||||
logger = WriterBackedKaptLogger(isVerbose = true),
|
||||
mapDiagnosticLocations = true,
|
||||
processorOptions = emptyMap()
|
||||
).doAnnotationProcessing(listOf(javaSourceFile), listOf(processor))
|
||||
@@ -117,7 +78,7 @@ class JavaKaptContextTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = KaptError::class)
|
||||
@Test(expected = KaptBaseError::class)
|
||||
fun testException() {
|
||||
val exceptionMessage = "Here we are!"
|
||||
|
||||
@@ -131,19 +92,19 @@ class JavaKaptContextTest {
|
||||
|
||||
try {
|
||||
doAnnotationProcessing(File(TEST_DATA_DIR, "Simple.java"), processor, TEST_DATA_DIR)
|
||||
} catch (e: KaptError) {
|
||||
assertEquals(KaptError.Kind.EXCEPTION, e.kind)
|
||||
} catch (e: KaptBaseError) {
|
||||
assertEquals(KaptBaseError.Kind.EXCEPTION, e.kind)
|
||||
assertEquals("Here we are!", e.cause!!.message)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = KaptError::class)
|
||||
@Test(expected = KaptBaseError::class)
|
||||
fun testParsingError() {
|
||||
try {
|
||||
doAnnotationProcessing(File(TEST_DATA_DIR, "ParseError.java"), simpleProcessor(), TEST_DATA_DIR)
|
||||
} catch (e: KaptError) {
|
||||
assertEquals(KaptError.Kind.ERROR_RAISED, e.kind)
|
||||
} catch (e: KaptBaseError) {
|
||||
assertEquals(KaptBaseError.Kind.ERROR_RAISED, e.kind)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
@@ -17,16 +17,20 @@ dependencies {
|
||||
compile(project(":compiler:frontend"))
|
||||
compile(project(":compiler:frontend.java"))
|
||||
compile(project(":compiler:plugin-api"))
|
||||
compileOnly(project(":kotlin-annotation-processing-base"))
|
||||
compileOnly(project(":kotlin-annotation-processing-runtime"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compileOnly(intellijDep()) { includeJars("asm-all") }
|
||||
|
||||
testCompile(project(":compiler:tests-common"))
|
||||
testCompile(projectTests(":compiler:tests-common"))
|
||||
testCompile(project(":kotlin-annotation-processing-base"))
|
||||
testCompile(projectTests(":kotlin-annotation-processing-base"))
|
||||
testCompile(commonDep("junit:junit"))
|
||||
testCompile(project(":kotlin-annotation-processing-runtime"))
|
||||
|
||||
embeddedComponents(project(":kotlin-annotation-processing-runtime")) { isTransitive = false }
|
||||
embeddedComponents(project(":kotlin-annotation-processing-base")) { isTransitive = false }
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
||||
@@ -17,16 +17,20 @@ dependencies {
|
||||
compile(project(":compiler:frontend"))
|
||||
compile(project(":compiler:frontend.java"))
|
||||
compile(project(":compiler:plugin-api"))
|
||||
compileOnly(project(":kotlin-annotation-processing-base"))
|
||||
compileOnly(project(":kotlin-annotation-processing-runtime"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compileOnly(intellijDep()) { includeJars("asm-all") }
|
||||
|
||||
testCompile(project(":compiler:tests-common"))
|
||||
testCompile(projectTests(":compiler:tests-common"))
|
||||
testCompile(project(":kotlin-annotation-processing-base"))
|
||||
testCompile(projectTests(":kotlin-annotation-processing-base"))
|
||||
testCompile(commonDep("junit:junit"))
|
||||
testCompile(project(":kotlin-annotation-processing-runtime"))
|
||||
|
||||
embeddedComponents(project(":kotlin-annotation-processing-runtime")) { isTransitive = false }
|
||||
embeddedComponents(project(":kotlin-annotation-processing-base")) { isTransitive = false }
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
||||
@@ -17,16 +17,20 @@ dependencies {
|
||||
compile(project(":compiler:frontend"))
|
||||
compile(project(":compiler:frontend.java"))
|
||||
compile(project(":compiler:plugin-api"))
|
||||
compileOnly(project(":kotlin-annotation-processing-base"))
|
||||
compileOnly(project(":kotlin-annotation-processing-runtime"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compileOnly(intellijDep()) { includeJars("asm-all") }
|
||||
|
||||
testCompile(project(":compiler:tests-common"))
|
||||
testCompile(projectTests(":compiler:tests-common"))
|
||||
testCompile(project(":kotlin-annotation-processing-base"))
|
||||
testCompile(projectTests(":kotlin-annotation-processing-base"))
|
||||
testCompile(commonDep("junit:junit"))
|
||||
testCompile(project(":kotlin-annotation-processing-runtime"))
|
||||
|
||||
embeddedComponents(project(":kotlin-annotation-processing-runtime")) { isTransitive = false }
|
||||
embeddedComponents(project(":kotlin-annotation-processing-base")) { isTransitive = false }
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
||||
@@ -16,14 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.kapt3
|
||||
|
||||
import com.intellij.ide.ClassUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.sun.tools.javac.code.Flags
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import com.sun.tools.javac.tree.Pretty
|
||||
import com.sun.tools.javac.tree.TreeMaker
|
||||
import com.sun.tools.javac.util.Context
|
||||
import com.sun.tools.javac.util.Convert
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.OUTPUT
|
||||
@@ -39,39 +37,29 @@ import org.jetbrains.kotlin.container.ComponentProvider
|
||||
import org.jetbrains.kotlin.context.ProjectContext
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.kapt3.AptMode.*
|
||||
import org.jetbrains.kotlin.kapt3.base.KaptContext
|
||||
import org.jetbrains.kotlin.kapt3.base.KaptPaths
|
||||
import org.jetbrains.kotlin.kapt3.base.ProcessorLoader
|
||||
import org.jetbrains.kotlin.kapt3.base.doAnnotationProcessing
|
||||
import org.jetbrains.kotlin.kapt3.base.util.KaptBaseError
|
||||
import org.jetbrains.kotlin.kapt3.diagnostic.KaptError
|
||||
import org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter
|
||||
import org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter.KaptStub
|
||||
import org.jetbrains.kotlin.kapt3.stubs.KaptLineMappingCollector.Companion.KAPT_METADATA_EXTENSION
|
||||
import org.jetbrains.kotlin.kapt3.util.KaptLogger
|
||||
import org.jetbrains.kotlin.kapt3.util.getPackageNameJava9Aware
|
||||
import org.jetbrains.kotlin.kapt3.base.stubs.KaptStubLineInformation.Companion.KAPT_METADATA_EXTENSION
|
||||
import org.jetbrains.kotlin.kapt3.base.util.getPackageNameJava9Aware
|
||||
import org.jetbrains.kotlin.kapt3.base.util.info
|
||||
import org.jetbrains.kotlin.kapt3.util.MessageCollectorBackedKaptLogger
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.PartialAnalysisHandlerExtension
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.StringWriter
|
||||
import java.io.Writer
|
||||
import java.net.URLClassLoader
|
||||
import java.util.*
|
||||
import javax.annotation.processing.Processor
|
||||
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(
|
||||
paths: KaptPaths,
|
||||
options: Map<String, String>,
|
||||
@@ -82,14 +70,18 @@ class ClasspathBasedKapt3Extension(
|
||||
correctErrorTypes: Boolean,
|
||||
mapDiagnosticLocations: Boolean,
|
||||
pluginInitializedTime: Long,
|
||||
logger: KaptLogger,
|
||||
logger: MessageCollectorBackedKaptLogger,
|
||||
compilerConfiguration: CompilerConfiguration
|
||||
) : AbstractKapt3Extension(paths, options, javacOptions, annotationProcessorFqNames,
|
||||
aptMode, pluginInitializedTime, logger, correctErrorTypes, mapDiagnosticLocations, compilerConfiguration) {
|
||||
override val analyzePartially: Boolean
|
||||
get() = useLightAnalysis
|
||||
|
||||
private var annotationProcessingClassLoader: URLClassLoader? = null
|
||||
private var processorLoader: ProcessorLoader? = null
|
||||
|
||||
override fun loadProcessors(): List<Processor> {
|
||||
return ProcessorLoader(paths, annotationProcessorFqNames, logger).also { this.processorLoader = it }.loadProcessors()
|
||||
}
|
||||
|
||||
override fun analysisCompleted(
|
||||
project: Project,
|
||||
@@ -100,54 +92,7 @@ class ClasspathBasedKapt3Extension(
|
||||
try {
|
||||
return super.analysisCompleted(project, module, bindingTrace, files)
|
||||
} finally {
|
||||
annotationProcessingClassLoader?.close()
|
||||
ClassUtilCore.clearJarURLCache()
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadProcessors(): List<Processor> {
|
||||
ClassUtilCore.clearJarURLCache()
|
||||
|
||||
val classpath = (paths.annotationProcessingClasspath + paths.compileClasspath).distinct()
|
||||
val classLoader = URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray())
|
||||
this.annotationProcessingClassLoader = classLoader
|
||||
|
||||
val processors = if (annotationProcessorFqNames.isNotEmpty()) {
|
||||
logger.info("Annotation processor class names are set, skip AP discovery")
|
||||
annotationProcessorFqNames.mapNotNull { tryLoadProcessor(it, classLoader) }
|
||||
} else {
|
||||
logger.info("Need to discovery annotation processors in the AP classpath")
|
||||
ServiceLoader.load(Processor::class.java, classLoader).toList()
|
||||
}
|
||||
|
||||
if (processors.isEmpty()) {
|
||||
logger.info("No annotation processors available, aborting")
|
||||
} else {
|
||||
logger.info { "Annotation processors: " + processors.joinToString { it::class.java.canonicalName } }
|
||||
}
|
||||
|
||||
return processors
|
||||
}
|
||||
|
||||
private fun tryLoadProcessor(fqName: String, classLoader: ClassLoader): Processor? {
|
||||
val annotationProcessorClass = try {
|
||||
Class.forName(fqName, true, classLoader)
|
||||
} catch (e: Throwable) {
|
||||
logger.warn("Can't find annotation processor class $fqName: ${e.message}")
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
val annotationProcessorInstance = annotationProcessorClass.newInstance()
|
||||
if (annotationProcessorInstance !is Processor) {
|
||||
logger.warn("$fqName is not an instance of 'Processor'")
|
||||
return null
|
||||
}
|
||||
|
||||
return annotationProcessorInstance
|
||||
} catch (e: Throwable) {
|
||||
logger.warn("Can't load annotation processor class $fqName: ${e.message}")
|
||||
return null
|
||||
processorLoader?.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,7 +104,7 @@ abstract class AbstractKapt3Extension(
|
||||
val annotationProcessorFqNames: List<String>,
|
||||
val aptMode: AptMode,
|
||||
val pluginInitializedTime: Long,
|
||||
val logger: KaptLogger,
|
||||
val logger: MessageCollectorBackedKaptLogger,
|
||||
val correctErrorTypes: Boolean,
|
||||
val mapDiagnosticLocations: Boolean,
|
||||
val compilerConfiguration: CompilerConfiguration
|
||||
@@ -205,9 +150,7 @@ abstract class AbstractKapt3Extension(
|
||||
|
||||
val kaptContext = generateStubs(project, module, bindingTrace.bindingContext, files)
|
||||
|
||||
try {
|
||||
runAnnotationProcessing(kaptContext, processors)
|
||||
} catch (error: KaptError) {
|
||||
fun handleKaptError(error: KaptError): AnalysisResult {
|
||||
val cause = error.cause
|
||||
|
||||
if (cause != null) {
|
||||
@@ -215,6 +158,20 @@ abstract class AbstractKapt3Extension(
|
||||
}
|
||||
|
||||
return AnalysisResult.compilationError(bindingTrace.bindingContext)
|
||||
}
|
||||
|
||||
try {
|
||||
runAnnotationProcessing(kaptContext, processors)
|
||||
} catch (error: KaptBaseError) {
|
||||
val kind = when (error.kind) {
|
||||
KaptBaseError.Kind.EXCEPTION -> KaptError.Kind.EXCEPTION
|
||||
KaptBaseError.Kind.ERROR_RAISED -> KaptError.Kind.ERROR_RAISED
|
||||
}
|
||||
|
||||
val cause = error.cause
|
||||
return handleKaptError(if (cause != null) KaptError(kind, cause) else KaptError(kind))
|
||||
} catch (error: KaptError) {
|
||||
return handleKaptError(error)
|
||||
} catch (thr: Throwable) {
|
||||
return AnalysisResult.internalError(bindingTrace.bindingContext, thr)
|
||||
} finally {
|
||||
@@ -232,10 +189,14 @@ abstract class AbstractKapt3Extension(
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
return KaptContext(paths, false, aptMode, logger, project, BindingContext.EMPTY, emptyList(), emptyMap(), null,
|
||||
mapDiagnosticLocations, options, javacOptions)
|
||||
return KaptContext(paths, false, logger, mapDiagnosticLocations, options, javacOptions)
|
||||
}
|
||||
|
||||
logger.info { "Kotlin files to compile: " + files.map { it.virtualFile?.name ?: "<in memory ${it.hashCode()}>" } }
|
||||
@@ -245,10 +206,11 @@ abstract class AbstractKapt3Extension(
|
||||
}
|
||||
}
|
||||
|
||||
private fun runAnnotationProcessing(kaptContext: KaptContext<*>, processors: List<Processor>) {
|
||||
private fun runAnnotationProcessing(kaptContext: KaptContext, processors: List<Processor>) {
|
||||
if (!aptMode.runAnnotationProcessing) return
|
||||
|
||||
val javaSourceFiles = collectJavaSourceFiles()
|
||||
val javaSourceFiles = paths.collectJavaSourceFiles()
|
||||
logger.info { "Java source files: " + javaSourceFiles.joinToString { it.canonicalPath } }
|
||||
|
||||
val (annotationProcessingTime) = measureTimeMillis {
|
||||
kaptContext.doAnnotationProcessing(javaSourceFiles, processors)
|
||||
@@ -262,7 +224,7 @@ abstract class AbstractKapt3Extension(
|
||||
module: ModuleDescriptor,
|
||||
bindingContext: BindingContext,
|
||||
files: List<KtFile>
|
||||
): KaptContext<GenerationState> {
|
||||
): KaptContextForStubGeneration {
|
||||
val builderFactory = Kapt3BuilderFactory()
|
||||
|
||||
val targetId = TargetId(
|
||||
@@ -288,11 +250,13 @@ abstract class AbstractKapt3Extension(
|
||||
logger.info { "Stubs compilation took $classFilesCompilationTime ms" }
|
||||
logger.info { "Compiled classes: " + compiledClasses.joinToString { it.name } }
|
||||
|
||||
return KaptContext(paths, false, aptMode, logger, project, bindingContext, compiledClasses, origins, generationState,
|
||||
mapDiagnosticLocations, options, javacOptions)
|
||||
return KaptContextForStubGeneration(
|
||||
paths, false, logger, project, bindingContext, compiledClasses, origins, generationState,
|
||||
mapDiagnosticLocations, options, javacOptions
|
||||
)
|
||||
}
|
||||
|
||||
private fun generateKotlinSourceStubs(kaptContext: KaptContext<GenerationState>) {
|
||||
private fun generateKotlinSourceStubs(kaptContext: KaptContextForStubGeneration) {
|
||||
val converter = ClassFileToSourceStubConverter(kaptContext, generateNonExistentClass = true, correctErrorTypes = correctErrorTypes)
|
||||
|
||||
val (stubGenerationTime, kaptStubs) = measureTimeMillis {
|
||||
@@ -306,16 +270,7 @@ abstract class AbstractKapt3Extension(
|
||||
saveIncrementalData(kaptContext, logger.messageCollector, converter)
|
||||
}
|
||||
|
||||
private fun collectJavaSourceFiles(): List<File> {
|
||||
val javaFilesFromJavaSourceRoots = (paths.javaSourceRoots + paths.stubsOutputDir).flatMap {
|
||||
root -> root.walk().filter { it.isFile && it.extension == "java" }.toList()
|
||||
}
|
||||
logger.info { "Java source files: " + javaFilesFromJavaSourceRoots.joinToString { it.canonicalPath } }
|
||||
|
||||
return javaFilesFromJavaSourceRoots
|
||||
}
|
||||
|
||||
protected open fun saveStubs(kaptContext: KaptContext<*>, stubs: List<KaptStub>) {
|
||||
protected open fun saveStubs(kaptContext: KaptContext, stubs: List<KaptStub>) {
|
||||
for (kaptStub in stubs) {
|
||||
val stub = kaptStub.file
|
||||
val className = (stub.defs.first { it is JCTree.JCClassDecl } as JCTree.JCClassDecl).simpleName.toString()
|
||||
@@ -332,7 +287,7 @@ abstract class AbstractKapt3Extension(
|
||||
}
|
||||
|
||||
protected open fun saveIncrementalData(
|
||||
kaptContext: KaptContext<GenerationState>,
|
||||
kaptContext: KaptContextForStubGeneration,
|
||||
messageCollector: MessageCollector,
|
||||
converter: ClassFileToSourceStubConverter) {
|
||||
val incrementalDataOutputDir = paths.incrementalDataOutputDir ?: return
|
||||
|
||||
@@ -52,7 +52,10 @@ import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.SOURCE_OUT
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.STUBS_OUTPUT_DIR_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.USE_LIGHT_ANALYSIS_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor.Companion.VERBOSE_MODE_OPTION
|
||||
import org.jetbrains.kotlin.kapt3.util.KaptLogger
|
||||
import org.jetbrains.kotlin.kapt3.base.Kapt
|
||||
import org.jetbrains.kotlin.kapt3.base.KaptPaths
|
||||
import org.jetbrains.kotlin.kapt3.base.log
|
||||
import org.jetbrains.kotlin.kapt3.util.MessageCollectorBackedKaptLogger
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
|
||||
@@ -195,10 +198,6 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
|
||||
}
|
||||
|
||||
class Kapt3ComponentRegistrar : ComponentRegistrar {
|
||||
private companion object {
|
||||
private const val JAVAC_CONTEXT_CLASS = "com.sun.tools.javac.util.Context"
|
||||
}
|
||||
|
||||
private fun decodeList(options: String): Map<String, String> {
|
||||
val map = LinkedHashMap<String, String>()
|
||||
|
||||
@@ -224,14 +223,11 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
|
||||
val isVerbose = configuration.get(Kapt3ConfigurationKeys.VERBOSE_MODE) == "true"
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
?: PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, isVerbose)
|
||||
val logger = KaptLogger(isVerbose, messageCollector)
|
||||
val logger = MessageCollectorBackedKaptLogger(isVerbose, messageCollector)
|
||||
|
||||
fun abortAnalysis() = AnalysisHandlerExtension.registerExtension(project, AbortAnalysisHandlerExtension())
|
||||
|
||||
try {
|
||||
Class.forName(JAVAC_CONTEXT_CLASS)
|
||||
} catch (e: ClassNotFoundException) {
|
||||
logger.error("'$JAVAC_CONTEXT_CLASS' class can't be found ('tools.jar' is absent in the plugin classpath). Kapt won't work.")
|
||||
if (!Kapt.checkJavacComponentsAccess(logger)) {
|
||||
abortAnalysis()
|
||||
return
|
||||
}
|
||||
@@ -284,28 +280,24 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
|
||||
val correctErrorTypes = configuration.get(Kapt3ConfigurationKeys.CORRECT_ERROR_TYPES) == "true"
|
||||
val mapDiagnosticLocations = configuration.get(Kapt3ConfigurationKeys.MAP_DIAGNOSTIC_LOCATIONS) == "true"
|
||||
|
||||
val paths = KaptPaths(
|
||||
project.basePath?.let(::File),
|
||||
compileClasspath, apClasspath, javaSourceRoots, sourcesOutputDir, classFilesOutputDir,
|
||||
stubsOutputDir, incrementalDataOutputDir
|
||||
)
|
||||
|
||||
if (isVerbose) {
|
||||
logger.info("Kapt3 is enabled.")
|
||||
logger.info("Annotation processing mode: $aptMode")
|
||||
logger.info("Use light analysis: $useLightAnalysis")
|
||||
logger.info("Correct error types: $correctErrorTypes")
|
||||
logger.info("Map diagnostic locations: $mapDiagnosticLocations")
|
||||
logger.info("Source output directory: $sourcesOutputDir")
|
||||
logger.info("Classes output directory: $classFilesOutputDir")
|
||||
logger.info("Stubs output directory: $stubsOutputDir")
|
||||
logger.info("Incremental data output directory: $incrementalDataOutputDir")
|
||||
logger.info("Compile classpath: " + compileClasspath.joinToString())
|
||||
logger.info("Annotation processing classpath: " + apClasspath.joinToString())
|
||||
paths.log(logger)
|
||||
logger.info("Annotation processors: " + annotationProcessors.joinToString())
|
||||
logger.info("Java source roots: " + javaSourceRoots.joinToString())
|
||||
logger.info("Options: $apOptions")
|
||||
logger.info("Javac options: $apOptions")
|
||||
logger.info("AP options: $apOptions")
|
||||
}
|
||||
|
||||
val paths = KaptPaths(
|
||||
compileClasspath, apClasspath, javaSourceRoots, sourcesOutputDir, classFilesOutputDir,
|
||||
stubsOutputDir, incrementalDataOutputDir
|
||||
)
|
||||
|
||||
val kapt3AnalysisCompletedHandlerExtension = ClasspathBasedKapt3Extension(
|
||||
paths, apOptions, javacCliOptions, annotationProcessors,
|
||||
aptMode, useLightAnalysis, correctErrorTypes, mapDiagnosticLocations, System.currentTimeMillis(), logger, configuration
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.sun.tools.javac.tree.TreeMaker
|
||||
import com.sun.tools.javac.util.Context
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.kapt3.base.KaptContext
|
||||
import org.jetbrains.kotlin.kapt3.base.KaptPaths
|
||||
import org.jetbrains.kotlin.kapt3.base.util.KaptLogger
|
||||
import org.jetbrains.kotlin.kapt3.javac.KaptTreeMaker
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.org.objectweb.asm.tree.ClassNode
|
||||
|
||||
class KaptContextForStubGeneration(
|
||||
paths: KaptPaths,
|
||||
withJdk: Boolean,
|
||||
logger: KaptLogger,
|
||||
val project: Project,
|
||||
val bindingContext: BindingContext,
|
||||
val compiledClasses: List<ClassNode>,
|
||||
val origins: Map<Any, JvmDeclarationOrigin>,
|
||||
val generationState: GenerationState,
|
||||
mapDiagnosticLocations: Boolean,
|
||||
processorOptions: Map<String, String>,
|
||||
javacOptions: Map<String, String> = emptyMap()
|
||||
) : KaptContext(paths, withJdk, logger, mapDiagnosticLocations, processorOptions, javacOptions) {
|
||||
private val treeMaker = TreeMaker.instance(context)
|
||||
|
||||
override fun preregisterTreeMaker(context: Context) {
|
||||
KaptTreeMaker.preRegister(context, this)
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
(treeMaker as? KaptTreeMaker)?.dispose()
|
||||
generationState.destroy()
|
||||
super.close()
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -17,10 +17,9 @@
|
||||
package org.jetbrains.kotlin.kapt3.javac
|
||||
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import org.jetbrains.kotlin.kapt3.util.getPackageNameJava9Aware
|
||||
import org.jetbrains.kotlin.kapt3.base.util.getPackageNameJava9Aware
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.net.URL
|
||||
import javax.lang.model.element.Modifier
|
||||
import javax.lang.model.element.NestingKind
|
||||
import javax.tools.JavaFileObject
|
||||
|
||||
@@ -27,13 +27,13 @@ import com.sun.tools.javac.util.Context
|
||||
import com.sun.tools.javac.util.Name
|
||||
import com.sun.tools.javac.util.Names
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.kapt3.KaptContext
|
||||
import org.jetbrains.kotlin.kapt3.KaptContextForStubGeneration
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.Type.*
|
||||
import org.jetbrains.org.objectweb.asm.tree.ClassNode
|
||||
|
||||
class KaptTreeMaker(context: Context, kaptContext: KaptContext<*>) : TreeMaker(context), Disposable {
|
||||
class KaptTreeMaker(context: Context, kaptContext: KaptContextForStubGeneration) : TreeMaker(context), Disposable {
|
||||
private var kaptContext = DisposableReference(kaptContext)
|
||||
|
||||
val nameTable: Name.Table = Names.instance(context).table
|
||||
@@ -171,7 +171,7 @@ class KaptTreeMaker(context: Context, kaptContext: KaptContext<*>) : TreeMaker(c
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal fun preRegister(context: Context, kaptContext: KaptContext<*>) {
|
||||
internal fun preRegister(context: Context, kaptContext: KaptContextForStubGeneration) {
|
||||
context.put(treeMakerKey, Context.Factory<TreeMaker> { KaptTreeMaker(it, kaptContext) })
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.kapt3.mapJList
|
||||
import org.jetbrains.kotlin.kapt3.base.mapJList
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
|
||||
+9
-4
@@ -24,14 +24,19 @@ import com.sun.tools.javac.tree.JCTree.*
|
||||
import com.sun.tools.javac.tree.TreeMaker
|
||||
import com.sun.tools.javac.tree.TreeScanner
|
||||
import kotlinx.kapt.KaptIgnored
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.kapt3.*
|
||||
import org.jetbrains.kotlin.kapt3.javac.KaptTreeMaker
|
||||
import org.jetbrains.kotlin.kapt3.javac.KaptJavaFileObject
|
||||
import org.jetbrains.kotlin.kapt3.javac.kaptError
|
||||
import org.jetbrains.kotlin.kapt3.base.plus
|
||||
import org.jetbrains.kotlin.kapt3.base.javac.kaptError
|
||||
import org.jetbrains.kotlin.kapt3.base.mapJList
|
||||
import org.jetbrains.kotlin.kapt3.base.mapJListIndexed
|
||||
import org.jetbrains.kotlin.kapt3.base.pairedListToMap
|
||||
import org.jetbrains.kotlin.kapt3.base.util.TopLevelJava9Aware
|
||||
import org.jetbrains.kotlin.kapt3.base.stubs.KaptStubLineInformation
|
||||
import org.jetbrains.kotlin.kapt3.stubs.ErrorTypeCorrector.TypeKind.*
|
||||
import org.jetbrains.kotlin.kapt3.util.*
|
||||
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
|
||||
@@ -55,7 +60,7 @@ import javax.lang.model.element.ElementKind
|
||||
import com.sun.tools.javac.util.List as JavacList
|
||||
|
||||
class ClassFileToSourceStubConverter(
|
||||
val kaptContext: KaptContext<GenerationState>,
|
||||
val kaptContext: KaptContextForStubGeneration,
|
||||
val generateNonExistentClass: Boolean,
|
||||
val correctErrorTypes: Boolean
|
||||
) {
|
||||
@@ -146,7 +151,7 @@ class ClassFileToSourceStubConverter(
|
||||
|
||||
val metadataFile = File(
|
||||
forSource.parentFile,
|
||||
forSource.nameWithoutExtension + KaptLineMappingCollector.KAPT_METADATA_EXTENSION
|
||||
forSource.nameWithoutExtension + KaptStubLineInformation.KAPT_METADATA_EXTENSION
|
||||
)
|
||||
|
||||
metadataFile.writeBytes(kaptMetadata)
|
||||
|
||||
+3
-3
@@ -22,9 +22,9 @@ import com.sun.tools.javac.tree.JCTree
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.codegen.state.updateArgumentModeFromAnnotations
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.kapt3.javac.kaptError
|
||||
import org.jetbrains.kotlin.kapt3.mapJList
|
||||
import org.jetbrains.kotlin.kapt3.mapJListIndexed
|
||||
import org.jetbrains.kotlin.kapt3.base.javac.kaptError
|
||||
import org.jetbrains.kotlin.kapt3.base.mapJList
|
||||
import org.jetbrains.kotlin.kapt3.base.mapJListIndexed
|
||||
import org.jetbrains.kotlin.kapt3.stubs.ErrorTypeCorrector.TypeKind.METHOD_PARAMETER_TYPE
|
||||
import org.jetbrains.kotlin.kapt3.stubs.ErrorTypeCorrector.TypeKind.RETURN_TYPE
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ import com.sun.tools.javac.tree.JCTree
|
||||
import com.sun.tools.javac.tree.TreeScanner
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||
import org.jetbrains.kotlin.kapt3.KaptContext
|
||||
import org.jetbrains.kotlin.kapt3.KaptContextForStubGeneration
|
||||
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
|
||||
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -35,7 +35,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.tree.FieldNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
|
||||
class KDocCommentKeeper(private val kaptContext: KaptContext<*>) {
|
||||
class KDocCommentKeeper(private val kaptContext: KaptContextForStubGeneration) {
|
||||
private val docCommentTable = KaptDocCommentTable()
|
||||
|
||||
fun getDocTable(file: JCTree.JCCompilationUnit): DocCommentTable {
|
||||
|
||||
+8
-75
@@ -19,75 +19,17 @@ package org.jetbrains.kotlin.kapt3.stubs
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import org.jetbrains.kotlin.kapt3.KaptContext
|
||||
import org.jetbrains.kotlin.kapt3.KaptContextForStubGeneration
|
||||
import org.jetbrains.kotlin.kapt3.base.stubs.KaptStubLineInformation
|
||||
import org.jetbrains.kotlin.kapt3.base.stubs.KotlinPosition
|
||||
import org.jetbrains.kotlin.kapt3.base.stubs.LineInfoMap
|
||||
import org.jetbrains.kotlin.kapt3.base.stubs.getJavacSignature
|
||||
import org.jetbrains.org.objectweb.asm.tree.ClassNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.FieldNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
import java.io.*
|
||||
|
||||
data class KotlinPosition(val path: String, val isRelativePath: Boolean, val pos: Int)
|
||||
|
||||
private typealias LineInfoMap = MutableMap<String, KotlinPosition>
|
||||
|
||||
class KaptLineMappingCollector(private val kaptContext: KaptContext<*>) {
|
||||
companion object {
|
||||
const val KAPT_METADATA_EXTENSION = ".kapt_metadata"
|
||||
private const val METADATA_VERSION = 1
|
||||
|
||||
fun parseFileInfo(file: JCTree.JCCompilationUnit): FileInfo {
|
||||
val sourceUri = file.sourcefile
|
||||
?.toUri()
|
||||
?.takeIf { it.isAbsolute && !it.isOpaque && it.path != null && it.scheme?.toLowerCase() == "file" } ?: return FileInfo.EMPTY
|
||||
|
||||
val sourceFile = File(sourceUri).takeIf { it.exists() } ?: return FileInfo.EMPTY
|
||||
val kaptMetadataFile = File(sourceFile.parentFile, sourceFile.nameWithoutExtension + KAPT_METADATA_EXTENSION)
|
||||
|
||||
if (!kaptMetadataFile.isFile) {
|
||||
return FileInfo.EMPTY
|
||||
}
|
||||
|
||||
return deserialize(kaptMetadataFile.readBytes())
|
||||
}
|
||||
|
||||
private fun deserialize(data: ByteArray): FileInfo {
|
||||
val lineInfo: LineInfoMap = mutableMapOf()
|
||||
val signatureInfo = mutableMapOf<String, String>()
|
||||
|
||||
val ois = ObjectInputStream(ByteArrayInputStream(data))
|
||||
|
||||
val version = ois.readInt()
|
||||
if (version != METADATA_VERSION) {
|
||||
return FileInfo.EMPTY
|
||||
}
|
||||
|
||||
val lineInfoCount = ois.readInt()
|
||||
repeat(lineInfoCount) {
|
||||
val fqName = ois.readUTF()
|
||||
val path = ois.readUTF()
|
||||
val isRelative = ois.readBoolean()
|
||||
val pos = ois.readInt()
|
||||
|
||||
lineInfo[fqName] = KotlinPosition(path, isRelative, pos)
|
||||
}
|
||||
|
||||
val signatureCount = ois.readInt()
|
||||
repeat(signatureCount) {
|
||||
val javacSignature = ois.readUTF()
|
||||
val methodDesc = ois.readUTF()
|
||||
|
||||
signatureInfo[javacSignature] = methodDesc
|
||||
}
|
||||
|
||||
return FileInfo(lineInfo, signatureInfo)
|
||||
}
|
||||
|
||||
private fun getJavacSignature(decl: JCTree.JCMethodDecl): String {
|
||||
val name = decl.name.toString()
|
||||
val params = decl.parameters.joinToString { it.getType().toString() }
|
||||
return "$name($params)"
|
||||
}
|
||||
}
|
||||
|
||||
class KaptLineMappingCollector(private val kaptContext: KaptContextForStubGeneration) {
|
||||
private val lineInfo: LineInfoMap = mutableMapOf()
|
||||
private val signatureInfo = mutableMapOf<String, String>()
|
||||
|
||||
@@ -106,7 +48,7 @@ class KaptLineMappingCollector(private val kaptContext: KaptContext<*>) {
|
||||
}
|
||||
|
||||
fun registerSignature(decl: JCTree.JCMethodDecl, method: MethodNode) {
|
||||
signatureInfo[getJavacSignature(decl)] = method.name + method.desc
|
||||
signatureInfo[decl.getJavacSignature()] = method.name + method.desc
|
||||
}
|
||||
|
||||
private fun register(asmNode: Any, fqName: String) {
|
||||
@@ -142,7 +84,7 @@ class KaptLineMappingCollector(private val kaptContext: KaptContext<*>) {
|
||||
val os = ByteArrayOutputStream()
|
||||
val oos = ObjectOutputStream(os)
|
||||
|
||||
oos.writeInt(METADATA_VERSION)
|
||||
oos.writeInt(KaptStubLineInformation.METADATA_VERSION)
|
||||
|
||||
oos.writeInt(lineInfo.size)
|
||||
for ((fqName, kotlinPosition) in lineInfo) {
|
||||
@@ -161,13 +103,4 @@ class KaptLineMappingCollector(private val kaptContext: KaptContext<*>) {
|
||||
oos.flush()
|
||||
return os.toByteArray()
|
||||
}
|
||||
|
||||
class FileInfo(private val lineInfo: LineInfoMap, private val signatureInfo: Map<String, String>) {
|
||||
companion object {
|
||||
val EMPTY = FileInfo(mutableMapOf(), emptyMap())
|
||||
}
|
||||
|
||||
fun getPositionFor(fqName: String) = lineInfo[fqName]
|
||||
fun getMethodDescriptor(decl: JCTree.JCMethodDecl) = signatureInfo[getJavacSignature(decl)]
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -24,8 +24,8 @@ import org.jetbrains.org.objectweb.asm.signature.SignatureVisitor
|
||||
import java.util.*
|
||||
import org.jetbrains.kotlin.kapt3.stubs.ElementKind.*
|
||||
import org.jetbrains.kotlin.kapt3.javac.KaptTreeMaker
|
||||
import org.jetbrains.kotlin.kapt3.mapJList
|
||||
import org.jetbrains.kotlin.kapt3.mapJListIndexed
|
||||
import org.jetbrains.kotlin.kapt3.base.mapJList
|
||||
import org.jetbrains.kotlin.kapt3.base.mapJListIndexed
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.org.objectweb.asm.signature.SignatureReader
|
||||
import com.sun.tools.javac.util.List as JavacList
|
||||
|
||||
+20
-28
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.util
|
||||
@@ -20,38 +9,37 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
|
||||
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
|
||||
import org.jetbrains.kotlin.kapt3.base.util.KaptLogger
|
||||
import java.io.PrintWriter
|
||||
import java.io.StringWriter
|
||||
|
||||
class KaptLogger(
|
||||
val isVerbose: Boolean,
|
||||
val messageCollector: MessageCollector = PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, isVerbose)
|
||||
) {
|
||||
class MessageCollectorBackedKaptLogger(
|
||||
override val isVerbose: Boolean,
|
||||
val messageCollector: MessageCollector = PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, isVerbose)
|
||||
) : KaptLogger {
|
||||
private companion object {
|
||||
val PREFIX = "[kapt] "
|
||||
}
|
||||
|
||||
fun info(message: String) {
|
||||
override val errorWriter = makeWriter(CompilerMessageSeverity.ERROR)
|
||||
override val warnWriter = makeWriter(CompilerMessageSeverity.STRONG_WARNING)
|
||||
override val infoWriter = makeWriter(CompilerMessageSeverity.WARNING)
|
||||
|
||||
override fun info(message: String) {
|
||||
if (isVerbose) {
|
||||
messageCollector.report(CompilerMessageSeverity.INFO, PREFIX + message)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun info(message: () -> String) {
|
||||
if (isVerbose) {
|
||||
info(message())
|
||||
}
|
||||
}
|
||||
|
||||
fun warn(message: String) {
|
||||
|
||||
override fun warn(message: String) {
|
||||
messageCollector.report(CompilerMessageSeverity.WARNING, PREFIX + message)
|
||||
}
|
||||
|
||||
fun error(message: String) {
|
||||
override fun error(message: String) {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, PREFIX + message)
|
||||
}
|
||||
|
||||
fun exception(e: Throwable) {
|
||||
override fun exception(e: Throwable) {
|
||||
val stacktrace = run {
|
||||
val writer = StringWriter()
|
||||
e.printStackTrace(PrintWriter(writer))
|
||||
@@ -59,4 +47,8 @@ class KaptLogger(
|
||||
}
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, PREFIX + "An exception occurred: " + stacktrace)
|
||||
}
|
||||
|
||||
private fun makeWriter(severity: CompilerMessageSeverity): PrintWriter {
|
||||
return PrintWriter(MessageCollectorBackedWriter(messageCollector, severity))
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.kapt3
|
||||
|
||||
import com.sun.tools.javac.util.List as JavacList
|
||||
|
||||
internal inline fun <T, R> mapJList(values: Iterable<T>?, f: (T) -> R?): JavacList<R> {
|
||||
if (values == null) return JavacList.nil()
|
||||
|
||||
var result = JavacList.nil<R>()
|
||||
for (item in values) {
|
||||
f(item)?.let { result = result.append(it) }
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
internal inline fun <T, R> mapJListIndexed(values: Iterable<T>?, f: (Int, T) -> R?): JavacList<R> {
|
||||
if (values == null) return JavacList.nil()
|
||||
|
||||
var result = JavacList.nil<R>()
|
||||
values.forEachIndexed { index, item ->
|
||||
f(index, item)?.let { result = result.append(it) }
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
internal inline fun <T> mapPairedValuesJList(valuePairs: List<Any>?, f: (String, Any) -> T?): JavacList<T> {
|
||||
if (valuePairs == null || valuePairs.isEmpty()) return JavacList.nil()
|
||||
|
||||
val size = valuePairs.size
|
||||
var result = JavacList.nil<T>()
|
||||
assert(size % 2 == 0)
|
||||
var index = 0
|
||||
while (index < size) {
|
||||
val key = valuePairs[index] as String
|
||||
val value = valuePairs[index + 1]
|
||||
f(key, value)?.let { result = result.prepend(it) }
|
||||
index += 2
|
||||
}
|
||||
return result.reverse()
|
||||
}
|
||||
|
||||
internal fun pairedListToMap(valuePairs: List<Any>?): Map<String, Any?> {
|
||||
val map = mutableMapOf<String, Any?>()
|
||||
|
||||
mapPairedValuesJList(valuePairs) { key, value ->
|
||||
map.put(key, value)
|
||||
}
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
internal operator fun <T : Any> JavacList<T>.plus(other: JavacList<T>): JavacList<T> {
|
||||
return this.appendList(other)
|
||||
}
|
||||
+12
-8
@@ -16,19 +16,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.kapt3.test
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.sun.tools.javac.tree.JCTree
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.codegen.CodegenTestCase
|
||||
import org.jetbrains.kotlin.codegen.GenerationUtils
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.kapt3.*
|
||||
import org.jetbrains.kotlin.kapt3.AptMode.STUBS_AND_APT
|
||||
import org.jetbrains.kotlin.kapt3.base.KaptContext
|
||||
import org.jetbrains.kotlin.kapt3.base.KaptPaths
|
||||
import org.jetbrains.kotlin.kapt3.javac.KaptJavaFileObject
|
||||
import org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter
|
||||
import org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter.KaptStub
|
||||
import org.jetbrains.kotlin.kapt3.util.KaptLogger
|
||||
import org.jetbrains.kotlin.kapt3.util.MessageCollectorBackedKaptLogger
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
@@ -130,10 +131,11 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() {
|
||||
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, *javaSources)
|
||||
|
||||
val kapt3Extension = Kapt3ExtensionForTests(processors, javaSources.toList(), sourceOutputDir, this.options,
|
||||
val project = myEnvironment.project
|
||||
val kapt3Extension = Kapt3ExtensionForTests(project, processors, javaSources.toList(), sourceOutputDir, this.options,
|
||||
stubsOutputDir = stubsDir, incrementalDataOutputDir = incrementalDataDir)
|
||||
|
||||
AnalysisHandlerExtension.registerExtension(myEnvironment.project, kapt3Extension)
|
||||
AnalysisHandlerExtension.registerExtension(project, kapt3Extension)
|
||||
|
||||
try {
|
||||
loadMultiFiles(files)
|
||||
@@ -153,6 +155,7 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() {
|
||||
}
|
||||
|
||||
protected class Kapt3ExtensionForTests(
|
||||
project: Project,
|
||||
private val processors: List<Processor>,
|
||||
javaSourceRoots: List<File>,
|
||||
outputDir: File,
|
||||
@@ -161,10 +164,11 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() {
|
||||
incrementalDataOutputDir: File
|
||||
) : AbstractKapt3Extension(
|
||||
KaptPaths(
|
||||
project.basePath?.let(::File),
|
||||
PathUtil.getJdkClassesRootsFromCurrentJre() + PathUtil.kotlinPathsForIdeaPlugin.stdlibPath,
|
||||
emptyList(), javaSourceRoots, outputDir, outputDir, stubsOutputDir, incrementalDataOutputDir
|
||||
), options, emptyMap(), emptyList(), STUBS_AND_APT, System.currentTimeMillis(),
|
||||
KaptLogger(true), correctErrorTypes = true, mapDiagnosticLocations = true,
|
||||
MessageCollectorBackedKaptLogger(true), correctErrorTypes = true, mapDiagnosticLocations = true,
|
||||
compilerConfiguration = CompilerConfiguration.EMPTY
|
||||
) {
|
||||
internal var savedStubs: String? = null
|
||||
@@ -172,7 +176,7 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() {
|
||||
|
||||
override fun loadProcessors() = processors
|
||||
|
||||
override fun saveStubs(kaptContext: KaptContext<*>, stubs: List<KaptStub>) {
|
||||
override fun saveStubs(kaptContext: KaptContext, stubs: List<KaptStub>) {
|
||||
if (this.savedStubs != null) {
|
||||
error("Stubs are already saved")
|
||||
}
|
||||
@@ -186,7 +190,7 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() {
|
||||
}
|
||||
|
||||
override fun saveIncrementalData(
|
||||
kaptContext: KaptContext<GenerationState>,
|
||||
kaptContext: KaptContextForStubGeneration,
|
||||
messageCollector: MessageCollector,
|
||||
converter: ClassFileToSourceStubConverter
|
||||
) {
|
||||
|
||||
+19
-13
@@ -32,12 +32,15 @@ import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||
import org.jetbrains.kotlin.codegen.CodegenTestCase
|
||||
import org.jetbrains.kotlin.codegen.CodegenTestFiles
|
||||
import org.jetbrains.kotlin.codegen.GenerationUtils
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.kapt3.*
|
||||
import org.jetbrains.kotlin.kapt3.base.KaptContext
|
||||
import org.jetbrains.kotlin.kapt3.base.KaptPaths
|
||||
import org.jetbrains.kotlin.kapt3.base.doAnnotationProcessing
|
||||
import org.jetbrains.kotlin.kapt3.base.javac.KaptJavaLog
|
||||
import org.jetbrains.kotlin.kapt3.base.parseJavaFiles
|
||||
import org.jetbrains.kotlin.kapt3.javac.KaptJavaFileObject
|
||||
import org.jetbrains.kotlin.kapt3.javac.KaptJavaLog
|
||||
import org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter
|
||||
import org.jetbrains.kotlin.kapt3.util.KaptLogger
|
||||
import org.jetbrains.kotlin.kapt3.util.MessageCollectorBackedKaptLogger
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.PartialAnalysisHandlerExtension
|
||||
@@ -112,7 +115,7 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
|
||||
val classBuilderFactory = Kapt3BuilderFactory()
|
||||
val generationState = GenerationUtils.compileFiles(myFiles.psiFiles, myEnvironment, classBuilderFactory)
|
||||
|
||||
val logger = KaptLogger(isVerbose = true, messageCollector = messageCollector)
|
||||
val logger = MessageCollectorBackedKaptLogger(isVerbose = true, messageCollector = messageCollector)
|
||||
|
||||
val javacOptions = wholeFile.getOptionValues("JAVAC_OPTION")
|
||||
.map { opt ->
|
||||
@@ -121,22 +124,25 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
|
||||
}.toMap()
|
||||
|
||||
var javaFiles: List<File>? = null
|
||||
var kaptContext: KaptContext<*>? = null
|
||||
var kaptContext: KaptContext? = null
|
||||
|
||||
try {
|
||||
val sourceOutputDir = Files.createTempDirectory("kaptRunner").toFile()
|
||||
|
||||
val paths = KaptPaths(
|
||||
generationState.project.basePath?.let(::File),
|
||||
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)
|
||||
kaptContext = KaptContextForStubGeneration(
|
||||
paths, true,
|
||||
logger, generationState.project, generationState.bindingContext, classBuilderFactory.compiledClasses,
|
||||
classBuilderFactory.origins, generationState, mapDiagnosticLocations = true,
|
||||
processorOptions = emptyMap(), javacOptions = javacOptions
|
||||
)
|
||||
|
||||
javaFiles = files
|
||||
.filter { it.name.toLowerCase().endsWith(".java") }
|
||||
@@ -154,7 +160,7 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
|
||||
}
|
||||
|
||||
protected fun convert(
|
||||
kaptContext: KaptContext<GenerationState>,
|
||||
kaptContext: KaptContextForStubGeneration,
|
||||
javaFiles: List<File>,
|
||||
generateNonExistentClass: Boolean,
|
||||
correctErrorTypes: Boolean
|
||||
@@ -201,7 +207,7 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
|
||||
protected fun File.getOptionValues(name: String) = getRawOptionValues(name).map { it.drop("// ".length + name.length).trim() }
|
||||
|
||||
protected abstract fun check(
|
||||
kaptContext: KaptContext<GenerationState>,
|
||||
kaptContext: KaptContextForStubGeneration,
|
||||
javaFiles: List<File>,
|
||||
txtFile: File,
|
||||
wholeFile: File)
|
||||
@@ -239,7 +245,7 @@ open class AbstractClassFileToSourceStubConverterTest : AbstractKotlinKapt3Test(
|
||||
doTestWithJdk9(AbstractClassFileToSourceStubConverterTest::class.java, filePath)
|
||||
}
|
||||
|
||||
override fun check(kaptContext: KaptContext<GenerationState>, javaFiles: List<File>, txtFile: File, wholeFile: File) {
|
||||
override fun check(kaptContext: KaptContextForStubGeneration, javaFiles: List<File>, txtFile: File, wholeFile: File) {
|
||||
val generateNonExistentClass = wholeFile.isOptionSet("NON_EXISTENT_CLASS")
|
||||
val correctErrorTypes = wholeFile.isOptionSet("CORRECT_ERROR_TYPES")
|
||||
val validate = !wholeFile.isOptionSet("NO_VALIDATION")
|
||||
@@ -298,7 +304,7 @@ open class AbstractClassFileToSourceStubConverterTest : AbstractKotlinKapt3Test(
|
||||
}
|
||||
|
||||
abstract class AbstractKotlinKaptContextTest : AbstractKotlinKapt3Test() {
|
||||
override fun check(kaptContext: KaptContext<GenerationState>, javaFiles: List<File>, txtFile: File, wholeFile: File) {
|
||||
override fun check(kaptContext: KaptContextForStubGeneration, javaFiles: List<File>, txtFile: File, wholeFile: File) {
|
||||
val compilationUnits = convert(kaptContext, javaFiles, generateNonExistentClass = false, correctErrorTypes = true)
|
||||
|
||||
kaptContext.doAnnotationProcessing(
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package org.jetbrains.kotlin.kapt3.test
|
||||
|
||||
import com.intellij.openapi.util.SystemInfoRt
|
||||
import org.jetbrains.kotlin.kapt3.util.isJava9OrLater
|
||||
import org.jetbrains.kotlin.kapt3.base.util.isJava9OrLater
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
@@ -27,7 +27,7 @@ import java.util.concurrent.TimeUnit
|
||||
interface Java9TestLauncher {
|
||||
fun doTestWithJdk9(mainClass: Class<*>, arg: String) {
|
||||
// Already under Java 9
|
||||
if (isJava9OrLater) return
|
||||
if (isJava9OrLater()) return
|
||||
|
||||
//TODO unmute after investigation (tests are failing on TeamCity)
|
||||
if (SystemInfoRt.isWindows) return
|
||||
|
||||
@@ -147,6 +147,7 @@ include ":kotlin-build-common",
|
||||
":examples:annotation-processor-example",
|
||||
":kotlin-script-util",
|
||||
":kotlin-annotation-processing",
|
||||
":kotlin-annotation-processing-base",
|
||||
":kotlin-annotation-processing-runtime",
|
||||
":kotlin-annotation-processing-gradle",
|
||||
":kotlin-annotation-processing-embeddable",
|
||||
@@ -255,6 +256,7 @@ project(':kotlin-script-util').projectDir = "$rootDir/libraries/tools/kotlin-scr
|
||||
project(':kotlin-annotation-processing-gradle').projectDir = "$rootDir/libraries/tools/kotlin-annotation-processing" as File
|
||||
project(':kotlin-annotation-processing-embeddable').projectDir = "$rootDir/prepare/kotlin-annotation-processing-embeddable" as File
|
||||
project(':kotlin-annotation-processing').projectDir = "$rootDir/plugins/kapt3/kapt3-compiler" as File
|
||||
project(':kotlin-annotation-processing-base').projectDir = "$rootDir/plugins/kapt3/kapt3-base" as File
|
||||
project(':kotlin-annotation-processing-runtime').projectDir = "$rootDir/plugins/kapt3/kapt3-runtime" as File
|
||||
project(':plugins:kapt3-idea').projectDir = "$rootDir/plugins/kapt3/kapt3-idea" as File
|
||||
project(':examples:kotlin-jsr223-local-example').projectDir = "$rootDir/libraries/examples/kotlin-jsr223-local-example" as File
|
||||
|
||||
Reference in New Issue
Block a user