[FIR] KT-44698: Print file:line:offset on K2 crash

^KT-44698 Fixed
This commit is contained in:
Nikolay Lunyak
2022-09-21 15:08:52 +03:00
committed by teamcity
parent bba5b87733
commit 2e9f9f987b
24 changed files with 363 additions and 147 deletions
@@ -0,0 +1,90 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.util
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
val Throwable.classNameAndMessage get() = "${this::class.qualifiedName}: $message"
class SourceCodeAnalysisException(val source: KtSourceElement, override val cause: Throwable) : Exception() {
override val message get() = cause.classNameAndMessage
}
inline fun <R> whileAnalysing(element: KtSourceElement?, block: () -> R): R {
return try {
block()
} catch (throwable: Throwable) {
throw throwable.wrapIntoSourceCodeAnalysisExceptionIfNeeded(element)
}
}
@PublishedApi
internal fun Throwable.wrapIntoSourceCodeAnalysisExceptionIfNeeded(element: KtSourceElement?) = when (this) {
is SourceCodeAnalysisException -> this
is IndexNotReadyException -> this
is ControlFlowException -> this
is VirtualMachineError -> this
else -> when (element?.kind) {
is KtRealSourceElementKind -> SourceCodeAnalysisException(element, this)
else -> this
}
}
class FileAnalysisException(
private val path: String,
override val cause: Throwable,
private val lineAndOffset: Pair<Int, Int>? = null,
) : Exception() {
override val message
get(): String {
val (line, offset) = lineAndOffset ?: return "Somewhere in file $path: ${cause.classNameAndMessage}"
return "While analysing $path:${line + 1}:${offset + 1}: ${cause.classNameAndMessage}"
}
}
inline fun <R> withFileAnalysisExceptionWrapping(
filePath: String?,
fileSource: AbstractKtSourceElement?,
crossinline linesMapping: (Int) -> Pair<Int, Int>?,
block: () -> R,
): R {
return try {
block()
} catch (throwable: Throwable) {
throw throwable.wrapIntoFileAnalysisExceptionIfNeeded(filePath, fileSource) { linesMapping(it) }
}
}
@PublishedApi
internal fun Throwable.wrapIntoFileAnalysisExceptionIfNeeded(
filePath: String?,
fileSource: AbstractKtSourceElement?,
linesMapping: (Int) -> Pair<Int, Int>?,
) = when {
filePath == null -> this
this is SourceCodeAnalysisException -> when (fileSource) {
source -> FileAnalysisException(filePath, cause)
else -> FileAnalysisException(filePath, cause, linesMapping(source.startOffset))
}
this is IndexNotReadyException -> this
this is ControlFlowException -> this
this is VirtualMachineError -> this
else -> FileAnalysisException(filePath, this)
}
inline fun <R> withSourceCodeAnalysisExceptionUnwrapping(block: () -> R): R {
return try {
block()
} catch (throwable: Throwable) {
throw if (throwable is SourceCodeAnalysisException) throwable.cause else throwable
}
}