Switch to File instead of String for classpaths in script dependencies

This commit is contained in:
Ilya Chernikov
2016-06-14 19:00:12 +02:00
committed by Pavel V. Talanov
parent 5e3ba36cc1
commit 64bb47ed37
12 changed files with 43 additions and 41 deletions
@@ -152,8 +152,7 @@ class KotlinCoreEnvironment private constructor(
KotlinScriptExternalImportsProvider.getInstance(project)?.run {
configuration.addJvmClasspathRoots(
getCombinedClasspathFor(sourceFiles)
.map { File(it).canonicalFile }
.distinct())
.distinctBy { it.absolutePath })
}
}
@@ -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 <TF> 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<File> = evaluatedClasspath + extDeps.classpath
override val imports = extDeps.imports
override val sources = extDeps.sources.evalWithVars(environmentVars).distinct()
override val sources: Iterable<File> = extDeps.sources
}
!evaluatedClasspath.isEmpty() ->
object : KotlinScriptExternalDependencies {
override val classpath = evaluatedClasspath
override val classpath: Iterable<File> = evaluatedClasspath
}
else -> null
}
@@ -58,15 +58,15 @@ interface KotlinScriptDefinition {
}
interface KotlinScriptExternalDependencies {
val classpath: Iterable<String> get() = emptyList()
val classpath: Iterable<File> get() = emptyList()
val imports: Iterable<String> get() = emptyList()
val sources: Iterable<String> get() = emptyList()
val sources: Iterable<File> get() = emptyList()
}
class KotlinScriptExternalDependenciesUnion(val dependencies: Iterable<KotlinScriptExternalDependencies>) : KotlinScriptExternalDependencies {
override val classpath: Iterable<String> get() = dependencies.flatMap { it.classpath }
override val classpath: Iterable<File> get() = dependencies.flatMap { it.classpath }
override val imports: Iterable<String> get() = dependencies.flatMap { it.imports }
override val sources: Iterable<String> get() = dependencies.flatMap { it.sources }
override val sources: Iterable<File> get() = dependencies.flatMap { it.sources }
}
data class ScriptParameter(val name: Name, val type: KotlinType)
@@ -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<String> = cacheLock.read {
fun getKnownCombinedClasspath(): List<File> = cacheLock.read {
cache.values.flatMap { it.classpath }
}.distinct()
fun <TF> getCombinedClasspathFor(files: Iterable<TF>): List<String> =
fun <TF> getCombinedClasspathFor(files: Iterable<TF>): List<File> =
getExternalImports(files)
.flatMap { it.classpath }
.distinct()
@@ -30,7 +30,7 @@ import java.util.*
class KotlinScriptExternalDependenciesConfig : KotlinScriptExternalDependencies {
@Tag("classpath")
@AbstractCollection(surroundWithTag = false, elementTag = "path", elementValueAttribute = "")
override var classpath: MutableList<String> = ArrayList()
override var classpath: Iterable<File> = 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<String> = ArrayList()
override var sources: Iterable<File> = ArrayList()
}
fun loadScriptExternalImportConfigs(configFile: File): List<KotlinScriptExternalDependenciesConfig> =
@@ -75,7 +75,7 @@ data class KotlinScriptDefinitionFromTemplate(val template: KClass<out Any>, 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)
}
@@ -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<String>? = null) : KotlinScriptDefinition {
abstract class BaseScriptDefinition (val extension: String, val cp: List<File>? = null) : KotlinScriptDefinition {
override val name = "Test Kotlin Script"
override fun <TF> isScript(file: TF): Boolean = getFileName(file).endsWith(extension)
override fun getScriptName(script: KtScript): Name = ScriptNameUtil.fileNameWithExtensionStripped(script, extension)
override fun <TF> getDependenciesFor(file: TF, project: Project): KotlinScriptExternalDependencies? =
object : KotlinScriptExternalDependencies {
override val classpath = cp ?: (classpathFromProperty() + classpathFromClassloader(BaseScriptDefinition::class.java.classLoader)).distinct()
override val classpath: Iterable<File> = cp ?: (classpathFromProperty() + classpathFromClassloader(BaseScriptDefinition::class.java.classLoader)).distinct()
}
}
open class SimpleParamsWithClasspathTestScriptDefinition(extension: String, val parameters: List<ScriptParameter>, classpath: List<String>? = null, val extraDependencies: KotlinScriptExternalDependencies? = null)
open class SimpleParamsWithClasspathTestScriptDefinition(extension: String, val parameters: List<ScriptParameter>, classpath: List<File>? = 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<ScriptParameter>) : SimpleParamsWithClasspathTestScriptDefinition(extension, parameters)
class ReflectedParamClassTestScriptDefinition(extension: String, val paramName: String, val parameter: KClass<out Any>, classpath: List<String>? = null)
class ReflectedParamClassTestScriptDefinition(extension: String, val paramName: String, val parameter: KClass<out Any>, classpath: List<File>? = null)
: BaseScriptDefinition(extension, classpath)
{
override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) =
listOf(makeReflectedClassScriptParameter(scriptDescriptor, Name.identifier(paramName), parameter))
}
open class ReflectedSuperclassTestScriptDefinition(extension: String, parameters: List<ScriptParameter>, val superclass: KClass<out Any>, classpath: List<String>? = null)
open class ReflectedSuperclassTestScriptDefinition(extension: String, parameters: List<ScriptParameter>, val superclass: KClass<out Any>, classpath: List<File>? = null)
: SimpleParamsWithClasspathTestScriptDefinition(extension, parameters, classpath)
{
override fun getScriptSupertypes(scriptDescriptor: ScriptDescriptor): List<KotlinType> =
@@ -63,14 +63,14 @@ class ReflectedSuperclassWithParamsTestScriptDefinition(extension: String,
parameters: List<ScriptParameter>,
superclass: KClass<out Any>,
val superclassParameters: List<ScriptParameter>,
classpath: List<String>? = null)
classpath: List<File>? = null)
: ReflectedSuperclassTestScriptDefinition(extension, parameters, superclass, classpath)
{
override fun getScriptParametersToPassToSuperclass(scriptDescriptor: ScriptDescriptor): List<Name> =
superclassParameters.map { it.name }
}
class StandardWithClasspathScriptDefinition(extension: String, classpath: List<String>? = null)
class StandardWithClasspathScriptDefinition(extension: String, classpath: List<File>? = null)
: BaseScriptDefinition(extension, classpath)
{
override fun getScriptParameters(scriptDescriptor: ScriptDescriptor) =
@@ -78,14 +78,14 @@ class StandardWithClasspathScriptDefinition(extension: String, classpath: List<S
}
class SimpleScriptExtraDependencies(
override val classpath: List<String>,
override val classpath: Iterable<File>,
override val imports: List<String> = emptyList()
) : KotlinScriptExternalDependencies
fun classpathFromProperty(): List<String> =
fun classpathFromProperty(): List<File> =
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<String> =
fun classpathFromClassloader(classLoader: ClassLoader): List<File> =
(classLoader as? URLClassLoader)?.urLs
?.mapNotNull { it.toFile()?.canonicalPath }
?.mapNotNull { it.toFile() }
?: emptyList()
@@ -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 {
@@ -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<File> = classpathFromClassloader() + cp
}
}
private fun classpathFromClassloader(): List<String> =
private fun classpathFromClassloader(): List<File> =
(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()
}
@@ -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
@@ -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 ->
@@ -33,7 +33,7 @@ class GradleScriptTemplateProvider(project: Project, gim: GradleInstallationMana
override val templateClass: String = "org.gradle.script.lang.kotlin.KotlinBuildScript"
override val dependenciesClasspath: Iterable<String> =
gradleLibsPath?.listFiles { file -> file.extension == "jar" && depLibsPrefixes.any { file.name.startsWith(it) } }
?.map { it.absolutePath }
?.map { it.canonicalPath }
?: emptyList()
override val context: Any? = gradleHome