Implement support for non-kts scripts in gradle

#KT-26784 fixed
This commit is contained in:
Ilya Chernikov
2018-08-30 13:39:16 +03:00
parent 9ae478e4fc
commit a03bfb3561
18 changed files with 171 additions and 36 deletions
@@ -0,0 +1,9 @@
/*
* 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.build
val DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS = listOf("kt", "kts")
@@ -21,11 +21,8 @@ import java.io.File
fun File.isJavaFile() = fun File.isJavaFile() =
extension.equals("java", ignoreCase = true) extension.equals("java", ignoreCase = true)
fun File.isKotlinFile(): Boolean = fun File.isKotlinFile(sourceFilesExtensions: List<String>): Boolean =
extension.let { !isJavaFile() && sourceFilesExtensions.any { it.equals(extension, ignoreCase = true) }
"kt".equals(it, ignoreCase = true) ||
"kts".equals(it, ignoreCase = true)
}
fun File.isClassFile(): Boolean = fun File.isClassFile(): Boolean =
extension.equals("class", ignoreCase = true) extension.equals("class", ignoreCase = true)
@@ -10,7 +10,8 @@ import java.io.File
class DirtyFilesContainer( class DirtyFilesContainer(
private val caches: IncrementalCachesManager<*>, private val caches: IncrementalCachesManager<*>,
private val reporter: ICReporter private val reporter: ICReporter,
private val sourceFilesExtensions: List<String>
) { ) {
private val myDirtyFiles = HashSet<File>() private val myDirtyFiles = HashSet<File>()
@@ -18,7 +19,7 @@ class DirtyFilesContainer(
ArrayList(myDirtyFiles) ArrayList(myDirtyFiles)
fun add(files: Iterable<File>) { fun add(files: Iterable<File>) {
val existingKotlinFiles = files.filter { it.isKotlinFile() } val existingKotlinFiles = files.filter { it.isKotlinFile(sourceFilesExtensions) }
if (existingKotlinFiles.isNotEmpty()) { if (existingKotlinFiles.isNotEmpty()) {
myDirtyFiles.addAll(existingKotlinFiles) myDirtyFiles.addAll(existingKotlinFiles)
} }
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.incremental package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
import org.jetbrains.kotlin.build.GeneratedFile import org.jetbrains.kotlin.build.GeneratedFile
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
@@ -50,6 +51,7 @@ abstract class IncrementalCompilerRunner<
protected val cacheDirectory = File(workingDir, cacheDirName) protected val cacheDirectory = File(workingDir, cacheDirName)
protected val dirtySourcesSinceLastTimeFile = File(workingDir, DIRTY_SOURCES_FILE_NAME) protected val dirtySourcesSinceLastTimeFile = File(workingDir, DIRTY_SOURCES_FILE_NAME)
protected val lastBuildInfoFile = File(workingDir, LAST_BUILD_INFO_FILE_NAME) protected val lastBuildInfoFile = File(workingDir, LAST_BUILD_INFO_FILE_NAME)
protected open val kotlinSourceFilesExtensions: List<String> = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
protected abstract fun isICEnabled(): Boolean protected abstract fun isICEnabled(): Boolean
protected abstract fun createCacheManager(args: Args): CacheManager protected abstract fun createCacheManager(args: Args): CacheManager
@@ -85,7 +87,7 @@ abstract class IncrementalCompilerRunner<
if (providedChangedFiles == null) { if (providedChangedFiles == null) {
caches.inputsCache.sourceSnapshotMap.compareAndUpdate(allSourceFiles) caches.inputsCache.sourceSnapshotMap.compareAndUpdate(allSourceFiles)
} }
val allKotlinFiles = allSourceFiles.filter { it.isKotlinFile() } val allKotlinFiles = allSourceFiles.filter { it.isKotlinFile(kotlinSourceFilesExtensions) }
return compileIncrementally(args, caches, allKotlinFiles, CompilationMode.Rebuild(), messageCollector) return compileIncrementally(args, caches, allKotlinFiles, CompilationMode.Rebuild(), messageCollector)
} }
@@ -281,8 +283,8 @@ abstract class IncrementalCompilerRunner<
changedFiles: ChangedFiles.Known changedFiles: ChangedFiles.Known
): DirtyData { ): DirtyData {
val removedClasses = HashSet<String>() val removedClasses = HashSet<String>()
val dirtyFiles = changedFiles.modified.filterTo(HashSet()) { it.isKotlinFile() } val dirtyFiles = changedFiles.modified.filterTo(HashSet()) { it.isKotlinFile(kotlinSourceFilesExtensions) }
val removedFiles = changedFiles.removed.filterTo(HashSet()) { it.isKotlinFile() } val removedFiles = changedFiles.removed.filterTo(HashSet()) { it.isKotlinFile(kotlinSourceFilesExtensions) }
val existingClasses = classesFqNames(dirtyFiles) val existingClasses = classesFqNames(dirtyFiles)
val previousClasses = caches.platformCache val previousClasses = caches.platformCache
@@ -90,7 +90,7 @@ class IncrementalJsCompilerRunner(
val lastBuildInfo = BuildInfo.read(lastBuildInfoFile) val lastBuildInfo = BuildInfo.read(lastBuildInfoFile)
?: return CompilationMode.Rebuild { "No information on previous build" } ?: return CompilationMode.Rebuild { "No information on previous build" }
val dirtyFiles = DirtyFilesContainer(caches, reporter) val dirtyFiles = DirtyFilesContainer(caches, reporter, kotlinSourceFilesExtensions)
initDirtyFiles(dirtyFiles, changedFiles) initDirtyFiles(dirtyFiles, changedFiles)
val libs = (args.libraries ?: "").split(File.pathSeparator).map { File(it) } val libs = (args.libraries ?: "").split(File.pathSeparator).map { File(it) }
@@ -22,6 +22,7 @@ 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.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
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
@@ -40,7 +41,6 @@ import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.multiproject.EmptyModulesApiHistory import org.jetbrains.kotlin.incremental.multiproject.EmptyModulesApiHistory
import org.jetbrains.kotlin.incremental.multiproject.ModulesApiHistory import org.jetbrains.kotlin.incremental.multiproject.ModulesApiHistory
import org.jetbrains.kotlin.incremental.storage.version.CacheVersionManager import org.jetbrains.kotlin.incremental.storage.version.CacheVersionManager
import org.jetbrains.kotlin.incremental.util.Either
import org.jetbrains.kotlin.load.java.JavaClassesTracker import org.jetbrains.kotlin.load.java.JavaClassesTracker
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
@@ -57,8 +57,8 @@ fun makeIncrementally(
messageCollector: MessageCollector = MessageCollector.NONE, messageCollector: MessageCollector = MessageCollector.NONE,
reporter: ICReporter = EmptyICReporter reporter: ICReporter = EmptyICReporter
) { ) {
val kotlinExtensions = listOf("kt", "kts") val kotlinExtensions = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
val allExtensions = kotlinExtensions + listOf("java") val allExtensions = kotlinExtensions + "java"
val rootsWalk = sourceRoots.asSequence().flatMap { it.walk() } val rootsWalk = sourceRoots.asSequence().flatMap { it.walk() }
val files = rootsWalk.filter(File::isFile) val files = rootsWalk.filter(File::isFile)
val sourceFiles = files.filter { it.extension.toLowerCase() in allExtensions }.toList() val sourceFiles = files.filter { it.extension.toLowerCase() in allExtensions }.toList()
@@ -75,7 +75,8 @@ fun makeIncrementally(
usePreciseJavaTracking = true, usePreciseJavaTracking = true,
localStateDirs = emptyList(), localStateDirs = emptyList(),
buildHistoryFile = buildHistoryFile, buildHistoryFile = buildHistoryFile,
modulesApiHistory = EmptyModulesApiHistory modulesApiHistory = EmptyModulesApiHistory,
kotlinSourceFilesExtensions = kotlinExtensions
) )
compiler.compile(sourceFiles, args, messageCollector, providedChangedFiles = null) compiler.compile(sourceFiles, args, messageCollector, providedChangedFiles = null)
} }
@@ -104,9 +105,10 @@ class IncrementalJvmCompilerRunner(
cachesVersionManagers: List<CacheVersionManager>, cachesVersionManagers: List<CacheVersionManager>,
reporter: ICReporter, reporter: ICReporter,
private val usePreciseJavaTracking: Boolean, private val usePreciseJavaTracking: Boolean,
buildHistoryFile: File, buildHistoryFile: File,
localStateDirs: Collection<File>, localStateDirs: Collection<File>,
private val modulesApiHistory: ModulesApiHistory private val modulesApiHistory: ModulesApiHistory,
override val kotlinSourceFilesExtensions: List<String> = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
) : IncrementalCompilerRunner<K2JVMCompilerArguments, IncrementalJvmCachesManager>( ) : IncrementalCompilerRunner<K2JVMCompilerArguments, IncrementalJvmCachesManager>(
workingDir, workingDir,
"caches-jvm", "caches-jvm",
@@ -145,7 +147,7 @@ class IncrementalJvmCompilerRunner(
changedFiles: ChangedFiles.Known, changedFiles: ChangedFiles.Known,
args: K2JVMCompilerArguments args: K2JVMCompilerArguments
): CompilationMode { ): CompilationMode {
val dirtyFiles = DirtyFilesContainer(caches, reporter) val dirtyFiles = DirtyFilesContainer(caches, reporter, kotlinSourceFilesExtensions)
initDirtyFiles(dirtyFiles, changedFiles) initDirtyFiles(dirtyFiles, changedFiles)
val lastBuildInfo = BuildInfo.read(lastBuildInfoFile) ?: return CompilationMode.Rebuild { "No information on previous build" } val lastBuildInfo = BuildInfo.read(lastBuildInfoFile) ?: return CompilationMode.Rebuild { "No information on previous build" }
@@ -204,7 +204,7 @@ abstract class AbstractLookupTrackerTest : TestWithWorkingDir() {
val testDir = File(path) val testDir = File(path)
val workToOriginalFileMap = HashMap(copyTestSources(testDir, srcDir, filePrefix = "")) val workToOriginalFileMap = HashMap(copyTestSources(testDir, srcDir, filePrefix = ""))
var dirtyFiles = srcDir.walk().filterTo(HashSet()) { it.isKotlinFile() } var dirtyFiles = srcDir.walk().filterTo(HashSet()) { it.isKotlinFile(listOf("kt", "kts")) }
val steps = getModificationsToPerform(testDir, moduleNames = null, allowNoFilesWithSuffixInTestData = true, touchPolicy = TouchPolicy.CHECKSUM) val steps = getModificationsToPerform(testDir, moduleNames = null, allowNoFilesWithSuffixInTestData = true, touchPolicy = TouchPolicy.CHECKSUM)
.filter { it.isNotEmpty() } .filter { it.isNotEmpty() }
@@ -39,4 +39,6 @@ interface KotlinSourceSet : Named, HasKotlinDependencies {
const val COMMON_MAIN_SOURCE_SET_NAME = "commonMain" const val COMMON_MAIN_SOURCE_SET_NAME = "commonMain"
const val COMMON_TEST_SOURCE_SET_NAME = "commonTest" const val COMMON_TEST_SOURCE_SET_NAME = "commonTest"
} }
val customSourceFilesExtensions: Iterable<String> // lazy iterable expected
} }
@@ -45,6 +45,7 @@ dependencies {
compileOnly project(':kotlin-compiler-runner') compileOnly project(':kotlin-compiler-runner')
compileOnly project(':kotlin-annotation-processing') compileOnly project(':kotlin-annotation-processing')
compileOnly project(':kotlin-annotation-processing-gradle') compileOnly project(':kotlin-annotation-processing-gradle')
compileOnly project(':kotlin-scripting-compiler')
compileOnly 'com.android.tools.build:gradle:2.0.0' compileOnly 'com.android.tools.build:gradle:2.0.0'
compileOnly 'org.codehaus.groovy:groovy-all:2.4.12' compileOnly 'org.codehaus.groovy:groovy-all:2.4.12'
@@ -62,6 +63,7 @@ dependencies {
runtime project(path: ':kotlin-annotation-processing-gradle', configuration: "runtimeJar") runtime project(path: ':kotlin-annotation-processing-gradle', configuration: "runtimeJar")
runtime project(path: ':kotlin-android-extensions', configuration: 'runtimeJar') runtime project(path: ':kotlin-android-extensions', configuration: 'runtimeJar')
runtime project(path: ':kotlin-compiler-runner', configuration: 'runtimeJar') runtime project(path: ':kotlin-compiler-runner', configuration: 'runtimeJar')
runtime project(path: ':kotlin-scripting-compiler-embeddable', configuration: 'runtimeJar')
runtime project(':kotlin-reflect') runtime project(':kotlin-reflect')
// com.android.tools.build:gradle has ~50 unneeded transitive dependencies // com.android.tools.build:gradle has ~50 unneeded transitive dependencies
@@ -162,6 +162,7 @@ internal class Kotlin2JvmSourceSetProcessor(
override fun doTargetSpecificProcessing() { override fun doTargetSpecificProcessing() {
Kapt3KotlinGradleSubplugin.createAptConfigurationIfNeeded(project, kotlinCompilation.compilationName) Kapt3KotlinGradleSubplugin.createAptConfigurationIfNeeded(project, kotlinCompilation.compilationName)
ScriptingGradleSubplugin.createDiscoveryConfigurationIfNeeded(project, kotlinCompilation.compilationName)
project.afterEvaluate { project -> project.afterEvaluate { project ->
val javaTask = javaSourceSet?.let { project.tasks.findByName(it.compileJavaTaskName) as JavaCompile } val javaTask = javaSourceSet?.let { project.tasks.findByName(it.compileJavaTaskName) as JavaCompile }
@@ -70,10 +70,12 @@ abstract class AbstractKotlinCompilation(
override val kotlinSourceSets: MutableSet<KotlinSourceSet> = mutableSetOf() override val kotlinSourceSets: MutableSet<KotlinSourceSet> = mutableSetOf()
open fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) { open fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) {
val compileTask = target.project.tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*> (target.project.tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*>).apply {
compileTask.source(sourceSet.kotlin) source(sourceSet.kotlin)
if (addAsCommonSources) { sourceFilesExtensions(sourceSet.customSourceFilesExtensions)
compileTask.commonSourceSet += sourceSet.kotlin if (addAsCommonSources) {
commonSourceSet += sourceSet.kotlin
}
} }
} }
@@ -12,6 +12,7 @@ import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.internal.file.DefaultSourceDirectorySet import org.gradle.api.internal.file.DefaultSourceDirectorySet
import org.gradle.api.internal.file.FileResolver import org.gradle.api.internal.file.FileResolver
import org.gradle.util.ConfigureUtil import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
@@ -53,7 +54,9 @@ class DefaultKotlinSourceSet(
get() = lowerCamelCaseName(runtimeOnlyConfigurationName, METADATA_CONFIGURATION_NAME_SUFFIX) get() = lowerCamelCaseName(runtimeOnlyConfigurationName, METADATA_CONFIGURATION_NAME_SUFFIX)
override val kotlin: SourceDirectorySet = createDefaultSourceDirectorySet(name + " Kotlin source", fileResolver).apply { override val kotlin: SourceDirectorySet = createDefaultSourceDirectorySet(name + " Kotlin source", fileResolver).apply {
filter.include("**/*.java", "**/*.kt", "**/*.kts") filter.include("**/*.java")
filter.include("**/*.kt")
filter.include("**/*.kts")
} }
override val languageSettings: LanguageSettingsBuilder = DefaultLanguageSettingsBuilder() override val languageSettings: LanguageSettingsBuilder = DefaultLanguageSettingsBuilder()
@@ -89,6 +92,16 @@ class DefaultKotlinSourceSet(
get() = dependsOnSourceSetsImpl get() = dependsOnSourceSetsImpl
override fun toString(): String = "source set $name" override fun toString(): String = "source set $name"
override val customSourceFilesExtensions: Iterable<String>
get() = Iterable {
kotlin.filter.includes.mapNotNull { pattern ->
pattern.substringAfterLast('.').takeUnless { extension ->
DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS.any { extension.equals(it, ignoreCase = true) }
|| extension.any { it == '\\' || it == '/' }
}
}.iterator()
}
} }
private fun KotlinSourceSet.checkForCircularDependencies(): Unit { private fun KotlinSourceSet.checkForCircularDependencies(): Unit {
@@ -5,18 +5,104 @@
package org.jetbrains.kotlin.gradle.scripting.internal package org.jetbrains.kotlin.gradle.scripting.internal
import org.gradle.api.DefaultTask
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.scripting.ScriptingExtension import org.jetbrains.kotlin.gradle.scripting.ScriptingExtension
import org.jetbrains.kotlin.gradle.tasks.GradleMessageCollector
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptDefinitionsFromClasspathDiscoverySource
import kotlin.properties.Delegates
class ScriptingGradleSubplugin : Plugin<Project> { class ScriptingGradleSubplugin : Plugin<Project> {
companion object { companion object {
fun isEnabled(project: Project) = project.plugins.findPlugin(ScriptingGradleSubplugin::class.java) != null fun isEnabled(project: Project) = project.plugins.findPlugin(ScriptingGradleSubplugin::class.java) != null
val MAIN_CONFIGURATION_NAME = "kotlinScriptDef"
fun getConfigurationName(sourceSetName: String): String = when (sourceSetName) {
"main" -> MAIN_CONFIGURATION_NAME
else -> "$sourceSetName${MAIN_CONFIGURATION_NAME.capitalize()}"
}
fun createDiscoveryConfigurationIfNeeded(project: Project, sourceSetName: String) {
project.configurations.maybeCreate(getConfigurationName(sourceSetName))
}
} }
override fun apply(project: Project) {} override fun apply(project: Project) {
project.afterEvaluate {
val javaPluginConvention = project.convention.findPlugin(JavaPluginConvention::class.java)
if (javaPluginConvention?.sourceSets?.isEmpty() == false) {
project.tasks.all { task ->
if (task is KotlinCompile) {
val configuration = project.configurations.findByName(getConfigurationName(task.sourceSetName))
if (configuration?.isEmpty == false) {
javaPluginConvention.sourceSets.findByName(task.sourceSetName)?.let { sourceSet ->
val extensionsTask =
project.tasks.create(
"discover${task.sourceSetName.capitalize()}ScriptsExtensions",
DiscoverScriptExtensionsTask::class.java
)
extensionsTask.sourceSet = sourceSet
extensionsTask.discoveryClasspathConfiguration = configuration
extensionsTask.kotlinCompile = task
task.dependsOn.add(extensionsTask)
}
}
}
}
} else {
project.logger.warn("kotlin scripting plugin: applied to a non-JVM project $project")
}
}
}
}
open class DiscoverScriptExtensionsTask : DefaultTask() {
@get:Internal
internal var sourceSet: SourceSet by Delegates.notNull()
@get:Internal
internal var discoveryClasspathConfiguration: Configuration by Delegates.notNull()
@get:Internal
internal var kotlinCompile: KotlinCompile by Delegates.notNull()
override fun getDependsOn(): MutableSet<Any> = kotlinCompile.dependsOn
@TaskAction
@Suppress("unused")
fun findKnownScriptExtensions() {
val scriptingClasspath = discoveryClasspathConfiguration.files.takeIf { it.isNotEmpty() } ?: return
val definitions =
ScriptDefinitionsFromClasspathDiscoverySource(
scriptingClasspath.toList(), emptyMap(),
GradleMessageCollector(project.logger)
).definitions
val extensions = definitions.mapTo(arrayListOf(), KotlinScriptDefinition::fileExtension)
val kotlinSourceSet = sourceSet.getConvention(KOTLIN_DSL_NAME) as? KotlinSourceSet
if (kotlinSourceSet == null) {
project.logger.warn("kotlin scripting plugin: kotlin source set not found: $project.$sourceSet")
} else if (extensions.isNotEmpty()) {
project.logger.info("kotlin scripting plugin: Add new extensions to the sourceset $project.$sourceSet: $extensions")
kotlinSourceSet.kotlin.filter.include(extensions.map { "**/*.$it" })
}
}
} }
class ScriptingKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> { class ScriptingKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
@@ -40,7 +40,7 @@ internal open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompil
K2MetadataCompilerArguments() K2MetadataCompilerArguments()
override fun getSourceRoots(): SourceRoots = override fun getSourceRoots(): SourceRoots =
SourceRoots.KotlinOnly.create(getSource()) SourceRoots.KotlinOnly.create(getSource(), sourceFilesExtensions)
override fun findKotlinCompilerClasspath(project: Project): List<File> = override fun findKotlinCompilerClasspath(project: Project): List<File> =
findKotlinMetadataCompilerClasspath(project) findKotlinMetadataCompilerClasspath(project)
@@ -22,8 +22,8 @@ internal sealed class SourceRoots(val kotlinSourceFiles: List<File>) {
class ForJvm(kotlinSourceFiles: List<File>, val javaSourceRoots: Set<File>) : SourceRoots(kotlinSourceFiles) { class ForJvm(kotlinSourceFiles: List<File>, val javaSourceRoots: Set<File>) : SourceRoots(kotlinSourceFiles) {
companion object { companion object {
fun create(taskSource: FileTree, sourceRoots: FilteringSourceRootsContainer): ForJvm { fun create(taskSource: FileTree, sourceRoots: FilteringSourceRootsContainer, sourceFilesExtensions: List<String>): ForJvm {
val kotlinSourceFiles = (taskSource as Iterable<File>).filter(File::isKotlinFile) val kotlinSourceFiles = (taskSource as Iterable<File>).filter { it.isKotlinFile(sourceFilesExtensions) }
val javaSourceRoots = findRootsForSources( val javaSourceRoots = findRootsForSources(
sourceRoots.sourceRoots, taskSource.filter(File::isJavaFile)) sourceRoots.sourceRoots, taskSource.filter(File::isJavaFile))
return ForJvm(kotlinSourceFiles, javaSourceRoots) return ForJvm(kotlinSourceFiles, javaSourceRoots)
@@ -53,7 +53,8 @@ internal sealed class SourceRoots(val kotlinSourceFiles: List<File>) {
class KotlinOnly(kotlinSourceFiles: List<File>) : SourceRoots(kotlinSourceFiles) { class KotlinOnly(kotlinSourceFiles: List<File>) : SourceRoots(kotlinSourceFiles) {
companion object { companion object {
fun create(taskSource: FileTree) = KotlinOnly((taskSource as Iterable<File>).filter(File::isKotlinFile)) fun create(taskSource: FileTree, sourceFilesExtensions: List<String>) =
KotlinOnly((taskSource as Iterable<File>).filter { it.isKotlinFile(sourceFilesExtensions) })
} }
} }
} }
@@ -15,6 +15,7 @@ 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.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
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
@@ -153,6 +154,16 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
get() = (classpath + additionalClasspath) get() = (classpath + additionalClasspath)
.filterTo(LinkedHashSet(), File::exists) .filterTo(LinkedHashSet(), File::exists)
private val sourceFilesExtensionsSources: MutableList<Iterable<String>> = mutableListOf()
@get:Input
val sourceFilesExtensions: List<String>
get() = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS + sourceFilesExtensionsSources.flatten()
internal fun sourceFilesExtensions(extensions: Iterable<String>) {
sourceFilesExtensionsSources.add(extensions)
}
private val kotlinExt: KotlinProjectExtension private val kotlinExt: KotlinProjectExtension
get() = project.extensions.findByType(KotlinProjectExtension::class.java)!! get() = project.extensions.findByType(KotlinProjectExtension::class.java)!!
@@ -360,7 +371,7 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
} }
@Internal @Internal
override fun getSourceRoots() = SourceRoots.ForJvm.create(getSource(), sourceRootsContainer) override fun getSourceRoots() = SourceRoots.ForJvm.create(getSource(), sourceRootsContainer, sourceFilesExtensions)
override fun callCompiler(args: K2JVMCompilerArguments, sourceRoots: SourceRoots, changedFiles: ChangedFiles) { override fun callCompiler(args: K2JVMCompilerArguments, sourceRoots: SourceRoots, changedFiles: ChangedFiles) {
sourceRoots as SourceRoots.ForJvm sourceRoots as SourceRoots.ForJvm
@@ -487,7 +498,7 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(),
kotlinOptionsImpl.updateArguments(args) kotlinOptionsImpl.updateArguments(args)
} }
override fun getSourceRoots() = SourceRoots.KotlinOnly.create(getSource()) override fun getSourceRoots() = SourceRoots.KotlinOnly.create(getSource(), sourceFilesExtensions)
@get:InputFiles @get:InputFiles
@get:Optional @get:Optional
@@ -13,11 +13,8 @@ import java.util.*
internal fun File.isJavaFile() = internal fun File.isJavaFile() =
extension.equals("java", ignoreCase = true) extension.equals("java", ignoreCase = true)
internal fun File.isKotlinFile(): Boolean = internal fun File.isKotlinFile(sourceFilesExtensions: List<String>): Boolean =
extension.let { !isJavaFile() && sourceFilesExtensions.any { it.equals(extension, ignoreCase = true) }
"kt".equals(it, ignoreCase = true) ||
"kts".equals(it, ignoreCase = true)
}
internal fun File.isClassFile(): Boolean = internal fun File.isClassFile(): Boolean =
extension.equals("class", ignoreCase = true) extension.equals("class", ignoreCase = true)
@@ -14,6 +14,7 @@ dependencies {
compileOnly(project(":compiler:cli")) compileOnly(project(":compiler:cli"))
compile(project(":kotlin-scripting-common")) compile(project(":kotlin-scripting-common"))
compile(project(":kotlin-scripting-jvm")) compile(project(":kotlin-scripting-jvm"))
compile(project(":kotlin-stdlib"))
compileOnly(project(":kotlin-reflect-api")) compileOnly(project(":kotlin-reflect-api"))
compileOnly(intellijCoreDep()) { includeJars("intellij-core") } compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
compileOnly(intellijDep()) { includeJars("asm-all") } compileOnly(intellijDep()) { includeJars("asm-all") }
@@ -34,6 +35,14 @@ sourceSets {
"test" { projectDefault() } "test" { projectDefault() }
} }
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
kotlinOptions {
languageVersion = "1.2"
apiVersion = "1.2"
freeCompilerArgs += "-Xskip-metadata-version-check"
}
}
val jar = runtimeJar { val jar = runtimeJar {
from(fileTree("$projectDir/src")) { include("META-INF/**") } from(fileTree("$projectDir/src")) { include("META-INF/**") }
} }