diff --git a/idea/testData/script/definition/highlighting/additionalImports/script.kts b/idea/testData/script/definition/highlighting/additionalImports/script.kts index 115ee1e05da..fcf0b86213c 100644 --- a/idea/testData/script/definition/highlighting/additionalImports/script.kts +++ b/idea/testData/script/definition/highlighting/additionalImports/script.kts @@ -5,3 +5,5 @@ val g = listOf("a", "b", "c") val time = measureNanoTime { println("text") } + +// DEPENDENCIES: classpath:runtime-classes; imports:kotlin.system.* \ No newline at end of file diff --git a/idea/testData/script/definition/highlighting/additionalImports/template/template.kt b/idea/testData/script/definition/highlighting/additionalImports/template/template.kt deleted file mode 100644 index 5536ba2a039..00000000000 --- a/idea/testData/script/definition/highlighting/additionalImports/template/template.kt +++ /dev/null @@ -1,25 +0,0 @@ -package custom.scriptDefinition - -import kotlin.script.dependencies.* -import kotlin.script.templates.* -import java.io.File -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Future - -class TestDependenciesResolver : ScriptDependenciesResolver { - override fun resolve( - script: ScriptContents, - environment: Map?, - report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies? - ): Future { - return CompletableFuture.completedFuture( - object : KotlinScriptExternalDependencies { - override val classpath: Iterable = listOf(environment?.get("runtime-classes") as File) - override val imports: Iterable = listOf("kotlin.system.*") - }) - - } -} - -@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts") -class Template \ No newline at end of file diff --git a/idea/testData/script/definition/highlighting/customLibrary/script.kts b/idea/testData/script/definition/highlighting/customLibrary/script.kts index 2dd961dbe8f..5659890d0fe 100644 --- a/idea/testData/script/definition/highlighting/customLibrary/script.kts +++ b/idea/testData/script/definition/highlighting/customLibrary/script.kts @@ -6,3 +6,4 @@ doStuff(c1, c2) doStuff(c1, 3) +// DEPENDENCIES: classpath:lib-classes; imports:custom.library.* \ No newline at end of file diff --git a/idea/testData/script/definition/highlighting/customLibrary/template/template.kt b/idea/testData/script/definition/highlighting/customLibrary/template/template.kt deleted file mode 100644 index 95829012dfe..00000000000 --- a/idea/testData/script/definition/highlighting/customLibrary/template/template.kt +++ /dev/null @@ -1,28 +0,0 @@ -package custom.scriptDefinition - -import kotlin.script.dependencies.* -import kotlin.script.templates.* -import java.io.File -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Future - -class TestDependenciesResolver : ScriptDependenciesResolver { - override fun resolve( - script: ScriptContents, - environment: Map?, - report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies? - ): Future { - return CompletableFuture.completedFuture( - object : KotlinScriptExternalDependencies { - override val classpath: Iterable = listOf( - environment?.get("lib-classes") as File - ) - - override val imports: Iterable = listOf("custom.library.*") - }) - - } -} - -@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts") -class Template \ No newline at end of file diff --git a/idea/testData/script/definition/highlighting/javaNestedClass/script.kts b/idea/testData/script/definition/highlighting/javaNestedClass/script.kts index e78b27e8e4a..4a8136003e6 100644 --- a/idea/testData/script/definition/highlighting/javaNestedClass/script.kts +++ b/idea/testData/script/definition/highlighting/javaNestedClass/script.kts @@ -6,4 +6,6 @@ fun f( i: JavaInterface.F.I ) { -} \ No newline at end of file +} + +// DEPENDENCIES: classpath:lib-classes; imports:custom.library.* \ No newline at end of file diff --git a/idea/testData/script/definition/highlighting/javaNestedClass/template/template.kt b/idea/testData/script/definition/highlighting/javaNestedClass/template/template.kt deleted file mode 100644 index 95829012dfe..00000000000 --- a/idea/testData/script/definition/highlighting/javaNestedClass/template/template.kt +++ /dev/null @@ -1,28 +0,0 @@ -package custom.scriptDefinition - -import kotlin.script.dependencies.* -import kotlin.script.templates.* -import java.io.File -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Future - -class TestDependenciesResolver : ScriptDependenciesResolver { - override fun resolve( - script: ScriptContents, - environment: Map?, - report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies? - ): Future { - return CompletableFuture.completedFuture( - object : KotlinScriptExternalDependencies { - override val classpath: Iterable = listOf( - environment?.get("lib-classes") as File - ) - - override val imports: Iterable = listOf("custom.library.*") - }) - - } -} - -@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts") -class Template \ No newline at end of file diff --git a/idea/testData/script/definition/highlighting/simple/script.kts b/idea/testData/script/definition/highlighting/simple/script.kts index 7560fe48c1a..a43e3349e0d 100644 --- a/idea/testData/script/definition/highlighting/simple/script.kts +++ b/idea/testData/script/definition/highlighting/simple/script.kts @@ -4,4 +4,6 @@ val g = listOf("a", "b", "c") val time = measureNanoTime { println("text") -} \ No newline at end of file +} + +// DEPENDENCIES: classpath:runtime-classes \ No newline at end of file diff --git a/idea/testData/script/definition/highlighting/simple/template/template.kt b/idea/testData/script/definition/highlighting/simple/template/template.kt deleted file mode 100644 index 9c1f28e4cb6..00000000000 --- a/idea/testData/script/definition/highlighting/simple/template/template.kt +++ /dev/null @@ -1,24 +0,0 @@ -package custom.scriptDefinition - -import kotlin.script.dependencies.* -import kotlin.script.templates.* -import java.io.File -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Future - -class TestDependenciesResolver : ScriptDependenciesResolver { - override fun resolve( - script: ScriptContents, - environment: Map?, - report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies? - ): Future { - return CompletableFuture.completedFuture( - object : KotlinScriptExternalDependencies { - override val classpath: Iterable = listOf(environment?.get("runtime-classes") as File) - }) - - } -} - -@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts") -class Template \ No newline at end of file diff --git a/idea/testData/script/definition/navigation/javaLib/script.kts b/idea/testData/script/definition/navigation/javaLib/script.kts index d93c75fa993..fc773231fed 100644 --- a/idea/testData/script/definition/navigation/javaLib/script.kts +++ b/idea/testData/script/definition/navigation/javaLib/script.kts @@ -1,3 +1,6 @@ test.Utils.foo("asd") + +// DEPENDENCIES: classpath:lib-classes + // REF: (in test.Utils).foo(String) // FILE: test/Utils.class \ No newline at end of file diff --git a/idea/testData/script/definition/navigation/javaLib/template/template.kt b/idea/testData/script/definition/navigation/javaLib/template/template.kt deleted file mode 100644 index b92172b09af..00000000000 --- a/idea/testData/script/definition/navigation/javaLib/template/template.kt +++ /dev/null @@ -1,24 +0,0 @@ -package custom.scriptDefinition - -import kotlin.script.dependencies.* -import kotlin.script.templates.* -import java.io.File -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Future - -class TestDependenciesResolver : ScriptDependenciesResolver { - override fun resolve( - script: ScriptContents, - environment: Map?, - report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies? - ): Future { - return CompletableFuture.completedFuture( - object : KotlinScriptExternalDependencies { - override val classpath: Iterable = listOf(environment?.get("lib-classes") as File) - }) - - } -} - -@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts") -class Template diff --git a/idea/testData/script/definition/navigation/javaLibWithSources/script.kts b/idea/testData/script/definition/navigation/javaLibWithSources/script.kts index 4d33fafa8b3..014e152a0e0 100644 --- a/idea/testData/script/definition/navigation/javaLibWithSources/script.kts +++ b/idea/testData/script/definition/navigation/javaLibWithSources/script.kts @@ -1,3 +1,6 @@ test.Utils.foo("asd") + +// DEPENDENCIES: classpath:lib-classes; sources:lib-source + // REF: (in test.Utils).foo(String) // FILE: test/Utils.java \ No newline at end of file diff --git a/idea/testData/script/definition/navigation/javaLibWithSources/template/template.kt b/idea/testData/script/definition/navigation/javaLibWithSources/template/template.kt deleted file mode 100644 index d1d5876b823..00000000000 --- a/idea/testData/script/definition/navigation/javaLibWithSources/template/template.kt +++ /dev/null @@ -1,25 +0,0 @@ -package custom.scriptDefinition - -import kotlin.script.dependencies.* -import kotlin.script.templates.* -import java.io.File -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Future - -class TestDependenciesResolver : ScriptDependenciesResolver { - override fun resolve( - script: ScriptContents, - environment: Map?, - report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies? - ): Future { - return CompletableFuture.completedFuture( - object : KotlinScriptExternalDependencies { - override val classpath: Iterable = listOf(environment?.get("lib-classes") as File) - override val sources: Iterable = listOf(environment?.get("lib-source") as File) - }) - - } -} - -@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts") -class Template diff --git a/idea/testData/script/definition/navigation/kotlinLib/script.kts b/idea/testData/script/definition/navigation/kotlinLib/script.kts index 2d3b36bc7f4..697d7ae1b3f 100644 --- a/idea/testData/script/definition/navigation/kotlinLib/script.kts +++ b/idea/testData/script/definition/navigation/kotlinLib/script.kts @@ -1,3 +1,6 @@ test.KObject.foo() + +// DEPENDENCIES: classpath:lib-classes + // REF: (in test.KObject).foo() // FILE: test/KObject.class \ No newline at end of file diff --git a/idea/testData/script/definition/navigation/kotlinLib/template/template.kt b/idea/testData/script/definition/navigation/kotlinLib/template/template.kt deleted file mode 100644 index b92172b09af..00000000000 --- a/idea/testData/script/definition/navigation/kotlinLib/template/template.kt +++ /dev/null @@ -1,24 +0,0 @@ -package custom.scriptDefinition - -import kotlin.script.dependencies.* -import kotlin.script.templates.* -import java.io.File -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Future - -class TestDependenciesResolver : ScriptDependenciesResolver { - override fun resolve( - script: ScriptContents, - environment: Map?, - report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies? - ): Future { - return CompletableFuture.completedFuture( - object : KotlinScriptExternalDependencies { - override val classpath: Iterable = listOf(environment?.get("lib-classes") as File) - }) - - } -} - -@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts") -class Template diff --git a/idea/testData/script/definition/navigation/kotlinLibWithSources/script.kts b/idea/testData/script/definition/navigation/kotlinLibWithSources/script.kts index 4bb59364d3d..72716834c16 100644 --- a/idea/testData/script/definition/navigation/kotlinLibWithSources/script.kts +++ b/idea/testData/script/definition/navigation/kotlinLibWithSources/script.kts @@ -1,3 +1,6 @@ test.KObject.foo() + +// DEPENDENCIES: classpath:lib-classes; sources:lib-source + // REF: (in test.KObject).foo() // FILE: test/custom.kt \ No newline at end of file diff --git a/idea/testData/script/definition/navigation/kotlinLibWithSources/template/template.kt b/idea/testData/script/definition/navigation/kotlinLibWithSources/template/template.kt deleted file mode 100644 index d1d5876b823..00000000000 --- a/idea/testData/script/definition/navigation/kotlinLibWithSources/template/template.kt +++ /dev/null @@ -1,25 +0,0 @@ -package custom.scriptDefinition - -import kotlin.script.dependencies.* -import kotlin.script.templates.* -import java.io.File -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Future - -class TestDependenciesResolver : ScriptDependenciesResolver { - override fun resolve( - script: ScriptContents, - environment: Map?, - report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies? - ): Future { - return CompletableFuture.completedFuture( - object : KotlinScriptExternalDependencies { - override val classpath: Iterable = listOf(environment?.get("lib-classes") as File) - override val sources: Iterable = listOf(environment?.get("lib-source") as File) - }) - - } -} - -@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts") -class Template diff --git a/idea/testData/script/definition/navigation/stdlib/script.kts b/idea/testData/script/definition/navigation/stdlib/script.kts index bb954d983c8..6a1d9078825 100644 --- a/idea/testData/script/definition/navigation/stdlib/script.kts +++ b/idea/testData/script/definition/navigation/stdlib/script.kts @@ -1,4 +1,6 @@ val g = listOf("a", "b", "c") +// DEPENDENCIES: classpath:runtime-classes + // REF: (kotlin.collections).listOf(vararg T) // FILE: collections/CollectionsKt.class \ No newline at end of file diff --git a/idea/testData/script/definition/navigation/stdlib/template/template.kt b/idea/testData/script/definition/navigation/stdlib/template/template.kt deleted file mode 100644 index 9c1f28e4cb6..00000000000 --- a/idea/testData/script/definition/navigation/stdlib/template/template.kt +++ /dev/null @@ -1,24 +0,0 @@ -package custom.scriptDefinition - -import kotlin.script.dependencies.* -import kotlin.script.templates.* -import java.io.File -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Future - -class TestDependenciesResolver : ScriptDependenciesResolver { - override fun resolve( - script: ScriptContents, - environment: Map?, - report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies? - ): Future { - return CompletableFuture.completedFuture( - object : KotlinScriptExternalDependencies { - override val classpath: Iterable = listOf(environment?.get("runtime-classes") as File) - }) - - } -} - -@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts") -class Template \ No newline at end of file diff --git a/idea/testData/script/definition/navigation/stdlibWithSources/script.kts b/idea/testData/script/definition/navigation/stdlibWithSources/script.kts index 53a3b8b5af3..3445eaaf62d 100644 --- a/idea/testData/script/definition/navigation/stdlibWithSources/script.kts +++ b/idea/testData/script/definition/navigation/stdlibWithSources/script.kts @@ -1,4 +1,6 @@ val g = listOf("a", "b", "c") +// DEPENDENCIES: classpath:runtime-classes; sources:runtime-source + // REF: (kotlin.collections).listOf(vararg T) // FILE: collections/Collections.kt \ No newline at end of file diff --git a/idea/testData/script/definition/navigation/stdlibWithSources/template/template.kt b/idea/testData/script/definition/navigation/stdlibWithSources/template/template.kt deleted file mode 100644 index cea2466bfc7..00000000000 --- a/idea/testData/script/definition/navigation/stdlibWithSources/template/template.kt +++ /dev/null @@ -1,25 +0,0 @@ -package custom.scriptDefinition - -import kotlin.script.dependencies.* -import kotlin.script.templates.* -import java.io.File -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Future - -class TestDependenciesResolver : ScriptDependenciesResolver { - override fun resolve( - script: ScriptContents, - environment: Map?, - report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies? - ): Future { - return CompletableFuture.completedFuture( - object : KotlinScriptExternalDependencies { - override val classpath: Iterable = listOf(environment?.get("runtime-classes") as File) - override val sources: Iterable = listOf(environment?.get("runtime-source") as File) - }) - - } -} - -@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts") -class Template \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/script/AbstractScriptConfigurationTest.kt b/idea/tests/org/jetbrains/kotlin/idea/script/AbstractScriptConfigurationTest.kt index 9367b857e4a..ac1b34ea820 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/script/AbstractScriptConfigurationTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/script/AbstractScriptConfigurationTest.kt @@ -37,11 +37,18 @@ import org.jetbrains.kotlin.utils.PathUtil import org.junit.Assert import java.io.File import java.util.regex.Pattern +import kotlin.script.dependencies.Environment +import kotlin.script.dependencies.ScriptContents +import kotlin.script.experimental.dependencies.AsyncDependenciesResolver +import kotlin.script.experimental.dependencies.DependenciesResolver +import kotlin.script.experimental.dependencies.ScriptDependencies +import kotlin.script.experimental.dependencies.asSuccess +import kotlin.script.templates.ScriptTemplateDefinition abstract class AbstractScriptConfigurationHighlightingTest : AbstractScriptConfigurationTest() { override fun doTest(path: String) { - configureScriptEnvironment(path) + registerScriptTemplateProvider(createScriptEnvironment(path)) super.doTest(setupScriptFile(path)) } @@ -50,7 +57,7 @@ abstract class AbstractScriptConfigurationHighlightingTest : AbstractScriptConfi abstract class AbstractScriptConfigurationNavigationTest : AbstractScriptConfigurationTest() { override fun doTest(path: String) { - configureScriptEnvironment(path) + registerScriptTemplateProvider(createScriptEnvironment(path)) myFixture.configureFromExistingVirtualFile(setupScriptFile(path)) val reference = myFixture.getReferenceAtCaretPosition()!! @@ -69,20 +76,56 @@ abstract class AbstractScriptConfigurationNavigationTest : AbstractScriptConfigu } } +private val validKeys = setOf("sources", "classpath", "imports") +private const val useDefaultTemplate = "// DEPENDENCIES:" +private fun String.splitOrEmpty(delimeters: String) = split(delimeters).takeIf { it.size > 1 } ?: emptyList() +private val switches = listOf( + useDefaultTemplate +) + abstract class AbstractScriptConfigurationTest : AbstractPsiCheckerTest() { - protected fun configureScriptEnvironment(path: String) { - val templateOutDir = compileLibToDir( - File("${path}template"), - PathUtil.kotlinPathsForDistDirectory.scriptRuntimePath.path - ) + protected fun createScriptEnvironment(path: String): Environment { + val defaultEnvironment = defaultEnvironment(path) + val env = mutableMapOf() + File("${path}script.kts").forEachLine { line -> + line.trim().takeIf { useDefaultTemplate in it }?.substringAfter(useDefaultTemplate)?.split(";")?.forEach { entry -> + val (key, values) = entry.splitOrEmpty(":").map { it.trim() } + assert(key in validKeys) { "Unexpected key: $key" } + env[key] = values.split(",").map { + val str = it.trim() + defaultEnvironment[str] ?: str + } + } - val libSrcDir = File("${path}lib") - val libClasses = if (libSrcDir.isDirectory) { - compileLibToDir(libSrcDir) + switches.forEach { + if (it in line) { + env[it] = true + } + } } - else null + if (env[useDefaultTemplate] == true && defaultEnvironment["template-classes"] != null) { + error("Script configuration should be defined by either '$useDefaultTemplate' clause or via template in 'template' directory") + } + env.putAll(defaultEnvironment) + return env + } - registerScriptTemplateProvider(templateOutDir, libClasses, libSrcDir) + private fun defaultEnvironment(path: String): Map { + val templateOutDir = File("${path}template").takeIf { it.isDirectory }?.let { + compileLibToDir(it, PathUtil.kotlinPathsForDistDirectory.scriptRuntimePath.path) + } + + val libSrcDir = File("${path}lib").takeIf { it.isDirectory } + + val libClasses = libSrcDir?.let { compileLibToDir(it) } + + return mapOf( + "runtime-classes" to ForTestCompileRuntime.runtimeJarForTests(), + "runtime-source" to File("libraries/stdlib/src"), + "lib-classes" to libClasses, + "lib-source" to libSrcDir, + "template-classes" to templateOutDir + ) } protected fun setupScriptFile(path: String): VirtualFile { @@ -112,17 +155,13 @@ abstract class AbstractScriptConfigurationTest : AbstractPsiCheckerTest() { return outDir } - private fun registerScriptTemplateProvider(templateDir: File, libClasses: File?, libSource: File?) { - val provider = TestScriptTemplateProvider( - templateDir, - mapOf( - "runtime-classes" to ForTestCompileRuntime.runtimeJarForTests(), - "runtime-source" to File("libraries/stdlib/src"), - "lib-classes" to libClasses, - "lib-source" to libSource, - "template-classes" to templateDir - ) - ) + protected fun registerScriptTemplateProvider(environment: Environment) { + val provider = if (environment[useDefaultTemplate] == true) { + FromTextTemplateProvider(environment) + } + else { + CustomScriptTemplateProvider(environment) + } PlatformTestUtil.registerExtension( Extensions.getArea(project), @@ -136,12 +175,36 @@ abstract class AbstractScriptConfigurationTest : AbstractPsiCheckerTest() { override fun getProjectDescriptor() = KotlinLightProjectDescriptor.INSTANCE } -class TestScriptTemplateProvider( - compiledTemplateDir: File, +class CustomScriptTemplateProvider( override val environment: Map ) : ScriptTemplatesProvider { override val id = "Test" override val isValid = true override val templateClassNames = listOf("custom.scriptDefinition.Template") - override val templateClasspath = listOf(compiledTemplateDir) + override val templateClasspath = listOfNotNull(environment["template-classes"] as? File) } + +class FromTextTemplateProvider( + override val environment: Map +) : ScriptTemplatesProvider { + override val id = "Test" + override val isValid = true + override val templateClassNames = listOf("org.jetbrains.kotlin.idea.script.Template") + override val templateClasspath get() = emptyList() +} + + +class FromTextDependenciesResolver : AsyncDependenciesResolver { + @Suppress("UNCHECKED_CAST") + suspend override fun resolveAsync(scriptContents: ScriptContents, environment: Environment): DependenciesResolver.ResolveResult { + return ScriptDependencies( + classpath = (environment["classpath"] as? List).orEmpty(), + imports = (environment["imports"] as? List).orEmpty(), + sources = (environment["sources"] as? List).orEmpty() + ).asSuccess() + } +} + +@Suppress("unused") +@ScriptTemplateDefinition(FromTextDependenciesResolver::class, scriptFilePattern = "script.kts") +class Template \ No newline at end of file