Repl: refactor ide code

More accurate class names
Move all shared state to KotlinConsoleRunner class
This commit is contained in:
Pavel V. Talanov
2015-10-22 19:06:29 +03:00
parent e10df1a05d
commit 0fe3ef7cf4
16 changed files with 160 additions and 130 deletions
@@ -20,29 +20,33 @@ import com.intellij.execution.process.BaseOSProcessHandler
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.console.actions.logError
import org.jetbrains.kotlin.console.highlight.KotlinHistoryHighlighter
private val XML_PREAMBLE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
public class KotlinConsoleExecutor(
private val runner: KotlinConsoleRunner,
private val historyManager: KotlinConsoleHistoryManager,
private val historyHighlighter: KotlinHistoryHighlighter
) {
public class CommandExecutor(private val runner: KotlinConsoleRunner) {
private val commandHistory = runner.commandHistory
private val historyUpdater = HistoryUpdater(runner)
fun executeCommand() = WriteCommandAction.runWriteCommandAction(runner.project) {
val commandText = getTrimmedCommandText()
if (commandText.isEmpty()) {
return@runWriteCommandAction
}
val historyDocumentRange = historyUpdater.printNewCommandInHistory(commandText)
commandHistory.addEntry(CommandHistory.Entry(commandText, historyDocumentRange))
sendCommandToProcess(commandText)
}
private fun getTrimmedCommandText(): String {
val consoleView = runner.consoleView
val document = consoleView.editorDocument
val inputText = document.text.trim()
if (inputText.isNotEmpty()) {
historyHighlighter.printNewCommandInHistory(inputText)
submitCommand(inputText)
}
return inputText
}
private fun submitCommand(command: String) {
historyManager.updateHistory(command)
private fun sendCommandToProcess(command: String) {
val processHandler = runner.processHandler
val processInputOS = processHandler.processInput ?: return logError(javaClass, "<p>Broken process stream</p>")
val charset = (processHandler as? BaseOSProcessHandler)?.charset ?: Charsets.UTF_8
@@ -0,0 +1,43 @@
/*
* 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.console
import com.intellij.openapi.util.TextRange
class CommandHistory {
class Entry(
val entryText: String,
val rangeInHistoryDocument: TextRange
)
private val entries = arrayListOf<Entry>()
val listeners = arrayListOf<HistoryUpdateListener>()
operator fun get(i: Int) = entries[i]
fun addEntry(entry: Entry) {
entries.add(entry)
listeners.forEach { it.onNewEntry(entry) }
}
val size: Int
get() = entries.size
}
interface HistoryUpdateListener {
fun onNewEntry(entry: CommandHistory.Entry)
}
@@ -24,7 +24,7 @@ import com.intellij.openapi.compiler.CompilerManager
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
public class KotlinConsoleCompilerHelper(
public class ConsoleCompilerHelper(
private val project: Project,
private val module: Module,
private val executor: Executor,
@@ -20,27 +20,20 @@ import com.intellij.codeInsight.lookup.LookupManager
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.editor.ex.EditorEx
import com.intellij.openapi.editor.ex.util.EditorUtil
import com.intellij.openapi.project.Project
import java.awt.event.KeyAdapter
import java.awt.event.KeyEvent
public class KotlinConsoleHistoryManager(private val runner: KotlinConsoleRunner) : KeyAdapter() {
private val project = runner.project
private val consoleEditor: EditorEx by lazy { runner.consoleView.consoleEditor } // [consoleEditor] is null at the moment if instantiation
private val history = arrayListOf<String>()
class HistoryKeyListener(
private val project: Project, private val consoleEditor: EditorEx, private val history: CommandHistory
) : KeyAdapter(), HistoryUpdateListener {
private var historyPos = 0
private var prevCaretOffset = -1
private var unfinishedCommand = ""
val lastCommandLength: Int
get() = history.last().length()
public fun updateHistory(command: String) {
history.add(command)
override fun onNewEntry(entry: CommandHistory.Entry) {
// reset history positions
historyPos = history.size()
historyPos = history.size
prevCaretOffset = -1
unfinishedCommand = ""
}
@@ -50,13 +43,13 @@ public class KotlinConsoleHistoryManager(private val runner: KotlinConsoleRunner
}
override fun keyReleased(e: KeyEvent): Unit = when (e.keyCode) {
KeyEvent.VK_UP -> moveHistoryCursor(HistoryMove.UP)
KeyEvent.VK_UP -> moveHistoryCursor(HistoryMove.UP)
KeyEvent.VK_DOWN -> moveHistoryCursor(HistoryMove.DOWN)
KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT -> prevCaretOffset = consoleEditor.caretModel.offset
}
private fun moveHistoryCursor(move: HistoryMove) {
if (history.isEmpty()) return
if (history.size == 0) return
if (LookupManager.getInstance(project).activeLookup != null) return
val caret = consoleEditor.caretModel
@@ -74,29 +67,29 @@ public class KotlinConsoleHistoryManager(private val runner: KotlinConsoleRunner
return
}
if (historyPos == history.size()) {
if (historyPos == history.size) {
unfinishedCommand = document.text
}
historyPos = Math.max(historyPos - 1, 0)
WriteCommandAction.runWriteCommandAction(project) {
document.setText(history[historyPos])
document.setText(history[historyPos].entryText)
EditorUtil.scrollToTheEnd(consoleEditor)
prevCaretOffset = 0
caret.moveToOffset(0)
}
}
HistoryMove.DOWN -> {
if (historyPos == history.size()) return
if (historyPos == history.size) return
if (curLine != totalLines - 1 || (isMultiline && prevCaretOffset != document.textLength)) {
prevCaretOffset = curOffset
return
}
historyPos = Math.min(historyPos + 1, history.size())
historyPos = Math.min(historyPos + 1, history.size)
WriteCommandAction.runWriteCommandAction(project) {
document.setText(if (historyPos == history.size()) unfinishedCommand else history[historyPos])
document.setText(if (historyPos == history.size) unfinishedCommand else history[historyPos].entryText)
prevCaretOffset = document.textLength
EditorUtil.scrollToTheEnd(consoleEditor)
}
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.console.highlight
package org.jetbrains.kotlin.console
import com.intellij.execution.console.LanguageConsoleImpl
import com.intellij.openapi.editor.ex.EditorEx
@@ -22,28 +22,17 @@ import com.intellij.openapi.editor.ex.util.EditorUtil
import com.intellij.openapi.editor.markup.HighlighterLayer
import com.intellij.openapi.editor.markup.HighlighterTargetArea
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.console.KotlinConsoleRunner
import org.jetbrains.kotlin.console.gutter.KotlinConsoleIndicatorRenderer
import org.jetbrains.kotlin.console.gutter.ConsoleIndicatorRenderer
import org.jetbrains.kotlin.console.gutter.ReplIcons
public class KotlinHistoryHighlighter(private val runner: KotlinConsoleRunner ) {
public class HistoryUpdater(private val runner: KotlinConsoleRunner) {
private val consoleView: LanguageConsoleImpl by lazy { runner.consoleView as LanguageConsoleImpl }
var isReadLineMode: Boolean = false
set(value) {
if (value)
runner.changeConsoleEditorIndicator(ReplIcons.EDITOR_READLINE_INDICATOR)
else
runner.changeConsoleEditorIndicator(ReplIcons.EDITOR_INDICATOR)
field = value
}
fun printNewCommandInHistory(trimmedCommandText: String) {
fun printNewCommandInHistory(trimmedCommandText: String): TextRange {
val historyEditor = consoleView.historyViewer
addLineBreakIfNeeded(historyEditor)
val startOffset = historyEditor.document.textLength
val endOffset = startOffset + trimmedCommandText.length()
val endOffset = startOffset + trimmedCommandText.length
addCommandTextToHistoryEditor(trimmedCommandText)
EditorUtil.scrollToTheEnd(historyEditor)
@@ -52,9 +41,10 @@ public class KotlinHistoryHighlighter(private val runner: KotlinConsoleRunner )
historyEditor.markupModel.addRangeHighlighter(
startOffset, endOffset, HighlighterLayer.LAST, null, HighlighterTargetArea.EXACT_RANGE
).apply {
val historyMarker = if (isReadLineMode) ReplIcons.READLINE_MARKER else ReplIcons.COMMAND_MARKER
gutterIconRenderer = KotlinConsoleIndicatorRenderer(historyMarker)
val historyMarker = if (runner.isReadLineMode) ReplIcons.READLINE_MARKER else ReplIcons.COMMAND_MARKER
gutterIconRenderer = ConsoleIndicatorRenderer(historyMarker)
}
return TextRange(startOffset, endOffset)
}
private fun addCommandTextToHistoryEditor(trimmedCommandText: String) {
@@ -67,11 +57,11 @@ public class KotlinHistoryHighlighter(private val runner: KotlinConsoleRunner )
}
private fun addLineBreakIfNeeded(historyEditor: EditorEx) {
if (isReadLineMode) return
if (runner.isReadLineMode) return
val historyDocument = historyEditor.document
val historyText = historyDocument.text
val textLength = historyText.length()
val textLength = historyText.length
if (!historyText.endsWith('\n')) {
historyDocument.insertString(textLength, "\n")
@@ -88,7 +78,7 @@ public class KotlinHistoryHighlighter(private val runner: KotlinConsoleRunner )
private fun addFoldingRegion(historyEditor: EditorEx, startOffset: Int, endOffset: Int, command: String) {
val cmdLines = command.lines()
val linesCount = cmdLines.size()
val linesCount = cmdLines.size
if (linesCount < 2) return
val foldingModel = historyEditor.foldingModel
@@ -40,15 +40,15 @@ private val REPL_TITLE = "Kotlin REPL"
public class KotlinConsoleKeeper(val project: Project) {
private val consoleMap: MutableMap<VirtualFile, KotlinConsoleRunner> = ConcurrentHashMap()
fun getConsoleByVirtualFile(virtualFile: VirtualFile) = consoleMap.get(virtualFile)
fun getConsoleByVirtualFile(virtualFile: VirtualFile) = consoleMap[virtualFile]
fun putVirtualFileToConsole(virtualFile: VirtualFile, console: KotlinConsoleRunner) = consoleMap.put(virtualFile, console)
fun removeConsole(virtualFile: VirtualFile) = consoleMap.remove(virtualFile)
fun run(module: Module, testMode: Boolean = false, previousCompilationFailed: Boolean = false): KotlinConsoleRunner? {
fun run(module: Module, previousCompilationFailed: Boolean = false): KotlinConsoleRunner? {
val path = module.moduleFilePath
val cmdLine = createCommandLine(module) ?: return run { errorNotification(project, "Module SDK not found"); null }
val consoleRunner = KotlinConsoleRunner(module, cmdLine, testMode, previousCompilationFailed, project, REPL_TITLE, path)
val consoleRunner = KotlinConsoleRunner(module, cmdLine, previousCompilationFailed, project, REPL_TITLE, path)
consoleRunner.initAndRun()
consoleRunner.setupGutters()
@@ -103,7 +103,7 @@ public class KotlinConsoleKeeper(val project: Project) {
}
private fun addPathToCompiledOutput(paramList: ParametersList, module: Module) {
val compiledModulePath = CompilerPathsEx.getOutputPaths(arrayOf(module)).join(File.pathSeparator)
val compiledModulePath = CompilerPathsEx.getOutputPaths(arrayOf(module)).joinToString(File.pathSeparator)
val moduleDependencies = OrderEnumerator.orderEntries(module).recursively().pathsList.pathsString
val compiledOutputClasspath = "$compiledModulePath${File.pathSeparator}$moduleDependencies"
@@ -47,12 +47,9 @@ import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.console.actions.BuildAndRestartConsoleAction
import org.jetbrains.kotlin.console.actions.KtExecuteCommandAction
import org.jetbrains.kotlin.console.gutter.IconWithTooltip
import org.jetbrains.kotlin.console.gutter.KotlinConsoleGutterContentProvider
import org.jetbrains.kotlin.console.gutter.KotlinConsoleIndicatorRenderer
import org.jetbrains.kotlin.console.gutter.ConsoleGutterContentProvider
import org.jetbrains.kotlin.console.gutter.ConsoleIndicatorRenderer
import org.jetbrains.kotlin.console.gutter.ReplIcons
import org.jetbrains.kotlin.console.highlight.KotlinHistoryHighlighter
import org.jetbrains.kotlin.console.highlight.KotlinReplOutputHighlighter
import org.jetbrains.kotlin.console.highlight.ReplColors
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.completion.doNotComplete
import org.jetbrains.kotlin.psi.KtFile
@@ -65,26 +62,38 @@ private val KOTLIN_SHELL_EXECUTE_ACTION_ID = "KotlinShellExecute"
public class KotlinConsoleRunner(
val module: Module,
private val cmdLine: GeneralCommandLine,
private val testMode: Boolean,
private val previousCompilationFailed: Boolean,
internal val previousCompilationFailed: Boolean,
myProject: Project,
title: String,
path: String?
) : AbstractConsoleRunnerWithHistory<LanguageConsoleView>(myProject, title, path) {
private val historyManager = KotlinConsoleHistoryManager(this)
private val historyHighlighter = KotlinHistoryHighlighter(this)
internal val commandHistory = CommandHistory()
var isReadLineMode: Boolean = false
set(value) {
if (value)
changeConsoleEditorIndicator(ReplIcons.EDITOR_READLINE_INDICATOR)
else
changeConsoleEditorIndicator(ReplIcons.EDITOR_INDICATOR)
field = value
}
fun changeConsoleEditorIndicator(newIconWithTooltip: IconWithTooltip) = WriteCommandAction.runWriteCommandAction(project) {
consoleEditorHighlighter.gutterIconRenderer = ConsoleIndicatorRenderer(newIconWithTooltip)
}
private var consoleEditorHighlighter by Delegates.notNull<RangeHighlighter>()
private var disposableDescriptor by Delegates.notNull<RunContentDescriptor>()
val executor = KotlinConsoleExecutor(this, historyManager, historyHighlighter)
var compilerHelper: KotlinConsoleCompilerHelper by Delegates.notNull()
val executor = CommandExecutor(this)
var compilerHelper: ConsoleCompilerHelper by Delegates.notNull()
override fun createProcess() = cmdLine.createProcess()
override fun createConsoleView(): LanguageConsoleView? {
val consoleView = LanguageConsoleBuilder()
.gutterContentProvider(KotlinConsoleGutterContentProvider())
.gutterContentProvider(ConsoleGutterContentProvider())
.build(project, KotlinLanguage.INSTANCE)
consoleView.prompt = null
@@ -94,7 +103,9 @@ public class KotlinConsoleRunner(
val consoleEditor = consoleView.consoleEditor
setupPlaceholder(consoleEditor)
consoleEditor.contentComponent.addKeyListener(historyManager)
val historyKeyListener = HistoryKeyListener(module.project, consoleEditor, commandHistory)
consoleEditor.contentComponent.addKeyListener(historyKeyListener)
commandHistory.listeners.add(historyKeyListener)
val executeAction = KtExecuteCommandAction(consoleView.virtualFile)
executeAction.registerCustomShortcutSet(CommonShortcuts.CTRL_ENTER, consoleView.consoleEditor.component)
@@ -103,9 +114,8 @@ public class KotlinConsoleRunner(
}
override fun createProcessHandler(process: Process): OSProcessHandler {
val processHandler = KotlinReplOutputHandler(
historyHighlighter,
KotlinReplOutputHighlighter(this, historyManager, testMode, previousCompilationFailed),
val processHandler = ReplOutputHandler(
this,
process,
cmdLine.commandLineString
)
@@ -131,7 +141,7 @@ public class KotlinConsoleRunner(
contentDescriptor: RunContentDescriptor
): List<AnAction> {
disposableDescriptor = contentDescriptor
compilerHelper = KotlinConsoleCompilerHelper(project, module, defaultExecutor, contentDescriptor)
compilerHelper = ConsoleCompilerHelper(project, module, defaultExecutor, contentDescriptor)
val actionList = arrayListOf<AnAction>(
BuildAndRestartConsoleAction(this),
@@ -192,17 +202,13 @@ public class KotlinConsoleRunner(
}
fun addGutterIndicator(editor: EditorEx, iconWithTooltip: IconWithTooltip): RangeHighlighter {
val indicator = KotlinConsoleIndicatorRenderer(iconWithTooltip)
val indicator = ConsoleIndicatorRenderer(iconWithTooltip)
val editorMarkup = editor.markupModel
val indicatorHighlighter = editorMarkup.addRangeHighlighter(
0, editor.document.textLength, HighlighterLayer.LAST, null, HighlighterTargetArea.LINES_IN_RANGE
)
return indicatorHighlighter apply { gutterIconRenderer = indicator }
}
fun changeConsoleEditorIndicator(newIconWithTooltip: IconWithTooltip) = WriteCommandAction.runWriteCommandAction(project) {
consoleEditorHighlighter.gutterIconRenderer = KotlinConsoleIndicatorRenderer(newIconWithTooltip)
return indicatorHighlighter.apply { gutterIconRenderer = indicator }
}
@TestOnly fun dispose() {
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.console.highlight
package org.jetbrains.kotlin.console
import com.intellij.execution.ui.ConsoleViewContentType
import com.intellij.openapi.editor.markup.TextAttributes
@@ -31,16 +31,16 @@ public object ReplColors {
public val WARNING_INFO_CONTENT_TYPE: ConsoleViewContentType =
ConsoleViewContentType(
"KOTLIN_CONSOLE_WARNING_INFO",
TextAttributes() apply { fontType = Font.ITALIC; foregroundColor = JBColor.RED }
TextAttributes().apply { fontType = Font.ITALIC; foregroundColor = JBColor.RED }
)
public val INITIAL_PROMPT_CONTENT_TYPE: ConsoleViewContentType =
ConsoleViewContentType(
"KOTLIN_CONSOLE_INITIAL_PROMPT",
TextAttributes() apply { fontType = Font.BOLD }
TextAttributes().apply { fontType = Font.BOLD }
)
public val USER_OUTPUT_CONTENT_TYPE: ConsoleViewContentType =
ConsoleViewContentType(
"KOTLIN_CONSOLE_USER_OUTPUT",
TextAttributes() apply { fontType = Font.ITALIC; foregroundColor = Colors.DARK_GREEN }
TextAttributes().apply { fontType = Font.ITALIC; foregroundColor = Colors.DARK_GREEN }
)
}
@@ -20,8 +20,6 @@ import com.intellij.execution.process.OSProcessHandler
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.TextRange
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.console.highlight.KotlinHistoryHighlighter
import org.jetbrains.kotlin.console.highlight.KotlinReplOutputHighlighter
import org.jetbrains.kotlin.diagnostics.Severity
import org.w3c.dom.Element
import org.xml.sax.InputSource
@@ -36,15 +34,15 @@ public val SOURCE_CHARS: Array<String> = arrayOf("\n", "#")
data class SeverityDetails(val severity: Severity, val description: String, val range: TextRange)
public class KotlinReplOutputHandler(
private val historyHighlighter: KotlinHistoryHighlighter,
private val outputHighlighter: KotlinReplOutputHighlighter,
class ReplOutputHandler(
private val runner: KotlinConsoleRunner,
process: Process,
commandLine: String
) : OSProcessHandler(process, commandLine) {
private var isBuildInfoChecked = false
private val dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
private val outputProcessor = ReplOutputProcessor(runner)
override fun isSilentlyDestroyOnClose() = true
@@ -62,24 +60,24 @@ public class KotlinReplOutputHandler(
when (outputType) {
"INITIAL_PROMPT" -> buildWarningIfNeededBeforeInit(content)
"HELP_PROMPT" -> outputHighlighter.printHelp(content)
"USER_OUTPUT" -> outputHighlighter.printUserOutput(content)
"REPL_RESULT" -> outputHighlighter.printResultWithGutterIcon(content)
"READLINE_START" -> historyHighlighter.isReadLineMode = true
"READLINE_END" -> historyHighlighter.isReadLineMode = false
"HELP_PROMPT" -> outputProcessor.printHelp(content)
"USER_OUTPUT" -> outputProcessor.printUserOutput(content)
"REPL_RESULT" -> outputProcessor.printResultWithGutterIcon(content)
"READLINE_START" -> runner.isReadLineMode = true
"READLINE_END" -> runner.isReadLineMode = false
"REPL_INCOMPLETE",
"COMPILE_ERROR" -> outputHighlighter.highlightCompilerErrors(createCompilerMessages(content))
"RUNTIME_ERROR" -> outputHighlighter.printRuntimeError("${content.trim()}\n")
"INTERNAL_ERROR" -> outputHighlighter.printInternalErrorMessage(content)
"COMPILE_ERROR" -> outputProcessor.highlightCompilerErrors(createCompilerMessages(content))
"RUNTIME_ERROR" -> outputProcessor.printRuntimeError("${content.trim()}\n")
"INTERNAL_ERROR" -> outputProcessor.printInternalErrorMessage(content)
}
}
private fun buildWarningIfNeededBeforeInit(content: String) {
if (!isBuildInfoChecked) {
outputHighlighter.printBuildInfoWarningIfNeeded()
outputProcessor.printBuildInfoWarningIfNeeded()
isBuildInfoChecked = true
}
outputHighlighter.printInitialPrompt(content)
outputProcessor.printInitialPrompt(content)
}
private fun strToSource(s: String, encoding: Charset = Charsets.UTF_8) = InputSource(ByteArrayInputStream(s.toByteArray(encoding)))
@@ -14,13 +14,14 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.console.highlight
package org.jetbrains.kotlin.console
import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.codeInsight.daemon.impl.HighlightInfoType
import com.intellij.execution.console.LanguageConsoleImpl
import com.intellij.execution.ui.ConsoleViewContentType
import com.intellij.lang.annotation.HighlightSeverity
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.editor.colors.CodeInsightColors
import com.intellij.openapi.editor.colors.TextAttributesKey
@@ -28,21 +29,15 @@ import com.intellij.openapi.editor.markup.HighlighterLayer
import com.intellij.openapi.editor.markup.HighlighterTargetArea
import com.intellij.openapi.editor.markup.TextAttributes
import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.console.KotlinConsoleHistoryManager
import org.jetbrains.kotlin.console.KotlinConsoleRunner
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.KotlinConsoleErrorRenderer
import org.jetbrains.kotlin.console.gutter.KotlinConsoleIndicatorRenderer
import org.jetbrains.kotlin.console.gutter.ConsoleErrorRenderer
import org.jetbrains.kotlin.console.gutter.ConsoleIndicatorRenderer
import org.jetbrains.kotlin.console.gutter.ReplIcons
import org.jetbrains.kotlin.diagnostics.Severity
public class KotlinReplOutputHighlighter(
private val runner: KotlinConsoleRunner,
private val historyManager: KotlinConsoleHistoryManager,
private val testMode: Boolean,
private val previousCompilationFailed: Boolean
public class ReplOutputProcessor(
private val runner: KotlinConsoleRunner
) {
private val project = runner.project
private val consoleView = runner.consoleView as LanguageConsoleImpl
@@ -53,7 +48,7 @@ public class KotlinReplOutputHighlighter(
private fun textOffsets(text: String): Pair<Int, Int> {
consoleView.flushDeferredText() // flush before getting offsets to calculate them properly
val oldLen = historyDocument.textLength
val newLen = oldLen + text.length()
val newLen = oldLen + text.length
return Pair(oldLen, newLen)
}
@@ -68,7 +63,7 @@ public class KotlinReplOutputHighlighter(
historyMarkup.addRangeHighlighter(
startOffset, endOffset, HighlighterLayer.LAST, null, HighlighterTargetArea.EXACT_RANGE
) apply { gutterIconRenderer = KotlinConsoleIndicatorRenderer(iconWithTooltip) }
).apply { gutterIconRenderer = ConsoleIndicatorRenderer(iconWithTooltip) }
}
private fun printWarningMessage(message: String, isAddHyperlink: Boolean) = WriteCommandAction.runWriteCommandAction(project) {
@@ -86,8 +81,8 @@ public class KotlinReplOutputHighlighter(
}
fun printBuildInfoWarningIfNeeded() {
if (testMode) return
if (previousCompilationFailed) return printWarningMessage("There were compilation errors in module ${runner.module.name}", false)
if (ApplicationManager.getApplication().isUnitTestMode) return
if (runner.previousCompilationFailed) return printWarningMessage("There were compilation errors in module ${runner.module.name}", false)
if (runner.compilerHelper.moduleIsUpToDate()) return
val compilerWarningMessage = "Youre running the REPL with outdated classes: "
@@ -109,7 +104,8 @@ public class KotlinReplOutputHighlighter(
}
fun highlightCompilerErrors(compilerMessages: List<SeverityDetails>) = WriteCommandAction.runWriteCommandAction(project) {
val lastCommandStartOffset = historyDocument.textLength - historyManager.lastCommandLength - 1
val commandHistory = runner.commandHistory
val lastCommandStartOffset = historyDocument.textLength - commandHistory[commandHistory.size - 1].entryText.length - 1
val lastCommandStartLine = historyDocument.getLineNumber(lastCommandStartOffset)
val historyCommandRunIndicator = historyMarkup.allHighlighters.filter {
historyDocument.getLineNumber(it.startOffset) == lastCommandStartLine && it.gutterIconRenderer != null
@@ -120,7 +116,7 @@ public class KotlinReplOutputHighlighter(
}.groupBy { message ->
val cmdStart = lastCommandStartOffset + message.range.startOffset
historyEditor.document.getLineNumber(cmdStart)
}.values().map { messages ->
}.values.map { messages ->
val highlighters = messages.map { message ->
val cmdStart = lastCommandStartOffset + message.range.startOffset
val cmdEnd = lastCommandStartOffset + Math.max(message.range.endOffset, message.range.startOffset + 1)
@@ -135,9 +131,9 @@ public class KotlinReplOutputHighlighter(
for ((highlighter, messages) in highlighterAndMessagesByLine) {
if (historyDocument.getLineNumber(highlighter.startOffset) == lastCommandStartLine)
historyCommandRunIndicator.gutterIconRenderer = KotlinConsoleErrorRenderer(messages)
historyCommandRunIndicator.gutterIconRenderer = ConsoleErrorRenderer(messages)
else
highlighter.gutterIconRenderer = KotlinConsoleErrorRenderer(messages)
highlighter.gutterIconRenderer = ConsoleErrorRenderer(messages)
}
}
@@ -24,7 +24,7 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.popup.JBPopupFactory
import org.jetbrains.kotlin.console.KotlinConsoleKeeper
public class KotlinConsoleModuleDialog(private val project: Project) {
public class ConsoleModuleDialog(private val project: Project) {
private val TITLE = "Choose context module..."
public fun showIfNeeded(dataContext: DataContext) {
@@ -34,9 +34,9 @@ public class KotlinConsoleModuleDialog(private val project: Project) {
val modules = ModuleManager.getInstance(project).modules
if (modules.isEmpty()) return errorNotification(project, "No modules were found")
if (modules.size() == 1) return runConsole(modules.first())
if (modules.size == 1) return runConsole(modules.first())
val moduleActions = modules sortedBy { it.name } map { createRunAction(it) }
val moduleActions = modules.sortedBy { it.name }.map { createRunAction(it) }
val moduleGroup = DefaultActionGroup(moduleActions)
val modulePopup = JBPopupFactory.getInstance().createActionGroupPopup(
@@ -40,7 +40,7 @@ public class RunKotlinConsoleAction : AnAction() {
override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return errorNotification(null, "Project not found")
KotlinConsoleModuleDialog(project).showIfNeeded(e.dataContext)
ConsoleModuleDialog(project).showIfNeeded(e.dataContext)
}
}
@@ -20,7 +20,7 @@ import com.intellij.openapi.editor.markup.GutterIconRenderer
import org.jetbrains.kotlin.console.SeverityDetails
import org.jetbrains.kotlin.diagnostics.Severity
public class KotlinConsoleErrorRenderer(private val messages: List<SeverityDetails>) : GutterIconRenderer() {
public class ConsoleErrorRenderer(private val messages: List<SeverityDetails>) : GutterIconRenderer() {
private fun msgType(severity: Severity) = when (severity) {
Severity.ERROR -> "Error:"
Severity.WARNING -> "Warning:"
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.console.gutter
import com.intellij.execution.console.BasicGutterContentProvider
import com.intellij.openapi.editor.Editor
public class KotlinConsoleGutterContentProvider : BasicGutterContentProvider() {
public class ConsoleGutterContentProvider : BasicGutterContentProvider() {
/**
* This method overriding is needed to prevent [BasicGutterContentProvider] from adding some strange unicode
* symbols of zero width and to ease range highlighting.
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.console.gutter
import com.intellij.openapi.editor.markup.GutterIconRenderer
public class KotlinConsoleIndicatorRenderer(iconWithTooltip: IconWithTooltip) : GutterIconRenderer() {
public class ConsoleIndicatorRenderer(iconWithTooltip: IconWithTooltip) : GutterIconRenderer() {
private val icon = iconWithTooltip.icon
private val tooltip = iconWithTooltip.tooltip
@@ -26,5 +26,5 @@ public class KotlinConsoleIndicatorRenderer(iconWithTooltip: IconWithTooltip) :
override fun getTooltipText() = tooltip
override fun hashCode() = icon.hashCode()
override fun equals(other: Any?) = icon == (other as? KotlinConsoleIndicatorRenderer)?.icon ?: null
override fun equals(other: Any?) = icon == (other as? ConsoleIndicatorRenderer)?.icon ?: null
}
@@ -34,7 +34,7 @@ public class KotlinReplTest : PlatformTestCase() {
override fun setUp() {
super.setUp()
consoleRunner = KotlinConsoleKeeper.getInstance(project).run(module, testMode = true)!!
consoleRunner = KotlinConsoleKeeper.getInstance(project).run(module)!!
}
override fun tearDown() {