Psi2ir: improve exception stack traces
- Do not wrap exceptions resulting from generating error expressions multiple times, as that could lead to stack traces where the identical code is wrapped many times and is printed in the exception message on each step, which was difficult to read - Add element location (file name, line number & position) to the message, similarly to exceptions from codegen, when catching and rethrowing exceptions at the top level
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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
|
||||
|
||||
class BackendException(message: String, cause: Throwable?) : IllegalStateException(message, cause)
|
||||
@@ -232,12 +232,13 @@ object CodegenUtil {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun reportBackendException(exception: Throwable, phase: String, fileUrl: String?): Nothing {
|
||||
fun reportBackendException(exception: Throwable, phase: String, location: String?, additionalMessage: String? = null): Nothing {
|
||||
// CompilationException (the only KotlinExceptionWithAttachments possible here) is already supposed
|
||||
// to have all information about the context.
|
||||
if (exception is KotlinExceptionWithAttachments) throw exception
|
||||
throw IllegalStateException(
|
||||
getExceptionMessage("Backend", "Exception during $phase", exception, fileUrl),
|
||||
throw BackendException(
|
||||
getExceptionMessage("Backend", "Exception during $phase", exception, location) +
|
||||
additionalMessage?.let { "\n" + it }.orEmpty(),
|
||||
exception
|
||||
)
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public class PackageCodegenImpl implements PackageCodegen {
|
||||
}
|
||||
catch (Throwable e) {
|
||||
VirtualFile vFile = file.getVirtualFile();
|
||||
CodegenUtil.reportBackendException(e, "file facade code generation", vFile == null ? null : vFile.getUrl());
|
||||
CodegenUtil.reportBackendException(e, "file facade code generation", vFile == null ? null : vFile.getUrl(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+19
-6
@@ -16,10 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendException
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
@@ -58,13 +61,23 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktDeclaration)
|
||||
)
|
||||
}
|
||||
} catch (e: BackendException) {
|
||||
throw e
|
||||
} catch (e: Throwable) {
|
||||
if (context.configuration.ignoreErrors) {
|
||||
context.irFactory.createErrorDeclaration(
|
||||
ktDeclaration.startOffsetSkippingComments, ktDeclaration.endOffset,
|
||||
getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktDeclaration)
|
||||
)
|
||||
} else throw e
|
||||
when {
|
||||
context.configuration.ignoreErrors -> {
|
||||
context.irFactory.createErrorDeclaration(
|
||||
ktDeclaration.startOffsetSkippingComments, ktDeclaration.endOffset,
|
||||
getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktDeclaration)
|
||||
)
|
||||
}
|
||||
e is ErrorExpressionException ->
|
||||
CodegenUtil.reportBackendException(e.cause ?: e, "psi2ir", PsiDiagnosticUtils.atLocation(e.ktElement), e.message)
|
||||
else -> {
|
||||
val psiFile = ktDeclaration.containingKtFile
|
||||
CodegenUtil.reportBackendException(e, "psi2ir", psiFile.virtualFile?.path ?: psiFile.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-3
@@ -27,11 +27,11 @@ import org.jetbrains.kotlin.types.ErrorUtils
|
||||
class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
private val ignoreErrors: Boolean get() = context.configuration.ignoreErrors
|
||||
|
||||
private inline fun generateErrorExpression(ktElement: KtElement, e: Throwable? = null, body: () -> IrExpression) =
|
||||
private inline fun generateErrorExpression(ktElement: KtElement, e: Throwable? = null, body: () -> IrExpression): IrExpression =
|
||||
if (ignoreErrors)
|
||||
body()
|
||||
else
|
||||
throw RuntimeException("${e?.message}: ${ktElement::class.java.simpleName}:\n${ktElement.text}", e)
|
||||
throw ErrorExpressionException(ktElement, e)
|
||||
|
||||
fun generateErrorExpression(ktElement: KtElement, e: Throwable): IrExpression =
|
||||
generateErrorExpression(ktElement, e) {
|
||||
@@ -80,4 +80,9 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
|
||||
irErrorCall
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class ErrorExpressionException(val ktElement: KtElement, cause: Throwable?) : RuntimeException(
|
||||
"${cause?.message}: ${ktElement::class.java.simpleName}:\n${ktElement.text}",
|
||||
cause
|
||||
)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendException
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
@@ -73,6 +74,10 @@ class StatementGenerator(
|
||||
private fun KtElement.genStmt(): IrStatement =
|
||||
try {
|
||||
deparenthesize().accept(this@StatementGenerator, null)
|
||||
} catch (e: BackendException) {
|
||||
throw e
|
||||
} catch (e: ErrorExpressionException) {
|
||||
throw e
|
||||
} catch (e: Throwable) {
|
||||
ErrorExpressionGenerator(this@StatementGenerator).generateErrorExpression(this, e)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user