JS: fix support of throwable constructors without message and/or cause parameters
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
class CustomException : Throwable {
|
||||||
|
constructor(message: String?, cause: Throwable?) : super(message, cause)
|
||||||
|
|
||||||
|
constructor(message: String?) : super(message, null)
|
||||||
|
|
||||||
|
constructor(cause: Throwable?) : super(cause)
|
||||||
|
|
||||||
|
constructor() : super()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var t = CustomException("O", Throwable("K"))
|
||||||
|
if (t.message != "O" || t.cause?.message != "K") return "fail1"
|
||||||
|
|
||||||
|
t = CustomException(Throwable("OK"))
|
||||||
|
if (t.message == null || t.message == "OK" || t.cause?.message != "OK") return "fail2"
|
||||||
|
|
||||||
|
t = CustomException("OK")
|
||||||
|
if (t.message != "OK" || t.cause != null) return "fail3"
|
||||||
|
|
||||||
|
t = CustomException()
|
||||||
|
if (t.message != null || t.cause != null) return "fail4"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -3,7 +3,13 @@ fun box(): String {
|
|||||||
if (t.message != "O" || t.cause?.message != "K") return "fail1"
|
if (t.message != "O" || t.cause?.message != "K") return "fail1"
|
||||||
|
|
||||||
t = Throwable(Throwable("OK"))
|
t = Throwable(Throwable("OK"))
|
||||||
if (t.message != null || t.cause?.message != "OK") return "fail2"
|
if (t.message == null || t.message == "OK" || t.cause?.message != "OK") return "fail2"
|
||||||
|
|
||||||
|
t = Throwable("OK")
|
||||||
|
if (t.message != "OK" || t.cause != null) return "fail3"
|
||||||
|
|
||||||
|
t = Throwable()
|
||||||
|
if (t.message != null || t.cause != null) return "fail4"
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
public final class CustomException {
|
||||||
|
public method <init>(): void
|
||||||
|
public method <init>(@org.jetbrains.annotations.Nullable p0: java.lang.String): void
|
||||||
|
public method <init>(@org.jetbrains.annotations.Nullable p0: java.lang.String, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): void
|
||||||
|
public method <init>(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ExceptionCauseKt {
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||||
|
}
|
||||||
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
public final class MyThrowable {
|
||||||
|
private final @org.jetbrains.annotations.NotNull field x: java.lang.String
|
||||||
|
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: java.lang.String, @org.jetbrains.annotations.Nullable p2: java.lang.Throwable): void
|
||||||
|
public synthetic method <init>(p0: java.lang.String, p1: java.lang.String, p2: java.lang.Throwable, p3: int, p4: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||||
|
public final @org.jetbrains.annotations.NotNull method getX(): java.lang.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ThrowableImplWithSecondaryConstructorKt {
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||||
|
}
|
||||||
+6
@@ -16169,6 +16169,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("exceptionCause.kt")
|
||||||
|
public void testExceptionCause() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/exceptionCause.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("explicitSuperCall.kt")
|
@TestMetadata("explicitSuperCall.kt")
|
||||||
public void testExplicitSuperCall() throws Exception {
|
public void testExplicitSuperCall() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/explicitSuperCall.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/explicitSuperCall.kt");
|
||||||
|
|||||||
@@ -16169,6 +16169,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("exceptionCause.kt")
|
||||||
|
public void testExceptionCause() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/exceptionCause.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("explicitSuperCall.kt")
|
@TestMetadata("explicitSuperCall.kt")
|
||||||
public void testExplicitSuperCall() throws Exception {
|
public void testExplicitSuperCall() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/explicitSuperCall.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/explicitSuperCall.kt");
|
||||||
|
|||||||
@@ -16169,6 +16169,12 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("exceptionCause.kt")
|
||||||
|
public void testExceptionCause() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/exceptionCause.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("explicitSuperCall.kt")
|
@TestMetadata("explicitSuperCall.kt")
|
||||||
public void testExplicitSuperCall() throws Exception {
|
public void testExplicitSuperCall() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/explicitSuperCall.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/explicitSuperCall.kt");
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ internal fun captureStack(baseClass: JsClass<in Throwable>, instance: Throwable)
|
|||||||
@JsName("newThrowable")
|
@JsName("newThrowable")
|
||||||
internal fun newThrowable(message: String?, cause: Throwable?): Throwable {
|
internal fun newThrowable(message: String?, cause: Throwable?): Throwable {
|
||||||
val throwable = js("new Error()")
|
val throwable = js("new Error()")
|
||||||
throwable.message = message
|
throwable.message = if (jsTypeOf(message) == "undefined" && cause != null) cause.toString() else message
|
||||||
throwable.cause = cause
|
throwable.cause = cause
|
||||||
return throwable
|
return throwable
|
||||||
}
|
}
|
||||||
@@ -20421,6 +20421,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("exceptionCause.kt")
|
||||||
|
public void testExceptionCause() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/exceptionCause.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("explicitSuperCall.kt")
|
@TestMetadata("explicitSuperCall.kt")
|
||||||
public void testExplicitSuperCall() throws Exception {
|
public void testExplicitSuperCall() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/explicitSuperCall.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/explicitSuperCall.kt");
|
||||||
|
|||||||
+21
-5
@@ -269,7 +269,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
|
|||||||
List<JsStatement> statements = context.getCurrentBlock().getStatements();
|
List<JsStatement> statements = context.getCurrentBlock().getStatements();
|
||||||
statements.add(JsAstUtils.asSyntheticStatement(superInvocation));
|
statements.add(JsAstUtils.asSyntheticStatement(superInvocation));
|
||||||
|
|
||||||
JsExpression messageArgument = JsLiteral.NULL;
|
JsExpression messageArgument = Namer.getUndefinedExpression();
|
||||||
JsExpression causeArgument = JsLiteral.NULL;
|
JsExpression causeArgument = JsLiteral.NULL;
|
||||||
for (ValueParameterDescriptor param : superCall.getResultingDescriptor().getValueParameters()) {
|
for (ValueParameterDescriptor param : superCall.getResultingDescriptor().getValueParameters()) {
|
||||||
ResolvedValueArgument argument = superCall.getValueArguments().get(param);
|
ResolvedValueArgument argument = superCall.getValueArguments().get(param);
|
||||||
@@ -283,10 +283,10 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
|
|||||||
JsExpression jsValue = Translation.translateAsExpression(value, context);
|
JsExpression jsValue = Translation.translateAsExpression(value, context);
|
||||||
|
|
||||||
if (KotlinBuiltIns.isStringOrNullableString(param.getType())) {
|
if (KotlinBuiltIns.isStringOrNullableString(param.getType())) {
|
||||||
messageArgument = jsValue;
|
messageArgument = context.cacheExpressionIfNeeded(jsValue);
|
||||||
}
|
}
|
||||||
else if (TypeUtilsKt.isConstructedFromClassWithGivenFqName(param.getType(), KotlinBuiltIns.FQ_NAMES.throwable)) {
|
else if (TypeUtilsKt.isConstructedFromClassWithGivenFqName(param.getType(), KotlinBuiltIns.FQ_NAMES.throwable)) {
|
||||||
causeArgument = jsValue;
|
causeArgument = context.cacheExpressionIfNeeded(jsValue);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
statements.add(JsAstUtils.asSyntheticStatement(jsValue));
|
statements.add(JsAstUtils.asSyntheticStatement(jsValue));
|
||||||
@@ -296,12 +296,28 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
|
|||||||
PropertyDescriptor messageProperty = DescriptorUtils.getPropertyByName(
|
PropertyDescriptor messageProperty = DescriptorUtils.getPropertyByName(
|
||||||
classDescriptor.getUnsubstitutedMemberScope(), Name.identifier("message"));
|
classDescriptor.getUnsubstitutedMemberScope(), Name.identifier("message"));
|
||||||
JsExpression messageRef = pureFqn(context.getNameForBackingField(messageProperty), receiver.deepCopy());
|
JsExpression messageRef = pureFqn(context.getNameForBackingField(messageProperty), receiver.deepCopy());
|
||||||
statements.add(JsAstUtils.asSyntheticStatement(JsAstUtils.assignment(messageRef, messageArgument)));
|
JsExpression messageIsUndefined = JsAstUtils.typeOfIs(messageArgument, context.program().getStringLiteral("undefined"));
|
||||||
|
JsExpression causeIsNull = new JsBinaryOperation(JsBinaryOperator.NEQ, causeArgument, JsLiteral.NULL);
|
||||||
|
JsExpression causeToStringCond = JsAstUtils.and(messageIsUndefined, causeIsNull);
|
||||||
|
JsExpression causeToString = new JsInvocation(pureFqn("toString", Namer.kotlinObject()), causeArgument.deepCopy());
|
||||||
|
|
||||||
|
JsExpression correctedMessage;
|
||||||
|
if (causeArgument == JsLiteral.NULL) {
|
||||||
|
correctedMessage = messageArgument.deepCopy();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (JsAstUtils.isUndefinedExpression(messageArgument)) {
|
||||||
|
causeToStringCond = causeIsNull;
|
||||||
|
}
|
||||||
|
correctedMessage = new JsConditional(causeToStringCond, causeToString, messageArgument);
|
||||||
|
}
|
||||||
|
|
||||||
|
statements.add(JsAstUtils.asSyntheticStatement(JsAstUtils.assignment(messageRef, correctedMessage)));
|
||||||
|
|
||||||
PropertyDescriptor causeProperty = DescriptorUtils.getPropertyByName(
|
PropertyDescriptor causeProperty = DescriptorUtils.getPropertyByName(
|
||||||
classDescriptor.getUnsubstitutedMemberScope(), Name.identifier("cause"));
|
classDescriptor.getUnsubstitutedMemberScope(), Name.identifier("cause"));
|
||||||
JsExpression causeRef = pureFqn(context.getNameForBackingField(causeProperty), receiver.deepCopy());
|
JsExpression causeRef = pureFqn(context.getNameForBackingField(causeProperty), receiver.deepCopy());
|
||||||
statements.add(JsAstUtils.asSyntheticStatement(JsAstUtils.assignment(causeRef, causeArgument)));
|
statements.add(JsAstUtils.asSyntheticStatement(JsAstUtils.assignment(causeRef, causeArgument.deepCopy())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
+1
-1
@@ -47,7 +47,7 @@ object ThrowableConstructorIntrinsicFactory : FunctionIntrinsicFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (constructor.valueParameters.size == 1 && hasCauseParameter) {
|
if (constructor.valueParameters.size == 1 && hasCauseParameter) {
|
||||||
argumentsToPass.add(0, JsLiteral.NULL)
|
argumentsToPass.add(0, Namer.getUndefinedExpression())
|
||||||
}
|
}
|
||||||
|
|
||||||
return JsInvocation(JsAstUtils.pureFqn("newThrowable", Namer.kotlinObject()), argumentsToPass)
|
return JsInvocation(JsAstUtils.pureFqn("newThrowable", Namer.kotlinObject()), argumentsToPass)
|
||||||
|
|||||||
Reference in New Issue
Block a user