Remove deprecated 'kotlin.useFallbackCompilerSearch' property.

^KT-46719 Fixed
This commit is contained in:
Yahor Berdnikau
2021-08-02 14:54:43 +02:00
committed by Space
parent 331681b40b
commit d375c52830
14 changed files with 45 additions and 243 deletions
@@ -79,7 +79,7 @@ class UpToDateIT : BaseGradleIT() {
override fun initProject(project: Project) = with(project) {
buildGradle.appendText(
"\nafterEvaluate { println 'compiler_cp=' + compileKotlin.getComputedCompilerClasspath\$kotlin_gradle_plugin().toList() }"
"\nafterEvaluate { println 'compiler_cp=' + compileKotlin.getDefaultCompilerClasspath\$kotlin_gradle_plugin().toList() }"
)
build("clean") { originalCompilerCp = "compiler_cp=\\[(.*)]".toRegex().find(output)!!.groupValues[1].split(", ") }
buildGradle.appendText("""${'\n'}
@@ -9,10 +9,11 @@ package org.jetbrains.kotlin.compilerRunner
import org.gradle.api.Project
import org.jetbrains.kotlin.commonizer.CliCommonizer
import org.jetbrains.kotlin.gradle.internal.KOTLIN_MODULE_GROUP
import org.jetbrains.kotlin.gradle.plugin.KLIB_COMMONIZER_CLASSPATH_CONFIGURATION_NAME
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_KLIB_COMMONIZER_EMBEDDABLE
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_MODULE_GROUP
private const val KOTLIN_KLIB_COMMONIZER_EMBEDDABLE = "kotlin-klib-commonizer-embeddable"
/**
* Creates an instance of [CliCommonizer] that is backed by [KotlinNativeCommonizerToolRunner] to adhere to user defined settings
@@ -15,7 +15,6 @@ import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.DependencySet
import org.gradle.api.artifacts.ExternalDependency
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.testing.AbstractTestTask
import org.gradle.api.tasks.testing.Test
import org.gradle.api.tasks.testing.junit.JUnitOptions
@@ -35,13 +34,14 @@ import org.jetbrains.kotlin.gradle.plugin.sources.withAllDependsOnSourceSets
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
import org.jetbrains.kotlin.gradle.plugin.sources.sourceSetDependencyConfigurationByScope
import org.jetbrains.kotlin.gradle.targets.jvm.JvmCompilationsTestRunSource
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_MODULE_GROUP
import org.jetbrains.kotlin.gradle.tasks.locateTask
import org.jetbrains.kotlin.gradle.testing.KotlinTaskTestRun
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
internal const val KOTLIN_MODULE_GROUP = "org.jetbrains.kotlin"
internal const val KOTLIN_COMPILER_EMBEDDABLE = "kotlin-compiler-embeddable"
internal fun customizeKotlinDependencies(project: Project) {
configureStdlibDefaultDependency(project)
if (project.topLevelExtension is KotlinProjectExtension) { // TODO: extend this logic to PM20
@@ -380,7 +380,7 @@ private fun KotlinTargetWithTests<*, *>.findTestRunsByCompilation(byCompilation:
}
//endregion
private fun Project.kotlinDependency(moduleName: String, versionOrNull: String?) =
internal fun Project.kotlinDependency(moduleName: String, versionOrNull: String?) =
project.dependencies.create("$KOTLIN_MODULE_GROUP:$moduleName${versionOrNull?.prependIndent(":").orEmpty()}")
private fun Project.tryWithDependenciesIfUnresolved(configuration: Configuration, action: (DependencySet) -> Unit) {
@@ -26,6 +26,7 @@ import org.gradle.process.CommandLineArgumentProvider
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.CLASS_STRUCTURE_ARTIFACT_TYPE
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformAction
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformLegacyAction
@@ -54,6 +55,12 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
target.configurations.create(KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME).apply {
val kaptDependency = getPluginArtifact().run { "$groupId:$artifactId:${target.getKotlinPluginVersion()}" }
dependencies.add(target.dependencies.create(kaptDependency))
dependencies.add(
target.kotlinDependency(
"kotlin-stdlib",
target.kotlinExtension.coreLibrariesVersion
)
)
}
registry.register(KaptModelBuilder())
@@ -46,7 +46,7 @@ abstract class KaptTask @Inject constructor(
val objectFactory = task.project.objects
val providerFactory = task.project.providers
task.compilerClasspath.from({ kotlinCompileTask.computedCompilerClasspath })
task.compilerClasspath.from({ kotlinCompileTask.defaultCompilerClasspath })
task.classpath.from(kotlinCompileTask.classpath)
task.kotlinSourceRoots.value(
providerFactory.provider { kotlinCompileTask.sourceRootsContainer.sourceRoots }
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.provider.ProviderFactory
@@ -24,7 +25,6 @@ import org.jetbrains.kotlin.gradle.internal.kapt.incremental.KaptIncrementalChan
import org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPluginWrapper
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.findKotlinStdlibClasspath
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
import org.jetbrains.kotlin.utils.PathUtil
import org.slf4j.LoggerFactory
@@ -51,7 +51,6 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
}
@get:Classpath
@Suppress("unused")
abstract val kaptJars: ConfigurableFileCollection
@get:Input
@@ -75,9 +74,6 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
@get:Input
internal abstract val addJdkClassesToClasspath: Property<Boolean>
@get:Classpath
internal val kotlinStdlibClasspath = findKotlinStdlibClasspath(project)
@get:Internal
internal val projectDir = project.projectDir
@@ -154,7 +150,7 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
return
}
val kaptClasspath = kaptJars.toList() + kotlinStdlibClasspath
val kaptClasspath = kaptJars
val isolationMode = getWorkerIsolationMode()
logger.info("Using workers $isolationMode isolation mode to run kapt")
val toolsJarURLSpec = defaultKotlinJavaToolchain.get()
@@ -191,7 +187,7 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
isolationMode: IsolationMode,
optionsForWorker: KaptOptionsForWorker,
toolsJarURLSpec: String,
kaptClasspath: List<File>
kaptClasspath: FileCollection
) {
val workQueue = when (isolationMode) {
IsolationMode.PROCESS -> workerExecutor.processIsolation {
@@ -26,6 +26,8 @@ import org.gradle.api.model.ObjectFactory
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.compilerRunner.registerCommonizerClasspathConfigurationIfNecessary
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.internal.KOTLIN_COMPILER_EMBEDDABLE
import org.jetbrains.kotlin.gradle.internal.KOTLIN_MODULE_GROUP
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin
@@ -39,8 +41,6 @@ import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin
import org.jetbrains.kotlin.gradle.targets.js.npm.addNpmDependencyExtension
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_COMPILER_EMBEDDABLE
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_MODULE_GROUP
import org.jetbrains.kotlin.gradle.testing.internal.KotlinTestsRegistry
import org.jetbrains.kotlin.gradle.tooling.buildKotlinToolingMetadataTask
import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility
@@ -33,8 +33,6 @@ import java.io.File
import java.util.*
internal fun PropertiesProvider.mapKotlinTaskProperties(task: AbstractKotlinCompile<*>) {
useFallbackCompilerSearch?.let { task.useFallbackCompilerSearch = it }
if (task is KotlinCompile) {
incrementalJvm?.let { task.incremental = it }
usePreciseJavaTracking?.let {
@@ -122,20 +120,6 @@ internal class PropertiesProvider private constructor(private val project: Proje
val useFir: Boolean?
get() = booleanProperty("kotlin.useFir")
private val useFallbackCompilerSearchPropName = "kotlin.useFallbackCompilerSearch"
@Deprecated("Unsupported and will be removed in next major releases")
val useFallbackCompilerSearch: Boolean?
get() {
if (property(useFallbackCompilerSearchPropName) != null) {
SingleWarningPerBuild.show(
project,
"Project property '$useFallbackCompilerSearchPropName' is deprecated."
)
}
return booleanProperty(useFallbackCompilerSearchPropName)
}
val keepMppDependenciesIntactInPoms: Boolean?
get() = booleanProperty("kotlin.mpp.keepMppDependenciesIntactInPoms")
@@ -110,7 +110,7 @@ abstract class KotlinJsIrLink @Inject constructor(
compilerRunner.get(),
{ createCompilerArgs() },
{ objects.fileCollection() },
computedCompilerClasspath,
defaultCompilerClasspath,
logger,
reportingSettings
)
@@ -83,9 +83,6 @@ abstract class KotlinCompileCommon @Inject constructor(
override fun getSourceRoots(): SourceRoots =
SourceRoots.KotlinOnly.create(getSource(), sourceFilesExtensions.get())
override fun findKotlinCompilerClasspath(project: Project): List<File> =
findKotlinMetadataCompilerClasspath(project)
override fun setupCompilerArgs(args: K2MetadataCompilerArguments, defaultsOnly: Boolean, ignoreClasspathResolutionErrors: Boolean) {
args.apply { fillDefaultValues() }
super.setupCompilerArgs(args, defaultsOnly = defaultsOnly, ignoreClasspathResolutionErrors = ignoreClasspathResolutionErrors)
@@ -124,7 +121,7 @@ abstract class KotlinCompileCommon @Inject constructor(
val outputItemCollector = OutputItemsCollectorImpl()
val compilerRunner = compilerRunner.get()
val environment = GradleCompilerEnvironment(
computedCompilerClasspath, messageCollector, outputItemCollector,
defaultCompilerClasspath, messageCollector, outputItemCollector,
reportingSettings = reportingSettings,
outputFiles = allOutputFiles()
)
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.Project
import org.gradle.api.file.FileTree
import org.gradle.api.tasks.*
import org.jetbrains.kotlin.cli.common.arguments.K2JSDceArguments
@@ -59,8 +58,6 @@ abstract class KotlinJsDce : AbstractKotlinCompileTool<K2JSDceArguments>(), Kotl
@get:Input
override val keep: MutableList<String> = mutableListOf()
override fun findKotlinCompilerClasspath(project: Project): List<File> = findKotlinJsDceClasspath(project)
override fun keep(vararg fqn: String) {
keep += fqn
}
@@ -90,7 +87,7 @@ abstract class KotlinJsDce : AbstractKotlinCompileTool<K2JSDceArguments>(), Kotl
val exitCode = runToolInSeparateProcess(
allArgs,
K2JSDce::class.java.name,
computedCompilerClasspath,
defaultCompilerClasspath,
log,
buildDir,
jvmArgs
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.*
import org.gradle.api.invocation.Gradle
import org.gradle.api.attributes.Attribute
@@ -92,15 +91,12 @@ abstract class AbstractKotlinCompileTool<T : CommonToolArguments>
return super.getClasspath()
}
@get:Input
internal var useFallbackCompilerSearch: Boolean = false
@get:Internal
override val metrics: BuildMetricsReporter =
BuildMetricsReporterImpl()
/**
* By default should be set by plugin from [COMPILER_CLASSPATH_CONFIGURATION_NAME] configuration.
* By default, should be set by plugin from [COMPILER_CLASSPATH_CONFIGURATION_NAME] configuration.
*
* Empty classpath will fail the build.
*/
@@ -108,20 +104,10 @@ abstract class AbstractKotlinCompileTool<T : CommonToolArguments>
internal val defaultCompilerClasspath: ConfigurableFileCollection =
project.objects.fileCollection()
@get:Classpath
internal val computedCompilerClasspath: FileCollection = project.objects.fileCollection().from({
when {
useFallbackCompilerSearch -> findKotlinCompilerClasspath(project)
else -> defaultCompilerClasspath
}
})
protected abstract fun findKotlinCompilerClasspath(project: Project): List<File>
init {
doFirst {
this.doFirst {
require(!defaultCompilerClasspath.isEmpty) {
"Default Kotlin compiler classpath is empty! Task: ${path} (${this::class.qualifiedName})"
"Default Kotlin compiler classpath is empty! Task: $path (${this::class.qualifiedName})"
}
}
}
@@ -644,9 +630,6 @@ abstract class KotlinCompile @Inject constructor(
incremental = true
}
override fun findKotlinCompilerClasspath(project: Project): List<File> =
findKotlinJvmCompilerClasspath(project)
override fun createCompilerArgs(): K2JVMCompilerArguments =
K2JVMCompilerArguments()
@@ -699,7 +682,7 @@ abstract class KotlinCompile @Inject constructor(
} else null
val environment = GradleCompilerEnvironment(
computedCompilerClasspath, messageCollector, outputItemCollector,
defaultCompilerClasspath, messageCollector, outputItemCollector,
outputFiles = allOutputFiles(),
reportingSettings = reportingSettings,
incrementalCompilationEnvironment = icEnv,
@@ -966,9 +949,6 @@ abstract class Kotlin2JsCompile @Inject constructor(
@get:Optional
abstract val optionalOutputFile: RegularFileProperty
override fun findKotlinCompilerClasspath(project: Project): List<File> =
findKotlinJsCompilerClasspath(project)
override fun createCompilerArgs(): K2JSCompilerArguments =
K2JSCompilerArguments()
@@ -1115,7 +1095,7 @@ abstract class Kotlin2JsCompile @Inject constructor(
} else null
val environment = GradleCompilerEnvironment(
computedCompilerClasspath, messageCollector, outputItemCollector,
defaultCompilerClasspath, messageCollector, outputItemCollector,
outputFiles = allOutputFiles(),
reportingSettings = reportingSettings,
incrementalCompilationEnvironment = icEnv
@@ -1,175 +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 org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ResolvedDependency
import org.gradle.api.initialization.dsl.ScriptHandler
import org.jetbrains.kotlin.gradle.plugin.KotlinPlugin
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
import java.io.File
import java.net.URLClassLoader
import java.net.URLDecoder
import java.nio.charset.Charset
import java.util.zip.ZipFile
private val K2JVM_COMPILER_CLASS = "org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"
private val K2JS_COMPILER_CLASS = "org.jetbrains.kotlin.cli.js.K2JSCompiler"
private val K2JS_DCE_CLASS = "org.jetbrains.kotlin.cli.js.dce.K2JSDce"
private val K2METADATA_COMPILER_CLASS = "org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler"
private val KOTLIN_STDLIB_EXPECTED_CLASS = "kotlin.collections.ArraysKt"
private val KOTLIN_SCRIPT_RUNTIME_EXPECTED_CLASS = "kotlin.script.templates.AnnotationsKt"
private val KOTLIN_SCRIPT_ANNOTATION_EXPECTED_CLASS = "kotlin.script.experimental.annotations.KotlinScript"
private val KOTLIN_JVM_SCRIPT_COMPILER_EXPECTED_CLASS = "kotlin.script.experimental.jvm.JvmScriptCompiler"
private val KOTLIN_REFLECT_EXPECTED_CLASS = "kotlin.reflect.full.KClasses"
private val TROVE4J_EXPECTED_CLASS = "gnu.trove.THashMap"
private val JNA_EXPECTED_CLASS = "com.sun.jna.Structure"
private val DAEMON_EXPECTED_CLASS = "org.jetbrains.kotlin.daemon.CompileServiceImpl"
internal const val KOTLIN_MODULE_GROUP = "org.jetbrains.kotlin"
private val KOTLIN_GRADLE_PLUGIN = "kotlin-gradle-plugin"
internal const val KOTLIN_COMPILER_EMBEDDABLE = "kotlin-compiler-embeddable"
private val KOTLIN_STDLIB = "kotlin-stdlib"
private val KOTLIN_SCRIPT_RUNTIME = "kotlin-script-runtime"
private val KOTLIN_SCRIPT_COMMON = "kotlin-scripting-common"
private val KOTLIN_SCRIPT_JVM = "kotlin-scripting-jvm"
private val KOTLIN_REFLECT = "kotlin-reflect"
internal const val KOTLIN_KLIB_COMMONIZER_EMBEDDABLE = "kotlin-klib-commonizer-embeddable"
internal fun findKotlinJvmCompilerClasspath(project: Project): List<File> =
findKotlinModuleJar(project, K2JVM_COMPILER_CLASS, KOTLIN_COMPILER_EMBEDDABLE).let {
if (it.isEmpty()) it
else it + findKotlinCompilerClasspath(project)
}
internal fun findKotlinJsCompilerClasspath(project: Project): List<File> =
findKotlinModuleJar(project, K2JS_COMPILER_CLASS, KOTLIN_COMPILER_EMBEDDABLE).let {
if (it.isEmpty()) it
else it + findKotlinCompilerClasspath(project)
}
internal fun findKotlinMetadataCompilerClasspath(project: Project): List<File> =
findKotlinModuleJar(project, K2METADATA_COMPILER_CLASS, KOTLIN_COMPILER_EMBEDDABLE).let {
if (it.isEmpty()) it
else it + findKotlinCompilerClasspath(project)
}
internal fun findKotlinJsDceClasspath(project: Project): List<File> =
findKotlinModuleJar(project, K2JS_DCE_CLASS, KOTLIN_COMPILER_EMBEDDABLE).let {
if (it.isEmpty()) it
else it + findKotlinCompilerClasspath(project)
}
internal fun findKotlinCompilerClasspath(project: Project): List<File> {
return findKotlinStdlibClasspath(project) +
findKotlinScriptRuntimeClasspath(project) +
findKotlinReflectClasspath(project) +
listOfNotNull(findTrove4j(), findJna(), findDaemon())
}
internal fun findJarByClass(classFqName: String): File? {
val classLoader = Thread.currentThread().contextClassLoader
val classFromJar = try {
classLoader.loadClass(classFqName)
} catch (e: ClassNotFoundException) {
null
} ?: return null
return findJarByClass(classFromJar)
}
internal fun findTrove4j() = findJarByClass(TROVE4J_EXPECTED_CLASS)
internal fun findJna() = findJarByClass(JNA_EXPECTED_CLASS)
internal fun findDaemon() = findJarByClass(DAEMON_EXPECTED_CLASS)
internal fun findKotlinStdlibClasspath(project: Project): List<File> =
findKotlinModuleJar(project, KOTLIN_STDLIB_EXPECTED_CLASS, KOTLIN_STDLIB)
internal fun findKotlinScriptRuntimeClasspath(project: Project): List<File> =
findKotlinModuleJar(project, KOTLIN_SCRIPT_RUNTIME_EXPECTED_CLASS, KOTLIN_SCRIPT_RUNTIME)
internal fun findKotlinReflectClasspath(project: Project): List<File> =
findKotlinModuleJar(project, KOTLIN_REFLECT_EXPECTED_CLASS, KOTLIN_REFLECT)
internal fun findJarByClass(klass: Class<*>): File? {
val classFileName = klass.name.substringAfterLast(".") + ".class"
val resource = klass.getResource(classFileName) ?: return null
val uri = resource.toString()
if (!uri.startsWith("jar:file:")) return null
val fileName = URLDecoder.decode(uri.removePrefix("jar:file:").substringBefore("!"), Charset.defaultCharset().name())
return File(fileName)
}
private fun findKotlinModuleJar(project: Project, expectedClassName: String, moduleId: String): List<File> {
val pluginVersion = project.getKotlinPluginVersion()
val filesToCheck = sequenceOf(getModuleFromClassLoader(moduleId, pluginVersion)) +
Sequence { findPotentialModuleJars(project, moduleId).iterator() } //call the body only when queried
val entryToFind = expectedClassName.replace(".", "/") + ".class"
return filesToCheck.filterNotNull().firstOrNull { it.hasEntry(entryToFind) }?.let { listOf(it) }.orEmpty()
}
private fun getModuleFromClassLoader(moduleId: String, moduleVersion: String): File? {
val urlClassLoader = KotlinPlugin::class.java.classLoader as? URLClassLoader ?: return null
return urlClassLoader.urLs
.firstOrNull { it.toString().endsWith("$moduleId-$moduleVersion.jar") }
?.let { File(it.toURI()) }
?.takeIf(File::exists)
}
private fun findPotentialModuleJars(project: Project, moduleId: String): Iterable<File> {
val projects = generateSequence(project) { it.parent }
val classpathConfigurations = projects
.map { it.buildscript.configurations.findByName(ScriptHandler.CLASSPATH_CONFIGURATION) }
.filterNotNull()
val allFiles = HashSet<File>()
for (configuration in classpathConfigurations) {
val compilerEmbeddable = findKotlinModuleDependency(configuration, moduleId)
if (compilerEmbeddable != null) {
return compilerEmbeddable.moduleArtifacts.map { it.file }
} else {
allFiles.addAll(configuration.files)
}
}
return allFiles
}
private fun findKotlinModuleDependency(configuration: Configuration, moduleId: String): ResolvedDependency? {
fun Iterable<ResolvedDependency>.findDependency(group: String, name: String): ResolvedDependency? =
find { it.moduleGroup == group && it.moduleName == name }
val firstLevelModuleDependencies = configuration.resolvedConfiguration.firstLevelModuleDependencies
val gradlePlugin = firstLevelModuleDependencies.findDependency(KOTLIN_MODULE_GROUP, KOTLIN_GRADLE_PLUGIN)
return gradlePlugin?.children?.findDependency(KOTLIN_MODULE_GROUP, moduleId)
}
private fun File.hasEntry(entryToFind: String): Boolean {
val zip = ZipFile(this)
try {
return zip.getEntry(entryToFind) != null
} catch (e: Exception) {
return false
} finally {
zip.close()
}
}
@@ -6,8 +6,10 @@
package org.jetbrains.kotlin.gradle.internal.kapt.classloaders
import com.google.gson.Gson
import org.jetbrains.kotlin.gradle.tasks.findJarByClass
import org.junit.Test
import java.io.File
import java.net.URLDecoder
import java.nio.charset.Charset
import kotlin.test.assertNotSame
import kotlin.test.assertSame
@@ -77,4 +79,17 @@ class ClassLoadersCacheTest {
"Bottom ClassLoader should be recreated as class path changed"
)
}
private fun findJarByClass(klass: Class<*>): File? {
val classFileName = klass.name.substringAfterLast(".") + ".class"
val resource = klass.getResource(classFileName) ?: return null
val uri = resource.toString()
if (!uri.startsWith("jar:file:")) return null
val fileName = URLDecoder.decode(
uri.removePrefix("jar:file:").substringBefore("!"),
Charset.defaultCharset().name()
)
return File(fileName)
}
}