Scratch: find correct line to report error at
^KT-23480 Fixed EA-117936 Fixed
This commit is contained in:
+29
-14
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
||||
import java.io.File
|
||||
|
||||
@@ -180,8 +181,12 @@ class KtCompilingExecutor(file: ScratchFile) : ScratchExecutor(file) {
|
||||
if (psiFile == scratchPsiFile) {
|
||||
if (diagnostic.psiElement.containingFile == psiFile) {
|
||||
val scratchExpression = file.findExpression(diagnostic.psiElement)
|
||||
handlers.forEach {
|
||||
it.handle(file, scratchExpression, ScratchOutput(errorText, ScratchOutputType.ERROR))
|
||||
if (scratchExpression == null) {
|
||||
LOG.error("Couldn't find expression to report error: ${diagnostic.psiElement.getElementTextWithContext()}")
|
||||
handlers.forEach { it.error(file, errorText) }
|
||||
|
||||
} else {
|
||||
handlers.forEach { it.handle(file, scratchExpression, ScratchOutput(errorText, ScratchOutputType.ERROR)) }
|
||||
}
|
||||
} else {
|
||||
handlers.forEach { it.error(file, errorText) }
|
||||
@@ -201,12 +206,14 @@ class KtCompilingExecutor(file: ScratchFile) : ScratchExecutor(file) {
|
||||
handlers.forEach { it.onFinish(file) }
|
||||
}
|
||||
|
||||
private fun ScratchFile.findExpression(psiElement: PsiElement): ScratchExpression {
|
||||
return findExpression(psiElement.getLineNumber(true), psiElement.getLineNumber(false))
|
||||
private fun ScratchFile.findExpression(psiElement: PsiElement): ScratchExpression? {
|
||||
val lineStart = psiElement.getLineNumber(true)
|
||||
val lineEnd = psiElement.getLineNumber(false)
|
||||
return getExpressions().firstOrNull { it.lineStart == lineStart || it.lineEnd == lineEnd }
|
||||
}
|
||||
|
||||
private fun ScratchFile.findExpression(lineStart: Int, lineEnd: Int): ScratchExpression {
|
||||
return getExpressions().first { it.lineStart == lineStart && it.lineEnd == lineEnd }
|
||||
private fun ScratchFile.findExpression(lineStart: Int, lineEnd: Int): ScratchExpression? {
|
||||
return getExpressions().firstOrNull { it.lineStart == lineStart && it.lineEnd == lineEnd }
|
||||
}
|
||||
|
||||
private inner class ProcessOutputParser {
|
||||
@@ -234,18 +241,26 @@ class KtCompilingExecutor(file: ScratchFile) : ScratchExecutor(file) {
|
||||
if (isGeneratedOutput(line)) {
|
||||
val lineWoPrefix = line.removePrefix(KtScratchSourceFileProcessor.GENERATED_OUTPUT_PREFIX)
|
||||
if (isResultEnd(lineWoPrefix)) {
|
||||
val (startLine, endLine) = extractLineInfoFrom(lineWoPrefix)
|
||||
val extractedLineInfo = extractLineInfoFrom(lineWoPrefix)
|
||||
?: return error("Couldn't extract line info from line: $lineWoPrefix")
|
||||
val (startLine, endLine) = extractedLineInfo
|
||||
val scratchExpression = file.findExpression(startLine, endLine)
|
||||
userOutput.forEach { output ->
|
||||
handlers.forEach {
|
||||
it.handle(file, scratchExpression, ScratchOutput(output, ScratchOutputType.OUTPUT))
|
||||
if (scratchExpression == null) {
|
||||
LOG.error(
|
||||
"Couldn't find expression with start line = $startLine, end line = $endLine.\n" +
|
||||
file.getExpressions().joinToString("\n")
|
||||
)
|
||||
} else {
|
||||
userOutput.forEach { output ->
|
||||
handlers.forEach {
|
||||
it.handle(file, scratchExpression, ScratchOutput(output, ScratchOutputType.OUTPUT))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results.forEach { result ->
|
||||
handlers.forEach {
|
||||
it.handle(file, scratchExpression, ScratchOutput(result, ScratchOutputType.RESULT))
|
||||
results.forEach { result ->
|
||||
handlers.forEach {
|
||||
it.handle(file, scratchExpression, ScratchOutput(result, ScratchOutputType.RESULT))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
foo.forEach { // ERROR: Unresolved reference: foo; Cannot choose among the following candidates without completing type inference:
|
||||
1 + 1
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
foo.forEach {
|
||||
1 + 1
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
foo.forEach { // ERROR: error: unresolved reference: foo
|
||||
1 + 1
|
||||
}
|
||||
+10
@@ -66,6 +66,11 @@ public class ScratchRunActionTestGenerated extends AbstractScratchRunActionTest
|
||||
runTest("idea/testData/scratch/unresolved.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("unresolvedMultiline.kts")
|
||||
public void testUnresolvedMultiline() throws Exception {
|
||||
runTest("idea/testData/scratch/unresolvedMultiline.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("userOutput.kts")
|
||||
public void testUserOutput() throws Exception {
|
||||
runTest("idea/testData/scratch/userOutput.kts");
|
||||
@@ -129,6 +134,11 @@ public class ScratchRunActionTestGenerated extends AbstractScratchRunActionTest
|
||||
runTest("idea/testData/scratch/unresolved.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("unresolvedMultiline.kts")
|
||||
public void testUnresolvedMultiline() throws Exception {
|
||||
runTest("idea/testData/scratch/unresolvedMultiline.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("userOutput.kts")
|
||||
public void testUserOutput() throws Exception {
|
||||
runTest("idea/testData/scratch/userOutput.kts");
|
||||
|
||||
Reference in New Issue
Block a user