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:
+11
-7
@@ -18,9 +18,7 @@ package org.jetbrains.kotlin.cli.common.messages
|
|||||||
|
|
||||||
import com.intellij.openapi.util.io.FileUtil.toSystemDependentName
|
import com.intellij.openapi.util.io.FileUtil.toSystemDependentName
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.PsiErrorElement
|
|
||||||
import com.intellij.psi.PsiModifierListOwner
|
|
||||||
import com.intellij.psi.util.PsiFormatUtil
|
import com.intellij.psi.util.PsiFormatUtil
|
||||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
||||||
@@ -170,9 +168,7 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
|
|||||||
return hasErrors
|
return hasErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reportSyntaxErrors(
|
fun reportSyntaxErrors(file: PsiElement, reporter: DiagnosticMessageReporter): SyntaxErrorReport {
|
||||||
file: PsiElement,
|
|
||||||
reporter: DiagnosticMessageReporter): SyntaxErrorReport {
|
|
||||||
class ErrorReportingVisitor : AnalyzingUtils.PsiErrorElementVisitor() {
|
class ErrorReportingVisitor : AnalyzingUtils.PsiErrorElementVisitor() {
|
||||||
var hasErrors = false
|
var hasErrors = false
|
||||||
var allErrorsAtEof = true
|
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) {
|
private fun <E : PsiElement> reportDiagnostic(element: E, factory: DiagnosticFactory0<E>, message: String) {
|
||||||
val diagnostic = MyDiagnostic(element, factory, message)
|
val diagnostic = MyDiagnostic(element, factory, message)
|
||||||
AnalyzerWithCompilerReport.reportDiagnostic(diagnostic, reporter)
|
AnalyzerWithCompilerReport.reportDiagnostic(diagnostic, reporter)
|
||||||
if (element.textRange.startOffset != file.textRange.endOffset) {
|
if (allErrorsAtEof && !element.isAtEof()) {
|
||||||
allErrorsAtEof = false
|
allErrorsAtEof = false
|
||||||
}
|
}
|
||||||
hasErrors = true
|
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) {
|
override fun visitErrorElement(element: PsiErrorElement) {
|
||||||
val description = element.errorDescription
|
val description = element.errorDescription
|
||||||
reportDiagnostic(element, SYNTAX_ERROR_FACTORY,
|
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);
|
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")
|
@TestMetadata("functionOnSeveralLines.repl")
|
||||||
public void testFunctionOnSeveralLines() throws Exception {
|
public void testFunctionOnSeveralLines() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/repl/multiline/functionOnSeveralLines.repl");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/repl/multiline/functionOnSeveralLines.repl");
|
||||||
|
|||||||
Reference in New Issue
Block a user