Reintroduce history check between compile and eval, place generation into code line and id

This commit is contained in:
Ilya Chernikov
2017-02-07 12:35:04 +01:00
parent 7b2ea001c1
commit b23911fd59
16 changed files with 82 additions and 89 deletions
@@ -28,7 +28,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock
class ReplCompilerStageHistory(private val state: GenericReplCompilerState) : BasicReplStageHistory<ScriptDescriptor>(state.lock) {
override fun resetTo(id: ILineId): Iterable<ILineId> {
state.generation.incrementAndGet()
val removedCompiledLines = super.resetTo(id)
val removedAnalyzedLines = state.analyzerEngine.resetToLine(id.no)
@@ -49,13 +48,14 @@ abstract class GenericReplCheckerState: IReplStageState<ScriptDescriptor> {
val psiFile: KtFile,
val errorHolder: DiagnosticMessageHolder)
val generation = AtomicLong(1)
var lastLineState: LineState? = null // for transferring state to the compiler in most typical case
}
class GenericReplCompilerState(environment: KotlinCoreEnvironment, override val lock: ReentrantReadWriteLock = ReentrantReadWriteLock()) : IReplStageState<ScriptDescriptor>, GenericReplCheckerState() {
override val history: IReplStageHistory<ScriptDescriptor> = ReplCompilerStageHistory(this)
override val history = ReplCompilerStageHistory(this)
override val currentGeneration: Int get() = (history as BasicReplStageHistory<*>).currentGeneration.get()
val analyzerEngine = ReplCodeAnalyzer(environment)
@@ -71,7 +71,7 @@ open class GenericReplChecker(
override fun check(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCheckResult {
state.lock.write {
val checkerState = state.asState(GenericReplCheckerState::class.java)
val scriptFileName = makeScriptBaseName(codeLine, checkerState.generation.get())
val scriptFileName = makeScriptBaseName(codeLine)
val virtualFile =
LightVirtualFile("$scriptFileName${KotlinParserDefinition.STD_SCRIPT_EXT}", KotlinLanguage.INSTANCE, StringUtil.convertLineSeparators(codeLine.code)).apply {
charset = CharsetToolkit.UTF8_CHARSET
@@ -49,8 +49,6 @@ open class GenericReplCompiler(disposable: Disposable,
state.lock.write {
val compilerState = state.asState(GenericReplCompilerState::class.java)
val currentGeneration = compilerState.generation.get()
val (psiFile, errorHolder) = run {
if (compilerState.lastLineState == null || compilerState.lastLineState!!.codeLine != codeLine) {
val res = checker.check(state, codeLine)
@@ -95,10 +93,11 @@ open class GenericReplCompiler(disposable: Disposable,
setOf(psiFile.script!!.containingKtFile),
org.jetbrains.kotlin.codegen.CompilationErrorHandler.THROW_EXCEPTION)
val generatedClassname = makeScriptBaseName(codeLine, currentGeneration)
val generatedClassname = makeScriptBaseName(codeLine)
compilerState.history.push(LineId(codeLine), scriptDescriptor)
return ReplCompileResult.CompiledClasses(LineId(codeLine),
compilerState.history.map { it.id },
generatedClassname,
generationState.factory.asList().map { CompiledClassData(it.relativePath, it.asByteArray()) },
generationState.replSpecific.hasResult,
@@ -98,7 +98,7 @@ class ReplInterpreter(
return LineResult.Error.CompileTime(errorHolder.renderedDiagnostics)
}
val analysisResult = analyzerEngine.analyzeReplLine(psiFile, ReplCodeLine(lineNumber, "fake line"))
val analysisResult = analyzerEngine.analyzeReplLine(psiFile, ReplCodeLine(lineNumber, 0, "fake line"))
AnalyzerWithCompilerReport.reportDiagnostics(analysisResult.diagnostics, errorHolder)
val scriptDescriptor = when (analysisResult) {
is ReplCodeAnalyzer.ReplLineAnalysisResult.WithErrors -> return LineResult.Error.CompileTime(errorHolder.renderedDiagnostics)