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
|
@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
|
// CompilationException (the only KotlinExceptionWithAttachments possible here) is already supposed
|
||||||
// to have all information about the context.
|
// to have all information about the context.
|
||||||
if (exception is KotlinExceptionWithAttachments) throw exception
|
if (exception is KotlinExceptionWithAttachments) throw exception
|
||||||
throw IllegalStateException(
|
throw BackendException(
|
||||||
getExceptionMessage("Backend", "Exception during $phase", exception, fileUrl),
|
getExceptionMessage("Backend", "Exception during $phase", exception, location) +
|
||||||
|
additionalMessage?.let { "\n" + it }.orEmpty(),
|
||||||
exception
|
exception
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public class PackageCodegenImpl implements PackageCodegen {
|
|||||||
}
|
}
|
||||||
catch (Throwable e) {
|
catch (Throwable e) {
|
||||||
VirtualFile vFile = file.getVirtualFile();
|
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
|
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.CallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
@@ -58,13 +61,23 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
|||||||
getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktDeclaration)
|
getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktDeclaration)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
} catch (e: BackendException) {
|
||||||
|
throw e
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
if (context.configuration.ignoreErrors) {
|
when {
|
||||||
context.irFactory.createErrorDeclaration(
|
context.configuration.ignoreErrors -> {
|
||||||
ktDeclaration.startOffsetSkippingComments, ktDeclaration.endOffset,
|
context.irFactory.createErrorDeclaration(
|
||||||
getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktDeclaration)
|
ktDeclaration.startOffsetSkippingComments, ktDeclaration.endOffset,
|
||||||
)
|
getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktDeclaration)
|
||||||
} else throw e
|
)
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-2
@@ -27,11 +27,11 @@ import org.jetbrains.kotlin.types.ErrorUtils
|
|||||||
class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||||
private val ignoreErrors: Boolean get() = context.configuration.ignoreErrors
|
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)
|
if (ignoreErrors)
|
||||||
body()
|
body()
|
||||||
else
|
else
|
||||||
throw RuntimeException("${e?.message}: ${ktElement::class.java.simpleName}:\n${ktElement.text}", e)
|
throw ErrorExpressionException(ktElement, e)
|
||||||
|
|
||||||
fun generateErrorExpression(ktElement: KtElement, e: Throwable): IrExpression =
|
fun generateErrorExpression(ktElement: KtElement, e: Throwable): IrExpression =
|
||||||
generateErrorExpression(ktElement, e) {
|
generateErrorExpression(ktElement, e) {
|
||||||
@@ -81,3 +81,8 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
package org.jetbrains.kotlin.psi2ir.generators
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.BackendException
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
@@ -73,6 +74,10 @@ class StatementGenerator(
|
|||||||
private fun KtElement.genStmt(): IrStatement =
|
private fun KtElement.genStmt(): IrStatement =
|
||||||
try {
|
try {
|
||||||
deparenthesize().accept(this@StatementGenerator, null)
|
deparenthesize().accept(this@StatementGenerator, null)
|
||||||
|
} catch (e: BackendException) {
|
||||||
|
throw e
|
||||||
|
} catch (e: ErrorExpressionException) {
|
||||||
|
throw e
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
ErrorExpressionGenerator(this@StatementGenerator).generateErrorExpression(this, e)
|
ErrorExpressionGenerator(this@StatementGenerator).generateErrorExpression(this, e)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user