diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptDependenciesClassFinder.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptDependenciesClassFinder.kt index fd2544e1546..2c5f3debb3a 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptDependenciesClassFinder.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptDependenciesClassFinder.kt @@ -24,12 +24,6 @@ class KotlinScriptDependenciesClassFinder( .getAllScriptsDependenciesClassFiles().filter { it.isValid }.toList() override fun findClass(qualifiedName: String, scope: GlobalSearchScope): PsiClass? { - val scriptDependencies = - ScriptConfigurationManager.getInstance(project).getAllScriptsDependenciesClassFiles() - val firstJarInDependencies = scriptDependencies.firstOrNull() ?: return null - - if (!scope.contains(firstJarInDependencies)) return null - val classByFileName = super.findClass(qualifiedName, scope) if (classByFileName != null) { return classByFileName.isInScope(scope) diff --git a/idea/testData/script/definition/highlighting/multipleScripts/lib/Some.java b/idea/testData/script/definition/highlighting/multipleScripts/lib/Some.java new file mode 100644 index 00000000000..24152b5387d --- /dev/null +++ b/idea/testData/script/definition/highlighting/multipleScripts/lib/Some.java @@ -0,0 +1,5 @@ +package custom.project; + +public class Some { + // some class for library +} \ No newline at end of file diff --git a/idea/testData/script/definition/highlighting/multipleScripts/mainModule/info.txt b/idea/testData/script/definition/highlighting/multipleScripts/mainModule/info.txt new file mode 100644 index 00000000000..f443533b0f5 --- /dev/null +++ b/idea/testData/script/definition/highlighting/multipleScripts/mainModule/info.txt @@ -0,0 +1,3 @@ +This module is needed to have some module in tested project. +This will lead to absence of sdk roots in ScriptConfigurationManager.allScriptClassRoots, +because they are indexed by IDEA as module SDK roots \ No newline at end of file diff --git a/idea/testData/script/definition/highlighting/multipleScripts/script.kts b/idea/testData/script/definition/highlighting/multipleScripts/script.kts new file mode 100644 index 00000000000..d73ffe40b3b --- /dev/null +++ b/idea/testData/script/definition/highlighting/multipleScripts/script.kts @@ -0,0 +1,3 @@ +plugins() + +// TEMPLATES: template-classes-names:custom.scriptDefinition.TemplateForFirstLoadedScript,custom.scriptDefinition.TemplateForMainScript \ No newline at end of file diff --git a/idea/testData/script/definition/highlighting/multipleScripts/scriptFirstLoaded.mykts b/idea/testData/script/definition/highlighting/multipleScripts/scriptFirstLoaded.mykts new file mode 100644 index 00000000000..c0ae962f04e --- /dev/null +++ b/idea/testData/script/definition/highlighting/multipleScripts/scriptFirstLoaded.mykts @@ -0,0 +1 @@ +plugins() \ No newline at end of file diff --git a/idea/testData/script/definition/highlighting/multipleScripts/template/Project.java b/idea/testData/script/definition/highlighting/multipleScripts/template/Project.java new file mode 100644 index 00000000000..7f58124254a --- /dev/null +++ b/idea/testData/script/definition/highlighting/multipleScripts/template/Project.java @@ -0,0 +1,7 @@ +package custom.project; + +public class Project { + public void plugins() { + + } +} \ No newline at end of file diff --git a/idea/testData/script/definition/highlighting/multipleScripts/template/template.kt b/idea/testData/script/definition/highlighting/multipleScripts/template/template.kt new file mode 100644 index 00000000000..0a1eebe874f --- /dev/null +++ b/idea/testData/script/definition/highlighting/multipleScripts/template/template.kt @@ -0,0 +1,74 @@ +package custom.scriptDefinition + +import java.io.File +import kotlin.script.experimental.annotations.KotlinScript +import kotlin.script.experimental.api.* +import kotlin.script.experimental.host.ScriptingHostConfiguration +import kotlin.script.experimental.host.ScriptingHostConfigurationKeys +import kotlin.script.experimental.jvm.JvmDependency +import kotlin.script.experimental.jvm.dependenciesFromClassContext +import kotlin.script.experimental.jvm.jdkHome +import kotlin.script.experimental.jvm.jvm +import kotlin.script.experimental.util.PropertiesCollection + +val ScriptingHostConfigurationKeys.getEnvironment by PropertiesCollection.key<() -> Map?>() + +@KotlinScript( + displayName = "Definition for scriptFirstLoaded.mykts", + fileExtension = "mykts", + compilationConfiguration = DefinitionForFirstLoadedScript::class +) +open class TemplateForFirstLoadedScript(val args: Array) + +@Suppress("UNCHECKED_CAST") +object DefinitionForFirstLoadedScript : ScriptCompilationConfiguration( + { + ide { + acceptedLocations(ScriptAcceptedLocation.Everywhere) + } + refineConfiguration { + beforeCompiling { context -> + val environment = context.compilationConfiguration[ScriptCompilationConfiguration.hostConfiguration]?.let { + it[ScriptingHostConfiguration.getEnvironment]?.invoke() + }.orEmpty() + + // lib-classes as script dependencies: they will be the first in allScriptDependenciesClassFiles + context.compilationConfiguration.with { + dependencies(JvmDependency(environment["lib-classes"] as File)) + }.asSuccess() + } + } + } +) + +@KotlinScript( + displayName = "Definition for main script", + fileExtension = "kts", + compilationConfiguration = DefinitionForMainScript::class +) +open class TemplateForMainScript(val args: Array) + +@Suppress("UNCHECKED_CAST") +object DefinitionForMainScript : ScriptCompilationConfiguration( + { + baseClass(custom.project.Project::class) + ide { + acceptedLocations(ScriptAcceptedLocation.Everywhere) + } + refineConfiguration { + beforeCompiling { context -> + val environment = context.compilationConfiguration[ScriptCompilationConfiguration.hostConfiguration]?.let { + it[ScriptingHostConfiguration.getEnvironment]?.invoke() + }.orEmpty() + + // template-classes as script dependencies: they will be the second in allScriptDependenciesClassFiles + context.compilationConfiguration.with { + dependencies(JvmDependency(environment["template-classes"] as File)) + + implicitReceivers(custom.project.Project::class) + }.asSuccess() + } + } + } +) + diff --git a/idea/tests/org/jetbrains/kotlin/idea/script/AbstractScriptConfigurationTest.kt b/idea/tests/org/jetbrains/kotlin/idea/script/AbstractScriptConfigurationTest.kt index c016e5e0d31..38268c8b98e 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/script/AbstractScriptConfigurationTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/script/AbstractScriptConfigurationTest.kt @@ -114,13 +114,23 @@ abstract class AbstractScriptConfigurationTest : KotlinCompletionTestCase() { myModule = createTestModuleFromDir(it) } - File(path).listFiles { file -> file.name.startsWith("module") }.filter { it.exists() }.forEach { - val newModule = createTestModuleFromDir(it) - assert(myModule != null) { "Main module should exists" } - ModuleRootModificationUtil.addDependency(myModule, newModule) + File(path) + .listFiles { file -> file.name.startsWith("module") } + ?.filter { it.exists() } + ?.forEach { + val newModule = createTestModuleFromDir(it) + assert(myModule != null) { "Main module should exists" } + ModuleRootModificationUtil.addDependency(myModule, newModule) + } + + File(path).listFiles { file -> + file.name.startsWith("script") && file.name != SCRIPT_NAME + }?.forEach { + createFileAndSyncDependencies(it) } - if (module != null) { + // If script is inside module + if (module != null && mainScriptFile.parentFile.name.toLowerCase().contains("module")) { module.addDependency( projectLibrary( "script-runtime", @@ -337,18 +347,18 @@ abstract class AbstractScriptConfigurationTest : KotlinCompletionTestCase() { //TODO: tmpDir would be enough, but there is tricky fail under AS otherwise val outDir = KotlinTestUtils.tmpDirForReusableFolder("${getTestName(false)}${srcDir.name}Out") - val kotlinSourceFiles = FileUtil.findFilesByMask(Pattern.compile(".+\\.kt$"), srcDir) - if (kotlinSourceFiles.isNotEmpty()) { - MockLibraryUtil.compileKotlin(srcDir.path, outDir, extraClasspath = *classpath) - } - val javaSourceFiles = FileUtil.findFilesByMask(Pattern.compile(".+\\.java$"), srcDir) if (javaSourceFiles.isNotEmpty()) { KotlinTestUtils.compileJavaFiles( javaSourceFiles, - listOf("-cp", StringUtil.join(listOf(*classpath, outDir), File.pathSeparator), "-d", outDir.path) + listOf("-cp", StringUtil.join(listOf(*classpath), File.pathSeparator), "-d", outDir.path) ) } + val kotlinSourceFiles = FileUtil.findFilesByMask(Pattern.compile(".+\\.kt$"), srcDir) + if (kotlinSourceFiles.isNotEmpty()) { + MockLibraryUtil.compileKotlin(srcDir.path, outDir, extraClasspath = *arrayOf(*classpath, outDir.path)) + } + return outDir } diff --git a/idea/tests/org/jetbrains/kotlin/idea/script/AbstractScriptConfigurationTest.kt.203 b/idea/tests/org/jetbrains/kotlin/idea/script/AbstractScriptConfigurationTest.kt.203 index c57049f3ed2..910649bcf3a 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/script/AbstractScriptConfigurationTest.kt.203 +++ b/idea/tests/org/jetbrains/kotlin/idea/script/AbstractScriptConfigurationTest.kt.203 @@ -114,13 +114,23 @@ abstract class AbstractScriptConfigurationTest : KotlinCompletionTestCase() { myModule = createTestModuleFromDir(it) } - File(path).listFiles { file -> file.name.startsWith("module") }.filter { it.exists() }.forEach { - val newModule = createTestModuleFromDir(it) - assert(myModule != null) { "Main module should exists" } - ModuleRootModificationUtil.addDependency(myModule, newModule) + File(path) + .listFiles { file -> file.name.startsWith("module") } + ?.filter { it.exists() } + ?.forEach { + val newModule = createTestModuleFromDir(it) + assert(myModule != null) { "Main module should exists" } + ModuleRootModificationUtil.addDependency(myModule, newModule) + } + + File(path).listFiles { file -> + file.name.startsWith("script") && file.name != SCRIPT_NAME + }?.forEach { + createFileAndSyncDependencies(it) } - if (module != null) { + // If script is inside module + if (module != null && mainScriptFile.parentFile.name.toLowerCase().contains("module")) { module.addDependency( projectLibrary( "script-runtime", @@ -337,18 +347,18 @@ abstract class AbstractScriptConfigurationTest : KotlinCompletionTestCase() { //TODO: tmpDir would be enough, but there is tricky fail under AS otherwise val outDir = KotlinTestUtils.tmpDirForReusableFolder("${getTestName(false)}${srcDir.name}Out") - val kotlinSourceFiles = FileUtil.findFilesByMask(Pattern.compile(".+\\.kt$"), srcDir) - if (kotlinSourceFiles.isNotEmpty()) { - MockLibraryUtil.compileKotlin(srcDir.path, outDir, extraClasspath = *classpath) - } - val javaSourceFiles = FileUtil.findFilesByMask(Pattern.compile(".+\\.java$"), srcDir) if (javaSourceFiles.isNotEmpty()) { KotlinTestUtils.compileJavaFiles( javaSourceFiles, - listOf("-cp", StringUtil.join(listOf(*classpath, outDir), File.pathSeparator), "-d", outDir.path) + listOf("-cp", StringUtil.join(listOf(*classpath), File.pathSeparator), "-d", outDir.path) ) } + val kotlinSourceFiles = FileUtil.findFilesByMask(Pattern.compile(".+\\.kt$"), srcDir) + if (kotlinSourceFiles.isNotEmpty()) { + MockLibraryUtil.compileKotlin(srcDir.path, outDir, extraClasspath = *arrayOf(*classpath, outDir.path)) + } + return outDir } diff --git a/idea/tests/org/jetbrains/kotlin/idea/script/ScriptConfigurationHighlightingTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/script/ScriptConfigurationHighlightingTestGenerated.java index 47b89595b05..2953e4c5bdd 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/script/ScriptConfigurationHighlightingTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/script/ScriptConfigurationHighlightingTestGenerated.java @@ -105,6 +105,11 @@ public class ScriptConfigurationHighlightingTestGenerated extends AbstractScript runTest("idea/testData/script/definition/highlighting/multiModule/"); } + @TestMetadata("multipleScripts") + public void testMultipleScripts() throws Exception { + runTest("idea/testData/script/definition/highlighting/multipleScripts/"); + } + @TestMetadata("nestedClass") public void testNestedClass() throws Exception { runTest("idea/testData/script/definition/highlighting/nestedClass/");