[JS SCRIPT] refactor js script infrastructure

- Implement proper script compiler proxy to correctly handle script and its closed-world dependencies
 - Clean up zoo of JsScriptCompilers
This commit is contained in:
Roman Artemev
2019-09-25 20:50:23 +03:00
committed by romanart
parent f59e393e37
commit c0f279811e
25 changed files with 404 additions and 357 deletions
@@ -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++
@@ -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() {
@@ -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)
}