diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/CompilationException.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/CompilationException.java index 25445136fee..d3765564c74 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/CompilationException.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/CompilationException.java @@ -16,18 +16,16 @@ package org.jetbrains.kotlin.codegen; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.util.Computable; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.diagnostics.DiagnosticUtils; +import org.jetbrains.kotlin.util.ExceptionUtilKt; public class CompilationException extends RuntimeException { private final PsiElement element; public CompilationException(@NotNull String message, @Nullable Throwable cause, @Nullable PsiElement element) { - super(getMessage(message, cause, element), cause); + super(ExceptionUtilKt.getExceptionMessage("Back-end (JVM)", message, cause, element), cause); this.element = element; } @@ -35,40 +33,4 @@ public class CompilationException extends RuntimeException { public PsiElement getElement() { return element; } - - - private static String where(@NotNull Throwable cause) { - StackTraceElement[] stackTrace = cause.getStackTrace(); - if (stackTrace != null && stackTrace.length > 0) { - return stackTrace[0].getFileName() + ":" + stackTrace[0].getLineNumber(); - } - return "unknown"; - } - - public static String getMessage(@NotNull final String message, @Nullable final Throwable cause, @Nullable final PsiElement element) { - return ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public String compute() { - StringBuilder result = - new StringBuilder("Back-end (JVM) Internal error: ").append(message).append("\n"); - if (cause != null) { - String causeMessage = cause.getMessage(); - result.append("Cause: ").append(causeMessage == null ? cause.toString() : causeMessage).append("\n"); - } - if (element != null) { - result.append("File being compiled and position: ").append(DiagnosticUtils.atLocation(element)).append("\n"); - result.append("PsiElement: ").append(element.getText()).append("\n"); - } - else { - result.append("Element is unknown"); - } - - if (cause != null) { - result.append("The root cause was thrown at: ").append(where(cause)); - } - - return result.toString(); - } - }); - } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ExceptionWrappingKtVisitorVoid.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ExceptionWrappingKtVisitorVoid.kt new file mode 100644 index 00000000000..de7c6fa3700 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ExceptionWrappingKtVisitorVoid.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2016 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.resolve + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtVisitorVoid +import org.jetbrains.kotlin.util.KotlinFrontEndException + +class ExceptionWrappingKtVisitorVoid(private val delegate: KtVisitorVoid) : KtVisitorVoid() { + override fun visitElement(element: PsiElement) { + element.accept(delegate) + } + + override fun visitDeclaration(dcl: KtDeclaration) { + try { + dcl.accept(delegate) + } catch (e: KotlinFrontEndException) { + throw e + } catch (t: Throwable) { + throw KotlinFrontEndException("Failed to analyze declaration ${dcl.name}", t, dcl) + } + } +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt index 587d0122a3c..e8856ed8e99 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt @@ -61,10 +61,12 @@ class LazyTopDownAnalyzer( // fill in the context for (declaration in declarations) { - declaration.accept(object : KtVisitorVoid() { + // The 'visitor' variable is used inside + var visitor: KtVisitorVoid? = null + visitor = ExceptionWrappingKtVisitorVoid(object : KtVisitorVoid() { private fun registerDeclarations(declarations: List) { for (jetDeclaration in declarations) { - jetDeclaration.accept(this) + jetDeclaration.accept(visitor!!) } } @@ -177,6 +179,8 @@ class LazyTopDownAnalyzer( typeAliases.add(typeAlias) } }) + + declaration.accept(visitor) } createFunctionDescriptors(c, functions) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/util/KotlinFrontEndException.kt b/compiler/frontend/src/org/jetbrains/kotlin/util/KotlinFrontEndException.kt index 685677ffced..c0daf7d9310 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/util/KotlinFrontEndException.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/util/KotlinFrontEndException.kt @@ -16,4 +16,12 @@ package org.jetbrains.kotlin.util -class KotlinFrontEndException(message: String, cause: Throwable) : RuntimeException(message, cause) +import com.intellij.psi.PsiElement + +class KotlinFrontEndException(message: String, cause: Throwable) : RuntimeException(message, cause) { + constructor( + message: String, + cause: Throwable, + element: PsiElement + ) : this(getExceptionMessage("Front-end", message, cause, element), cause) +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/util/exceptionUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/util/exceptionUtil.kt new file mode 100644 index 00000000000..bf2ccffaf25 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/util/exceptionUtil.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2010-2016 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.util + +import com.intellij.openapi.application.ApplicationManager +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.diagnostics.DiagnosticUtils + +fun getExceptionMessage( + subsystemName: String, + message: String, + cause: Throwable?, + element: PsiElement? +): String = ApplicationManager.getApplication().runReadAction { + val result = StringBuilder(subsystemName + " Internal error: ").append(message).append("\n") + if (cause != null) { + val causeMessage = cause.message + result.append("Cause: ").append(causeMessage ?: cause.toString()).append("\n") + } + + if (element != null) { + result.append("File being compiled and position: ").append(DiagnosticUtils.atLocation(element)).append("\n") + result.append("PsiElement: ").append(element.text).append("\n") + } + else { + result.append("Element is unknown") + } + + if (cause != null) { + result.append("The root cause was thrown at: ").append(where(cause)) + } + + result.toString() + } + +private fun where(cause: Throwable): String { + val stackTrace = cause.stackTrace + if (stackTrace != null && stackTrace.size > 0) { + return stackTrace[0].fileName + ":" + stackTrace[0].lineNumber + } + return "unknown" +}