IR: wrap exceptions and add file path in per-file lowerings

Also add file path to the wrapped exception in JVM IR codegen
This commit is contained in:
Alexander Udalov
2019-11-28 19:17:30 +01:00
parent fd627603a0
commit 2552540f71
7 changed files with 27 additions and 66 deletions
@@ -23,7 +23,9 @@ import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.util.getExceptionMessage
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
object CodegenUtil { object CodegenUtil {
@JvmStatic @JvmStatic
@@ -236,4 +238,15 @@ object CodegenUtil {
{ it.declaresDefaultValue() } { it.declaresDefaultValue() }
) )
} }
@JvmStatic
fun reportBackendException(exception: Throwable, phase: String, fileUrl: String?): 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),
exception
)
}
} }
@@ -1,40 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen;
import org.jetbrains.kotlin.util.ExceptionUtilKt;
import static org.jetbrains.kotlin.utils.ExceptionUtilsKt.rethrow;
public class CompilationErrorHandler {
public static void reportException(Throwable exception, String fileUrl) {
// CompilationException is already supposed to have all information about the context
if (exception instanceof CompilationException) {
try {
throw exception;
}
catch (Throwable t) {
throw rethrow(t);
}
}
throw new IllegalStateException(
ExceptionUtilKt.getExceptionMessage("Backend", "Exception during code generation", exception, fileUrl),
exception
);
}
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.codegen package org.jetbrains.kotlin.codegen
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProcessCanceledException
import org.jetbrains.kotlin.backend.common.CodegenUtil import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
@@ -25,7 +24,6 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.IncrementalCompilation import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.JvmAnalysisFlags import org.jetbrains.kotlin.config.JvmAnalysisFlags
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
@@ -171,11 +169,7 @@ class MultifileClassCodegenImpl(
} catch (e: ProcessCanceledException) { } catch (e: ProcessCanceledException) {
throw e throw e
} catch (e: Throwable) { } catch (e: Throwable) {
CompilationErrorHandler.reportException(e, file.virtualFile?.url ?: "no file") CodegenUtil.reportBackendException(e, "multi-file class part code generation", file.virtualFile?.url)
DiagnosticUtils.throwIfRunningOnServer(e)
if (ApplicationManager.getApplication().isInternal) {
e.printStackTrace()
}
} }
} }
} }
@@ -288,7 +282,7 @@ class MultifileClassCodegenImpl(
} }
object DelegateToCompiledMemberGenerationStrategy : FunctionGenerationStrategy() { object DelegateToCompiledMemberGenerationStrategy : FunctionGenerationStrategy() {
override fun skipNotNullAssertionsForParameters(): kotlin.Boolean { override fun skipNotNullAssertionsForParameters(): Boolean {
throw IllegalStateException("shouldn't be called") throw IllegalStateException("shouldn't be called")
} }
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.codegen; package org.jetbrains.kotlin.codegen;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.SmartList; import com.intellij.util.SmartList;
@@ -28,7 +27,6 @@ import org.jetbrains.kotlin.codegen.context.PackageContext;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor; import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo; import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil; import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName;
@@ -73,12 +71,7 @@ public class PackageCodegenImpl implements PackageCodegen {
} }
catch (Throwable e) { catch (Throwable e) {
VirtualFile vFile = file.getVirtualFile(); VirtualFile vFile = file.getVirtualFile();
CompilationErrorHandler.reportException(e, vFile == null ? "no file" : vFile.getUrl()); CodegenUtil.reportBackendException(e, "file facade code generation", vFile == null ? null : vFile.getUrl());
DiagnosticUtils.throwIfRunningOnServer(e);
if (ApplicationManager.getApplication().isInternal()) {
//noinspection CallToPrintStackTrace
e.printStackTrace();
}
} }
} }
} }
@@ -17,9 +17,9 @@ fun getExceptionMessage(
append(subsystemName).append(" Internal error: ").appendln(message) append(subsystemName).append(" Internal error: ").appendln(message)
if (location != null) { if (location != null) {
append("File being compiled at position: ").appendln(location) append("File being compiled: ").appendln(location)
} else { } else {
append("Element is unknown") appendln("File is unknown")
} }
if (cause != null) { if (cause != null) {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.backend.common.phaser package org.jetbrains.kotlin.backend.common.phaser
import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.lower import org.jetbrains.kotlin.backend.common.lower
@@ -174,7 +175,11 @@ fun <Context : CommonBackendContext> performByIrFile(
input: IrModuleFragment input: IrModuleFragment
): IrModuleFragment { ): IrModuleFragment {
for (irFile in input.files) { for (irFile in input.files) {
lower.invoke(phaseConfig, phaserState.changeType(), context, irFile) try {
lower.invoke(phaseConfig, phaserState.changeType(), context, irFile)
} catch (e: Throwable) {
CodegenUtil.reportBackendException(e, "IR lowering", irFile.fileEntry.name)
}
} }
// TODO: no guarantee that module identity is preserved by `lower` // TODO: no guarantee that module identity is preserved by `lower`
@@ -5,13 +5,13 @@
package org.jetbrains.kotlin.backend.jvm package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
import org.jetbrains.kotlin.backend.jvm.serialization.JvmMangler import org.jetbrains.kotlin.backend.jvm.serialization.JvmMangler
import org.jetbrains.kotlin.codegen.CompilationErrorHandler
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
@@ -71,11 +71,7 @@ object JvmBackendFacade {
context.typeMapper.mapType(context.referenceClass(descriptor).defaultType) context.typeMapper.mapType(context.referenceClass(descriptor).defaultType)
} }
try { JvmLower(context).lower(irModuleFragment)
JvmLower(context).lower(irModuleFragment)
} catch (e: Throwable) {
CompilationErrorHandler.reportException(e, null)
}
for (generateMultifileFacade in listOf(true, false)) { for (generateMultifileFacade in listOf(true, false)) {
for (irFile in irModuleFragment.files) { for (irFile in irModuleFragment.files) {
@@ -95,7 +91,7 @@ object JvmBackendFacade {
} }
state.afterIndependentPart() state.afterIndependentPart()
} catch (e: Throwable) { } catch (e: Throwable) {
CompilationErrorHandler.reportException(e, null) // TODO ktFile.virtualFile.url CodegenUtil.reportBackendException(e, "code generation", irFile.fileEntry.name)
} }
} }
} }