From 6f22baa0f6f9aa6fd991278977e417579617a20d Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 6 Jun 2017 17:55:53 +0300 Subject: [PATCH] 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 --- .../messages/AnalyzerWithCompilerReport.kt | 18 +++++++++++------- .../repl/multiline/blankLinesAndComments.repl | 19 +++++++++++++++++++ .../repl/ReplInterpreterTestGenerated.java | 6 ++++++ 3 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/repl/multiline/blankLinesAndComments.repl diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt index ee9e8e93529..c04992a8ec9 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt @@ -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 reportDiagnostic(element: E, factory: DiagnosticFactory0, 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, diff --git a/compiler/testData/repl/multiline/blankLinesAndComments.repl b/compiler/testData/repl/multiline/blankLinesAndComments.repl new file mode 100644 index 00000000000..369106b7f8c --- /dev/null +++ b/compiler/testData/repl/multiline/blankLinesAndComments.repl @@ -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 diff --git a/compiler/tests/org/jetbrains/kotlin/repl/ReplInterpreterTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/repl/ReplInterpreterTestGenerated.java index 07606bf6522..e4559000631 100644 --- a/compiler/tests/org/jetbrains/kotlin/repl/ReplInterpreterTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/repl/ReplInterpreterTestGenerated.java @@ -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");