org.jetbrains.kotlin.backend.common.CompilationException.kt Maven / Gradle / Ivy
/*
* Copyright 2010-2021 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.backend.common
import com.intellij.openapi.progress.ProcessCanceledException
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.path
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.dumpKotlinLike
import org.jetbrains.kotlin.ir.util.fileOrNull
class CompilationException(
message: String,
// file is not known in any moment, need to set it later in catch to save stacktrace
var file: IrFile?,
val ir: Any?, /* IrElement | IrType */
cause: Throwable? = null
) : RuntimeException(message, cause) {
override val message: String
get() = try {
buildString {
appendLine("Back-end: Please report this problem https://kotl.in/issue")
path?.let { appendLine("$it:$line:$column") }
content?.let { appendLine("Problem with `$it`") }
append("Details: " + super.message)
}
} catch (e: Throwable) {
throw IllegalStateException("Problem with constructing exception message").also {
it.stackTrace = stackTrace
}
}
val line: Int
get() {
val irStartOffset = irStartOffset
?: return UNDEFINED_OFFSET
if (irStartOffset == UNDEFINED_OFFSET) return UNDEFINED_OFFSET
val lineNumber = file?.fileEntry?.getLineNumber(irStartOffset)
?: return UNDEFINED_OFFSET
return lineNumber + 1
}
val column: Int
get() {
val irStartOffset = irStartOffset
?: return UNDEFINED_OFFSET
if (irStartOffset == UNDEFINED_OFFSET) return UNDEFINED_OFFSET
val columnNumber = file?.fileEntry?.getColumnNumber(irStartOffset)
?: return UNDEFINED_OFFSET
return columnNumber + 1
}
private val irStartOffset: Int?
get() = (ir as? IrElement)?.startOffset
val path: String?
get() = file?.path
val content: String?
get() = when (ir) {
is IrElement -> ir.dumpKotlinLike()
is IrType -> ir.dumpKotlinLike()
else -> null
}
}
fun compilationException(message: String, element: IrElement): Nothing {
throw CompilationException(message, null, element)
}
fun compilationException(message: String, type: IrType?): Nothing {
throw CompilationException(message, null, type)
}
fun compilationException(message: String, declaration: IrDeclaration): Nothing {
val file = try {
declaration.fileOrNull
} catch (e: Throwable) {
null
}
throw CompilationException(message, file, declaration)
}
fun Throwable.wrapWithCompilationException(
message: String,
file: IrFile,
element: IrElement?
): RuntimeException {
return if (this is ProcessCanceledException)
this
else
CompilationException(
"$message: ${this::class.qualifiedName}: ${this.message}",
file,
element,
cause = this
).apply {
stackTrace = [email protected]
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy