REPL: improve "are all errors at EOF" detection

Also ignore whitespaces and comments that appear after the last error in
a REPL line

 #KT-15172 Fixed
This commit is contained in:
Alexander Udalov
2017-06-06 17:55:53 +03:00
parent 2326b5faf3
commit 6f22baa0f6
3 changed files with 36 additions and 7 deletions
@@ -18,9 +18,7 @@ package org.jetbrains.kotlin.cli.common.messages
import com.intellij.openapi.util.io.FileUtil.toSystemDependentName
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiErrorElement
import com.intellij.psi.PsiModifierListOwner
import com.intellij.psi.*
import com.intellij.psi.util.PsiFormatUtil
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
@@ -170,9 +168,7 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
return hasErrors
}
fun reportSyntaxErrors(
file: PsiElement,
reporter: DiagnosticMessageReporter): SyntaxErrorReport {
fun reportSyntaxErrors(file: PsiElement, reporter: DiagnosticMessageReporter): SyntaxErrorReport {
class ErrorReportingVisitor : AnalyzingUtils.PsiErrorElementVisitor() {
var hasErrors = false
var allErrorsAtEof = true
@@ -180,12 +176,20 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
private fun <E : PsiElement> reportDiagnostic(element: E, factory: DiagnosticFactory0<E>, message: String) {
val diagnostic = MyDiagnostic(element, factory, message)
AnalyzerWithCompilerReport.reportDiagnostic(diagnostic, reporter)
if (element.textRange.startOffset != file.textRange.endOffset) {
if (allErrorsAtEof && !element.isAtEof()) {
allErrorsAtEof = false
}
hasErrors = true
}
private fun PsiElement.isAtEof(): Boolean {
var element = this
while (true) {
element = element.nextSibling ?: return true
if (element !is PsiWhiteSpace || element !is PsiComment) return false
}
}
override fun visitErrorElement(element: PsiErrorElement) {
val description = element.errorDescription
reportDiagnostic(element, SYNTAX_ERROR_FACTORY,
@@ -0,0 +1,19 @@
>>> fun f1(): String {
...
... return "1"
... }
>>> fun f2(): String { // comment
... return "2" // comment
... } // comment
>>> fun f3(): String {
... /* comment */
...
... // comment
... return "3"
... }
>>> fun f4(): String {
... return "4"
... }
>>>
>>> f1() + f2() + f3() + f4()
1234
@@ -281,6 +281,12 @@ public class ReplInterpreterTestGenerated extends AbstractReplInterpreterTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/repl/multiline"), Pattern.compile("^(.+)\\.repl$"), TargetBackend.ANY, true);
}
@TestMetadata("blankLinesAndComments.repl")
public void testBlankLinesAndComments() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/repl/multiline/blankLinesAndComments.repl");
doTest(fileName);
}
@TestMetadata("functionOnSeveralLines.repl")
public void testFunctionOnSeveralLines() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/repl/multiline/functionOnSeveralLines.repl");