From a03bfb3561421e6655d04c05dbcaec83ac488f9b Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Thu, 30 Aug 2018 13:39:16 +0300 Subject: [PATCH] Implement support for non-kts scripts in gradle #KT-26784 fixed --- .../jetbrains/kotlin/build/sourcesUtils.kt | 9 ++ .../jetbrains/kotlin/incremental/fileUtils.kt | 7 +- .../kotlin/incremental/DirtyFilesContainer.kt | 5 +- .../incremental/IncrementalCompilerRunner.kt | 8 +- .../IncrementalJsCompilerRunner.kt | 2 +- .../IncrementalJvmCompilerRunner.kt | 16 ++-- .../jps/build/AbstractLookupTrackerTest.kt | 2 +- .../kotlin/gradle/plugin/KotlinSourceSet.kt | 2 + .../tools/kotlin-gradle-plugin/build.gradle | 2 + .../kotlin/gradle/plugin/KotlinPlugin.kt | 1 + .../gradle/plugin/mpp/kotlinCompilations.kt | 10 ++- .../plugin/sources/DefaultKotlinSourceSet.kt | 15 +++- .../internal/ScriptingGradleSubplugin.kt | 88 ++++++++++++++++++- .../gradle/tasks/KotlinCompileCommon.kt | 2 +- .../kotlin/gradle/tasks/SourceRoots.kt | 7 +- .../jetbrains/kotlin/gradle/tasks/Tasks.kt | 15 +++- .../kotlin/gradle/utils/fileUtils.kt | 7 +- .../scripting/scripting-cli/build.gradle.kts | 9 ++ 18 files changed, 171 insertions(+), 36 deletions(-) create mode 100644 build-common/src/org/jetbrains/kotlin/build/sourcesUtils.kt diff --git a/build-common/src/org/jetbrains/kotlin/build/sourcesUtils.kt b/build-common/src/org/jetbrains/kotlin/build/sourcesUtils.kt new file mode 100644 index 00000000000..170f5edf4f2 --- /dev/null +++ b/build-common/src/org/jetbrains/kotlin/build/sourcesUtils.kt @@ -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") + diff --git a/build-common/src/org/jetbrains/kotlin/incremental/fileUtils.kt b/build-common/src/org/jetbrains/kotlin/incremental/fileUtils.kt index 459ae02d2e2..a3c595c2add 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/fileUtils.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/fileUtils.kt @@ -21,11 +21,8 @@ import java.io.File fun File.isJavaFile() = extension.equals("java", ignoreCase = true) -fun File.isKotlinFile(): Boolean = - extension.let { - "kt".equals(it, ignoreCase = true) || - "kts".equals(it, ignoreCase = true) - } +fun File.isKotlinFile(sourceFilesExtensions: List): Boolean = + !isJavaFile() && sourceFilesExtensions.any { it.equals(extension, ignoreCase = true) } fun File.isClassFile(): Boolean = extension.equals("class", ignoreCase = true) diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/DirtyFilesContainer.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/DirtyFilesContainer.kt index 2be16541638..a101de686ad 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/DirtyFilesContainer.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/DirtyFilesContainer.kt @@ -10,7 +10,8 @@ import java.io.File class DirtyFilesContainer( private val caches: IncrementalCachesManager<*>, - private val reporter: ICReporter + private val reporter: ICReporter, + private val sourceFilesExtensions: List ) { private val myDirtyFiles = HashSet() @@ -18,7 +19,7 @@ class DirtyFilesContainer( ArrayList(myDirtyFiles) fun add(files: Iterable) { - val existingKotlinFiles = files.filter { it.isKotlinFile() } + val existingKotlinFiles = files.filter { it.isKotlinFile(sourceFilesExtensions) } if (existingKotlinFiles.isNotEmpty()) { myDirtyFiles.addAll(existingKotlinFiles) } diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt index 11ef456e106..12affd8e27d 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt @@ -16,6 +16,7 @@ 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.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments @@ -50,6 +51,7 @@ abstract class IncrementalCompilerRunner< protected val cacheDirectory = File(workingDir, cacheDirName) protected val dirtySourcesSinceLastTimeFile = File(workingDir, DIRTY_SOURCES_FILE_NAME) protected val lastBuildInfoFile = File(workingDir, LAST_BUILD_INFO_FILE_NAME) + protected open val kotlinSourceFilesExtensions: List = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS protected abstract fun isICEnabled(): Boolean protected abstract fun createCacheManager(args: Args): CacheManager @@ -85,7 +87,7 @@ abstract class IncrementalCompilerRunner< if (providedChangedFiles == null) { 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) } @@ -281,8 +283,8 @@ abstract class IncrementalCompilerRunner< changedFiles: ChangedFiles.Known ): DirtyData { val removedClasses = HashSet() - val dirtyFiles = changedFiles.modified.filterTo(HashSet()) { it.isKotlinFile() } - val removedFiles = changedFiles.removed.filterTo(HashSet()) { it.isKotlinFile() } + val dirtyFiles = changedFiles.modified.filterTo(HashSet()) { it.isKotlinFile(kotlinSourceFilesExtensions) } + val removedFiles = changedFiles.removed.filterTo(HashSet()) { it.isKotlinFile(kotlinSourceFilesExtensions) } val existingClasses = classesFqNames(dirtyFiles) val previousClasses = caches.platformCache diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt index ff7bfcf7e27..0367f191803 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt @@ -90,7 +90,7 @@ class IncrementalJsCompilerRunner( val lastBuildInfo = BuildInfo.read(lastBuildInfoFile) ?: return CompilationMode.Rebuild { "No information on previous build" } - val dirtyFiles = DirtyFilesContainer(caches, reporter) + val dirtyFiles = DirtyFilesContainer(caches, reporter, kotlinSourceFilesExtensions) initDirtyFiles(dirtyFiles, changedFiles) val libs = (args.libraries ?: "").split(File.pathSeparator).map { File(it) } diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt index c100b729249..a87fc9a6ba7 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt @@ -22,6 +22,7 @@ import com.intellij.psi.PsiClass import com.intellij.psi.PsiFile import com.intellij.psi.PsiFileFactory 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.GeneratedJvmClass 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.ModulesApiHistory 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.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents @@ -57,8 +57,8 @@ fun makeIncrementally( messageCollector: MessageCollector = MessageCollector.NONE, reporter: ICReporter = EmptyICReporter ) { - val kotlinExtensions = listOf("kt", "kts") - val allExtensions = kotlinExtensions + listOf("java") + val kotlinExtensions = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS + val allExtensions = kotlinExtensions + "java" val rootsWalk = sourceRoots.asSequence().flatMap { it.walk() } val files = rootsWalk.filter(File::isFile) val sourceFiles = files.filter { it.extension.toLowerCase() in allExtensions }.toList() @@ -75,7 +75,8 @@ fun makeIncrementally( usePreciseJavaTracking = true, localStateDirs = emptyList(), buildHistoryFile = buildHistoryFile, - modulesApiHistory = EmptyModulesApiHistory + modulesApiHistory = EmptyModulesApiHistory, + kotlinSourceFilesExtensions = kotlinExtensions ) compiler.compile(sourceFiles, args, messageCollector, providedChangedFiles = null) } @@ -104,9 +105,10 @@ class IncrementalJvmCompilerRunner( cachesVersionManagers: List, reporter: ICReporter, private val usePreciseJavaTracking: Boolean, - buildHistoryFile: File, + buildHistoryFile: File, localStateDirs: Collection, - private val modulesApiHistory: ModulesApiHistory + private val modulesApiHistory: ModulesApiHistory, + override val kotlinSourceFilesExtensions: List = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS ) : IncrementalCompilerRunner( workingDir, "caches-jvm", @@ -145,7 +147,7 @@ class IncrementalJvmCompilerRunner( changedFiles: ChangedFiles.Known, args: K2JVMCompilerArguments ): CompilationMode { - val dirtyFiles = DirtyFilesContainer(caches, reporter) + val dirtyFiles = DirtyFilesContainer(caches, reporter, kotlinSourceFilesExtensions) initDirtyFiles(dirtyFiles, changedFiles) val lastBuildInfo = BuildInfo.read(lastBuildInfoFile) ?: return CompilationMode.Rebuild { "No information on previous build" } diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractLookupTrackerTest.kt b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractLookupTrackerTest.kt index 13a812223e1..cf61289e250 100644 --- a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractLookupTrackerTest.kt +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractLookupTrackerTest.kt @@ -204,7 +204,7 @@ abstract class AbstractLookupTrackerTest : TestWithWorkingDir() { val testDir = File(path) 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) .filter { it.isNotEmpty() } diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSet.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSet.kt index 7a43be44baa..de2ce8f135f 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSet.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSet.kt @@ -39,4 +39,6 @@ interface KotlinSourceSet : Named, HasKotlinDependencies { const val COMMON_MAIN_SOURCE_SET_NAME = "commonMain" const val COMMON_TEST_SOURCE_SET_NAME = "commonTest" } + + val customSourceFilesExtensions: Iterable // lazy iterable expected } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/build.gradle b/libraries/tools/kotlin-gradle-plugin/build.gradle index f69abf1a55b..88ca553654d 100644 --- a/libraries/tools/kotlin-gradle-plugin/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin/build.gradle @@ -45,6 +45,7 @@ dependencies { compileOnly project(':kotlin-compiler-runner') compileOnly project(':kotlin-annotation-processing') compileOnly project(':kotlin-annotation-processing-gradle') + compileOnly project(':kotlin-scripting-compiler') compileOnly 'com.android.tools.build:gradle:2.0.0' 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-android-extensions', configuration: 'runtimeJar') runtime project(path: ':kotlin-compiler-runner', configuration: 'runtimeJar') + runtime project(path: ':kotlin-scripting-compiler-embeddable', configuration: 'runtimeJar') runtime project(':kotlin-reflect') // com.android.tools.build:gradle has ~50 unneeded transitive dependencies diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index 15cd838591e..4504ae0394d 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -162,6 +162,7 @@ internal class Kotlin2JvmSourceSetProcessor( override fun doTargetSpecificProcessing() { Kapt3KotlinGradleSubplugin.createAptConfigurationIfNeeded(project, kotlinCompilation.compilationName) + ScriptingGradleSubplugin.createDiscoveryConfigurationIfNeeded(project, kotlinCompilation.compilationName) project.afterEvaluate { project -> val javaTask = javaSourceSet?.let { project.tasks.findByName(it.compileJavaTaskName) as JavaCompile } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt index bc4942f16e5..2120c5bd385 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt @@ -70,10 +70,12 @@ abstract class AbstractKotlinCompilation( override val kotlinSourceSets: MutableSet = mutableSetOf() open fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) { - val compileTask = target.project.tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*> - compileTask.source(sourceSet.kotlin) - if (addAsCommonSources) { - compileTask.commonSourceSet += sourceSet.kotlin + (target.project.tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*>).apply { + source(sourceSet.kotlin) + sourceFilesExtensions(sourceSet.customSourceFilesExtensions) + if (addAsCommonSources) { + commonSourceSet += sourceSet.kotlin + } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt index 2ffe332f3d7..1dcc33649d7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt @@ -12,6 +12,7 @@ import org.gradle.api.file.SourceDirectorySet import org.gradle.api.internal.file.DefaultSourceDirectorySet import org.gradle.api.internal.file.FileResolver 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.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder @@ -53,7 +54,9 @@ class DefaultKotlinSourceSet( get() = lowerCamelCaseName(runtimeOnlyConfigurationName, METADATA_CONFIGURATION_NAME_SUFFIX) 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() @@ -89,6 +92,16 @@ class DefaultKotlinSourceSet( get() = dependsOnSourceSetsImpl override fun toString(): String = "source set $name" + + override val customSourceFilesExtensions: Iterable + 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 { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/scripting/internal/ScriptingGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/scripting/internal/ScriptingGradleSubplugin.kt index 862b32662e3..8f81917ab1d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/scripting/internal/ScriptingGradleSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/scripting/internal/ScriptingGradleSubplugin.kt @@ -5,18 +5,104 @@ package org.jetbrains.kotlin.gradle.scripting.internal +import org.gradle.api.DefaultTask import org.gradle.api.Plugin 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.jetbrains.kotlin.gradle.plugin.* 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 { companion object { 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 = 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 { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt index dee586c546b..e8ec2463e04 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt @@ -40,7 +40,7 @@ internal open class KotlinCompileCommon : AbstractKotlinCompile = findKotlinMetadataCompilerClasspath(project) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/SourceRoots.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/SourceRoots.kt index bc5703d5042..230392c769b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/SourceRoots.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/SourceRoots.kt @@ -22,8 +22,8 @@ internal sealed class SourceRoots(val kotlinSourceFiles: List) { class ForJvm(kotlinSourceFiles: List, val javaSourceRoots: Set) : SourceRoots(kotlinSourceFiles) { companion object { - fun create(taskSource: FileTree, sourceRoots: FilteringSourceRootsContainer): ForJvm { - val kotlinSourceFiles = (taskSource as Iterable).filter(File::isKotlinFile) + fun create(taskSource: FileTree, sourceRoots: FilteringSourceRootsContainer, sourceFilesExtensions: List): ForJvm { + val kotlinSourceFiles = (taskSource as Iterable).filter { it.isKotlinFile(sourceFilesExtensions) } val javaSourceRoots = findRootsForSources( sourceRoots.sourceRoots, taskSource.filter(File::isJavaFile)) return ForJvm(kotlinSourceFiles, javaSourceRoots) @@ -53,7 +53,8 @@ internal sealed class SourceRoots(val kotlinSourceFiles: List) { class KotlinOnly(kotlinSourceFiles: List) : SourceRoots(kotlinSourceFiles) { companion object { - fun create(taskSource: FileTree) = KotlinOnly((taskSource as Iterable).filter(File::isKotlinFile)) + fun create(taskSource: FileTree, sourceFilesExtensions: List) = + KotlinOnly((taskSource as Iterable).filter { it.isKotlinFile(sourceFilesExtensions) }) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index 2ffa6e9c1ab..63f9a90babb 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -15,6 +15,7 @@ import org.gradle.api.tasks.Optional import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.JavaCompile 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.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments @@ -153,6 +154,16 @@ abstract class AbstractKotlinCompile() : AbstractKo get() = (classpath + additionalClasspath) .filterTo(LinkedHashSet(), File::exists) + private val sourceFilesExtensionsSources: MutableList> = mutableListOf() + + @get:Input + val sourceFilesExtensions: List + get() = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS + sourceFilesExtensionsSources.flatten() + + internal fun sourceFilesExtensions(extensions: Iterable) { + sourceFilesExtensionsSources.add(extensions) + } + private val kotlinExt: KotlinProjectExtension get() = project.extensions.findByType(KotlinProjectExtension::class.java)!! @@ -360,7 +371,7 @@ open class KotlinCompile : AbstractKotlinCompile(), Kotl } @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) { sourceRoots as SourceRoots.ForJvm @@ -487,7 +498,7 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile(), kotlinOptionsImpl.updateArguments(args) } - override fun getSourceRoots() = SourceRoots.KotlinOnly.create(getSource()) + override fun getSourceRoots() = SourceRoots.KotlinOnly.create(getSource(), sourceFilesExtensions) @get:InputFiles @get:Optional diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/fileUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/fileUtils.kt index 57fe1fc7eeb..f6ca2b23c2d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/fileUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/fileUtils.kt @@ -13,11 +13,8 @@ import java.util.* internal fun File.isJavaFile() = extension.equals("java", ignoreCase = true) -internal fun File.isKotlinFile(): Boolean = - extension.let { - "kt".equals(it, ignoreCase = true) || - "kts".equals(it, ignoreCase = true) - } +internal fun File.isKotlinFile(sourceFilesExtensions: List): Boolean = + !isJavaFile() && sourceFilesExtensions.any { it.equals(extension, ignoreCase = true) } internal fun File.isClassFile(): Boolean = extension.equals("class", ignoreCase = true) diff --git a/plugins/scripting/scripting-cli/build.gradle.kts b/plugins/scripting/scripting-cli/build.gradle.kts index 99edc23473f..e31e21b2fc6 100644 --- a/plugins/scripting/scripting-cli/build.gradle.kts +++ b/plugins/scripting/scripting-cli/build.gradle.kts @@ -14,6 +14,7 @@ dependencies { compileOnly(project(":compiler:cli")) compile(project(":kotlin-scripting-common")) compile(project(":kotlin-scripting-jvm")) + compile(project(":kotlin-stdlib")) compileOnly(project(":kotlin-reflect-api")) compileOnly(intellijCoreDep()) { includeJars("intellij-core") } compileOnly(intellijDep()) { includeJars("asm-all") } @@ -34,6 +35,14 @@ sourceSets { "test" { projectDefault() } } +tasks.withType> { + kotlinOptions { + languageVersion = "1.2" + apiVersion = "1.2" + freeCompilerArgs += "-Xskip-metadata-version-check" + } +} + val jar = runtimeJar { from(fileTree("$projectDir/src")) { include("META-INF/**") } }