Kapt: Remove kapt1 support from Gradle and incremental compilation
This commit is contained in:
+1
-13
@@ -16,16 +16,4 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.daemon.common
|
package org.jetbrains.kotlin.daemon.common
|
||||||
|
|
||||||
import java.rmi.RemoteException
|
interface IncrementalCompilerServicesFacade : CompilerServicesFacadeBase
|
||||||
|
|
||||||
interface IncrementalCompilerServicesFacade : CompilerServicesFacadeBase {
|
|
||||||
// AnnotationFileUpdater
|
|
||||||
@Throws(RemoteException::class)
|
|
||||||
fun hasAnnotationsFileUpdater(): Boolean
|
|
||||||
|
|
||||||
@Throws(RemoteException::class)
|
|
||||||
fun updateAnnotations(outdatedClassesJvmNames: Iterable<String>)
|
|
||||||
|
|
||||||
@Throws(RemoteException::class)
|
|
||||||
fun revert()
|
|
||||||
}
|
|
||||||
@@ -40,7 +40,6 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
|||||||
import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler
|
import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler
|
||||||
import org.jetbrains.kotlin.config.Services
|
import org.jetbrains.kotlin.config.Services
|
||||||
import org.jetbrains.kotlin.daemon.common.*
|
import org.jetbrains.kotlin.daemon.common.*
|
||||||
import org.jetbrains.kotlin.daemon.incremental.RemoteAnnotationsFileUpdater
|
|
||||||
import org.jetbrains.kotlin.daemon.report.CompileServicesFacadeMessageCollector
|
import org.jetbrains.kotlin.daemon.report.CompileServicesFacadeMessageCollector
|
||||||
import org.jetbrains.kotlin.daemon.report.DaemonMessageReporter
|
import org.jetbrains.kotlin.daemon.report.DaemonMessageReporter
|
||||||
import org.jetbrains.kotlin.daemon.report.DaemonMessageReporterPrintStreamAdapter
|
import org.jetbrains.kotlin.daemon.report.DaemonMessageReporterPrintStreamAdapter
|
||||||
@@ -486,7 +485,6 @@ class CompileServiceImpl(
|
|||||||
daemonMessageReporter: DaemonMessageReporter
|
daemonMessageReporter: DaemonMessageReporter
|
||||||
): ExitCode {
|
): ExitCode {
|
||||||
val reporter = RemoteICReporter(servicesFacade, compilationResults, incrementalCompilationOptions)
|
val reporter = RemoteICReporter(servicesFacade, compilationResults, incrementalCompilationOptions)
|
||||||
val annotationFileUpdater = if (servicesFacade.hasAnnotationsFileUpdater()) RemoteAnnotationsFileUpdater(servicesFacade) else null
|
|
||||||
|
|
||||||
val moduleFile = k2jvmArgs.buildFile?.let(::File)
|
val moduleFile = k2jvmArgs.buildFile?.let(::File)
|
||||||
assert(moduleFile?.exists() ?: false) { "Module does not exist ${k2jvmArgs.buildFile}" }
|
assert(moduleFile?.exists() ?: false) { "Module does not exist ${k2jvmArgs.buildFile}" }
|
||||||
@@ -536,7 +534,7 @@ class CompileServiceImpl(
|
|||||||
workingDir,
|
workingDir,
|
||||||
javaSourceRoots,
|
javaSourceRoots,
|
||||||
versions,
|
versions,
|
||||||
reporter, annotationFileUpdater,
|
reporter,
|
||||||
buildHistoryFile = incrementalCompilationOptions.multiModuleICSettings.buildHistoryFile,
|
buildHistoryFile = incrementalCompilationOptions.multiModuleICSettings.buildHistoryFile,
|
||||||
localStateDirs = incrementalCompilationOptions.localStateDirs,
|
localStateDirs = incrementalCompilationOptions.localStateDirs,
|
||||||
usePreciseJavaTracking = incrementalCompilationOptions.usePreciseJavaTracking,
|
usePreciseJavaTracking = incrementalCompilationOptions.usePreciseJavaTracking,
|
||||||
|
|||||||
-35
@@ -1,35 +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.daemon.incremental
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.annotation.AnnotationFileUpdater
|
|
||||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
|
||||||
import org.jetbrains.kotlin.daemon.common.IncrementalCompilerServicesFacade
|
|
||||||
import org.jetbrains.kotlin.daemon.common.IncrementalCompilationServicesFacade
|
|
||||||
import org.jetbrains.kotlin.incremental.ICReporter
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
internal class RemoteAnnotationsFileUpdater(private val servicesFacade: IncrementalCompilerServicesFacade) : AnnotationFileUpdater {
|
|
||||||
override fun updateAnnotations(outdatedClasses: Iterable<JvmClassName>) {
|
|
||||||
servicesFacade.updateAnnotations(outdatedClasses.map { it.internalName })
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun revert() {
|
|
||||||
servicesFacade.revert()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-37
@@ -1,37 +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.annotation
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Annotation file is generated by collecting annotated elements of generated files.
|
|
||||||
* When compiling incrementally, the compiler generates only subset of all classes,
|
|
||||||
* so after compilation annotation file contains only a subset of annotated elements,
|
|
||||||
* which breaks the build.
|
|
||||||
*
|
|
||||||
* The workaround is to:
|
|
||||||
* 1. backup old file before incremental compilation;
|
|
||||||
* 2. after each iteration of IC:
|
|
||||||
* 2.1 remove classes corresponding to dirty source files
|
|
||||||
* 2.2 add annotations from newly generated annotations file
|
|
||||||
*/
|
|
||||||
interface AnnotationFileUpdater {
|
|
||||||
fun updateAnnotations(outdatedClasses: Iterable<JvmClassName>)
|
|
||||||
fun revert()
|
|
||||||
}
|
|
||||||
|
|
||||||
+5
-21
@@ -22,7 +22,6 @@ import com.intellij.psi.PsiClass
|
|||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.PsiFileFactory
|
import com.intellij.psi.PsiFileFactory
|
||||||
import com.intellij.psi.PsiJavaFile
|
import com.intellij.psi.PsiJavaFile
|
||||||
import org.jetbrains.kotlin.annotation.AnnotationFileUpdater
|
|
||||||
import org.jetbrains.kotlin.build.GeneratedFile
|
import org.jetbrains.kotlin.build.GeneratedFile
|
||||||
import org.jetbrains.kotlin.build.GeneratedJvmClass
|
import org.jetbrains.kotlin.build.GeneratedJvmClass
|
||||||
import org.jetbrains.kotlin.build.JvmSourceRoot
|
import org.jetbrains.kotlin.build.JvmSourceRoot
|
||||||
@@ -103,7 +102,6 @@ class IncrementalJvmCompilerRunner(
|
|||||||
private val javaSourceRoots: Set<JvmSourceRoot>,
|
private val javaSourceRoots: Set<JvmSourceRoot>,
|
||||||
cacheVersions: List<CacheVersion>,
|
cacheVersions: List<CacheVersion>,
|
||||||
reporter: ICReporter,
|
reporter: ICReporter,
|
||||||
private var kaptAnnotationsFileUpdater: AnnotationFileUpdater? = null,
|
|
||||||
private val usePreciseJavaTracking: Boolean,
|
private val usePreciseJavaTracking: Boolean,
|
||||||
private val buildHistoryFile: File,
|
private val buildHistoryFile: File,
|
||||||
localStateDirs: Collection<File>,
|
localStateDirs: Collection<File>,
|
||||||
@@ -311,28 +309,14 @@ class IncrementalJvmCompilerRunner(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun preBuildHook(args: K2JVMCompilerArguments, compilationMode: CompilationMode) {
|
override fun preBuildHook(args: K2JVMCompilerArguments, compilationMode: CompilationMode) {
|
||||||
when (compilationMode) {
|
if (compilationMode is CompilationMode.Incremental) {
|
||||||
is CompilationMode.Incremental -> {
|
val destinationDir = args.destinationAsFile
|
||||||
val destinationDir = args.destinationAsFile
|
destinationDir.mkdirs()
|
||||||
destinationDir.mkdirs()
|
args.classpathAsList = listOf(destinationDir) + args.classpathAsList
|
||||||
args.classpathAsList = listOf(destinationDir) + args.classpathAsList
|
|
||||||
}
|
|
||||||
is CompilationMode.Rebuild -> {
|
|
||||||
// there is no point in updating annotation file since all files will be compiled anyway
|
|
||||||
kaptAnnotationsFileUpdater = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun postCompilationHook(exitCode: ExitCode) {
|
override fun postCompilationHook(exitCode: ExitCode) {}
|
||||||
if (exitCode == ExitCode.OK) {
|
|
||||||
// TODO: Is it ok that argument always was an empty list?
|
|
||||||
kaptAnnotationsFileUpdater?.updateAnnotations(emptyList())
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
kaptAnnotationsFileUpdater?.revert()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun updateCaches(
|
override fun updateCaches(
|
||||||
services: Services,
|
services: Services,
|
||||||
|
|||||||
+2
-17
@@ -41,13 +41,10 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools
|
|||||||
androidExt: BaseExtension,
|
androidExt: BaseExtension,
|
||||||
variantData: BaseVariant,
|
variantData: BaseVariant,
|
||||||
javaTask: AbstractCompile,
|
javaTask: AbstractCompile,
|
||||||
kotlinTask: KotlinCompile,
|
kotlinTask: KotlinCompile) {
|
||||||
kotlinAfterJavaTask: KotlinCompile?) {
|
|
||||||
|
|
||||||
val preJavaKotlinOutputFiles = mutableListOf<File>().apply {
|
val preJavaKotlinOutputFiles = mutableListOf<File>().apply {
|
||||||
if (kotlinAfterJavaTask == null) {
|
add(kotlinTask.destinationDir)
|
||||||
add(kotlinTask.destinationDir)
|
|
||||||
}
|
|
||||||
if (Kapt3GradleSubplugin.isEnabled(project)) {
|
if (Kapt3GradleSubplugin.isEnabled(project)) {
|
||||||
// Add Kapt3 output as well, since there's no SyncOutputTask with the new API
|
// Add Kapt3 output as well, since there's no SyncOutputTask with the new API
|
||||||
val kaptClasssesDir = Kapt3GradleSubplugin.getKaptGeneratedClassesDir(project, getVariantName(variantData))
|
val kaptClasssesDir = Kapt3GradleSubplugin.getKaptGeneratedClassesDir(project, getVariantName(variantData))
|
||||||
@@ -64,18 +61,6 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools
|
|||||||
kotlinClasspath + project.files(AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt))
|
kotlinClasspath + project.files(AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use kapt1 annotations file for up-to-date check since annotation processing is done with javac
|
|
||||||
kotlinTask.kaptOptions.annotationsFile?.let { javaTask.inputs.file(it) }
|
|
||||||
|
|
||||||
if (kotlinAfterJavaTask != null) {
|
|
||||||
val kotlinAfterJavaOutput = project.files(kotlinAfterJavaTask.destinationDir).builtBy(kotlinAfterJavaTask)
|
|
||||||
variantData.registerPostJavacGeneratedBytecode(kotlinAfterJavaOutput)
|
|
||||||
|
|
||||||
// Then we don't need the kotlinTask output in artifacts, but we need to use it for Java compilation.
|
|
||||||
// Add it to Java classpath -- note the `from` used to avoid accident classpath resolution.
|
|
||||||
javaTask.classpath = project.files(kotlinTask.destinationDir).from(javaTask.classpath)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the classpath entries that comes from the tested variant and register it as the friend path, lazily
|
// Find the classpath entries that comes from the tested variant and register it as the friend path, lazily
|
||||||
kotlinTask.friendPaths = lazy {
|
kotlinTask.friendPaths = lazy {
|
||||||
variantData.getCompileClasspathArtifacts(preJavaClasspathKey)
|
variantData.getCompileClasspathArtifacts(preJavaClasspathKey)
|
||||||
|
|||||||
-46
@@ -1,46 +0,0 @@
|
|||||||
package org.jetbrains.kotlin.annotation
|
|
||||||
|
|
||||||
import org.gradle.api.logging.Logging
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
internal class AnnotationFileUpdaterImpl(private val generatedAnnotationFile: File) : AnnotationFileUpdater {
|
|
||||||
private val logger = Logging.getLogger(this.javaClass)
|
|
||||||
private val lastSuccessfullyUpdatedFile = File.createTempFile("kapt-annotations-copy", "tmp")
|
|
||||||
|
|
||||||
init {
|
|
||||||
if (generatedAnnotationFile.exists()) {
|
|
||||||
generatedAnnotationFile.copyTo(lastSuccessfullyUpdatedFile, overwrite = true)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lastSuccessfullyUpdatedFile.writeText("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun updateAnnotations(outdatedClasses: Iterable<JvmClassName>) {
|
|
||||||
val outdatedClassesFqNames = outdatedClasses.mapTo(java.util.HashSet<String>()) { it.fqNameForClassNameWithoutDollars.asString() }
|
|
||||||
|
|
||||||
val annotationsProvider = MutableKotlinAnnotationProvider().apply {
|
|
||||||
addAnnotationsFrom(lastSuccessfullyUpdatedFile)
|
|
||||||
removeClasses(outdatedClassesFqNames)
|
|
||||||
logger.kotlinDebug { "Removed annotation entries for fq-names [${outdatedClassesFqNames.joinToString()}]" }
|
|
||||||
|
|
||||||
if (generatedAnnotationFile.exists()) {
|
|
||||||
addAnnotationsFrom(generatedAnnotationFile)
|
|
||||||
logger.kotlinDebug { "Added annotation entries from $generatedAnnotationFile" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
generatedAnnotationFile.delete()
|
|
||||||
generatedAnnotationFile.bufferedWriter().use { writer ->
|
|
||||||
annotationsProvider.writeAnnotations(CompactAnnotationWriter(writer))
|
|
||||||
logger.kotlinDebug { "Written updated annotations to $generatedAnnotationFile" }
|
|
||||||
}
|
|
||||||
generatedAnnotationFile.copyTo(lastSuccessfullyUpdatedFile, overwrite = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun revert() {
|
|
||||||
lastSuccessfullyUpdatedFile.copyTo(generatedAnnotationFile, overwrite = true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+5
-2
@@ -1,6 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* 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.compilerRunner
|
package org.jetbrains.kotlin.compilerRunner
|
||||||
|
|
||||||
import org.jetbrains.kotlin.annotation.AnnotationFileUpdater
|
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||||
import org.jetbrains.kotlin.config.Services
|
import org.jetbrains.kotlin.config.Services
|
||||||
import org.jetbrains.kotlin.daemon.common.MultiModuleICSettings
|
import org.jetbrains.kotlin.daemon.common.MultiModuleICSettings
|
||||||
@@ -32,7 +36,6 @@ internal class GradleIncrementalCompilerEnvironment(
|
|||||||
messageCollector: GradleMessageCollector,
|
messageCollector: GradleMessageCollector,
|
||||||
outputItemsCollector: OutputItemsCollector,
|
outputItemsCollector: OutputItemsCollector,
|
||||||
compilerArgs: CommonCompilerArguments,
|
compilerArgs: CommonCompilerArguments,
|
||||||
val kaptAnnotationsFileUpdater: AnnotationFileUpdater? = null,
|
|
||||||
val usePreciseJavaTracking: Boolean = false,
|
val usePreciseJavaTracking: Boolean = false,
|
||||||
val localStateDirs: List<File> = emptyList(),
|
val localStateDirs: List<File> = emptyList(),
|
||||||
val multiModuleICSettings: MultiModuleICSettings
|
val multiModuleICSettings: MultiModuleICSettings
|
||||||
|
|||||||
+7
-18
@@ -1,14 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* 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.compilerRunner
|
package org.jetbrains.kotlin.compilerRunner
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.logging.Logger
|
import org.gradle.api.logging.Logger
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
|
||||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||||
import org.jetbrains.kotlin.daemon.client.reportFromDaemon
|
import org.jetbrains.kotlin.daemon.client.reportFromDaemon
|
||||||
import org.jetbrains.kotlin.daemon.common.*
|
import org.jetbrains.kotlin.daemon.common.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
|
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import java.rmi.Remote
|
import java.rmi.Remote
|
||||||
import java.rmi.server.UnicastRemoteObject
|
import java.rmi.server.UnicastRemoteObject
|
||||||
@@ -45,20 +47,7 @@ internal open class GradleCompilerServicesFacadeImpl(
|
|||||||
|
|
||||||
internal class GradleIncrementalCompilerServicesFacadeImpl(
|
internal class GradleIncrementalCompilerServicesFacadeImpl(
|
||||||
project: Project,
|
project: Project,
|
||||||
private val environment: GradleIncrementalCompilerEnvironment,
|
environment: GradleIncrementalCompilerEnvironment,
|
||||||
port: Int = SOCKET_ANY_FREE_PORT
|
port: Int = SOCKET_ANY_FREE_PORT
|
||||||
) : GradleCompilerServicesFacadeImpl(project, environment.messageCollector, port),
|
) : GradleCompilerServicesFacadeImpl(project, environment.messageCollector, port),
|
||||||
IncrementalCompilerServicesFacade {
|
IncrementalCompilerServicesFacade
|
||||||
|
|
||||||
override fun hasAnnotationsFileUpdater(): Boolean =
|
|
||||||
environment.kaptAnnotationsFileUpdater != null
|
|
||||||
|
|
||||||
override fun updateAnnotations(outdatedClassesJvmNames: Iterable<String>) {
|
|
||||||
val jvmNames = outdatedClassesJvmNames.map { JvmClassName.byInternalName(it) }
|
|
||||||
environment.kaptAnnotationsFileUpdater!!.updateAnnotations(jvmNames)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun revert() {
|
|
||||||
environment.kaptAnnotationsFileUpdater!!.revert()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-442
@@ -1,442 +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.gradle.internal
|
|
||||||
|
|
||||||
import com.android.build.gradle.BaseExtension
|
|
||||||
import org.gradle.api.GradleException
|
|
||||||
import org.gradle.api.Project
|
|
||||||
import org.gradle.api.UnknownDomainObjectException
|
|
||||||
import org.gradle.api.file.FileCollection
|
|
||||||
import org.gradle.api.tasks.compile.AbstractCompile
|
|
||||||
import org.gradle.api.tasks.compile.JavaCompile
|
|
||||||
//import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
|
||||||
//import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
|
||||||
//import com.intellij.lang.Language
|
|
||||||
//import com.intellij.openapi.util.Disposer
|
|
||||||
//import com.intellij.psi.PsiFileFactory
|
|
||||||
//import com.intellij.psi.PsiJavaFile
|
|
||||||
//import com.intellij.psi.impl.PsiFileFactoryImpl
|
|
||||||
//import org.jetbrains.kotlin.config.CompilerConfiguration
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.kapt.generateAnnotationProcessorWrapper
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.kapt.generateKotlinAptAnnotation
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.isBuildCacheSupported
|
|
||||||
import java.io.File
|
|
||||||
import java.io.IOException
|
|
||||||
import java.util.zip.ZipFile
|
|
||||||
|
|
||||||
internal fun Project.initKapt(
|
|
||||||
kotlinTask: KotlinCompile,
|
|
||||||
javaTask: JavaCompile,
|
|
||||||
kaptManager: AnnotationProcessingManager,
|
|
||||||
variantName: String,
|
|
||||||
kotlinOptions: KotlinJvmOptionsImpl?,
|
|
||||||
subpluginEnvironment: SubpluginEnvironment,
|
|
||||||
tasksProvider: KotlinTasksProvider,
|
|
||||||
androidProjectHandler: AbstractAndroidProjectHandler<*>?
|
|
||||||
): KotlinCompile? {
|
|
||||||
val kaptExtension = extensions.getByType(KaptExtension::class.java)
|
|
||||||
val kotlinAfterJavaTask: KotlinCompile?
|
|
||||||
|
|
||||||
fun warnUnsupportedKapt1Option(optionName: String) {
|
|
||||||
kotlinTask.logger.kotlinWarn("'$optionName' option is not supported by this kapt implementation. " +
|
|
||||||
"Please add the \"apply plugin: 'kotlin-kapt\" line to your build script to enable it.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kaptExtension.processors.isNotEmpty()) warnUnsupportedKapt1Option("processors")
|
|
||||||
if (kaptExtension.correctErrorTypes) warnUnsupportedKapt1Option("correctErrorTypes")
|
|
||||||
|
|
||||||
if (kaptExtension.generateStubs) {
|
|
||||||
kotlinAfterJavaTask = createKotlinAfterJavaTask(javaTask, kotlinTask, kotlinOptions, tasksProvider)
|
|
||||||
|
|
||||||
kotlinTask.logger.kotlinDebug("kapt: Using class file stubs")
|
|
||||||
|
|
||||||
val stubsDir = File(buildDir, "tmp/kapt/$variantName/classFileStubs").apply { mkdirs() }
|
|
||||||
kotlinAfterJavaTask.destinationDir = kotlinTask.destinationDir
|
|
||||||
kotlinTask.destinationDir = stubsDir
|
|
||||||
kotlinTask.kaptOptions.generateStubs = true
|
|
||||||
|
|
||||||
kotlinAfterJavaTask.source(kaptManager.generatedKotlinSourceDir)
|
|
||||||
kotlinAfterJavaTask.source(kaptManager.aptOutputDir)
|
|
||||||
subpluginEnvironment.addSubpluginOptions(this, kotlinAfterJavaTask, javaTask, null, androidProjectHandler, null)
|
|
||||||
|
|
||||||
// javaTask.doLast {
|
|
||||||
// moveGeneratedJavaFilesToCorrespondingDirectories(kaptManager.aptOutputDir)
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (isBuildCacheSupported()) {
|
|
||||||
// Since Kapt1 is about to be dropped, disable the cache for it:
|
|
||||||
kotlinAfterJavaTask.outputs.doNotCacheIf("Caching is not supported with deprecated Kapt1") { true }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
kotlinAfterJavaTask = null
|
|
||||||
kotlinTask.logger.kotlinDebug("kapt: Class file stubs are not used")
|
|
||||||
}
|
|
||||||
|
|
||||||
javaTask.appendClasspathDynamically(kaptManager.wrappersDirectory)
|
|
||||||
javaTask.source(kaptManager.hackAnnotationDir)
|
|
||||||
|
|
||||||
kotlinTask.kaptOptions.supportInheritedAnnotations = kaptExtension.inheritedAnnotations
|
|
||||||
|
|
||||||
kotlinTask.doFirst {
|
|
||||||
kaptManager.generateJavaHackFile()
|
|
||||||
}
|
|
||||||
|
|
||||||
javaTask.doFirst {
|
|
||||||
kaptManager.setupKapt()
|
|
||||||
kaptManager.generateJavaHackFile()
|
|
||||||
kotlinAfterJavaTask?.source(kaptManager.generatedKotlinSourceDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
javaTask.doLast {
|
|
||||||
kaptManager.afterJavaCompile()
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlinTask.kaptOptions.annotationsFile = kaptManager.getAnnotationFile()
|
|
||||||
|
|
||||||
if (isBuildCacheSupported()) {
|
|
||||||
// Since Kapt1 is about to be dropped, disable the cache for it:
|
|
||||||
kotlinTask.outputs.doNotCacheIf("Caching is not supported with deprecated Kapt1") { true }
|
|
||||||
}
|
|
||||||
|
|
||||||
return kotlinAfterJavaTask
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Project.createKotlinAfterJavaTask(
|
|
||||||
javaTask: AbstractCompile,
|
|
||||||
kotlinTask: KotlinCompile,
|
|
||||||
kotlinOptions: KotlinJvmOptionsImpl?,
|
|
||||||
tasksProvider: KotlinTasksProvider
|
|
||||||
): KotlinCompile {
|
|
||||||
val kotlinAfterJavaTask = with (tasksProvider.createKotlinJVMTask(this, kotlinTask.name + KOTLIN_AFTER_JAVA_TASK_SUFFIX, kotlinTask.sourceSetName)) {
|
|
||||||
mapClasspath { kotlinTask.classpath }
|
|
||||||
this
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlinAfterJavaTask.dependsOn(javaTask)
|
|
||||||
javaTask.finalizedByIfNotFailed(kotlinAfterJavaTask)
|
|
||||||
kotlinAfterJavaTask.parentKotlinOptionsImpl = kotlinOptions
|
|
||||||
return kotlinAfterJavaTask
|
|
||||||
}
|
|
||||||
|
|
||||||
class AnnotationProcessingManager(
|
|
||||||
task: AbstractCompile,
|
|
||||||
private val javaTask: JavaCompile,
|
|
||||||
private val taskQualifier: String,
|
|
||||||
private val aptFiles: Set<File>,
|
|
||||||
val aptOutputDir: File,
|
|
||||||
private val aptWorkingDir: File,
|
|
||||||
private val androidVariant: Any? = null) {
|
|
||||||
|
|
||||||
private val project = task.project
|
|
||||||
val wrappersDirectory = File(aptWorkingDir, "wrappers")
|
|
||||||
val hackAnnotationDir = File(aptWorkingDir, "java_src")
|
|
||||||
|
|
||||||
private var originalJavaCompilerArgs: List<String>? = null
|
|
||||||
private var originalProcessorPath: FileCollection? = null
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
val JAVA_FQNAME_PATTERN = "^([\\p{L}_$][\\p{L}\\p{N}_$]*\\.)*[\\p{L}_$][\\p{L}\\p{N}_$]*$".toRegex()
|
|
||||||
val GEN_ANNOTATION = "__gen/annotation"
|
|
||||||
|
|
||||||
private val ANDROID_APT_PLUGIN_ID = "com.neenbedankt.android-apt"
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getAnnotationFile(): File {
|
|
||||||
if (!aptWorkingDir.exists()) aptWorkingDir.mkdirs()
|
|
||||||
return File(wrappersDirectory, "annotations.$taskQualifier.txt")
|
|
||||||
}
|
|
||||||
|
|
||||||
val generatedKotlinSourceDir: File
|
|
||||||
get() {
|
|
||||||
val kotlinGeneratedDir = File(aptWorkingDir, "kotlinGenerated")
|
|
||||||
if (!kotlinGeneratedDir.exists()) kotlinGeneratedDir.mkdirs()
|
|
||||||
return kotlinGeneratedDir
|
|
||||||
}
|
|
||||||
|
|
||||||
val kaptProcessorPath get() = setOf(wrappersDirectory) + aptFiles + javaTask.classpath
|
|
||||||
|
|
||||||
private fun allowToUseOriginalKapt(): Boolean {
|
|
||||||
return project.hasProperty("allow.original.kapt")
|
|
||||||
&& project.property("allow.original.kapt").toString().toBoolean()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setupKapt() {
|
|
||||||
originalJavaCompilerArgs = javaTask.options.compilerArgs
|
|
||||||
|
|
||||||
if (aptFiles.isEmpty()) return
|
|
||||||
|
|
||||||
val deprecationMessage = "${project.name}: " +
|
|
||||||
"Original kapt is deprecated. Please add \"apply plugin: 'kotlin-kapt'\" to your build.gradle."
|
|
||||||
|
|
||||||
if (allowToUseOriginalKapt()) {
|
|
||||||
project.logger.warn(deprecationMessage)
|
|
||||||
} else {
|
|
||||||
throw GradleException(deprecationMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project.plugins.findPlugin(ANDROID_APT_PLUGIN_ID) != null) {
|
|
||||||
project.logger.warn("Please do not use `$ANDROID_APT_PLUGIN_ID` with kapt.")
|
|
||||||
}
|
|
||||||
|
|
||||||
val annotationProcessorFqNames = lookupAnnotationProcessors(aptFiles)
|
|
||||||
|
|
||||||
generateAnnotationProcessorStubs(javaTask, annotationProcessorFqNames, wrappersDirectory)
|
|
||||||
|
|
||||||
setProcessorPathInJavaTask()
|
|
||||||
|
|
||||||
if (aptOutputDir.exists()) {
|
|
||||||
aptOutputDir.deleteRecursively()
|
|
||||||
}
|
|
||||||
addGeneratedSourcesOutputToCompilerArgs(javaTask, aptOutputDir)
|
|
||||||
|
|
||||||
appendAnnotationsArguments()
|
|
||||||
appendAdditionalComplerArgs()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun afterJavaCompile() {
|
|
||||||
val generatedFile = File(javaTask.destinationDir, "$GEN_ANNOTATION/Cl.class")
|
|
||||||
if (generatedFile.exists()) {
|
|
||||||
generatedFile.delete()
|
|
||||||
} else {
|
|
||||||
project.logger.kotlinDebug("kapt: Java file stub was not found at $generatedFile")
|
|
||||||
}
|
|
||||||
javaTask.options.compilerArgs = originalJavaCompilerArgs
|
|
||||||
tryRevertProcessorPathProperty()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun generateJavaHackFile() {
|
|
||||||
val javaHackPackageDir = File(hackAnnotationDir, GEN_ANNOTATION)
|
|
||||||
val javaHackClFile = File(javaHackPackageDir, "Cl.java")
|
|
||||||
|
|
||||||
if (!javaHackClFile.exists()) {
|
|
||||||
javaHackClFile.parentFile.mkdirs()
|
|
||||||
javaHackClFile.writeText("package __gen.annotation;\n" +
|
|
||||||
"class Cl { @__gen.KotlinAptAnnotation boolean v; }")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun appendAnnotationsArguments() {
|
|
||||||
javaTask.modifyCompilerArguments { list ->
|
|
||||||
list.add("-Akapt.annotations=" + getAnnotationFile())
|
|
||||||
list.add("-Akapt.kotlin.generated=" + generatedKotlinSourceDir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun appendAdditionalComplerArgs() {
|
|
||||||
val kaptExtension = project.extensions.getByType(KaptExtension::class.java)
|
|
||||||
val args = kaptExtension.getAdditionalArgumentsForJavac(project, androidVariant, getAndroidExtension())
|
|
||||||
if (args.isEmpty()) return
|
|
||||||
|
|
||||||
javaTask.modifyCompilerArguments { list ->
|
|
||||||
list.addAll(args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateAnnotationProcessorStubs(javaTask: JavaCompile, processorFqNames: Set<String>, outputDir: File) {
|
|
||||||
val aptAnnotationFile = generateKotlinAptAnnotation(outputDir)
|
|
||||||
project.logger.kotlinDebug("kapt: Stub annotation generated: $aptAnnotationFile")
|
|
||||||
|
|
||||||
val stubOutputPackageDir = File(outputDir, "__gen")
|
|
||||||
stubOutputPackageDir.mkdirs()
|
|
||||||
|
|
||||||
for (processorFqName in processorFqNames) {
|
|
||||||
val wrapperFile = generateAnnotationProcessorWrapper(
|
|
||||||
processorFqName,
|
|
||||||
"__gen",
|
|
||||||
stubOutputPackageDir,
|
|
||||||
getProcessorStubClassName(processorFqName),
|
|
||||||
taskQualifier)
|
|
||||||
|
|
||||||
project.logger.kotlinDebug("kapt: Wrapper for $processorFqName generated: $wrapperFile")
|
|
||||||
}
|
|
||||||
|
|
||||||
val annotationProcessorWrapperFqNames = processorFqNames
|
|
||||||
.map { fqName -> "__gen." + getProcessorStubClassName(fqName) }
|
|
||||||
.joinToString(",")
|
|
||||||
|
|
||||||
addWrappersToCompilerArgs(javaTask, annotationProcessorWrapperFqNames)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addWrappersToCompilerArgs(javaTask: JavaCompile, wrapperFqNames: String) {
|
|
||||||
javaTask.addCompilerArgument("-processor") { prevValue ->
|
|
||||||
if (prevValue != null) "$prevValue,$wrapperFqNames" else wrapperFqNames
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAndroidExtension(): BaseExtension? {
|
|
||||||
try {
|
|
||||||
return project.extensions.getByName("android") as BaseExtension
|
|
||||||
} catch (e: UnknownDomainObjectException) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addGeneratedSourcesOutputToCompilerArgs(javaTask: JavaCompile, outputDir: File) {
|
|
||||||
outputDir.mkdirs()
|
|
||||||
|
|
||||||
javaTask.addCompilerArgument("-s") { prevValue ->
|
|
||||||
if (prevValue != null)
|
|
||||||
javaTask.logger.warn("Destination for generated sources was modified by kapt. Previous value = $prevValue")
|
|
||||||
outputDir.absolutePath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setProcessorPathInJavaTask() {
|
|
||||||
val path = kaptProcessorPath
|
|
||||||
|
|
||||||
// If processor path property is supported, set it, otherwise set compiler argument:
|
|
||||||
val couldSetProperty = tryAppendProcessorPathProperty(path)
|
|
||||||
|
|
||||||
if (!couldSetProperty) {
|
|
||||||
javaTask.addCompilerArgument("-processorpath") { prevValue ->
|
|
||||||
if (prevValue != null)
|
|
||||||
javaTask.logger.warn("Processor path was modified by kapt. Previous value = $prevValue")
|
|
||||||
path.joinToString(postfix = prevValue?.let { File.pathSeparator + it }.orEmpty(),
|
|
||||||
separator = File.pathSeparator)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun tryAppendProcessorPathProperty(path: Iterable<File>): Boolean = try {
|
|
||||||
val optionsClass = javaTask.options.javaClass
|
|
||||||
val getPath = optionsClass.getMethod("getAnnotationProcessorPath")
|
|
||||||
val setPath = optionsClass.getMethod("setAnnotationProcessorPath", FileCollection::class.java)
|
|
||||||
|
|
||||||
originalProcessorPath = getPath(javaTask.options) as? FileCollection
|
|
||||||
|
|
||||||
if (originalProcessorPath != null)
|
|
||||||
javaTask.logger.warn("Processor path was modified by kapt. Previous value = $originalProcessorPath")
|
|
||||||
|
|
||||||
val newPath = javaTask.project.files(path + (originalProcessorPath ?: emptyList()))
|
|
||||||
setPath(javaTask.options, newPath)
|
|
||||||
true
|
|
||||||
} catch (_: NoSuchMethodException) {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun tryRevertProcessorPathProperty() {
|
|
||||||
try {
|
|
||||||
val optionsClass = javaTask.options.javaClass
|
|
||||||
val setPath = optionsClass.getMethod("setAnnotationProcessorPath", FileCollection::class.java)
|
|
||||||
|
|
||||||
setPath(javaTask.options, originalProcessorPath)
|
|
||||||
} catch (_: NoSuchMethodException) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getProcessorStubClassName(processorFqName: String): String {
|
|
||||||
return "AnnotationProcessorWrapper_${taskQualifier}_${processorFqName.replace('.', '_')}"
|
|
||||||
}
|
|
||||||
|
|
||||||
private inline fun JavaCompile.addCompilerArgument(name: String, value: (String?) -> String) {
|
|
||||||
modifyCompilerArguments { args ->
|
|
||||||
val argIndex = args.indexOfFirst { name == it }
|
|
||||||
|
|
||||||
if (argIndex >= 0 && args.size > (argIndex + 1)) {
|
|
||||||
args[argIndex + 1] = value(args[argIndex + 1])
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
args.add(name)
|
|
||||||
args.add(value(null))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inline fun JavaCompile.modifyCompilerArguments(modifier: (MutableList<String>) -> Unit) {
|
|
||||||
val compilerArgs: List<Any> = this.options.compilerArgs
|
|
||||||
val newCompilerArgs = compilerArgs.mapTo(arrayListOf<String>(), Any::toString)
|
|
||||||
modifier(newCompilerArgs)
|
|
||||||
options.compilerArgs = newCompilerArgs
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun lookupAnnotationProcessors(files: Set<File>): Set<String> {
|
|
||||||
fun withZipFile(file: File, job: (ZipFile) -> Unit) {
|
|
||||||
var zipFile: ZipFile? = null
|
|
||||||
try {
|
|
||||||
zipFile = ZipFile(file)
|
|
||||||
job(zipFile)
|
|
||||||
}
|
|
||||||
catch (e: IOException) {
|
|
||||||
// Do nothing (do not continue to search for annotation processors on error)
|
|
||||||
}
|
|
||||||
catch (e: IllegalStateException) {
|
|
||||||
// ZipFile was already closed for some reason
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
try {
|
|
||||||
zipFile?.close()
|
|
||||||
}
|
|
||||||
catch (e: IOException) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val annotationProcessors = hashSetOf<String>()
|
|
||||||
|
|
||||||
fun processLines(lines: Sequence<String>) {
|
|
||||||
for (line in lines) {
|
|
||||||
if (line.isBlank() || !JAVA_FQNAME_PATTERN.matches(line)) continue
|
|
||||||
annotationProcessors.add(line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (file in files) {
|
|
||||||
withZipFile(file) { zipFile ->
|
|
||||||
val entry = zipFile.getEntry("META-INF/services/javax.annotation.processing.Processor")
|
|
||||||
if (entry != null) {
|
|
||||||
zipFile.getInputStream(entry).reader().useLines(::processLines)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
project.logger.kotlinDebug("kapt: Discovered annotation processors: ${annotationProcessors.joinToString()}")
|
|
||||||
return annotationProcessors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Java files can be generated anywhere, but
|
|
||||||
// Kotlin searches for java fq-name only in directory corresponding to package.
|
|
||||||
// Previously this worked because generated files were added to classpath.
|
|
||||||
// However in that case incremental compilation worked unreliable with generated files.
|
|
||||||
// The solution is to post-process generated java files and move them to corresponding packages
|
|
||||||
//fun moveGeneratedJavaFilesToCorrespondingDirectories(generatedJavaSourceRoot: File) {
|
|
||||||
// val javaFiles = generatedJavaSourceRoot.walk().filter { it.extension.equals("java", ignoreCase = true) }.toList()
|
|
||||||
//
|
|
||||||
// if (javaFiles.isEmpty()) return
|
|
||||||
//
|
|
||||||
// val rootDisposable = Disposer.newDisposable()
|
|
||||||
// val configuration = CompilerConfiguration()
|
|
||||||
// val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
|
||||||
// val project = environment.project
|
|
||||||
// val psiFileFactory = PsiFileFactory.getInstance(project) as PsiFileFactoryImpl
|
|
||||||
//
|
|
||||||
// for (javaFile in javaFiles) {
|
|
||||||
// val psiFile = psiFileFactory.createFileFromText(javaFile.nameWithoutExtension, Language.findLanguageByID("JAVA")!!, javaFile.readText())
|
|
||||||
// val packageName = (psiFile as? PsiJavaFile)?.packageName ?: continue
|
|
||||||
// val expectedDir = File(generatedJavaSourceRoot, packageName.replace('.', '/'))
|
|
||||||
// val expectedFile = File(expectedDir, javaFile.name)
|
|
||||||
//
|
|
||||||
// if (javaFile != expectedFile) {
|
|
||||||
// expectedFile.parentFile.mkdirs()
|
|
||||||
// javaFile.copyTo(expectedFile, overwrite = true)
|
|
||||||
// javaFile.delete()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
+24
-14
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* 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.
|
||||||
* 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.gradle.internal
|
package org.jetbrains.kotlin.gradle.internal
|
||||||
@@ -59,7 +48,9 @@ class Kapt3GradleSubplugin : Plugin<Project> {
|
|||||||
File(project.project.buildDir, "generated/source/kaptKotlin/$sourceSetName")
|
File(project.project.buildDir, "generated/source/kaptKotlin/$sourceSetName")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun apply(project: Project) {}
|
override fun apply(project: Project) {
|
||||||
|
project.extensions.create("kapt", KaptExtension::class.java)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class KaptVariantData<T>(val variantData: T) {
|
abstract class KaptVariantData<T>(val variantData: T) {
|
||||||
@@ -170,6 +161,8 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
|||||||
javaSourceSet.name
|
javaSourceSet.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createAptConfigurationIfNeeded(project, sourceSetName)
|
||||||
|
|
||||||
val kaptExtension = project.extensions.getByType(KaptExtension::class.java)
|
val kaptExtension = project.extensions.getByType(KaptExtension::class.java)
|
||||||
|
|
||||||
val nonEmptyKaptConfigurations = kaptConfigurations.filter { configuration ->
|
val nonEmptyKaptConfigurations = kaptConfigurations.filter { configuration ->
|
||||||
@@ -196,6 +189,23 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
|||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createAptConfigurationIfNeeded(project: Project, sourceSetName: String): Configuration {
|
||||||
|
val configurationName = Kapt3KotlinGradleSubplugin.getKaptConfigurationName(sourceSetName)
|
||||||
|
|
||||||
|
project.configurations.findByName(configurationName)?.let { return it }
|
||||||
|
val aptConfiguration = project.configurations.create(configurationName)
|
||||||
|
|
||||||
|
if (aptConfiguration.name != Kapt3KotlinGradleSubplugin.MAIN_KAPT_CONFIGURATION_NAME) {
|
||||||
|
// The main configuration can be created after the current one. We should handle this case
|
||||||
|
val mainConfiguration = findMainKaptConfiguration(project)
|
||||||
|
?: createAptConfigurationIfNeeded(project, SourceSet.MAIN_SOURCE_SET_NAME)
|
||||||
|
|
||||||
|
aptConfiguration.extendsFrom(mainConfiguration)
|
||||||
|
}
|
||||||
|
|
||||||
|
return aptConfiguration
|
||||||
|
}
|
||||||
|
|
||||||
override fun getSubpluginKotlinTasks(project: Project, kotlinCompile: KotlinCompile): List<AbstractCompile> {
|
override fun getSubpluginKotlinTasks(project: Project, kotlinCompile: KotlinCompile): List<AbstractCompile> {
|
||||||
val kaptGenerateStubsTask = kotlinToKaptGenerateStubsTasksMap[kotlinCompile]
|
val kaptGenerateStubsTask = kotlinToKaptGenerateStubsTasksMap[kotlinCompile]
|
||||||
return if (kaptGenerateStubsTask == null) emptyList() else listOf(kaptGenerateStubsTask)
|
return if (kaptGenerateStubsTask == null) emptyList() else listOf(kaptGenerateStubsTask)
|
||||||
|
|||||||
+16
-121
@@ -2,7 +2,6 @@ package org.jetbrains.kotlin.gradle.plugin
|
|||||||
|
|
||||||
import com.android.build.gradle.BaseExtension
|
import com.android.build.gradle.BaseExtension
|
||||||
import com.android.build.gradle.BasePlugin
|
import com.android.build.gradle.BasePlugin
|
||||||
import com.android.build.gradle.api.AndroidSourceSet
|
|
||||||
import com.android.builder.model.SourceProvider
|
import com.android.builder.model.SourceProvider
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import com.intellij.openapi.util.text.StringUtil.compareVersionNumbers
|
import com.intellij.openapi.util.text.StringUtil.compareVersionNumbers
|
||||||
@@ -37,7 +36,6 @@ import java.util.*
|
|||||||
import java.util.concurrent.Callable
|
import java.util.concurrent.Callable
|
||||||
import java.util.jar.Manifest
|
import java.util.jar.Manifest
|
||||||
|
|
||||||
val KOTLIN_AFTER_JAVA_TASK_SUFFIX = "AfterJava"
|
|
||||||
val KOTLIN_DSL_NAME = "kotlin"
|
val KOTLIN_DSL_NAME = "kotlin"
|
||||||
val KOTLIN_JS_DSL_NAME = "kotlin2js"
|
val KOTLIN_JS_DSL_NAME = "kotlin2js"
|
||||||
val KOTLIN_OPTIONS_DSL_NAME = "kotlinOptions"
|
val KOTLIN_OPTIONS_DSL_NAME = "kotlinOptions"
|
||||||
@@ -145,7 +143,6 @@ internal class Kotlin2JvmSourceSetProcessor(
|
|||||||
tasksProvider.createKotlinJVMTask(project, taskName, sourceSet.name)
|
tasksProvider.createKotlinJVMTask(project, taskName, sourceSet.name)
|
||||||
|
|
||||||
override fun doTargetSpecificProcessing() {
|
override fun doTargetSpecificProcessing() {
|
||||||
val aptConfiguration = project.createAptConfiguration(sourceSet.name, kotlinPluginVersion)
|
|
||||||
kotlinSourceSet.kotlin.source(sourceSet.java)
|
kotlinSourceSet.kotlin.source(sourceSet.java)
|
||||||
|
|
||||||
project.afterEvaluate { project ->
|
project.afterEvaluate { project ->
|
||||||
@@ -156,26 +153,11 @@ internal class Kotlin2JvmSourceSetProcessor(
|
|||||||
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
||||||
project, kotlinTask, javaTask as JavaCompile, null, null, sourceSet)
|
project, kotlinTask, javaTask as JavaCompile, null, null, sourceSet)
|
||||||
|
|
||||||
var kotlinAfterJavaTask: KotlinCompile? = null
|
removeAnnotationProcessingPluginClasspathEntry(kotlinTask)
|
||||||
|
|
||||||
if (!Kapt3GradleSubplugin.isEnabled(project) && aptConfiguration.allDependencies.size > 1) {
|
|
||||||
javaTask.dependsOn(aptConfiguration.buildDependencies)
|
|
||||||
|
|
||||||
val (aptOutputDir, aptWorkingDir) = project.getAptDirsForSourceSet(sourceSetName)
|
|
||||||
|
|
||||||
val kaptManager = AnnotationProcessingManager(kotlinTask, javaTask, sourceSetName,
|
|
||||||
aptConfiguration.resolve(), aptOutputDir, aptWorkingDir)
|
|
||||||
|
|
||||||
kotlinAfterJavaTask = project.initKapt(kotlinTask, javaTask, kaptManager,
|
|
||||||
sourceSetName, null, subpluginEnvironment, tasksProvider, null)
|
|
||||||
} else {
|
|
||||||
removeAnnotationProcessingPluginClasspathEntry(kotlinTask)
|
|
||||||
}
|
|
||||||
|
|
||||||
// KotlinCompile.source(kotlinDirSet) should be called only after all java roots are added to kotlinDirSet
|
// KotlinCompile.source(kotlinDirSet) should be called only after all java roots are added to kotlinDirSet
|
||||||
// otherwise some java roots can be ignored
|
// otherwise some java roots can be ignored
|
||||||
kotlinTask.source(kotlinSourceSet.kotlin)
|
kotlinTask.source(kotlinSourceSet.kotlin)
|
||||||
kotlinAfterJavaTask?.source(kotlinSourceSet.kotlin)
|
|
||||||
appliedPlugins
|
appliedPlugins
|
||||||
.flatMap { it.getSubpluginKotlinTasks(project, kotlinTask) }
|
.flatMap { it.getSubpluginKotlinTasks(project, kotlinTask) }
|
||||||
.forEach { it.source(kotlinSourceSet.kotlin) }
|
.forEach { it.source(kotlinSourceSet.kotlin) }
|
||||||
@@ -185,12 +167,12 @@ internal class Kotlin2JvmSourceSetProcessor(
|
|||||||
var syncOutputTask: SyncOutputTask? = null
|
var syncOutputTask: SyncOutputTask? = null
|
||||||
|
|
||||||
if (!isSeparateClassesDirSupported) {
|
if (!isSeparateClassesDirSupported) {
|
||||||
syncOutputTask = createSyncOutputTask(project, kotlinTask, javaTask, kotlinAfterJavaTask, sourceSetName)
|
syncOutputTask = createSyncOutputTask(project, kotlinTask, javaTask, sourceSetName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (project.pluginManager.hasPlugin("java-library") && sourceSetName == SourceSet.MAIN_SOURCE_SET_NAME) {
|
if (project.pluginManager.hasPlugin("java-library") && sourceSetName == SourceSet.MAIN_SOURCE_SET_NAME) {
|
||||||
val (classesProviderTask, classesDirectory) = when {
|
val (classesProviderTask, classesDirectory) = when {
|
||||||
isSeparateClassesDirSupported -> (kotlinAfterJavaTask ?: kotlinTask).let { it to it.destinationDir }
|
isSeparateClassesDirSupported -> kotlinTask.let { it to it.destinationDir }
|
||||||
else -> syncOutputTask!!.let { it to it.javaOutputDir }
|
else -> syncOutputTask!!.let { it to it.javaOutputDir }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,7 +403,6 @@ internal open class KotlinPlugin(
|
|||||||
Kotlin2JvmSourceSetProcessor(project, javaBasePlugin, sourceSet, tasksProvider, kotlinSourceSetProvider, kotlinPluginVersion)
|
Kotlin2JvmSourceSetProcessor(project, javaBasePlugin, sourceSet, tasksProvider, kotlinSourceSetProvider, kotlinPluginVersion)
|
||||||
|
|
||||||
override fun apply(project: Project) {
|
override fun apply(project: Project) {
|
||||||
project.createKaptExtension()
|
|
||||||
project.pluginManager.apply(ScriptingGradleSubplugin::class.java)
|
project.pluginManager.apply(ScriptingGradleSubplugin::class.java)
|
||||||
super.apply(project)
|
super.apply(project)
|
||||||
}
|
}
|
||||||
@@ -509,8 +490,7 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
|
|||||||
androidExt: BaseExtension,
|
androidExt: BaseExtension,
|
||||||
variantData: V,
|
variantData: V,
|
||||||
javaTask: AbstractCompile,
|
javaTask: AbstractCompile,
|
||||||
kotlinTask: KotlinCompile,
|
kotlinTask: KotlinCompile)
|
||||||
kotlinAfterJavaTask: KotlinCompile?): Unit
|
|
||||||
|
|
||||||
protected abstract fun wrapVariantDataForKapt(variantData: V): KaptVariantData<V>
|
protected abstract fun wrapVariantDataForKapt(variantData: V): KaptVariantData<V>
|
||||||
|
|
||||||
@@ -523,16 +503,12 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
|
|||||||
val kotlinSourceSet = kotlinConfigurationTools.kotlinSourceSetProvider.create(sourceSet.name)
|
val kotlinSourceSet = kotlinConfigurationTools.kotlinSourceSetProvider.create(sourceSet.name)
|
||||||
kotlinSourceSet.kotlin.srcDir(project.file(project.file("src/${sourceSet.name}/kotlin")))
|
kotlinSourceSet.kotlin.srcDir(project.file(project.file("src/${sourceSet.name}/kotlin")))
|
||||||
sourceSet.addConvention(KOTLIN_DSL_NAME, kotlinSourceSet)
|
sourceSet.addConvention(KOTLIN_DSL_NAME, kotlinSourceSet)
|
||||||
|
|
||||||
aptConfigurations.put(sourceSet.name, project.createAptConfiguration(sourceSet.name, kotlinConfigurationTools.kotlinPluginVersion))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val kotlinOptions = KotlinJvmOptionsImpl()
|
val kotlinOptions = KotlinJvmOptionsImpl()
|
||||||
kotlinOptions.noJdk = true
|
kotlinOptions.noJdk = true
|
||||||
ext.addExtension(KOTLIN_OPTIONS_DSL_NAME, kotlinOptions)
|
ext.addExtension(KOTLIN_OPTIONS_DSL_NAME, kotlinOptions)
|
||||||
|
|
||||||
project.createKaptExtension()
|
|
||||||
|
|
||||||
project.afterEvaluate { project ->
|
project.afterEvaluate { project ->
|
||||||
if (project != null) {
|
if (project != null) {
|
||||||
val androidPluginIds = listOf("android", "com.android.application", "android-library", "com.android.library",
|
val androidPluginIds = listOf("android", "com.android.application", "android-library", "com.android.library",
|
||||||
@@ -585,49 +561,10 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
|
|||||||
kotlinTask.destinationDir = File(project.buildDir, "tmp/kotlin-classes/$variantDataName")
|
kotlinTask.destinationDir = File(project.buildDir, "tmp/kotlin-classes/$variantDataName")
|
||||||
kotlinTask.description = "Compiles the $variantDataName kotlin."
|
kotlinTask.description = "Compiles the $variantDataName kotlin."
|
||||||
|
|
||||||
val isKapt3Enabled = Kapt3GradleSubplugin.isEnabled(project)
|
removeAnnotationProcessingPluginClasspathEntry(kotlinTask)
|
||||||
|
|
||||||
val aptFiles = arrayListOf<File>()
|
configureSources(kotlinTask, variantData)
|
||||||
|
wireKotlinTasks(project, androidPlugin, androidExt, variantData, javaTask, kotlinTask)
|
||||||
if (!isKapt3Enabled) {
|
|
||||||
var hasAnyKaptDependency: Boolean = false
|
|
||||||
for (provider in getSourceProviders(variantData)) {
|
|
||||||
val aptConfiguration = aptConfigurations[(provider as AndroidSourceSet).name]
|
|
||||||
// Ignore if there's only an annotation processor wrapper in dependencies (added by default)
|
|
||||||
if (aptConfiguration != null && aptConfiguration.allDependencies.size > 1) {
|
|
||||||
javaTask.dependsOn(aptConfiguration.buildDependencies)
|
|
||||||
aptFiles.addAll(aptConfiguration.resolve())
|
|
||||||
hasAnyKaptDependency = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasAnyKaptDependency) {
|
|
||||||
removeAnnotationProcessingPluginClasspathEntry(kotlinTask)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
removeAnnotationProcessingPluginClasspathEntry(kotlinTask)
|
|
||||||
}
|
|
||||||
|
|
||||||
var kotlinAfterJavaTask: KotlinCompile? = null
|
|
||||||
|
|
||||||
if (javaTask is JavaCompile && aptFiles.isNotEmpty() && !isKapt3Enabled) {
|
|
||||||
val (aptOutputDir, aptWorkingDir) = project.getAptDirsForSourceSet(variantDataName)
|
|
||||||
|
|
||||||
addJavaSourceDirectoryToVariantModel(variantData, aptOutputDir)
|
|
||||||
|
|
||||||
val kaptManager = AnnotationProcessingManager(kotlinTask, javaTask, variantDataName,
|
|
||||||
aptFiles.toSet(), aptOutputDir, aptWorkingDir, variantData)
|
|
||||||
|
|
||||||
kotlinAfterJavaTask = project.initKapt(kotlinTask, javaTask, kaptManager,
|
|
||||||
variantDataName, rootKotlinOptions, subpluginEnvironment, tasksProvider, this)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (task in listOfNotNull(kotlinTask, kotlinAfterJavaTask)) {
|
|
||||||
configureSources(task, variantData)
|
|
||||||
}
|
|
||||||
|
|
||||||
wireKotlinTasks(project, androidPlugin, androidExt, variantData, javaTask,
|
|
||||||
kotlinTask, kotlinAfterJavaTask)
|
|
||||||
|
|
||||||
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
||||||
project, kotlinTask, javaTask, wrapVariantDataForKapt(variantData), this, null)
|
project, kotlinTask, javaTask, wrapVariantDataForKapt(variantData), this, null)
|
||||||
@@ -680,8 +617,6 @@ internal fun configureJavaTask(kotlinTask: KotlinCompile, javaTask: AbstractComp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Also, use kapt1 annotations file for up-to-date check since annotation processing is done with javac
|
// Also, use kapt1 annotations file for up-to-date check since annotation processing is done with javac
|
||||||
kotlinTask.kaptOptions.annotationsFile?.let { javaTask.inputsCompatible.fileCompatible(it) }
|
|
||||||
|
|
||||||
javaTask.dependsOn(kotlinTask)
|
javaTask.dependsOn(kotlinTask)
|
||||||
/*
|
/*
|
||||||
* It's important to modify javaTask.classpath only in doFirst,
|
* It's important to modify javaTask.classpath only in doFirst,
|
||||||
@@ -698,13 +633,10 @@ internal fun syncOutputTaskName(variantName: String) = "copy${variantName.capita
|
|||||||
|
|
||||||
internal fun createSyncOutputTask(
|
internal fun createSyncOutputTask(
|
||||||
project: Project,
|
project: Project,
|
||||||
kotlinTask: KotlinCompile,
|
kotlinCompile: KotlinCompile,
|
||||||
javaTask: AbstractCompile,
|
javaTask: AbstractCompile,
|
||||||
kotlinAfterJavaTask: KotlinCompile?,
|
|
||||||
variantName: String
|
variantName: String
|
||||||
): SyncOutputTask {
|
): SyncOutputTask {
|
||||||
// if kotlinAfterJavaTask is not null then kotlinTask compiles stubs, so don't sync them
|
|
||||||
val kotlinCompile = kotlinAfterJavaTask ?: kotlinTask
|
|
||||||
val kotlinDir = kotlinCompile.destinationDir
|
val kotlinDir = kotlinCompile.destinationDir
|
||||||
val javaDir = javaTask.destinationDir
|
val javaDir = javaTask.destinationDir
|
||||||
val taskName = syncOutputTaskName(variantName)
|
val taskName = syncOutputTaskName(variantName)
|
||||||
@@ -713,13 +645,11 @@ internal fun createSyncOutputTask(
|
|||||||
syncTask.kotlinOutputDir = kotlinDir
|
syncTask.kotlinOutputDir = kotlinDir
|
||||||
syncTask.javaOutputDir = javaDir
|
syncTask.javaOutputDir = javaDir
|
||||||
syncTask.kotlinTask = kotlinCompile
|
syncTask.kotlinTask = kotlinCompile
|
||||||
kotlinTask.javaOutputDir = javaDir
|
kotlinCompile.javaOutputDir = javaDir
|
||||||
kotlinAfterJavaTask?.javaOutputDir = javaDir
|
|
||||||
syncTask.kaptClassesDir = getKaptGeneratedClassesDir(project, variantName)
|
syncTask.kaptClassesDir = getKaptGeneratedClassesDir(project, variantName)
|
||||||
|
|
||||||
// copying should be executed after a latter task
|
// copying should be executed after a latter task
|
||||||
val previousTask = kotlinAfterJavaTask ?: javaTask
|
javaTask.finalizedByIfNotFailed(syncTask)
|
||||||
previousTask.finalizedByIfNotFailed(syncTask)
|
|
||||||
|
|
||||||
project.logger.kotlinDebug { "Created task ${syncTask.path} to copy kotlin classes from $kotlinDir to $javaDir" }
|
project.logger.kotlinDebug { "Created task ${syncTask.path} to copy kotlin classes from $kotlinDir to $javaDir" }
|
||||||
|
|
||||||
@@ -734,12 +664,12 @@ private val KOTLIN_ANNOTATION_PROCESSING_FILE_REGEX = "kotlin-annotation-process
|
|||||||
|
|
||||||
private fun removeAnnotationProcessingPluginClasspathEntry(kotlinCompile: KotlinCompile) {
|
private fun removeAnnotationProcessingPluginClasspathEntry(kotlinCompile: KotlinCompile) {
|
||||||
kotlinCompile.pluginOptions.classpath
|
kotlinCompile.pluginOptions.classpath
|
||||||
.map(::File)
|
.map(::File)
|
||||||
.filter { it.name.matches(KOTLIN_ANNOTATION_PROCESSING_FILE_REGEX) }
|
.filter { it.name.matches(KOTLIN_ANNOTATION_PROCESSING_FILE_REGEX) }
|
||||||
.forEach {
|
.forEach {
|
||||||
kotlinCompile.logger.kotlinDebug("Removing plugin classpath dependency $it")
|
kotlinCompile.logger.kotlinDebug("Removing plugin classpath dependency $it")
|
||||||
kotlinCompile.pluginOptions.removeClasspathEntry(it)
|
kotlinCompile.pluginOptions.removeClasspathEntry(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadSubplugins(project: Project): SubpluginEnvironment {
|
private fun loadSubplugins(project: Project): SubpluginEnvironment {
|
||||||
@@ -847,41 +777,6 @@ internal fun Task.registerSubpluginOptionsAsInputs(subpluginId: String, subplugi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Project.getAptDirsForSourceSet(sourceSetName: String): Pair<File, File> {
|
|
||||||
val aptOutputDir = File(buildDir, "generated/source/kapt")
|
|
||||||
val aptOutputDirForVariant = File(aptOutputDir, sourceSetName)
|
|
||||||
|
|
||||||
val aptWorkingDir = File(buildDir, "tmp/kapt")
|
|
||||||
val aptWorkingDirForVariant = File(aptWorkingDir, sourceSetName)
|
|
||||||
|
|
||||||
return aptOutputDirForVariant to aptWorkingDirForVariant
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Project.createAptConfiguration(sourceSetName: String, kotlinPluginVersion: String): Configuration {
|
|
||||||
val aptConfigurationName = Kapt3KotlinGradleSubplugin.getKaptConfigurationName(sourceSetName)
|
|
||||||
|
|
||||||
configurations.findByName(aptConfigurationName)?.let { return it }
|
|
||||||
val aptConfiguration = configurations.create(aptConfigurationName)
|
|
||||||
|
|
||||||
// Add base kotlin-annotation-processing artifact for the main kapt configuration,
|
|
||||||
// All other configurations (such as kaptTest) should extend the main one
|
|
||||||
if (aptConfiguration.name == Kapt3KotlinGradleSubplugin.MAIN_KAPT_CONFIGURATION_NAME) {
|
|
||||||
val kotlinAnnotationProcessingDep = "org.jetbrains.kotlin:kotlin-annotation-processing-gradle:$kotlinPluginVersion"
|
|
||||||
aptConfiguration.dependencies.add(dependencies.create(kotlinAnnotationProcessingDep))
|
|
||||||
} else {
|
|
||||||
// "main" configuration can be created after some other. We should handle this case
|
|
||||||
val mainConfiguration = Kapt3KotlinGradleSubplugin.findMainKaptConfiguration(this)
|
|
||||||
?: createAptConfiguration("main", kotlinPluginVersion)
|
|
||||||
aptConfiguration.extendsFrom(mainConfiguration)
|
|
||||||
}
|
|
||||||
|
|
||||||
return aptConfiguration
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Project.createKaptExtension() {
|
|
||||||
extensions.create("kapt", KaptExtension::class.java)
|
|
||||||
}
|
|
||||||
|
|
||||||
//copied from BasePlugin.getLocalVersion
|
//copied from BasePlugin.getLocalVersion
|
||||||
internal fun loadAndroidPluginVersion(): String? {
|
internal fun loadAndroidPluginVersion(): String? {
|
||||||
try {
|
try {
|
||||||
|
|||||||
+7
-3
@@ -1,3 +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.gradle.plugin
|
package org.jetbrains.kotlin.gradle.plugin
|
||||||
|
|
||||||
import com.android.build.gradle.BaseExtension
|
import com.android.build.gradle.BaseExtension
|
||||||
@@ -40,8 +45,7 @@ internal class LegacyAndroidAndroidProjectHandler(kotlinConfigurationTools: Kotl
|
|||||||
androidExt: BaseExtension,
|
androidExt: BaseExtension,
|
||||||
variantData: BaseVariantData<out BaseVariantOutputData>,
|
variantData: BaseVariantData<out BaseVariantOutputData>,
|
||||||
javaTask: AbstractCompile,
|
javaTask: AbstractCompile,
|
||||||
kotlinTask: KotlinCompile,
|
kotlinTask: KotlinCompile
|
||||||
kotlinAfterJavaTask: KotlinCompile?
|
|
||||||
) {
|
) {
|
||||||
kotlinTask.dependsOn(*javaTask.dependsOn.toTypedArray())
|
kotlinTask.dependsOn(*javaTask.dependsOn.toTypedArray())
|
||||||
|
|
||||||
@@ -56,7 +60,7 @@ internal class LegacyAndroidAndroidProjectHandler(kotlinConfigurationTools: Kotl
|
|||||||
}
|
}
|
||||||
|
|
||||||
configureJavaTask(kotlinTask, javaTask, logger)
|
configureJavaTask(kotlinTask, javaTask, logger)
|
||||||
createSyncOutputTask(project, kotlinTask, javaTask, kotlinAfterJavaTask, getVariantName(variantData))
|
createSyncOutputTask(project, kotlinTask, javaTask, getVariantName(variantData))
|
||||||
|
|
||||||
// In lib modules, the androidTest variants get the classes jar in their classpath instead of the Java
|
// In lib modules, the androidTest variants get the classes jar in their classpath instead of the Java
|
||||||
// destination dir. Attach the JAR to be consumed as friend path:
|
// destination dir. Attach the JAR to be consumed as friend path:
|
||||||
|
|||||||
-25
@@ -1,25 +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.gradle.tasks
|
|
||||||
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class KaptOptions {
|
|
||||||
var supportInheritedAnnotations: Boolean = false
|
|
||||||
var generateStubs: Boolean = false
|
|
||||||
var annotationsFile: File? = null
|
|
||||||
}
|
|
||||||
+4
-46
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* 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.
|
||||||
* 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.gradle.tasks
|
package org.jetbrains.kotlin.gradle.tasks
|
||||||
@@ -26,8 +15,6 @@ import org.gradle.api.tasks.Optional
|
|||||||
import org.gradle.api.tasks.compile.AbstractCompile
|
import org.gradle.api.tasks.compile.AbstractCompile
|
||||||
import org.gradle.api.tasks.compile.JavaCompile
|
import org.gradle.api.tasks.compile.JavaCompile
|
||||||
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
||||||
import org.jetbrains.kotlin.annotation.AnnotationFileUpdater
|
|
||||||
import org.jetbrains.kotlin.annotation.AnnotationFileUpdaterImpl
|
|
||||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
|
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
|
||||||
@@ -231,9 +218,6 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
|
|||||||
|
|
||||||
compilerCalled = true
|
compilerCalled = true
|
||||||
callCompiler(args, sourceRoots, ChangedFiles(inputs))
|
callCompiler(args, sourceRoots, ChangedFiles(inputs))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Internal
|
@Internal
|
||||||
@@ -283,11 +267,6 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
|
|||||||
@get:Internal
|
@get:Internal
|
||||||
internal open val sourceRootsContainer = FilteringSourceRootsContainer()
|
internal open val sourceRootsContainer = FilteringSourceRootsContainer()
|
||||||
|
|
||||||
private var kaptAnnotationsFileUpdater: AnnotationFileUpdater? = null
|
|
||||||
|
|
||||||
@get:Internal
|
|
||||||
val kaptOptions = KaptOptions()
|
|
||||||
|
|
||||||
/** A package prefix that is used for locating Java sources in a directory structure with non-full-depth packages.
|
/** A package prefix that is used for locating Java sources in a directory structure with non-full-depth packages.
|
||||||
*
|
*
|
||||||
* Example: a Java source file with `package com.example.my.package` is located in directory `src/main/java/my/package`.
|
* Example: a Java source file with `package com.example.my.package` is located in directory `src/main/java/my/package`.
|
||||||
@@ -315,9 +294,7 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
|
|||||||
|
|
||||||
override fun setupPlugins(compilerArgs: K2JVMCompilerArguments) {
|
override fun setupPlugins(compilerArgs: K2JVMCompilerArguments) {
|
||||||
compilerArgs.pluginClasspaths = pluginClasspath.toTypedArray()
|
compilerArgs.pluginClasspaths = pluginClasspath.toTypedArray()
|
||||||
|
compilerArgs.pluginOptions = pluginOptions.arguments.toTypedArray()
|
||||||
val kaptPluginOptions = getKaptPluginOptions()
|
|
||||||
compilerArgs.pluginOptions = (pluginOptions.arguments + kaptPluginOptions.arguments).toTypedArray()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setupCompilerArgs(args: K2JVMCompilerArguments, defaultsOnly: Boolean) {
|
override fun setupCompilerArgs(args: K2JVMCompilerArguments, defaultsOnly: Boolean) {
|
||||||
@@ -366,7 +343,7 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
|
|||||||
computedCompilerClasspath,
|
computedCompilerClasspath,
|
||||||
if (hasFilesInTaskBuildDirectory()) changedFiles else ChangedFiles.Unknown(),
|
if (hasFilesInTaskBuildDirectory()) changedFiles else ChangedFiles.Unknown(),
|
||||||
taskBuildDirectory,
|
taskBuildDirectory,
|
||||||
messageCollector, outputItemCollector, args, kaptAnnotationsFileUpdater,
|
messageCollector, outputItemCollector, args,
|
||||||
usePreciseJavaTracking = usePreciseJavaTracking,
|
usePreciseJavaTracking = usePreciseJavaTracking,
|
||||||
localStateDirs = outputDirectories,
|
localStateDirs = outputDirectories,
|
||||||
multiModuleICSettings = multiModuleICSettings
|
multiModuleICSettings = multiModuleICSettings
|
||||||
@@ -429,25 +406,6 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
|
|||||||
throwGradleExceptionIfError(exitCode)
|
throwGradleExceptionIfError(exitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getKaptPluginOptions() =
|
|
||||||
CompilerPluginOptions().apply {
|
|
||||||
kaptOptions.annotationsFile?.let { kaptAnnotationsFile ->
|
|
||||||
if (incremental) {
|
|
||||||
kaptAnnotationsFileUpdater = AnnotationFileUpdaterImpl(kaptAnnotationsFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
addPluginArgument(ANNOTATIONS_PLUGIN_NAME, FilesSubpluginOption("output", listOf(kaptAnnotationsFile)))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kaptOptions.generateStubs) {
|
|
||||||
addPluginArgument(ANNOTATIONS_PLUGIN_NAME, FilesSubpluginOption("stubs", listOf(destinationDir)))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kaptOptions.supportInheritedAnnotations) {
|
|
||||||
addPluginArgument(ANNOTATIONS_PLUGIN_NAME, SubpluginOption("inherited", true.toString()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// override setSource to track source directory sets and files (for generated android folders)
|
// override setSource to track source directory sets and files (for generated android folders)
|
||||||
override fun setSource(sources: Any?) {
|
override fun setSource(sources: Any?) {
|
||||||
sourceRootsContainer.set(sources)
|
sourceRootsContainer.set(sources)
|
||||||
|
|||||||
Reference in New Issue
Block a user