[FIR] KT-56846: Unwrap SourceCodeAnalysisException on transformFile
^KT-56846 Fixed Merge-request: KT-MR-9065 Merged-by: Nikolay Lunyak <Nikolay.Lunyak@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
7b04201e77
commit
a2e2a96fd3
@@ -5,11 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.util
|
||||
|
||||
import com.intellij.lang.LighterASTNode
|
||||
import com.intellij.openapi.diagnostic.ControlFlowException
|
||||
import com.intellij.openapi.project.IndexNotReadyException
|
||||
import org.jetbrains.kotlin.AbstractKtSourceElement
|
||||
import org.jetbrains.kotlin.KtRealSourceElementKind
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||
import org.jetbrains.kotlin.*
|
||||
|
||||
val Throwable.classNameAndMessage get() = "${this::class.qualifiedName}: $message"
|
||||
|
||||
@@ -43,22 +43,60 @@ class FileAnalysisException(
|
||||
|
||||
fun Throwable.wrapIntoFileAnalysisExceptionIfNeeded(
|
||||
filePath: String?,
|
||||
fileSource: AbstractKtSourceElement?,
|
||||
fileSource: KtSourceElement?,
|
||||
linesMapping: (Int) -> Pair<Int, Int>?,
|
||||
) = when {
|
||||
filePath == null -> this
|
||||
|
||||
this is SourceCodeAnalysisException -> when (fileSource) {
|
||||
source -> FileAnalysisException(filePath, cause)
|
||||
filePath == null || fileSource == null -> when (this) {
|
||||
is SourceCodeAnalysisException -> error("Sourceless FirFile contains a FirElement with a real source element")
|
||||
else -> this
|
||||
}
|
||||
this is SourceCodeAnalysisException -> when {
|
||||
fileSource == source -> FileAnalysisException(filePath, cause)
|
||||
source.isDefinitelyNotInsideFile(fileSource) -> reportFileMismatch(source, fileSource, cause)
|
||||
else -> FileAnalysisException(filePath, cause, linesMapping(source.startOffset))
|
||||
}
|
||||
|
||||
this is IndexNotReadyException -> this
|
||||
this is ControlFlowException -> this
|
||||
this is VirtualMachineError -> this
|
||||
else -> FileAnalysisException(filePath, this)
|
||||
}
|
||||
|
||||
private fun KtSourceElement.isDefinitelyNotInsideFile(fileSource: KtSourceElement): Boolean {
|
||||
val thisPsi = psi
|
||||
val otherPsi = fileSource.psi
|
||||
|
||||
return when {
|
||||
thisPsi != null && otherPsi != null -> thisPsi.containingFile != otherPsi
|
||||
else -> !lighterASTNode.isInside(fileSource.lighterASTNode, treeStructure)
|
||||
}
|
||||
}
|
||||
|
||||
private fun reportFileMismatch(source: KtSourceElement, fileSource: KtSourceElement, cause: Throwable): Throwable {
|
||||
val thisPsi = source.psi
|
||||
val otherPsi = fileSource.psi
|
||||
val comparison = "This:\n\n${source.text?.asQuote}\n\n...is not present in"
|
||||
|
||||
val expectedFileMessage = if (thisPsi != null && otherPsi != null) {
|
||||
val actualPath = thisPsi.containingFile.virtualFile.path
|
||||
val expectedPath = otherPsi.containingFile.virtualFile.path
|
||||
"$expectedPath, but rather in $actualPath"
|
||||
} else {
|
||||
"...${fileSource.text?.asQuote}"
|
||||
}
|
||||
|
||||
return IllegalStateException(
|
||||
"KtSourceElement inside a SourceCodeAnalysisException was matched against the wrong FirFile source. $comparison$expectedFileMessage",
|
||||
cause,
|
||||
)
|
||||
}
|
||||
|
||||
private val CharSequence.asQuote: String
|
||||
get() = split("\n").joinToString("\n") { "> $it" }
|
||||
|
||||
private fun LighterASTNode.isInside(other: LighterASTNode, tree: FlyweightCapableTreeStructure<LighterASTNode>): Boolean {
|
||||
return generateSequence(tree.getParent(this)) { tree.getParent(it) }.any { it == other }
|
||||
}
|
||||
|
||||
inline fun <R> withSourceCodeAnalysisExceptionUnwrapping(block: () -> R): R {
|
||||
return try {
|
||||
block()
|
||||
|
||||
Reference in New Issue
Block a user