JS: make kotlin.Throwable = Error. See KT-15312

This commit is contained in:
Alexey Andreev
2016-12-29 13:37:30 +03:00
parent c565697e77
commit f34093db9f
18 changed files with 299 additions and 52 deletions
@@ -0,0 +1,9 @@
fun box(): String {
var t = Throwable("O", Throwable("K"))
if (t.message != "O" || t.cause?.message != "K") return "fail1"
t = Throwable(Throwable("OK"))
if (t.message != null || t.cause?.message != "OK") return "fail2"
return "OK"
}
@@ -0,0 +1,3 @@
public final class ThrowableCauseKt {
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
}
@@ -16223,6 +16223,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
doTest(fileName);
}
@TestMetadata("throwableCause.kt")
public void testThrowableCause() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/throwableCause.kt");
doTest(fileName);
}
@TestMetadata("throwableImpl.kt")
public void testThrowableImpl() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/throwableImpl.kt");
@@ -16223,6 +16223,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("throwableCause.kt")
public void testThrowableCause() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/throwableCause.kt");
doTest(fileName);
}
@TestMetadata("throwableImpl.kt")
public void testThrowableImpl() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/throwableImpl.kt");
@@ -16223,6 +16223,12 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis
doTest(fileName);
}
@TestMetadata("throwableCause.kt")
public void testThrowableCause() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/throwableCause.kt");
doTest(fileName);
}
@TestMetadata("throwableImpl.kt")
public void testThrowableImpl() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/throwableImpl.kt");
@@ -601,6 +601,19 @@ public class DescriptorUtils {
throw new IllegalStateException("Function not found");
}
@NotNull
public static PropertyDescriptor getPropertyByName(@NotNull MemberScope scope, @NotNull Name name) {
Collection<DeclarationDescriptor> callables = scope.getContributedDescriptors(
DescriptorKindFilter.CALLABLES, MemberScope.Companion.getALL_NAME_FILTER());
for (DeclarationDescriptor d : callables) {
if (d instanceof PropertyDescriptor && name.equals(d.getOriginal().getName())) {
return (PropertyDescriptor) d;
}
}
throw new IllegalStateException("Property not found");
}
@NotNull
public static CallableMemberDescriptor getDirectMember(@NotNull CallableMemberDescriptor descriptor) {
return descriptor instanceof PropertyAccessorDescriptor
@@ -25,10 +25,10 @@ public abstract class JsExpression extends SourceInfoAwareJsNode {
return new JsExpressionStatement(this);
}
protected abstract static class JsExpressionHasArguments extends JsExpression implements HasArguments {
public abstract static class JsExpressionHasArguments extends JsExpression implements HasArguments {
protected final List<JsExpression> arguments;
public JsExpressionHasArguments(List<JsExpression> arguments) {
protected JsExpressionHasArguments(List<JsExpression> arguments) {
this.arguments = arguments;
}
-47
View File
@@ -1,47 +0,0 @@
/*
* 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 kotlin
import kotlin.js.internal.JsError
/**
* The base class for all errors and exceptions. Only instances of this class can be thrown or caught.
*
* @param message the detail message string.
* @param cause the cause of this throwable.
*/
public open class Throwable(open val message: String?, open val cause: Throwable?) : JsError(message) {
constructor(message: String?) : this(message, null)
constructor(cause: Throwable?) : this(cause?.toString(), cause)
constructor() : this(null, null)
init {
var e = JsError(message)
copyOwnProperties(e, this)
val t: dynamic = this
t.name = t.constructor.name
}
}
private fun copyOwnProperties(from: dynamic, to: dynamic) {
val names: Array<String> = js("Object").getOwnPropertyNames(from);
for (name in names) {
to[name] = from[name];
}
}
+18
View File
@@ -46,4 +46,22 @@ fun subSequence(c: CharSequence, startIndex: Int, endIndex: Int): CharSequence {
else {
return c.asDynamic().`subSequence_vux9f0$`(startIndex, endIndex)
}
}
@JsName("captureStack")
internal fun captureStack(baseClass: JsClass<in Throwable>, instance: Throwable) {
if (js("Error").captureStackTrace) {
js("Error").captureStackTrace(instance, instance::class.js);
}
else {
instance.asDynamic().stack = js("new Error()").stack;
}
}
@JsName("newThrowable")
internal fun newThrowable(message: String?, cause: Throwable?): Throwable {
val throwable = js("new Error()")
throwable.message = message
throwable.cause = cause
return throwable
}
@@ -20487,6 +20487,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
doTest(fileName);
}
@TestMetadata("throwableCause.kt")
public void testThrowableCause() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/throwableCause.kt");
doTest(fileName);
}
@TestMetadata("throwableImpl.kt")
public void testThrowableImpl() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/throwableImpl.kt");
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.calls.tasks.DynamicCallsKt;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.serialization.js.ModuleKind;
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
import java.util.*;
@@ -248,6 +249,9 @@ public final class StaticContext {
if (KotlinBuiltIns.isAny(classDescriptor)) {
return pureFqn("Object", null);
}
else if (TypeUtilsKt.isThrowable(classDescriptor.getDefaultType())) {
return pureFqn("Error", null);
}
}
SuggestedName suggested = nameSuggestion.suggest(descriptor);
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getSupertypesWithoutFakes
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getPrimaryConstructorParameters
import org.jetbrains.kotlin.js.translate.utils.jsAstUtils.toInvocationWith
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.psi.KtSecondaryConstructor
@@ -87,6 +88,7 @@ class ClassTranslator private constructor(
translatePropertiesAsConstructorParameters(nonConstructorContext)
val bodyVisitor = DeclarationBodyVisitor(descriptor, nonConstructorContext, enumInitFunction)
bodyVisitor.traverseContainer(classDeclaration, nonConstructorContext)
mayBeAddThrowableProperties(context)
constructorFunction.body.statements += bodyVisitor.initializerStatements
delegationTranslator.generateDelegated()
@@ -455,6 +457,23 @@ class ClassTranslator private constructor(
EnumTranslator(context(), descriptor, entries).generateStandardMethods()
}
private fun mayBeAddThrowableProperties(context: TranslationContext) {
if (!TranslationUtils.isImmediateSubtypeOfError(descriptor)) return
val properties = listOf("message", "cause")
.map { Name.identifier(it) }
.map { DescriptorUtils.getPropertyByName(descriptor.unsubstitutedMemberScope, it) }
.filter { !it.kind.isReal }
for (property in properties) {
val propertyTranslator = DefaultPropertyTranslator(property, context, JsLiteral.NULL)
val literal = JsObjectLiteral(true)
val getterFunction = context.getFunctionObject(property.getter!!)
propertyTranslator.generateDefaultGetterFunction(property.getter!!, getterFunction)
literal.propertyInitializers += JsPropertyInitializer(context.program().getStringLiteral("get"), getterFunction)
context.addAccessorsToPrototype(descriptor, property, literal)
}
}
private fun generatedBridgeMethods() {
if (isAnnotation()) return
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.js.translate.initializer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor;
import org.jetbrains.kotlin.js.backend.ast.*;
@@ -26,21 +27,28 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.context.UsageTracker;
import org.jetbrains.kotlin.js.translate.declaration.DelegationTranslator;
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
import org.jetbrains.kotlin.js.translate.general.Translation;
import org.jetbrains.kotlin.js.translate.reference.CallArgumentTranslator;
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator;
import org.jetbrains.kotlin.js.translate.utils.BindingUtils;
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils;
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
import org.jetbrains.kotlin.js.translate.utils.jsAstUtils.AstUtilsKt;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.KtClassOrObject;
import org.jetbrains.kotlin.psi.KtEnumEntry;
import org.jetbrains.kotlin.psi.KtExpression;
import org.jetbrains.kotlin.psi.KtParameter;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument;
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
import java.util.ArrayList;
import java.util.Arrays;
@@ -63,6 +71,8 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
@NotNull
private final ClassDescriptor classDescriptor;
private final ConstructorDescriptor primaryConstructor;
private int ordinal;
public ClassInitializerTranslator(
@@ -75,6 +85,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
this.initFunction = initFunction;
this.context = context.contextWithScope(initFunction);
classDescriptor = BindingUtils.getClassDescriptor(bindingContext(), classDeclaration);
primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
}
public void setOrdinal(int ordinal) {
@@ -89,7 +100,6 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
public void generateInitializeMethod(DelegationTranslator delegationTranslator) {
addOuterClassReference(classDescriptor);
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
if (primaryConstructor != null) {
initFunction.getBody().getStatements().addAll(setDefaultValueForArguments(primaryConstructor, context()));
@@ -106,6 +116,8 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
}
}
addThrowableCall();
delegationTranslator.addInitCode(initFunction.getBody().getStatements());
new InitializerVisitor().traverseContainer(classDeclaration, context().innerBlock(initFunction.getBody()));
}
@@ -168,6 +180,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
}
else if (hasAncestorClass(bindingContext(), classDeclaration)) {
ResolvedCall<FunctionDescriptor> superCall = getSuperCall(bindingContext(), classDeclaration);
if (superCall == null) {
if (DescriptorUtils.isEnumEntry(classDescriptor)) {
addCallToSuperMethod(getAdditionalArgumentsForEnumConstructor(), initializer);
@@ -175,6 +188,11 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
return;
}
if (TranslationUtils.isImmediateSubtypeOfError(classDescriptor)) {
emulateSuperCallToNativeError(superCall);
return;
}
if (classDeclaration instanceof KtEnumEntry) {
JsExpression expression = CallTranslator.translate(context(), superCall, null);
@@ -239,6 +257,49 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
}
}
private void emulateSuperCallToNativeError(@NotNull ResolvedCall<FunctionDescriptor> superCall) {
ClassDescriptor superClass = DescriptorUtilsKt.getSuperClassOrAny(classDescriptor);
JsExpression superClassRef = ReferenceTranslator.translateAsTypeReference(superClass, context);
JsExpression superInvocation = new JsInvocation(Namer.getFunctionCallRef(superClassRef), JsLiteral.THIS);
initFunction.getBody().getStatements().add(JsAstUtils.asSyntheticStatement(superInvocation));
JsExpression messageArgument = JsLiteral.NULL;
JsExpression causeArgument = JsLiteral.NULL;
for (ValueParameterDescriptor param : superCall.getResultingDescriptor().getValueParameters()) {
ResolvedValueArgument argument = superCall.getValueArguments().get(param);
if (!(argument instanceof ExpressionValueArgument)) continue;
ExpressionValueArgument exprArgument = (ExpressionValueArgument) argument;
assert exprArgument.getValueArgument() != null;
KtExpression value = exprArgument.getValueArgument().getArgumentExpression();
assert value != null;
JsExpression jsValue = Translation.translateAsExpression(value, context);
if (KotlinBuiltIns.isStringOrNullableString(param.getType())) {
messageArgument = jsValue;
}
else if (TypeUtilsKt.isConstructedFromClassWithGivenFqName(param.getType(), KotlinBuiltIns.FQ_NAMES.throwable)) {
causeArgument = jsValue;
}
else {
initFunction.getBody().getStatements().add(JsAstUtils.asSyntheticStatement(jsValue));
}
}
PropertyDescriptor messageProperty = DescriptorUtils.getPropertyByName(
classDescriptor.getUnsubstitutedMemberScope(), Name.identifier("message"));
JsExpression messageRef = pureFqn(context.getNameForBackingField(messageProperty), JsLiteral.THIS);
initFunction.getBody().getStatements().add(JsAstUtils.asSyntheticStatement(
JsAstUtils.assignment(messageRef, messageArgument)));
PropertyDescriptor causeProperty = DescriptorUtils.getPropertyByName(
classDescriptor.getUnsubstitutedMemberScope(), Name.identifier("cause"));
JsExpression causeRef = pureFqn(context.getNameForBackingField(causeProperty), JsLiteral.THIS);
initFunction.getBody().getStatements().add(JsAstUtils.asSyntheticStatement(
JsAstUtils.assignment(causeRef, causeArgument)));
}
@NotNull
private List<JsExpression> getAdditionalArgumentsForEnumConstructor() {
List<JsExpression> additionalArguments = new ArrayList<JsExpression>();
@@ -302,4 +363,21 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
initFunction.getBody().getStatements().add(
InitializerUtils.generateInitializerForProperty(context(), propertyDescriptor, initialValue));
}
private void addThrowableCall() {
if (!TranslationUtils.isExceptionClass(classDescriptor)) return;
if (TranslationUtils.isImmediateSubtypeOfError(classDescriptor)) {
ClassDescriptor superClass = DescriptorUtilsKt.getSuperClassOrAny(classDescriptor);
JsExpression invocation = new JsInvocation(
pureFqn("captureStack", Namer.kotlinObject()),
ReferenceTranslator.translateAsTypeReference(superClass, context()),
JsLiteral.THIS);
initFunction.getBody().getStatements().add(JsAstUtils.asSyntheticStatement(invocation));
}
JsExpression nameLiteral = context.program().getStringLiteral(context.getInnerNameForDescriptor(classDescriptor).getIdent());
JsExpression nameAssignment = JsAstUtils.assignment(pureFqn("name", JsLiteral.THIS), nameLiteral);
initFunction.getBody().getStatements().add(JsAstUtils.asSyntheticStatement(nameAssignment));
}
}
@@ -46,6 +46,8 @@ public final class FunctionIntrinsics {
register(ArrayFIF.INSTANCE);
register(TopLevelFIF.INSTANCE);
register(NumberAndCharConversionFIF.INSTANCE);
register(ThrowableConstructorIntrinsicFactory.INSTANCE);
register(ExceptionPropertyIntrinsicFactory.INSTANCE);
}
private void register(@NotNull FunctionIntrinsicFactory instance) {
@@ -0,0 +1,58 @@
/*
* 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.js.translate.intrinsic.functions.factories
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor
import org.jetbrains.kotlin.js.backend.ast.JsExpression
import org.jetbrains.kotlin.js.backend.ast.JsNameRef
import org.jetbrains.kotlin.js.translate.callTranslator.CallInfo
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.receivers.SuperCallReceiverValue
import org.jetbrains.kotlin.types.typeUtil.isThrowable
object ExceptionPropertyIntrinsicFactory : FunctionIntrinsicFactory {
override fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? {
if (descriptor !is PropertyGetterDescriptor) return null
val classDescriptor = descriptor.correspondingProperty.containingDeclaration as? ClassDescriptor ?: return null
if (!classDescriptor.defaultType.isThrowable()) return null
return Intrinsic
}
object Intrinsic : FunctionIntrinsic() {
override fun apply(callInfo: CallInfo, arguments: List<JsExpression>, context: TranslationContext): JsExpression {
val property = callInfo.resolvedCall.resultingDescriptor as PropertyDescriptor
if (callInfo.resolvedCall.call.explicitReceiver !is SuperCallReceiverValue) {
val name = context.getNameForDescriptor(property)
return JsNameRef(name, callInfo.dispatchReceiver!!)
}
val currentClassProperty = context.classDescriptor!!.unsubstitutedMemberScope
.getContributedDescriptors(DescriptorKindFilter.CALLABLES)
.filterIsInstance<PropertyDescriptor>()
.first { it.overriddenDescriptors.any { it == property } }
val fieldRef = JsAstUtils.pureFqn(context.getNameForBackingField(currentClassProperty), callInfo.dispatchReceiver!!)
return fieldRef
}
}
}
@@ -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.js.translate.intrinsic.functions.factories
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.js.backend.ast.JsExpression
import org.jetbrains.kotlin.js.backend.ast.JsInvocation
import org.jetbrains.kotlin.js.backend.ast.JsLiteral
import org.jetbrains.kotlin.js.translate.callTranslator.CallInfo
import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.typeUtil.isThrowable
object ThrowableConstructorIntrinsicFactory : FunctionIntrinsicFactory {
override fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? {
if (descriptor !is ConstructorDescriptor) return null
if (!descriptor.constructedClass.defaultType.isThrowable()) return null
return Intrinsic
}
object Intrinsic : FunctionIntrinsic() {
override fun apply(callInfo: CallInfo, arguments: List<JsExpression>, context: TranslationContext): JsExpression {
val constructor = callInfo.resolvedCall.resultingDescriptor
val argumentsToPass = arguments.toMutableList()
val hasCauseParameter = constructor.valueParameters.any {
it.type.constructor.declarationDescriptor?.fqNameSafe == KotlinBuiltIns.FQ_NAMES.throwable
}
if (constructor.valueParameters.size == 1 && hasCauseParameter) {
argumentsToPass.add(0, JsLiteral.NULL)
}
return JsInvocation(JsAstUtils.pureFqn("newThrowable", Namer.kotlinObject()), argumentsToPass)
}
}
}
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
import org.jetbrains.kotlin.serialization.deserialization.FindClassInModuleKt;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
import java.util.ArrayList;
import java.util.List;
@@ -399,4 +400,15 @@ public final class TranslationUtils {
ModalityKt.isOverridable(descriptor);
}
public static boolean isImmediateSubtypeOfError(@NotNull ClassDescriptor descriptor) {
if (!isExceptionClass(descriptor)) return false;
ClassDescriptor superClass = DescriptorUtilsKt.getSuperClassOrAny(descriptor);
return TypeUtilsKt.isThrowable(superClass.getDefaultType()) || AnnotationsUtils.isNativeObject(superClass);
}
public static boolean isExceptionClass(@NotNull ClassDescriptor descriptor) {
ModuleDescriptor module = DescriptorUtils.getContainingModule(descriptor);
return TypeUtilsKt.isSubtypeOf(descriptor.getDefaultType(), module.getBuiltIns().getThrowable().getDefaultType());
}
}
@@ -13,8 +13,6 @@ fun check(e: Throwable, expectedString: String) {
}
fun box(): String {
check(Throwable(), "Throwable: null")
check(Throwable("ccc"), "Throwable: ccc")
check(Exception(), "Exception: null")
check(Exception("bbb"), "Exception: bbb")
check(MyException(), "MyException: null")