[cli-repl][ide-console] Add logging of internal errors
Rename `jvmStatic` to `@JvmStatic`
This commit is contained in:
committed by
Pavel V. Talanov
parent
38285496cb
commit
9bf0c8453d
@@ -126,6 +126,7 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
configuration.put(JVMConfigurationKeys.MODULE_NAME, arguments.moduleName ?: JvmAbi.DEFAULT_MODULE_NAME)
|
configuration.put(JVMConfigurationKeys.MODULE_NAME, arguments.moduleName ?: JvmAbi.DEFAULT_MODULE_NAME)
|
||||||
|
|
||||||
if (arguments.module == null && arguments.freeArgs.isEmpty() && !arguments.version) {
|
if (arguments.module == null && arguments.freeArgs.isEmpty() && !arguments.version) {
|
||||||
|
configuration.put(JVMConfigurationKeys.MODULE_NAME, "replModule")
|
||||||
ReplFromTerminal.run(rootDisposable, configuration)
|
ReplFromTerminal.run(rootDisposable, configuration)
|
||||||
return ExitCode.OK
|
return ExitCode.OK
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.cli.common.KotlinVersion;
|
import org.jetbrains.kotlin.cli.common.KotlinVersion;
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.IdeLinebreaksUnescaper;
|
import org.jetbrains.kotlin.cli.jvm.repl.messages.IdeLinebreaksUnescaper;
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplErrorLogger;
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplSystemInWrapper;
|
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplSystemInWrapper;
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplSystemOutWrapper;
|
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplSystemOutWrapper;
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||||
@@ -44,8 +45,9 @@ public class ReplFromTerminal {
|
|||||||
private final boolean ideMode;
|
private final boolean ideMode;
|
||||||
private ReplSystemInWrapper replReader;
|
private ReplSystemInWrapper replReader;
|
||||||
private final ReplSystemOutWrapper replWriter;
|
private final ReplSystemOutWrapper replWriter;
|
||||||
|
private final ReplErrorLogger replErrorLogger;
|
||||||
|
|
||||||
private final ConsoleReader consoleReader;
|
private ConsoleReader consoleReader;
|
||||||
|
|
||||||
public ReplFromTerminal(
|
public ReplFromTerminal(
|
||||||
@NotNull final Disposable disposable,
|
@NotNull final Disposable disposable,
|
||||||
@@ -67,6 +69,8 @@ public class ReplFromTerminal {
|
|||||||
System.setIn(replReader);
|
System.setIn(replReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
replErrorLogger = new ReplErrorLogger(ideMode, replWriter);
|
||||||
|
|
||||||
new Thread("initialize-repl") {
|
new Thread("initialize-repl") {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -97,7 +101,7 @@ public class ReplFromTerminal {
|
|||||||
consoleReader.setHistory(new FileHistory(new File(new File(System.getProperty("user.home")), ".kotlin_history")));
|
consoleReader.setHistory(new FileHistory(new File(new File(System.getProperty("user.home")), ".kotlin_history")));
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw UtilsPackage.rethrow(e);
|
replErrorLogger.logException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,14 +139,14 @@ public class ReplFromTerminal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw UtilsPackage.rethrow(e);
|
replErrorLogger.logException(e);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
try {
|
try {
|
||||||
((FileHistory) consoleReader.getHistory()).flush();
|
((FileHistory) consoleReader.getHistory()).flush();
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
replWriter.printlnInnerError("failed to flush history: " + e);
|
replErrorLogger.logException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
|
|||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.di.ContainerForReplWithJava;
|
import org.jetbrains.kotlin.cli.jvm.repl.di.ContainerForReplWithJava;
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.di.DiPackage;
|
import org.jetbrains.kotlin.cli.jvm.repl.di.DiPackage;
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.DiagnosticMessageHolder;
|
import org.jetbrains.kotlin.cli.jvm.repl.messages.*;
|
||||||
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;
|
||||||
@@ -341,10 +338,10 @@ public class ReplInterpreter {
|
|||||||
scriptInstance = scriptInstanceConstructor.newInstance(constructorArgs);
|
scriptInstance = scriptInstanceConstructor.newInstance(constructorArgs);
|
||||||
}
|
}
|
||||||
catch (Throwable e) {
|
catch (Throwable e) {
|
||||||
setReplScriptExecuting(false);
|
|
||||||
return LineResult.runtimeError(renderStackTrace(e.getCause()));
|
return LineResult.runtimeError(renderStackTrace(e.getCause()));
|
||||||
|
} finally {
|
||||||
|
setReplScriptExecuting(false);
|
||||||
}
|
}
|
||||||
setReplScriptExecuting(false);
|
|
||||||
|
|
||||||
Field rvField = scriptClass.getDeclaredField("rv");
|
Field rvField = scriptClass.getDeclaredField("rv");
|
||||||
rvField.setAccessible(true);
|
rvField.setAccessible(true);
|
||||||
@@ -387,6 +384,8 @@ public class ReplInterpreter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Collections.reverse(newTrace);
|
Collections.reverse(newTrace);
|
||||||
|
|
||||||
|
// throw away last element which contains Line1.kts<init>(Unknown source)
|
||||||
List<StackTraceElement> resultingTrace = newTrace.subList(0, newTrace.size() - 1);
|
List<StackTraceElement> resultingTrace = newTrace.subList(0, newTrace.size() - 1);
|
||||||
|
|
||||||
cause.setStackTrace(resultingTrace.toArray(new StackTraceElement[resultingTrace.size()]));
|
cause.setStackTrace(resultingTrace.toArray(new StackTraceElement[resultingTrace.size()]));
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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 java.io.PrintWriter
|
||||||
|
import java.io.StringWriter
|
||||||
|
import kotlin.reflect.jvm.internal.impl.utils.UtilsPackage
|
||||||
|
|
||||||
|
public class ReplErrorLogger(private val ideMode: Boolean, private val replWriter: ReplSystemOutWrapper) {
|
||||||
|
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 UtilsPackage.rethrow(e ?: Throwable("null exception", e))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,7 +42,7 @@ public class ReplSystemInWrapper(
|
|||||||
$isReplScriptExecuting = value
|
$isReplScriptExecuting = value
|
||||||
}
|
}
|
||||||
|
|
||||||
override synchronized fun read(): Int {
|
override fun read(): Int {
|
||||||
if (isLastScriptByteProcessed && isReplScriptExecuting) {
|
if (isLastScriptByteProcessed && isReplScriptExecuting) {
|
||||||
isLastScriptByteProcessed = false
|
isLastScriptByteProcessed = false
|
||||||
return -1
|
return -1
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class ReplSystemOutWrapper(private val ideMode: Boolean, standardOut: Pri
|
|||||||
REPL_INCOMPLETE,
|
REPL_INCOMPLETE,
|
||||||
COMPILE_ERROR,
|
COMPILE_ERROR,
|
||||||
RUNTIME_ERROR,
|
RUNTIME_ERROR,
|
||||||
INNER_ERROR
|
INTERNAL_ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun print(x: Boolean) = printWithEscaping(x.toString())
|
override fun print(x: Boolean) = printWithEscaping(x.toString())
|
||||||
@@ -68,5 +68,5 @@ public class ReplSystemOutWrapper(private val ideMode: Boolean, standardOut: Pri
|
|||||||
fun printlnIncomplete() = printlnWithEscaping("", EscapeType.REPL_INCOMPLETE)
|
fun printlnIncomplete() = printlnWithEscaping("", EscapeType.REPL_INCOMPLETE)
|
||||||
fun printlnCompileError(x: String) = printlnWithEscaping(x, EscapeType.COMPILE_ERROR)
|
fun printlnCompileError(x: String) = printlnWithEscaping(x, EscapeType.COMPILE_ERROR)
|
||||||
fun printlnRuntimeError(x: String) = printlnWithEscaping(x, EscapeType.RUNTIME_ERROR)
|
fun printlnRuntimeError(x: String) = printlnWithEscaping(x, EscapeType.RUNTIME_ERROR)
|
||||||
fun printlnInnerError(x: String) = printlnWithEscaping(x, EscapeType.INNER_ERROR)
|
fun sendInternalErrorReport(x: String) = printlnWithEscaping(x, EscapeType.INTERNAL_ERROR)
|
||||||
}
|
}
|
||||||
@@ -38,5 +38,5 @@ fun parseXml(inputMessage: String): String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public object IdeLinebreaksUnescaper {
|
public object IdeLinebreaksUnescaper {
|
||||||
jvmStatic fun unescapeFromDiez(inputMessage: String) = StringUtil.replace(inputMessage, XML_REPLACEMENTS, SOURCE_CHARS)
|
@JvmStatic fun unescapeFromDiez(inputMessage: String) = StringUtil.replace(inputMessage, XML_REPLACEMENTS, SOURCE_CHARS)
|
||||||
}
|
}
|
||||||
@@ -25,8 +25,7 @@ import org.jetbrains.kotlin.test.TestJdkKind
|
|||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.util.ArrayDeque
|
import java.util.*
|
||||||
import java.util.ArrayList
|
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
import kotlin.text.Regex
|
import kotlin.text.Regex
|
||||||
|
|
||||||
|
|||||||
@@ -112,6 +112,6 @@ public class KotlinConsoleKeeper(val project: Project) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
jvmStatic fun getInstance(project: Project) = ServiceManager.getService(project, KotlinConsoleKeeper::class.java)
|
@JvmStatic fun getInstance(project: Project) = ServiceManager.getService(project, KotlinConsoleKeeper::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,7 +20,6 @@ import com.intellij.execution.process.OSProcessHandler
|
|||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import org.jetbrains.kotlin.console.actions.logError
|
|
||||||
import org.jetbrains.kotlin.console.highlight.KotlinHistoryHighlighter
|
import org.jetbrains.kotlin.console.highlight.KotlinHistoryHighlighter
|
||||||
import org.jetbrains.kotlin.console.highlight.KotlinReplOutputHighlighter
|
import org.jetbrains.kotlin.console.highlight.KotlinReplOutputHighlighter
|
||||||
import org.jetbrains.kotlin.diagnostics.Severity
|
import org.jetbrains.kotlin.diagnostics.Severity
|
||||||
@@ -68,7 +67,7 @@ public class KotlinReplOutputHandler(
|
|||||||
"REPL_INCOMPLETE",
|
"REPL_INCOMPLETE",
|
||||||
"COMPILE_ERROR" -> outputHighlighter.highlightCompilerErrors(createCompilerMessages(content))
|
"COMPILE_ERROR" -> outputHighlighter.highlightCompilerErrors(createCompilerMessages(content))
|
||||||
"RUNTIME_ERROR" -> outputHighlighter.printRuntimeError("${content.trim()}\n")
|
"RUNTIME_ERROR" -> outputHighlighter.printRuntimeError("${content.trim()}\n")
|
||||||
"INNER_ERROR" -> logError(this.javaClass, content)
|
"INTERNAL_ERROR" -> outputHighlighter.printInternalErrorMessage(content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-1
@@ -31,6 +31,7 @@ import com.intellij.psi.PsiDocumentManager
|
|||||||
import org.jetbrains.kotlin.console.KotlinConsoleHistoryManager
|
import org.jetbrains.kotlin.console.KotlinConsoleHistoryManager
|
||||||
import org.jetbrains.kotlin.console.KotlinConsoleRunner
|
import org.jetbrains.kotlin.console.KotlinConsoleRunner
|
||||||
import org.jetbrains.kotlin.console.SeverityDetails
|
import org.jetbrains.kotlin.console.SeverityDetails
|
||||||
|
import org.jetbrains.kotlin.console.actions.logError
|
||||||
import org.jetbrains.kotlin.console.gutter.IconWithTooltip
|
import org.jetbrains.kotlin.console.gutter.IconWithTooltip
|
||||||
import org.jetbrains.kotlin.console.gutter.KotlinConsoleErrorRenderer
|
import org.jetbrains.kotlin.console.gutter.KotlinConsoleErrorRenderer
|
||||||
import org.jetbrains.kotlin.console.gutter.KotlinConsoleIndicatorRenderer
|
import org.jetbrains.kotlin.console.gutter.KotlinConsoleIndicatorRenderer
|
||||||
@@ -108,7 +109,7 @@ public class KotlinReplOutputHighlighter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun highlightCompilerErrors(compilerMessages: List<SeverityDetails>) = WriteCommandAction.runWriteCommandAction(project) {
|
fun highlightCompilerErrors(compilerMessages: List<SeverityDetails>) = WriteCommandAction.runWriteCommandAction(project) {
|
||||||
val lastCommandStartOffset = historyDocument.textLength - historyManager.lastCommandLength
|
val lastCommandStartOffset = historyDocument.textLength - historyManager.lastCommandLength - 1
|
||||||
val lastCommandStartLine = historyDocument.getLineNumber(lastCommandStartOffset)
|
val lastCommandStartLine = historyDocument.getLineNumber(lastCommandStartOffset)
|
||||||
val historyCommandRunIndicator = historyMarkup.allHighlighters.filter {
|
val historyCommandRunIndicator = historyMarkup.allHighlighters.filter {
|
||||||
historyDocument.getLineNumber(it.startOffset) == lastCommandStartLine && it.gutterIconRenderer != null
|
historyDocument.getLineNumber(it.startOffset) == lastCommandStartLine && it.gutterIconRenderer != null
|
||||||
@@ -144,6 +145,12 @@ public class KotlinReplOutputHighlighter(
|
|||||||
printOutput(errorText, ConsoleViewContentType.ERROR_OUTPUT, ReplIcons.RUNTIME_EXCEPTION)
|
printOutput(errorText, ConsoleViewContentType.ERROR_OUTPUT, ReplIcons.RUNTIME_EXCEPTION)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun printInternalErrorMessage(internalErrorText: String) = WriteCommandAction.runWriteCommandAction(project) {
|
||||||
|
val promptText = "Internal error occurred. Please, send report to developers.\n"
|
||||||
|
printOutput(promptText, ConsoleViewContentType.ERROR_OUTPUT, ReplIcons.RUNTIME_EXCEPTION)
|
||||||
|
logError(this.javaClass, internalErrorText)
|
||||||
|
}
|
||||||
|
|
||||||
private fun getAttributesForSeverity(start: Int, end: Int, severity: Severity): TextAttributes {
|
private fun getAttributesForSeverity(start: Int, end: Int, severity: Severity): TextAttributes {
|
||||||
val attributes = when (severity) {
|
val attributes = when (severity) {
|
||||||
Severity.ERROR -> getAttributesForSeverity(HighlightInfoType.ERROR, HighlightSeverity.ERROR, CodeInsightColors.ERRORS_ATTRIBUTES, start, end)
|
Severity.ERROR -> getAttributesForSeverity(HighlightInfoType.ERROR, HighlightSeverity.ERROR, CodeInsightColors.ERRORS_ATTRIBUTES, start, end)
|
||||||
|
|||||||
Reference in New Issue
Block a user