diff --git a/compiler/testData/script/collectDependencies/imp_cycle_1.req1.kts b/compiler/testData/script/collectDependencies/imp_cycle_1.req1.kts new file mode 100644 index 00000000000..ba353eb199b --- /dev/null +++ b/compiler/testData/script/collectDependencies/imp_cycle_1.req1.kts @@ -0,0 +1,2 @@ + +@file:Import("imp_cycle_2.req1.kts") diff --git a/compiler/testData/script/collectDependencies/imp_cycle_2.req1.kts b/compiler/testData/script/collectDependencies/imp_cycle_2.req1.kts new file mode 100644 index 00000000000..1e9613df5ab --- /dev/null +++ b/compiler/testData/script/collectDependencies/imp_cycle_2.req1.kts @@ -0,0 +1,2 @@ + +@file:Import("imp_cycle_1.req1.kts") diff --git a/compiler/testData/script/collectDependencies/imp_imp_leaf.req1.kts b/compiler/testData/script/collectDependencies/imp_imp_leaf.req1.kts new file mode 100644 index 00000000000..128f4167c6c --- /dev/null +++ b/compiler/testData/script/collectDependencies/imp_imp_leaf.req1.kts @@ -0,0 +1,2 @@ + +@file:Import("imp_leaf.req1.kts") diff --git a/compiler/testData/script/collectDependencies/imp_leaf.req1.kts b/compiler/testData/script/collectDependencies/imp_leaf.req1.kts new file mode 100644 index 00000000000..7ad7045ab2c --- /dev/null +++ b/compiler/testData/script/collectDependencies/imp_leaf.req1.kts @@ -0,0 +1,2 @@ + +@file:Import("leaf.req1.kts") diff --git a/compiler/testData/script/collectDependencies/imp_leaf_and_imp_imp_leaf.req1.kts b/compiler/testData/script/collectDependencies/imp_leaf_and_imp_imp_leaf.req1.kts new file mode 100644 index 00000000000..9c175667c87 --- /dev/null +++ b/compiler/testData/script/collectDependencies/imp_leaf_and_imp_imp_leaf.req1.kts @@ -0,0 +1,4 @@ + +@file:Import("leaf.req1.kts") + +@file:Import("imp_leaf.req1.kts") diff --git a/compiler/testData/script/collectDependencies/imp_leaf_twice.req1.kts b/compiler/testData/script/collectDependencies/imp_leaf_twice.req1.kts new file mode 100644 index 00000000000..302f0323f70 --- /dev/null +++ b/compiler/testData/script/collectDependencies/imp_leaf_twice.req1.kts @@ -0,0 +1,4 @@ + +@file:Import("leaf.req1.kts") + +@file:Import("leaf.req1.kts") diff --git a/compiler/testData/script/collectDependencies/imp_leaf_with_deps.req1.kts b/compiler/testData/script/collectDependencies/imp_leaf_with_deps.req1.kts new file mode 100644 index 00000000000..8cefe8755bb --- /dev/null +++ b/compiler/testData/script/collectDependencies/imp_leaf_with_deps.req1.kts @@ -0,0 +1,3 @@ + +@file:Import("leaf_with_deps_1.req1.kts") +@file:Import("leaf_with_deps_2.req1.kts") diff --git a/compiler/testData/script/collectDependencies/imp_self.req1.kts b/compiler/testData/script/collectDependencies/imp_self.req1.kts new file mode 100644 index 00000000000..cadc97584f5 --- /dev/null +++ b/compiler/testData/script/collectDependencies/imp_self.req1.kts @@ -0,0 +1,2 @@ + +@file:Import("imp_self.req1.kts") diff --git a/compiler/testData/script/collectDependencies/leaf.req1.kts b/compiler/testData/script/collectDependencies/leaf.req1.kts new file mode 100644 index 00000000000..35bc2450492 --- /dev/null +++ b/compiler/testData/script/collectDependencies/leaf.req1.kts @@ -0,0 +1,3 @@ + +// nothing + diff --git a/compiler/testData/script/collectDependencies/leaf_with_deps_1.req1.kts b/compiler/testData/script/collectDependencies/leaf_with_deps_1.req1.kts new file mode 100644 index 00000000000..eeb4d6c1a6e --- /dev/null +++ b/compiler/testData/script/collectDependencies/leaf_with_deps_1.req1.kts @@ -0,0 +1,2 @@ + +@file:DependsOn("someDependency1.jar") diff --git a/compiler/testData/script/collectDependencies/leaf_with_deps_2.req1.kts b/compiler/testData/script/collectDependencies/leaf_with_deps_2.req1.kts new file mode 100644 index 00000000000..644a0182502 --- /dev/null +++ b/compiler/testData/script/collectDependencies/leaf_with_deps_2.req1.kts @@ -0,0 +1,2 @@ + +@file:DependsOn("someDependency2.jar") diff --git a/compiler/tests/org/jetbrains/kotlin/scripts/CollectScriptCompilationDependenciesTest.kt b/compiler/tests/org/jetbrains/kotlin/scripts/CollectScriptCompilationDependenciesTest.kt new file mode 100644 index 00000000000..59bbd1349de --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/scripts/CollectScriptCompilationDependenciesTest.kt @@ -0,0 +1,86 @@ +/* + * 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.scripts + +import junit.framework.TestCase +import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot +import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots +import org.jetbrains.kotlin.config.JVMConfigurationKeys +import org.jetbrains.kotlin.script.KotlinScriptDefinition +import org.jetbrains.kotlin.scripting.compiler.plugin.KotlinScriptDefinitionAdapterFromNewAPI +import org.jetbrains.kotlin.test.ConfigurationKind +import org.jetbrains.kotlin.test.KotlinTestUtils +import org.jetbrains.kotlin.test.TestJdkKind +import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase +import java.io.File +import kotlin.script.experimental.api.KotlinType +import kotlin.script.experimental.host.ScriptingHostConfiguration +import kotlin.script.experimental.host.createCompilationConfigurationFromTemplate +import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration + +private const val testDataPath = "compiler/testData/script/collectDependencies" + +class CollectScriptCompilationDependenciesTest : KtUsefulTestCase() { + + fun testCascadeImport() { + runTest("imp_imp_leaf.req1.kts", listOf("imp_leaf.req1.kts", "leaf.req1.kts")) + } + + fun testImportTwice() { + runTest("imp_leaf_twice.req1.kts", listOf("leaf.req1.kts")) + } + + fun testImportDiamond() { + runTest("imp_leaf_and_imp_imp_leaf.req1.kts", listOf("imp_leaf.req1.kts", "leaf.req1.kts")) + } + + fun testDirectImportCycle() { + runTest("imp_self.req1.kts", emptyList()) + } + + fun testIndirectImportCycle() { + runTest("imp_cycle_1.req1.kts", listOf("imp_cycle_2.req1.kts")) + } + + fun testImportWithDependenciesAdded() { + runTest( + "imp_leaf_with_deps.req1.kts", + listOf("leaf_with_deps_1.req1.kts", "leaf_with_deps_2.req1.kts"), + listOf(File("someDependency1.jar"), File("someDependency2.jar")) + ) + } + + private fun runTest(scriptFile: String, expectedDependencies: List, classPath: List = emptyList()) { + val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.NO_KOTLIN_REFLECT, TestJdkKind.MOCK_JDK).apply { + val hostConfiguration = ScriptingHostConfiguration(defaultJvmScriptingHostConfiguration) + val scriptDefinition = KotlinScriptDefinitionAdapterFromNewAPI( + createCompilationConfigurationFromTemplate( + KotlinType(TestScriptWithRequire::class), + hostConfiguration, KotlinScriptDefinition::class + ), + hostConfiguration + ) + add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, scriptDefinition) + + addKotlinSourceRoot(File(testDataPath, scriptFile).path) + } + val environment = KotlinCoreEnvironment.createForTests(testRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) + + val expectedSources = (expectedDependencies + scriptFile).sorted() + val actualSources = environment.getSourceFiles().map { it.name }.sorted() + + TestCase.assertEquals(expectedSources, actualSources) + + if (classPath.isNotEmpty()) { + + val actualClasspath = environment.configuration.jvmClasspathRoots + + TestCase.assertTrue("expect that $actualClasspath contains $classPath", actualClasspath.containsAll(classPath)) + } + } +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/scripts/ScriptCliCompilationTest.kt b/compiler/tests/org/jetbrains/kotlin/scripts/ScriptCliCompilationTest.kt index 6720b11041c..f1b01f9a89b 100644 --- a/compiler/tests/org/jetbrains/kotlin/scripts/ScriptCliCompilationTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/scripts/ScriptCliCompilationTest.kt @@ -22,7 +22,6 @@ import org.jetbrains.kotlin.test.TestJdkKind import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase import org.jetbrains.kotlin.utils.PathUtil import org.junit.Assert -import org.junit.Test import java.io.File import kotlin.reflect.KClass import kotlin.script.experimental.annotations.KotlinScript @@ -118,12 +117,12 @@ abstract class TestScriptWithRequire object TestScriptWithRequireConfiguration : ScriptCompilationConfiguration( { - defaultImports(Import::class) + defaultImports(Import::class, DependsOn::class) jvm { dependenciesFromCurrentContext(wholeClasspath = true) } refineConfiguration { - onAnnotations(Import::class) { context: ScriptConfigurationRefinementContext -> + onAnnotations(Import::class, DependsOn::class) { context: ScriptConfigurationRefinementContext -> val scriptBaseDir = (context.script as? FileScriptSource)?.file?.parentFile val sources = context.collectedData?.get(ScriptCollectedData.foundAnnotations) ?.flatMap { @@ -131,10 +130,13 @@ object TestScriptWithRequireConfiguration : ScriptCompilationConfiguration( FileScriptSource(scriptBaseDir?.resolve(sourceName) ?: File(sourceName)) } ?: emptyList() } - ?.takeIf { it.isNotEmpty() } - ?: return@onAnnotations context.compilationConfiguration.asSuccess() + val deps = context.collectedData?.get(ScriptCollectedData.foundAnnotations) + ?.mapNotNull { + (it as? DependsOn)?.path?.let(::File) + } ScriptCompilationConfiguration(context.compilationConfiguration) { - importScripts.append(sources) + if (sources?.isNotEmpty() == true) importScripts.append(sources) + if (deps?.isNotEmpty() == true) dependencies.append(JvmDependency(deps)) }.asSuccess() } }