From 64bb47ed37fd52365853dcb2e62476bfcc30ec76 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Tue, 14 Jun 2016 19:00:12 +0200 Subject: [PATCH] Switch to File instead of String for classpaths in script dependencies --- .../cli/jvm/compiler/KotlinCoreEnvironment.kt | 3 +-- .../KotlinConfigurableScriptDefinition.kt | 8 +++---- .../kotlin/script/KotlinScriptDefinition.kt | 8 +++---- .../KotlinScriptExternalImportsProvider.kt | 5 ++-- .../scriptExternalDependenciesConfig.kt | 4 ++-- .../jetbrains/kotlin/script/scriptTemplate.kt | 2 +- .../kotlin/scripts/TestScriptDefinitions.kt | 24 +++++++++---------- .../jetbrains/kotlin/scripts/ScriptTest.kt | 7 +++--- .../jetbrains/kotlin/scripts/ScriptTest2.kt | 11 +++++---- .../idea/caches/resolve/IdeaModuleInfos.kt | 2 +- .../KotlinScriptConfigurationManager.kt | 8 +++---- .../script/gradleScriptTemplateProvider.kt | 2 +- 12 files changed, 43 insertions(+), 41 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index e6a8454bfc9..7135cc19fa2 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -152,8 +152,7 @@ class KotlinCoreEnvironment private constructor( KotlinScriptExternalImportsProvider.getInstance(project)?.run { configuration.addJvmClasspathRoots( getCombinedClasspathFor(sourceFiles) - .map { File(it).canonicalFile } - .distinct()) + .distinctBy { it.absolutePath }) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinConfigurableScriptDefinition.kt b/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinConfigurableScriptDefinition.kt index c58696abc2c..7ed6f6e53f4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinConfigurableScriptDefinition.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinConfigurableScriptDefinition.kt @@ -44,7 +44,7 @@ data class KotlinConfigurableScriptDefinition(val config: KotlinScriptConfig, va override fun getScriptName(script: KtScript): Name = ScriptNameUtil.fileNameWithExtensionStripped(script, KotlinParserDefinition.STD_SCRIPT_EXT) - private val evaluatedClasspath by lazy { config.classpath.evalWithVars(environmentVars).distinct() } + private val evaluatedClasspath by lazy { config.classpath.evalWithVars(environmentVars).map { File(it) }.distinctBy { it.canonicalPath } } override fun getDependenciesFor(file: TF, project: Project): KotlinScriptExternalDependencies? = if (!isScript(file)) null @@ -53,13 +53,13 @@ data class KotlinConfigurableScriptDefinition(val config: KotlinScriptConfig, va when { extDeps != null -> object : KotlinScriptExternalDependencies { - override val classpath = evaluatedClasspath + extDeps.classpath.evalWithVars(environmentVars).distinct() + override val classpath: Iterable = evaluatedClasspath + extDeps.classpath override val imports = extDeps.imports - override val sources = extDeps.sources.evalWithVars(environmentVars).distinct() + override val sources: Iterable = extDeps.sources } !evaluatedClasspath.isEmpty() -> object : KotlinScriptExternalDependencies { - override val classpath = evaluatedClasspath + override val classpath: Iterable = evaluatedClasspath } else -> null } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptDefinition.kt b/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptDefinition.kt index a309ce70bcb..d6f1ebe089a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptDefinition.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptDefinition.kt @@ -58,15 +58,15 @@ interface KotlinScriptDefinition { } interface KotlinScriptExternalDependencies { - val classpath: Iterable get() = emptyList() + val classpath: Iterable get() = emptyList() val imports: Iterable get() = emptyList() - val sources: Iterable get() = emptyList() + val sources: Iterable get() = emptyList() } class KotlinScriptExternalDependenciesUnion(val dependencies: Iterable) : KotlinScriptExternalDependencies { - override val classpath: Iterable get() = dependencies.flatMap { it.classpath } + override val classpath: Iterable get() = dependencies.flatMap { it.classpath } override val imports: Iterable get() = dependencies.flatMap { it.imports } - override val sources: Iterable get() = dependencies.flatMap { it.sources } + override val sources: Iterable get() = dependencies.flatMap { it.sources } } data class ScriptParameter(val name: Name, val type: KotlinType) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptExternalImportsProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptExternalImportsProvider.kt index 7bc8eea3dcb..587acb6bd33 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptExternalImportsProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/script/KotlinScriptExternalImportsProvider.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.script import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.project.Project +import java.io.File import java.util.concurrent.locks.ReentrantReadWriteLock import kotlin.concurrent.read import kotlin.concurrent.write @@ -90,11 +91,11 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri } } - fun getKnownCombinedClasspath(): List = cacheLock.read { + fun getKnownCombinedClasspath(): List = cacheLock.read { cache.values.flatMap { it.classpath } }.distinct() - fun getCombinedClasspathFor(files: Iterable): List = + fun getCombinedClasspathFor(files: Iterable): List = getExternalImports(files) .flatMap { it.classpath } .distinct() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/script/scriptExternalDependenciesConfig.kt b/compiler/frontend/src/org/jetbrains/kotlin/script/scriptExternalDependenciesConfig.kt index 59e5546586c..5985e6c10f8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/script/scriptExternalDependenciesConfig.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/script/scriptExternalDependenciesConfig.kt @@ -30,7 +30,7 @@ import java.util.* class KotlinScriptExternalDependenciesConfig : KotlinScriptExternalDependencies { @Tag("classpath") @AbstractCollection(surroundWithTag = false, elementTag = "path", elementValueAttribute = "") - override var classpath: MutableList = ArrayList() + override var classpath: Iterable = ArrayList() @Tag("imports") @AbstractCollection(surroundWithTag = false, elementTag = "name", elementValueAttribute = "") @@ -38,7 +38,7 @@ class KotlinScriptExternalDependenciesConfig : KotlinScriptExternalDependencies @Tag("sources") @AbstractCollection(surroundWithTag = false, elementTag = "path", elementValueAttribute = "") - override var sources: MutableList = ArrayList() + override var sources: Iterable = ArrayList() } fun loadScriptExternalImportConfigs(configFile: File): List = diff --git a/compiler/frontend/src/org/jetbrains/kotlin/script/scriptTemplate.kt b/compiler/frontend/src/org/jetbrains/kotlin/script/scriptTemplate.kt index cf3e1d94cc8..c27e2c544e2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/script/scriptTemplate.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/script/scriptTemplate.kt @@ -75,7 +75,7 @@ data class KotlinScriptDefinitionFromTemplate(val template: KClass, val is PsiFile -> getAnnotationEntriesFromPsiFile(file) is VirtualFile -> getAnnotationEntriesFromVirtualFile(file, project) is File -> { - val virtualFile = (StandardFileSystems.local().findFileByPath(file.absolutePath) + val virtualFile = (StandardFileSystems.local().findFileByPath(file.canonicalPath) ?: throw java.lang.IllegalArgumentException("Unable to find file ${file.canonicalPath}")) getAnnotationEntriesFromVirtualFile(virtualFile, project) } diff --git a/compiler/tests-common/org/jetbrains/kotlin/scripts/TestScriptDefinitions.kt b/compiler/tests-common/org/jetbrains/kotlin/scripts/TestScriptDefinitions.kt index 677311dcad1..1d131992b49 100644 --- a/compiler/tests-common/org/jetbrains/kotlin/scripts/TestScriptDefinitions.kt +++ b/compiler/tests-common/org/jetbrains/kotlin/scripts/TestScriptDefinitions.kt @@ -27,17 +27,17 @@ import java.net.URL import java.net.URLClassLoader import kotlin.reflect.KClass -abstract class BaseScriptDefinition (val extension: String, val cp: List? = null) : KotlinScriptDefinition { +abstract class BaseScriptDefinition (val extension: String, val cp: List? = null) : KotlinScriptDefinition { override val name = "Test Kotlin Script" override fun isScript(file: TF): Boolean = getFileName(file).endsWith(extension) override fun getScriptName(script: KtScript): Name = ScriptNameUtil.fileNameWithExtensionStripped(script, extension) override fun getDependenciesFor(file: TF, project: Project): KotlinScriptExternalDependencies? = object : KotlinScriptExternalDependencies { - override val classpath = cp ?: (classpathFromProperty() + classpathFromClassloader(BaseScriptDefinition::class.java.classLoader)).distinct() + override val classpath: Iterable = cp ?: (classpathFromProperty() + classpathFromClassloader(BaseScriptDefinition::class.java.classLoader)).distinct() } } -open class SimpleParamsWithClasspathTestScriptDefinition(extension: String, val parameters: List, classpath: List? = null, val extraDependencies: KotlinScriptExternalDependencies? = null) +open class SimpleParamsWithClasspathTestScriptDefinition(extension: String, val parameters: List, classpath: List? = null, val extraDependencies: KotlinScriptExternalDependencies? = null) : BaseScriptDefinition(extension, classpath) { override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) = parameters @@ -45,14 +45,14 @@ open class SimpleParamsWithClasspathTestScriptDefinition(extension: String, val open class SimpleParamsTestScriptDefinition(extension: String, parameters: List) : SimpleParamsWithClasspathTestScriptDefinition(extension, parameters) -class ReflectedParamClassTestScriptDefinition(extension: String, val paramName: String, val parameter: KClass, classpath: List? = null) +class ReflectedParamClassTestScriptDefinition(extension: String, val paramName: String, val parameter: KClass, classpath: List? = null) : BaseScriptDefinition(extension, classpath) { override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) = listOf(makeReflectedClassScriptParameter(scriptDescriptor, Name.identifier(paramName), parameter)) } -open class ReflectedSuperclassTestScriptDefinition(extension: String, parameters: List, val superclass: KClass, classpath: List? = null) +open class ReflectedSuperclassTestScriptDefinition(extension: String, parameters: List, val superclass: KClass, classpath: List? = null) : SimpleParamsWithClasspathTestScriptDefinition(extension, parameters, classpath) { override fun getScriptSupertypes(scriptDescriptor: ScriptDescriptor): List = @@ -63,14 +63,14 @@ class ReflectedSuperclassWithParamsTestScriptDefinition(extension: String, parameters: List, superclass: KClass, val superclassParameters: List, - classpath: List? = null) + classpath: List? = null) : ReflectedSuperclassTestScriptDefinition(extension, parameters, superclass, classpath) { override fun getScriptParametersToPassToSuperclass(scriptDescriptor: ScriptDescriptor): List = superclassParameters.map { it.name } } -class StandardWithClasspathScriptDefinition(extension: String, classpath: List? = null) +class StandardWithClasspathScriptDefinition(extension: String, classpath: List? = null) : BaseScriptDefinition(extension, classpath) { override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) = @@ -78,14 +78,14 @@ class StandardWithClasspathScriptDefinition(extension: String, classpath: List, + override val classpath: Iterable, override val imports: List = emptyList() ) : KotlinScriptExternalDependencies -fun classpathFromProperty(): List = +fun classpathFromProperty(): List = System.getProperty("java.class.path")?.let { it.split(String.format("\\%s", File.pathSeparatorChar).toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() - .map { File(it).canonicalPath } + .map { File(it) } } ?: emptyList() fun URL.toFile() = @@ -97,8 +97,8 @@ fun URL.toFile() = else File(file) } -fun classpathFromClassloader(classLoader: ClassLoader): List = +fun classpathFromClassloader(classLoader: ClassLoader): List = (classLoader as? URLClassLoader)?.urLs - ?.mapNotNull { it.toFile()?.canonicalPath } + ?.mapNotNull { it.toFile() } ?: emptyList() diff --git a/compiler/tests/org/jetbrains/kotlin/scripts/ScriptTest.kt b/compiler/tests/org/jetbrains/kotlin/scripts/ScriptTest.kt index a46794d445a..adb35fa87c7 100644 --- a/compiler/tests/org/jetbrains/kotlin/scripts/ScriptTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/scripts/ScriptTest.kt @@ -119,7 +119,7 @@ class ScriptTest { val aClass1 = compileScript("fib_ext.kts", SimpleParamsWithClasspathTestScriptDefinition(".kts", numIntParam(), classpath = emptyList()), runIsolated = true, suppressOutput = true) Assert.assertNull(aClass1) - val cp = classpathFromClassloader(ScriptTest::class.java.classLoader).filter { it.contains("kotlin-runtime") || it.contains("junit") } + val cp = classpathFromClassloader(ScriptTest::class.java.classLoader).filter { it.name.contains("kotlin-runtime") || it.name.contains("junit") } Assert.assertFalse(cp.isEmpty()) val aClass2 = compileScript("fib_ext.kts", SimpleParamsWithClasspathTestScriptDefinition(".kts", numIntParam(), classpath = cp), runIsolated = true) @@ -131,7 +131,7 @@ class ScriptTest { val aClass1 = compileScript("fib_ext.kts", SimpleParamsWithClasspathTestScriptDefinition(".kts", numIntParam(), classpath = emptyList()), runIsolated = true, suppressOutput = true) Assert.assertNull(aClass1) - val cp = classpathFromClassloader(ScriptTest::class.java.classLoader).filter { it.contains("kotlin-runtime") || it.contains("junit") } + val cp = classpathFromClassloader(ScriptTest::class.java.classLoader).filter { it.name.contains("kotlin-runtime") || it.name.contains("junit") } Assert.assertFalse(cp.isEmpty()) val aClass2 = compileScript("fib_ext.kts", SimpleParamsWithClasspathTestScriptDefinition(".kts", numIntParam(), classpath = cp, extraDependencies = SimpleScriptExtraDependencies(cp)), runIsolated = true) @@ -145,7 +145,8 @@ class ScriptTest { StandardWithClasspathScriptDefinition( ".kts", listOf("dependencies/bootstrap-compiler/Kotlin/kotlinc/lib/kotlin-runtime.jar", - "dependencies/bootstrap-compiler/Kotlin/kotlinc/lib/kotlin-reflect.jar"))) + "dependencies/bootstrap-compiler/Kotlin/kotlinc/lib/kotlin-reflect.jar") + .map { File(it) })) Assert.assertNotNull(aClass) var exceptionThrown = false try { diff --git a/compiler/tests/org/jetbrains/kotlin/scripts/ScriptTest2.kt b/compiler/tests/org/jetbrains/kotlin/scripts/ScriptTest2.kt index a9c5e265a22..b727162c209 100644 --- a/compiler/tests/org/jetbrains/kotlin/scripts/ScriptTest2.kt +++ b/compiler/tests/org/jetbrains/kotlin/scripts/ScriptTest2.kt @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.test.TestJdkKind import org.jetbrains.kotlin.utils.PathUtil import org.junit.Assert import org.junit.Test +import java.io.File import java.net.URLClassLoader import kotlin.reflect.KClass @@ -123,20 +124,20 @@ class GetTestKotlinScriptDependencies : GetScriptDependencies { val cp = anns.flatMap { it.value.mapNotNull { when (it) { - is SimpleUntypedAst.Node.str -> if (it.value == "@{runtime}") kotlinPaths.runtimePath.canonicalPath else it.value + is SimpleUntypedAst.Node.str -> if (it.value == "@{runtime}") kotlinPaths.runtimePath else File(it.value) else -> null } } } return object : KotlinScriptExternalDependencies { - override val classpath = classpathFromClassloader() + cp + override val classpath: Iterable = classpathFromClassloader() + cp } } - private fun classpathFromClassloader(): List = + private fun classpathFromClassloader(): List = (GetTestKotlinScriptDependencies::class.java.classLoader as? URLClassLoader)?.urLs - ?.mapNotNull { it.toFile()?.canonicalPath } - ?.filter { it.contains("out/test") } + ?.mapNotNull { it.toFile() } + ?.filter { it.path.contains("out") && it.path.contains("test") } ?: emptyList() } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaModuleInfos.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaModuleInfos.kt index ac1dbe6566a..8cab812c7f7 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaModuleInfos.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaModuleInfos.kt @@ -310,7 +310,7 @@ internal data class ScriptModuleInfo(val project: Project, val module: Module?, // TODO: find out whether it should be cashed (some changes listener should be implemented for the cached roots) val jarfs = StandardFileSystems.jar() return scriptDefinition.getDependenciesFor(scriptFile, project)?.classpath - ?.map { File(it).canonicalFile } + ?.map { it.canonicalFile } ?.distinct() ?.mapNotNull { // TODO: ensure that the entries are checked elsewhere, so diagnostics is delivered to a user if files are not correctly specified diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptConfigurationManager.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptConfigurationManager.kt index ad4868fdf26..429048b2c1d 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptConfigurationManager.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/KotlinScriptConfigurationManager.kt @@ -69,11 +69,11 @@ class KotlinScriptConfigurationManager( return allScriptsClasspathCache!! } - private fun String.classpathEntryToVfs(): VirtualFile = - if (File(this).isDirectory) - StandardFileSystems.local()?.findFileByPath(this) ?: throw FileNotFoundException("Classpath entry points to a non-existent location: ${this}") + private fun File.classpathEntryToVfs(): VirtualFile = + if (isDirectory) + StandardFileSystems.local()?.findFileByPath(this.canonicalPath) ?: throw FileNotFoundException("Classpath entry points to a non-existent location: ${this}") else - StandardFileSystems.jar()?.findFileByPath(this + URLUtil.JAR_SEPARATOR) ?: throw FileNotFoundException("Classpath entry points to a file that is not a JAR archive: ${this}") + StandardFileSystems.jar()?.findFileByPath(this.canonicalPath + URLUtil.JAR_SEPARATOR) ?: throw FileNotFoundException("Classpath entry points to a file that is not a JAR archive: ${this}") fun getAllScriptsClasspathScope(): GlobalSearchScope? { return getAllScriptsClasspath().let { cp -> diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/gradleScriptTemplateProvider.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/gradleScriptTemplateProvider.kt index e99765bace9..247234ce4f5 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/gradleScriptTemplateProvider.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/gradleScriptTemplateProvider.kt @@ -33,7 +33,7 @@ class GradleScriptTemplateProvider(project: Project, gim: GradleInstallationMana override val templateClass: String = "org.gradle.script.lang.kotlin.KotlinBuildScript" override val dependenciesClasspath: Iterable = gradleLibsPath?.listFiles { file -> file.extension == "jar" && depLibsPrefixes.any { file.name.startsWith(it) } } - ?.map { it.absolutePath } + ?.map { it.canonicalPath } ?: emptyList() override val context: Any? = gradleHome