Implement script dependencies resolution directly from classloader

#KT-27956 fixed
This commit is contained in:
Ilya Chernikov
2019-09-11 14:16:25 +02:00
parent f8db150a2b
commit 61d517fb31
9 changed files with 199 additions and 30 deletions
@@ -12,6 +12,7 @@ dependencies {
compileOnly(project(":compiler:psi"))
compileOnly(project(":compiler:plugin-api"))
compileOnly(project(":compiler:cli"))
compileOnly(project(":core:descriptors.runtime"))
compile(project(":kotlin-scripting-common"))
compile(project(":kotlin-scripting-jvm"))
compile(project(":kotlin-scripting-compiler-impl"))
@@ -0,0 +1,61 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.scripting.compiler.plugin.impl
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.NotFoundClasses
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.runtime.components.*
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.load.java.lazy.SingleModuleClassResolver
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.load.kotlin.*
import kotlin.script.experimental.api.ScriptCompilationConfiguration
import kotlin.script.experimental.jvm.ClassLoaderByConfiguration
class PackageFragmentFromClassLoaderProviderExtension(
val classLoaderGetter: ClassLoaderByConfiguration,
val scriptCompilationConfiguration: ScriptCompilationConfiguration
) : PackageFragmentProviderExtension {
override fun getPackageFragmentProvider(
project: Project,
module: ModuleDescriptor,
storageManager: StorageManager,
trace: BindingTrace,
moduleInfo: ModuleInfo?,
lookupTracker: LookupTracker
): PackageFragmentProvider? {
val classLoader = classLoaderGetter(scriptCompilationConfiguration)
val reflectKotlinClassFinder = ReflectKotlinClassFinder(classLoader)
val deserializedDescriptorResolver = DeserializedDescriptorResolver()
val singleModuleClassResolver = SingleModuleClassResolver()
val notFoundClasses = NotFoundClasses(storageManager, module)
val lazyJavaPackageFragmentProvider =
makeLazyJavaPackageFragmentFromClassLoaderProvider(
classLoader, module, storageManager, notFoundClasses,
reflectKotlinClassFinder, deserializedDescriptorResolver, singleModuleClassResolver
)
val deserializationComponentsForJava =
makeDeserializationComponentsForJava(
module, storageManager, notFoundClasses, lazyJavaPackageFragmentProvider,
reflectKotlinClassFinder, deserializedDescriptorResolver
)
deserializedDescriptorResolver.setComponents(deserializationComponentsForJava)
return lazyJavaPackageFragmentProvider
}
}
@@ -18,12 +18,14 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension
import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptJvmCompilerProxy
import org.jetbrains.kotlin.scripting.compiler.plugin.dependencies.ScriptsCompilationDependencies
import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider
import kotlin.script.experimental.api.*
import kotlin.script.experimental.host.ScriptingHostConfiguration
import kotlin.script.experimental.jvm.JvmDependency
import kotlin.script.experimental.jvm.JvmDependencyFromClassLoader
import kotlin.script.experimental.jvm.compilationCache
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
import kotlin.script.experimental.jvm.jvm
@@ -138,6 +140,16 @@ private fun doCompile(
messageCollector: ScriptDiagnosticsMessageCollector,
getScriptConfiguration: (KtFile) -> ScriptCompilationConfiguration
): ResultWithDiagnostics<KJvmCompiledScript<Any>> {
context.baseScriptCompilationConfiguration[ScriptCompilationConfiguration.dependencies]?.forEach { dependency ->
if (dependency is JvmDependencyFromClassLoader) {
PackageFragmentProviderExtension.registerExtension(
context.environment.project,
PackageFragmentFromClassLoaderProviderExtension(dependency.classLoaderGetter, context.baseScriptCompilationConfiguration)
)
}
}
val analysisResult = analyze(sourceFiles, context.environment)
if (!analysisResult.shouldGenerateCode) return failure(
@@ -185,7 +185,7 @@ private fun createInitialCompilerConfiguration(
scriptCompilationConfiguration[ScriptCompilationConfiguration.dependencies]?.let { dependencies ->
addJvmClasspathRoots(
dependencies.flatMap {
(it as JvmDependency).classpath
(it as? JvmDependency)?.classpath ?: emptyList()
}
)
}