diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt index 6f560518646..fa6d51b1fa2 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt @@ -44,7 +44,7 @@ class JsIrBackendContext( val symbolTable: SymbolTable, irModuleFragment: IrModuleFragment, val additionalExportedDeclarations: Set, - override val configuration: CompilerConfiguration, + override val configuration: CompilerConfiguration, // TODO: remove configuration from backend context override val scriptMode: Boolean = false ) : CommonBackendContext { override val transformedFunction = mutableMapOf() diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt index 629ae7a824b..db66ac4c608 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt @@ -86,7 +86,7 @@ fun compile( return transformer.generateModule(moduleFragment) } -fun compileForRepl( +fun generateJsCode( context: JsIrBackendContext, moduleFragment: IrModuleFragment, nameTables: NameTables diff --git a/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/AbstractJsReplTest.kt b/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/AbstractJsReplTest.kt index bced0deb78e..68fb92e58a2 100644 --- a/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/AbstractJsReplTest.kt +++ b/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/AbstractJsReplTest.kt @@ -21,8 +21,7 @@ import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigura import org.jetbrains.kotlin.scripting.configuration.ScriptingConfigurationKeys import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition import org.jetbrains.kotlin.scripting.definitions.platform -import org.jetbrains.kotlin.scripting.repl.js.JsReplEvaluator -import org.jetbrains.kotlin.scripting.repl.js.ReplMessageCollector +import org.jetbrains.kotlin.scripting.repl.js.* import java.io.Closeable import kotlin.script.experimental.api.ScriptCompilationConfiguration import kotlin.script.experimental.api.baseClass @@ -31,22 +30,24 @@ import kotlin.script.experimental.host.ScriptingHostConfiguration import kotlin.script.experimental.jvm.JsDependency abstract class AbstractJsReplTest : Closeable { - abstract fun createCompiler(): ReplCompiler - abstract fun preprocessEvaluation() + protected lateinit var compilationState: JsReplCompilationState + protected lateinit var evaluationState: JsEvaluationState + + protected abstract fun createCompilationState(): JsReplCompilationState + protected abstract fun createEvaluationState(): JsEvaluationState fun compile(codeLine: ReplCodeLine): ReplCompileResult { - return compiler.compile(compiler.createState(), codeLine) + return JsReplCompiler(environment).compile(compilationState, codeLine) } fun evaluate(compileResult: ReplCompileResult.CompiledClasses): ReplEvalResult { - return jsEvaluator.eval(jsEvaluator.createState(), compileResult) + return JsReplEvaluator().eval(evaluationState, compileResult) } fun reset() { collector.clear() - compiler = createCompiler() - jsEvaluator = JsReplEvaluator() - preprocessEvaluation() + compilationState = createCompilationState() + evaluationState = createEvaluationState() } private val collector: MessageCollector = ReplMessageCollector() @@ -55,9 +56,6 @@ abstract class AbstractJsReplTest : Closeable { disposable, loadConfiguration(), EnvironmentConfigFiles.JS_CONFIG_FILES ) - lateinit var compiler: ReplCompiler - lateinit var jsEvaluator: JsReplEvaluator - private var snippetId: Int = 1 //index 0 for klib fun newSnippetId(): Int = snippetId++ diff --git a/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/JsReplTestAgainstBinaries.kt b/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/JsReplTestAgainstBinaries.kt index ed562e45de5..a32158a0b6c 100644 --- a/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/JsReplTestAgainstBinaries.kt +++ b/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/JsReplTestAgainstBinaries.kt @@ -5,37 +5,38 @@ package org.jetbrains.kotlin.scripting.repl.js.test -import org.jetbrains.kotlin.cli.common.repl.ReplCompiler import org.jetbrains.kotlin.ir.backend.js.utils.NameTables +import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.js.engine.ScriptEngineNashorn +import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplCodeAnalyzer import org.jetbrains.kotlin.scripting.repl.js.* +import java.util.concurrent.locks.ReentrantReadWriteLock +// 1. Compile dependencies +// 2. Save them as a binary dependency (name table and js string) +// 3. For each new state load dependency's table and js code class JsReplTestAgainstBinaries : AbstractJsReplTest() { private val dependencyLoader = DependencyLoader() - - private val runtimeBinary: String - private val nameTable: NameTables + private val dependencies = readLibrariesFromConfiguration(environment.configuration) init { - val dependencies = readLibrariesFromConfiguration(environment.configuration) - val compiler = ScriptDependencyCompiler(environment) - - val result = compiler.compile(dependencies) - runtimeBinary = result.first - nameTable = result.second + val nameTable = NameTables(emptyList()) + val compiler = JsScriptDependencyCompiler(environment.configuration, nameTable, SymbolTable()) + val runtimeBinary = compiler.compile(dependencies) dependencyLoader.saveScriptDependencyBinary(runtimeBinary) dependencyLoader.saveNames(nameTable) } - override fun createCompiler(): ReplCompiler { - return JsDebuggerCompiler(environment, dependencyLoader.loadNames()) + override fun createCompilationState(): JsReplCompilationState { + val replState = ReplCodeAnalyzer.ResettableAnalyzerState() + return JsReplCompilationState(ReentrantReadWriteLock(), dependencyLoader.loadNames(), dependencies, replState, SymbolTable()) } - override fun preprocessEvaluation() { - jsEvaluator.eval( - jsEvaluator.createState(), - createCompileResult(dependencyLoader.loadScriptDependencyBinary()) - ) + override fun createEvaluationState(): JsEvaluationState { + val state = JsEvaluationState(ReentrantReadWriteLock(), ScriptEngineNashorn()) + JsReplEvaluator().eval(state, createCompileResult(dependencyLoader.loadScriptDependencyBinary())) + return state } override fun close() { diff --git a/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/JsReplTestAgainstKlib.kt b/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/JsReplTestAgainstKlib.kt index e2f51b0d68e..aca5012b6d7 100644 --- a/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/JsReplTestAgainstKlib.kt +++ b/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/JsReplTestAgainstKlib.kt @@ -6,21 +6,43 @@ package org.jetbrains.kotlin.scripting.repl.js.test import com.intellij.openapi.util.Disposer -import org.jetbrains.kotlin.cli.common.repl.ReplCompiler +import org.jetbrains.kotlin.ir.backend.js.utils.NameTables +import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.js.engine.ScriptEngineNashorn +import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplCodeAnalyzer import org.jetbrains.kotlin.scripting.repl.js.* +import java.util.concurrent.locks.ReentrantReadWriteLock class JsReplTestAgainstKlib : AbstractJsReplTest() { - override fun createCompiler(): ReplCompiler = JsReplCompiler(environment) - override fun preprocessEvaluation() { - val scriptDependencyBinary = (compiler as JsReplCompiler).scriptDependencyBinary + private var dependencyCode: String? = null - jsEvaluator.eval( - jsEvaluator.createState(), - createCompileResult(scriptDependencyBinary) + override fun createCompilationState(): JsReplCompilationState { + val nameTables = NameTables(emptyList()) + val symbolTable = SymbolTable() + val dependencyCompiler = JsScriptDependencyCompiler(environment.configuration, nameTables, symbolTable) + val dependencies = readLibrariesFromConfiguration(environment.configuration) + dependencyCode = dependencyCompiler.compile(dependencies) + + return JsReplCompilationState( + ReentrantReadWriteLock(), + nameTables, + dependencies, + ReplCodeAnalyzer.ResettableAnalyzerState(), + symbolTable ) } + override fun createEvaluationState(): JsEvaluationState { + val state = JsEvaluationState(ReentrantReadWriteLock(), ScriptEngineNashorn()) + + JsReplEvaluator().eval(state, createCompileResult(dependencyCode ?: error("Dependencies has to be compiled first"))) + + dependencyCode = null + + return state + } + override fun close() { Disposer.dispose(disposable) } diff --git a/libraries/scripting/js/build.gradle.kts b/libraries/scripting/js/build.gradle.kts index 43985e52d2c..03498358b88 100644 --- a/libraries/scripting/js/build.gradle.kts +++ b/libraries/scripting/js/build.gradle.kts @@ -7,9 +7,9 @@ jvmTarget = "1.6" dependencies { compile(project(":kotlin-scripting-common")) - compile(project(":compiler:cli-common")) - compile(project(":js:js.engines")) - compile(intellijCoreDep()) { includeJars("intellij-core") } + compileOnly(project(":compiler:backend.js")) + compileOnly(project(":compiler:cli-common")) + compileOnly(project(":js:js.engines")) } sourceSets { diff --git a/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsReplEvaluator.kt b/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsReplEvaluator.kt index 3e8f906a891..0d221f19403 100644 --- a/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsReplEvaluator.kt +++ b/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsReplEvaluator.kt @@ -11,9 +11,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock class JsReplEvaluator : ReplEvaluator { //TODO: support println() - private val engine = ScriptEngineNashorn() - - override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> = JsState(lock) + override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> = JsEvaluationState(lock, ScriptEngineNashorn()) override fun eval( state: IReplStageState<*>, @@ -22,7 +20,8 @@ class JsReplEvaluator : ReplEvaluator { invokeWrapper: InvokeWrapper? ): ReplEvalResult { return try { - val evalResult = engine.eval(compileResult.data as String) + val evaluationState = state.asState(JsEvaluationState::class.java) + val evalResult = evaluationState.engine.eval(compileResult.data as String) ReplEvalResult.ValueResult("result", evalResult, "Any?") } catch (e: Exception) { ReplEvalResult.Error.Runtime("Error while evaluating", e) diff --git a/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsReplUtils.kt b/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsReplUtils.kt index c89f4fb9b29..b4386cbe65c 100644 --- a/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsReplUtils.kt +++ b/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsReplUtils.kt @@ -6,7 +6,10 @@ package org.jetbrains.kotlin.scripting.repl.js import org.jetbrains.kotlin.cli.common.repl.* +import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ScriptDescriptor +import org.jetbrains.kotlin.ir.backend.js.utils.NameTables +import org.jetbrains.kotlin.js.engine.ScriptEngine import java.util.concurrent.locks.ReentrantReadWriteLock import kotlin.reflect.KClass import kotlin.script.experimental.api.CompiledScript @@ -14,7 +17,7 @@ import kotlin.script.experimental.api.ResultWithDiagnostics import kotlin.script.experimental.api.ScriptCompilationConfiguration import kotlin.script.experimental.api.ScriptEvaluationConfiguration -class JsState(override val lock: ReentrantReadWriteLock) : IReplStageState { +abstract class JsState(override val lock: ReentrantReadWriteLock) : IReplStageState { override val history: IReplStageHistory get() = TODO("not implemented") @@ -23,7 +26,18 @@ class JsState(override val lock: ReentrantReadWriteLock) : IReplStageState) : JsState(lock) + +class JsEvaluationState(lock: ReentrantReadWriteLock, val engine: ScriptEngine) : JsState(lock) { + override fun dispose() { + engine.release() + } +} + +class JsCompiledScript( val jsCode: String, override val compilationConfiguration: ScriptCompilationConfiguration ) : CompiledScript { diff --git a/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptEvaluator.kt b/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptEvaluator.kt index f20764f8686..39708627e1f 100644 --- a/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptEvaluator.kt +++ b/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptEvaluator.kt @@ -17,7 +17,7 @@ class JsScriptEvaluator : ScriptEvaluator { scriptEvaluationConfiguration: ScriptEvaluationConfiguration ): ResultWithDiagnostics { return try { - val evalResult = engine.eval((compiledScript as CompiledToJsScript).jsCode) + val evalResult = engine.eval((compiledScript as JsCompiledScript).jsCode) ResultWithDiagnostics.Success( EvaluationResult( ResultValue.Value( diff --git a/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/jvmScriptCompilation.kt b/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/jvmScriptCompilation.kt index 95ab67572da..81803482dac 100644 --- a/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/jvmScriptCompilation.kt +++ b/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/jvmScriptCompilation.kt @@ -7,7 +7,7 @@ package kotlin.script.experimental.jvmhost -import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptJvmCompilerProxy +import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptCompilerProxy import org.jetbrains.kotlin.scripting.compiler.plugin.impl.ScriptJvmCompilerIsolated import kotlin.script.experimental.api.* import kotlin.script.experimental.host.ScriptingHostConfiguration @@ -16,12 +16,12 @@ import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration open class JvmScriptCompiler( baseHostConfiguration: ScriptingHostConfiguration = defaultJvmScriptingHostConfiguration, - compilerProxy: ScriptJvmCompilerProxy? = null + compilerProxy: ScriptCompilerProxy? = null ) : ScriptCompiler { val hostConfiguration = baseHostConfiguration.withDefaultsFrom(defaultJvmScriptingHostConfiguration) - val compilerProxy: ScriptJvmCompilerProxy = compilerProxy ?: ScriptJvmCompilerIsolated(hostConfiguration) + val compilerProxy: ScriptCompilerProxy = compilerProxy ?: ScriptJvmCompilerIsolated(hostConfiguration) override suspend operator fun invoke( script: SourceCode, diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/AbstractScriptEvaluationExtension.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/AbstractScriptEvaluationExtension.kt index 98e5018edc1..2a0dd045150 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/AbstractScriptEvaluationExtension.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/AbstractScriptEvaluationExtension.kt @@ -31,12 +31,7 @@ abstract class AbstractScriptEvaluationExtension : ScriptEvaluationExtension { ): KotlinCoreEnvironment abstract fun createScriptEvaluator(): ScriptEvaluator - - abstract suspend fun compilerInvoke( - environment: KotlinCoreEnvironment, - script: SourceCode, - scriptCompilationConfiguration: ScriptCompilationConfiguration - ): ResultWithDiagnostics> + abstract fun createScriptCompiler(environment: KotlinCoreEnvironment): ScriptCompilerProxy protected abstract fun ScriptEvaluationConfiguration.Builder.platformEvaluationConfiguration() @@ -82,22 +77,17 @@ abstract class AbstractScriptEvaluationExtension : ScriptEvaluationExtension { } val scriptCompilationConfiguration = definition.compilationConfiguration - - val scriptEvaluator = createScriptEvaluator() + val scriptCompiler = createScriptCompiler(environment) return runBlocking { - val compiledScript = compilerInvoke( - environment, - script, - scriptCompilationConfiguration - ).valueOr { + val compiledScript = scriptCompiler.compile(script, scriptCompilationConfiguration).valueOr { for (report in it.reports) { messageCollector.report(report.severity.toCompilerMessageSeverity(), report.render(withSeverity = false)) } return@runBlocking ExitCode.COMPILATION_ERROR } - val evalResult = scriptEvaluator.invoke(compiledScript, evaluationConfiguration).valueOr { + val evalResult = createScriptEvaluator().invoke(compiledScript, evaluationConfiguration).valueOr { for (report in it.reports) { messageCollector.report(report.severity.toCompilerMessageSeverity(), report.render(withSeverity = false)) } diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JsScriptEvaluationExtension.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JsScriptEvaluationExtension.kt index 003351c8680..1961c136045 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JsScriptEvaluationExtension.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JsScriptEvaluationExtension.kt @@ -6,22 +6,28 @@ package org.jetbrains.kotlin.scripting.compiler.plugin import com.intellij.core.JavaCoreProjectEnvironment +import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments +import org.jetbrains.kotlin.cli.common.repl.ReplCompileResult import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.ir.backend.js.utils.NameTables +import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.scripting.compiler.plugin.impl.JsScriptCompilerWithDependenciesProxy +import org.jetbrains.kotlin.scripting.compiler.plugin.impl.withMessageCollector import org.jetbrains.kotlin.scripting.configuration.ScriptingConfigurationKeys import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition import org.jetbrains.kotlin.scripting.definitions.platform -import org.jetbrains.kotlin.scripting.repl.js.CompiledToJsScript -import org.jetbrains.kotlin.scripting.repl.js.JsScriptCompiler -import org.jetbrains.kotlin.scripting.repl.js.JsScriptDependencyCompiler -import org.jetbrains.kotlin.scripting.repl.js.JsScriptEvaluator +import org.jetbrains.kotlin.scripting.repl.js.* import kotlin.script.experimental.api.* import kotlin.script.experimental.host.ScriptingHostConfiguration import kotlin.script.experimental.jvm.JsDependency +// TODO: the code below has to be considered as temporary hack and removed ASAP. +// Actual ScriptCompilationConfiguration should be set up from CompilerConfiguration. fun loadScriptConfiguration(configuration: CompilerConfiguration) { val scriptConfiguration = ScriptCompilationConfiguration { baseClass("kotlin.Any") @@ -55,37 +61,13 @@ class JsScriptEvaluationExtension : AbstractScriptEvaluationExtension() { return JsScriptEvaluator() } - private var environment: KotlinCoreEnvironment? = null - private var dependencyJsCode: String? = null - private val scriptCompiler: JsScriptCompiler by lazy { - val env = environment ?: error("Expected environment is initialized prior to compiler instantiation") - JsScriptCompiler(env).apply { - dependencyJsCode = JsScriptDependencyCompiler(env.configuration, nameTables, symbolTable).compile(dependencies) - } + private var scriptCompilerProxy: ScriptCompilerProxy? = null + + override fun createScriptCompiler(environment: KotlinCoreEnvironment): ScriptCompilerProxy { + return scriptCompilerProxy ?: JsScriptCompilerWithDependenciesProxy(environment).also { scriptCompilerProxy = it } } - override suspend fun compilerInvoke( - environment: KotlinCoreEnvironment, - script: SourceCode, - scriptCompilationConfiguration: ScriptCompilationConfiguration - ): ResultWithDiagnostics> { - - this.environment = environment - - return scriptCompiler.invoke(script, scriptCompilationConfiguration).onSuccess { - val compiledResult = it as CompiledToJsScript - val actualResult = dependencyJsCode?.let { d -> - dependencyJsCode = null - CompiledToJsScript(d + "\n" + compiledResult.jsCode, compiledResult.compilationConfiguration) - } ?: compiledResult - - ResultWithDiagnostics.Success(actualResult) - } - } - - override fun ScriptEvaluationConfiguration.Builder.platformEvaluationConfiguration() { - - } + override fun ScriptEvaluationConfiguration.Builder.platformEvaluationConfiguration() {} override fun isAccepted(arguments: CommonCompilerArguments): Boolean { return arguments is K2JSCompilerArguments diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JvmCliScriptEvaluationExtension.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JvmCliScriptEvaluationExtension.kt index 5d7fba2b972..6d7b7cf0795 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JvmCliScriptEvaluationExtension.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JvmCliScriptEvaluationExtension.kt @@ -43,18 +43,8 @@ class JvmCliScriptEvaluationExtension : AbstractScriptEvaluationExtension() { return BasicJvmScriptEvaluator() } - private var environment: KotlinCoreEnvironment? = null - private val scriptCompiler: ScriptJvmCompilerFromEnvironment by lazy { - ScriptJvmCompilerFromEnvironment(environment!!) - } - - override suspend fun compilerInvoke( - environment: KotlinCoreEnvironment, - script: SourceCode, - scriptCompilationConfiguration: ScriptCompilationConfiguration - ): ResultWithDiagnostics> { - this.environment = environment - return scriptCompiler.compile(script, scriptCompilationConfiguration) + override fun createScriptCompiler(environment: KotlinCoreEnvironment): ScriptCompilerProxy { + return ScriptJvmCompilerFromEnvironment(environment) } override fun isAccepted(arguments: CommonCompilerArguments): Boolean = diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptJvmCompilerProxy.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptCompilerProxy.kt similarity index 94% rename from plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptJvmCompilerProxy.kt rename to plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptCompilerProxy.kt index 1705f69897b..1acacb9eb5e 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptJvmCompilerProxy.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptCompilerProxy.kt @@ -10,7 +10,7 @@ import kotlin.script.experimental.api.ResultWithDiagnostics import kotlin.script.experimental.api.ScriptCompilationConfiguration import kotlin.script.experimental.api.SourceCode -interface ScriptJvmCompilerProxy { +interface ScriptCompilerProxy { fun compile( script: SourceCode, scriptCompilationConfiguration: ScriptCompilationConfiguration diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/AbstractJsScriptlikeCodeAnalyser.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/AbstractJsScriptlikeCodeAnalyser.kt new file mode 100644 index 00000000000..2d17b784c12 --- /dev/null +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/AbstractJsScriptlikeCodeAnalyser.kt @@ -0,0 +1,79 @@ +/* + * 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 org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace +import org.jetbrains.kotlin.config.languageVersionSettings +import org.jetbrains.kotlin.context.ContextForNewModule +import org.jetbrains.kotlin.context.ProjectContext +import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.descriptors.PackageFragmentProvider +import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl +import org.jetbrains.kotlin.diagnostics.Severity +import org.jetbrains.kotlin.frontend.js.di.createTopDownAnalyzerForJs +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker +import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.BindingTraceContext +import org.jetbrains.kotlin.resolve.TopDownAnalysisMode +import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory + +abstract class AbstractJsScriptlikeCodeAnalyser( + private val environment: KotlinCoreEnvironment, + private val dependencies: List +) { + + protected class JsScriptAnalysisResult( + val moduleDescriptor: ModuleDescriptor, + private val scriptDescriptor: ClassDescriptorWithResolutionScopes?, + val bindingContext: BindingContext + ) { + val isSuccess: Boolean get() = scriptDescriptor != null + val script: ClassDescriptorWithResolutionScopes get() = scriptDescriptor ?: error("Error occurred") + } + + protected fun analysisImpl(psi: KtFile): JsScriptAnalysisResult { + val trace: BindingTraceContext = NoScopeRecordCliBindingTrace() + val project = environment.project + val builtIns: KotlinBuiltIns = dependencies.single { it.allDependencyModules.isEmpty() }.builtIns + val moduleContext = ContextForNewModule( + ProjectContext(project, "TopDownAnalyzer for JS Script"), + Name.special("