Refactor ReplInterpreter and ReplFromTerminal classes
Drop some of the exception reporting code
This commit is contained in:
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.cli.jvm.repl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.repl.messages.*
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.repl.reader.ConsoleReplCommandReader
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.repl.reader.IdeReplCommandReader
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.repl.reader.ReplCommandReader
|
||||||
|
import java.io.PrintWriter
|
||||||
|
import java.io.StringWriter
|
||||||
|
|
||||||
|
interface ReplConfiguration {
|
||||||
|
val writer: ReplWriter
|
||||||
|
val errorLogger: ReplErrorLogger
|
||||||
|
val commandReader: ReplCommandReader
|
||||||
|
val allowIncompleteLines: Boolean
|
||||||
|
|
||||||
|
fun createDiagnosticHolder(): DiagnosticMessageHolder
|
||||||
|
fun onUserCodeExecuting(isExecuting: Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReplForIdeConfiguration : ReplConfiguration {
|
||||||
|
override val allowIncompleteLines: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
|
override fun onUserCodeExecuting(isExecuting: Boolean) {
|
||||||
|
sinWrapper.isReplScriptExecuting = isExecuting
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createDiagnosticHolder() = ReplIdeDiagnosticMessageHolder()
|
||||||
|
|
||||||
|
override val writer: ReplWriter
|
||||||
|
override val errorLogger: ReplErrorLogger
|
||||||
|
override val commandReader: ReplCommandReader
|
||||||
|
|
||||||
|
val sinWrapper: ReplSystemInWrapper
|
||||||
|
|
||||||
|
init {
|
||||||
|
// wrapper for `out` is required to escape every input in [ideMode];
|
||||||
|
// if [ideMode == false] then just redirects all input to [System.out]
|
||||||
|
// if user calls [System.setOut(...)] then undefined behaviour
|
||||||
|
val soutWrapper = ReplSystemOutWrapperForIde(System.out)
|
||||||
|
System.setOut(soutWrapper)
|
||||||
|
|
||||||
|
// wrapper for `in` is required to give user possibility of calling
|
||||||
|
// [readLine] from ide-console repl
|
||||||
|
sinWrapper = ReplSystemInWrapper(System.`in`, soutWrapper)
|
||||||
|
System.setIn(sinWrapper)
|
||||||
|
|
||||||
|
writer = soutWrapper
|
||||||
|
errorLogger = IdeReplErrorLogger(writer)
|
||||||
|
commandReader = IdeReplCommandReader()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConsoleReplConfiguration : ReplConfiguration {
|
||||||
|
override val allowIncompleteLines: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override fun onUserCodeExecuting(isExecuting: Boolean) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createDiagnosticHolder() = ReplTerminalDiagnosticMessageHolder()
|
||||||
|
|
||||||
|
override val writer: ReplWriter
|
||||||
|
override val errorLogger: ReplErrorLogger
|
||||||
|
override val commandReader: ReplCommandReader
|
||||||
|
|
||||||
|
init {
|
||||||
|
writer = ReplConsoleWriter()
|
||||||
|
errorLogger = object : ReplErrorLogger {
|
||||||
|
override fun logException(e: Throwable): Nothing {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commandReader = ConsoleReplCommandReader()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ReplErrorLogger {
|
||||||
|
fun logException(e: Throwable): Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
class IdeReplErrorLogger(private val replWriter: ReplWriter) : ReplErrorLogger {
|
||||||
|
override fun logException(e: Throwable): Nothing {
|
||||||
|
val errorStringWriter = StringWriter()
|
||||||
|
val errorPrintWriter = PrintWriter(errorStringWriter)
|
||||||
|
e.printStackTrace(errorPrintWriter)
|
||||||
|
|
||||||
|
val writerString = errorStringWriter.toString()
|
||||||
|
val internalErrorText = if (writerString.isEmpty()) "Unknown error" else writerString
|
||||||
|
|
||||||
|
replWriter.sendInternalErrorReport(internalErrorText)
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,115 +19,33 @@ package org.jetbrains.kotlin.cli.jvm.repl
|
|||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import org.jetbrains.kotlin.cli.common.KotlinVersion
|
import org.jetbrains.kotlin.cli.common.KotlinVersion
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.*
|
import org.jetbrains.kotlin.cli.jvm.repl.messages.unescapeLineBreaks
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.reader.ConsoleReplCommandReader
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.reader.IdeReplCommandReader
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.reader.ReplCommandReader
|
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.utils.*
|
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.util.Arrays
|
import java.util.*
|
||||||
|
import java.util.concurrent.Callable
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
import java.util.concurrent.Future
|
||||||
|
|
||||||
class ReplFromTerminal(
|
class ReplFromTerminal(
|
||||||
disposable: Disposable,
|
disposable: Disposable,
|
||||||
compilerConfiguration: CompilerConfiguration
|
compilerConfiguration: CompilerConfiguration,
|
||||||
) {
|
replConfiguration: ReplConfiguration
|
||||||
|
) : ReplConfiguration by replConfiguration {
|
||||||
|
|
||||||
private var replInterpreter: ReplInterpreter? = null
|
private val replInitializer: Future<ReplInterpreter> = Executors.newSingleThreadExecutor().submit(Callable {
|
||||||
private var replInitializationFailed: Throwable? = null
|
ReplInterpreter(disposable, compilerConfiguration, replConfiguration)
|
||||||
private val waitRepl = Object()
|
})
|
||||||
|
|
||||||
private val ideMode: Boolean
|
private val replInterpreter: ReplInterpreter
|
||||||
private var replReader: ReplSystemInWrapper? = null
|
get() = replInitializer.get()
|
||||||
private val replWriter: ReplWriter
|
|
||||||
private val replErrorLogger: ReplErrorLogger
|
|
||||||
|
|
||||||
private var commandReader: ReplCommandReader? = null
|
|
||||||
|
|
||||||
init {
|
|
||||||
val replIdeMode = System.getProperty("kotlin.repl.ideMode")
|
|
||||||
ideMode = replIdeMode != null && replIdeMode == "true"
|
|
||||||
|
|
||||||
// wrapper for `out` is required to escape every input in [ideMode];
|
|
||||||
// if [ideMode == false] then just redirects all input to [System.out]
|
|
||||||
// if user calls [System.setOut(...)] then undefined behaviour
|
|
||||||
if (ideMode) {
|
|
||||||
val soutWrapper = ReplSystemOutWrapperForIde(System.out)
|
|
||||||
replWriter = soutWrapper
|
|
||||||
System.setOut(soutWrapper)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
replWriter = ReplConsoleWriter()
|
|
||||||
}
|
|
||||||
|
|
||||||
// wrapper for `in` is required to give user possibility of calling
|
|
||||||
// [readLine] from ide-console repl
|
|
||||||
if (ideMode) {
|
|
||||||
replReader = ReplSystemInWrapper(System.`in`, replWriter)
|
|
||||||
System.setIn(replReader!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
replErrorLogger = ReplErrorLogger(ideMode, replWriter)
|
|
||||||
|
|
||||||
object : Thread("initialize-repl") {
|
|
||||||
override fun run() {
|
|
||||||
try {
|
|
||||||
replInterpreter = ReplInterpreter(disposable, compilerConfiguration, ideMode, replReader)
|
|
||||||
}
|
|
||||||
catch (e: Throwable) {
|
|
||||||
replInitializationFailed = e
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (waitRepl) {
|
|
||||||
waitRepl.notifyAll()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.start()
|
|
||||||
|
|
||||||
try {
|
|
||||||
commandReader = createCommandReader()
|
|
||||||
}
|
|
||||||
catch (e: Exception) {
|
|
||||||
replErrorLogger.logException(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createCommandReader(): ReplCommandReader {
|
|
||||||
return if (ideMode)
|
|
||||||
IdeReplCommandReader()
|
|
||||||
else
|
|
||||||
ConsoleReplCommandReader()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getReplInterpreter(): ReplInterpreter {
|
|
||||||
if (replInterpreter != null) {
|
|
||||||
return replInterpreter!!
|
|
||||||
}
|
|
||||||
synchronized (waitRepl) {
|
|
||||||
while (replInterpreter == null && replInitializationFailed == null) {
|
|
||||||
try {
|
|
||||||
waitRepl.wait()
|
|
||||||
}
|
|
||||||
catch (e: Throwable) {
|
|
||||||
throw rethrow(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (replInterpreter != null) {
|
|
||||||
return replInterpreter!!
|
|
||||||
}
|
|
||||||
throw rethrow(replInitializationFailed!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun doRun() {
|
private fun doRun() {
|
||||||
try {
|
try {
|
||||||
replWriter.printlnWelcomeMessage("Welcome to Kotlin version ${KotlinVersion.VERSION} " +
|
writer.printlnWelcomeMessage("Welcome to Kotlin version ${KotlinVersion.VERSION} " +
|
||||||
"(JRE ${System.getProperty("java.runtime.version")})")
|
"(JRE ${System.getProperty("java.runtime.version")})")
|
||||||
replWriter.printlnWelcomeMessage("Type :help for help, :quit for quit")
|
writer.printlnWelcomeMessage("Type :help for help, :quit for quit")
|
||||||
var next = WhatNextAfterOneLine.READ_LINE
|
var next = WhatNextAfterOneLine.READ_LINE
|
||||||
while (true) {
|
while (true) {
|
||||||
next = one(next)
|
next = one(next)
|
||||||
@@ -137,14 +55,14 @@ class ReplFromTerminal(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e: Exception) {
|
catch (e: Exception) {
|
||||||
replErrorLogger.logException(e)
|
errorLogger.logException(e)
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
try {
|
try {
|
||||||
commandReader!!.flushHistory()
|
commandReader.flushHistory()
|
||||||
}
|
}
|
||||||
catch (e: Exception) {
|
catch (e: Exception) {
|
||||||
replErrorLogger.logException(e)
|
errorLogger.logException(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -157,46 +75,40 @@ class ReplFromTerminal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun one(next: WhatNextAfterOneLine): WhatNextAfterOneLine {
|
private fun one(next: WhatNextAfterOneLine): WhatNextAfterOneLine {
|
||||||
try {
|
var line = commandReader.readLine(next) ?: return WhatNextAfterOneLine.QUIT
|
||||||
var line = commandReader!!.readLine(next) ?: return WhatNextAfterOneLine.QUIT
|
|
||||||
|
|
||||||
line = unescapeLineBreaks(line)
|
line = unescapeLineBreaks(line)
|
||||||
|
|
||||||
if (line.startsWith(":") && (line.length == 1 || line.get(1) != ':')) {
|
if (line.startsWith(":") && (line.length == 1 || line.get(1) != ':')) {
|
||||||
val notQuit = oneCommand(line.substring(1))
|
val notQuit = oneCommand(line.substring(1))
|
||||||
return if (notQuit) WhatNextAfterOneLine.READ_LINE else WhatNextAfterOneLine.QUIT
|
return if (notQuit) WhatNextAfterOneLine.READ_LINE else WhatNextAfterOneLine.QUIT
|
||||||
}
|
|
||||||
|
|
||||||
val lineResultType = eval(line)
|
|
||||||
if (lineResultType === ReplInterpreter.LineResultType.INCOMPLETE) {
|
|
||||||
return WhatNextAfterOneLine.INCOMPLETE
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return WhatNextAfterOneLine.READ_LINE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e: Exception) {
|
|
||||||
throw rethrow(e)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val lineResultType = eval(line)
|
||||||
|
if (lineResultType === ReplInterpreter.LineResultType.INCOMPLETE) {
|
||||||
|
return WhatNextAfterOneLine.INCOMPLETE
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return WhatNextAfterOneLine.READ_LINE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun eval(line: String): ReplInterpreter.LineResultType {
|
private fun eval(line: String): ReplInterpreter.LineResultType {
|
||||||
val lineResult = getReplInterpreter().eval(line)
|
val lineResult = replInterpreter.eval(line)
|
||||||
if (lineResult.type === ReplInterpreter.LineResultType.SUCCESS) {
|
if (lineResult.type === ReplInterpreter.LineResultType.SUCCESS) {
|
||||||
replWriter.notifyCommandSuccess()
|
writer.notifyCommandSuccess()
|
||||||
if (!lineResult.isUnit) {
|
if (!lineResult.isUnit) {
|
||||||
replWriter.outputCommandResult(lineResult.value)
|
writer.outputCommandResult(lineResult.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (lineResult.type === ReplInterpreter.LineResultType.INCOMPLETE) {
|
else if (lineResult.type === ReplInterpreter.LineResultType.INCOMPLETE) {
|
||||||
replWriter.notifyIncomplete()
|
writer.notifyIncomplete()
|
||||||
}
|
}
|
||||||
else if (lineResult.type === ReplInterpreter.LineResultType.COMPILE_ERROR) {
|
else if (lineResult.type === ReplInterpreter.LineResultType.COMPILE_ERROR) {
|
||||||
replWriter.outputCompileError(lineResult.errorText!!)
|
writer.outputCompileError(lineResult.errorText!!)
|
||||||
}
|
}
|
||||||
else if (lineResult.type === ReplInterpreter.LineResultType.RUNTIME_ERROR) {
|
else if (lineResult.type === ReplInterpreter.LineResultType.RUNTIME_ERROR) {
|
||||||
replWriter.outputRuntimeError(lineResult.errorText!!)
|
writer.outputRuntimeError(lineResult.errorText!!)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw IllegalStateException("unknown line result type: " + lineResult)
|
throw IllegalStateException("unknown line result type: " + lineResult)
|
||||||
@@ -208,15 +120,15 @@ class ReplFromTerminal(
|
|||||||
private fun oneCommand(command: String): Boolean {
|
private fun oneCommand(command: String): Boolean {
|
||||||
val split = splitCommand(command)
|
val split = splitCommand(command)
|
||||||
if (split.size >= 1 && command == "help") {
|
if (split.size >= 1 && command == "help") {
|
||||||
replWriter.printlnHelpMessage("Available commands:\n" +
|
writer.printlnHelpMessage("Available commands:\n" +
|
||||||
":help show this help\n" +
|
":help show this help\n" +
|
||||||
":quit exit the interpreter\n" +
|
":quit exit the interpreter\n" +
|
||||||
":dump bytecode dump classes to terminal\n" +
|
":dump bytecode dump classes to terminal\n" +
|
||||||
":load <file> load script from specified file")
|
":load <file> load script from specified file")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
else if (split.size >= 2 && split[0] == "dump" && split[1] == "bytecode") {
|
else if (split.size >= 2 && split[0] == "dump" && split[1] == "bytecode") {
|
||||||
getReplInterpreter().dumpClasses(PrintWriter(System.out))
|
replInterpreter.dumpClasses(PrintWriter(System.out))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
else if (split.size >= 1 && split[0] == "quit") {
|
else if (split.size >= 1 && split[0] == "quit") {
|
||||||
@@ -229,19 +141,25 @@ class ReplFromTerminal(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
replWriter.printlnHelpMessage("Unknown command\n" + "Type :help for help")
|
writer.printlnHelpMessage("Unknown command\n" + "Type :help for help")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private fun splitCommand(command: String): List<String> {
|
private fun splitCommand(command: String): List<String> {
|
||||||
return Arrays.asList(*command.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray())
|
return Arrays.asList(*command.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun run(disposable: Disposable, configuration: CompilerConfiguration) {
|
fun run(disposable: Disposable, configuration: CompilerConfiguration) {
|
||||||
ReplFromTerminal(disposable, configuration).doRun()
|
val replIdeMode = System.getProperty("kotlin.repl.ideMode") == "true"
|
||||||
|
val replConfiguration = if (replIdeMode) ReplForIdeConfiguration() else ConsoleReplConfiguration()
|
||||||
|
return try {
|
||||||
|
ReplFromTerminal(disposable, configuration, replConfiguration).doRun()
|
||||||
|
}
|
||||||
|
catch (e: Exception) {
|
||||||
|
replConfiguration.errorLogger.logException(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,10 +29,6 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
|||||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.CliReplAnalyzerEngine.ReplLineAnalysisResult.Successful
|
import org.jetbrains.kotlin.cli.jvm.repl.CliReplAnalyzerEngine.ReplLineAnalysisResult.Successful
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.CliReplAnalyzerEngine.ReplLineAnalysisResult.WithErrors
|
import org.jetbrains.kotlin.cli.jvm.repl.CliReplAnalyzerEngine.ReplLineAnalysisResult.WithErrors
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.DiagnosticMessageHolder
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplIdeDiagnosticMessageHolder
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplSystemInWrapper
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplTerminalDiagnosticMessageHolder
|
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
||||||
import org.jetbrains.kotlin.codegen.CompilationErrorHandler
|
import org.jetbrains.kotlin.codegen.CompilationErrorHandler
|
||||||
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
|
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
|
||||||
@@ -55,9 +51,8 @@ import java.net.URLClassLoader
|
|||||||
class ReplInterpreter(
|
class ReplInterpreter(
|
||||||
disposable: Disposable,
|
disposable: Disposable,
|
||||||
private val configuration: CompilerConfiguration,
|
private val configuration: CompilerConfiguration,
|
||||||
private val ideMode: Boolean,
|
private val replConfiguration: ReplConfiguration
|
||||||
private val replReader: ReplSystemInWrapper?
|
): ReplConfiguration by replConfiguration {
|
||||||
) {
|
|
||||||
private var lineNumber = 0
|
private var lineNumber = 0
|
||||||
|
|
||||||
private val earlierLines = arrayListOf<EarlierLine>()
|
private val earlierLines = arrayListOf<EarlierLine>()
|
||||||
@@ -135,12 +130,6 @@ class ReplInterpreter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDiagnosticHolder(): DiagnosticMessageHolder =
|
|
||||||
if (ideMode)
|
|
||||||
ReplIdeDiagnosticMessageHolder()
|
|
||||||
else
|
|
||||||
ReplTerminalDiagnosticMessageHolder()
|
|
||||||
|
|
||||||
fun eval(line: String): LineResult {
|
fun eval(line: String): LineResult {
|
||||||
++lineNumber
|
++lineNumber
|
||||||
|
|
||||||
@@ -158,13 +147,13 @@ class ReplInterpreter(
|
|||||||
val syntaxErrorReport = AnalyzerWithCompilerReport.reportSyntaxErrors(psiFile, errorHolder)
|
val syntaxErrorReport = AnalyzerWithCompilerReport.reportSyntaxErrors(psiFile, errorHolder)
|
||||||
|
|
||||||
if (syntaxErrorReport.isHasErrors && syntaxErrorReport.isAllErrorsAtEof) {
|
if (syntaxErrorReport.isHasErrors && syntaxErrorReport.isAllErrorsAtEof) {
|
||||||
return if (ideMode) {
|
return if (allowIncompleteLines) {
|
||||||
LineResult.compileError(errorHolder.renderedDiagnostics)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
previousIncompleteLines.add(line)
|
previousIncompleteLines.add(line)
|
||||||
LineResult.incomplete()
|
LineResult.incomplete()
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
LineResult.compileError(errorHolder.renderedDiagnostics)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
previousIncompleteLines.clear()
|
previousIncompleteLines.clear()
|
||||||
@@ -203,14 +192,14 @@ class ReplInterpreter(
|
|||||||
|
|
||||||
val scriptInstanceConstructor = scriptClass.getConstructor(*constructorParams)
|
val scriptInstanceConstructor = scriptClass.getConstructor(*constructorParams)
|
||||||
val scriptInstance = try {
|
val scriptInstance = try {
|
||||||
replReader?.isReplScriptExecuting = true
|
onUserCodeExecuting(true)
|
||||||
scriptInstanceConstructor.newInstance(*constructorArgs)
|
scriptInstanceConstructor.newInstance(*constructorArgs)
|
||||||
}
|
}
|
||||||
catch (e: Throwable) {
|
catch (e: Throwable) {
|
||||||
return LineResult.runtimeError(renderStackTrace(e.cause!!))
|
return LineResult.runtimeError(renderStackTrace(e.cause!!))
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
replReader?.isReplScriptExecuting = false
|
onUserCodeExecuting(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
val rvField = scriptClass.getDeclaredField(SCRIPT_RESULT_FIELD_NAME).apply { isAccessible = true }
|
val rvField = scriptClass.getDeclaredField(SCRIPT_RESULT_FIELD_NAME).apply { isAccessible = true }
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.cli.jvm.repl.messages
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.utils.rethrow
|
|
||||||
import java.io.PrintWriter
|
|
||||||
import java.io.StringWriter
|
|
||||||
|
|
||||||
class ReplErrorLogger(private val ideMode: Boolean, private val replWriter: ReplWriter) {
|
|
||||||
fun logException(e: Throwable?) {
|
|
||||||
if (ideMode) {
|
|
||||||
val errorStringWriter = StringWriter()
|
|
||||||
val errorPrintWriter = PrintWriter(errorStringWriter)
|
|
||||||
e?.printStackTrace(errorPrintWriter)
|
|
||||||
|
|
||||||
val writerString = errorStringWriter.toString()
|
|
||||||
val internalErrorText = if (writerString.isEmpty()) "Unknown error" else writerString
|
|
||||||
|
|
||||||
replWriter.sendInternalErrorReport(internalErrorText)
|
|
||||||
}
|
|
||||||
|
|
||||||
throw rethrow(e ?: Throwable("null exception", e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user