From 1c8478e46bba50c0834cf562ffc7881079cfff4d Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 25 Jan 2017 17:39:15 +0300 Subject: [PATCH] JS: fix translation of enum entries without parentheses that call secondary constructors, constructors with default parameters and varargs. See KT-15900, KT-14097 --- .../enum/defaultCtor/constructorWithVararg.kt | 2 -- ...econdaryConstructorWithDefaultArguments.kt | 3 -- .../secondaryConstructorWithVararg.kt | 3 -- .../codegen/box/enum/emptyConstructor.kt | 3 -- .../semantics/JsCodegenBoxTestGenerated.java | 32 +++---------------- .../declaration/DeclarationBodyVisitor.kt | 3 +- .../ClassInitializerTranslator.java | 24 +++++++------- 7 files changed, 16 insertions(+), 54 deletions(-) diff --git a/compiler/testData/codegen/box/enum/defaultCtor/constructorWithVararg.kt b/compiler/testData/codegen/box/enum/defaultCtor/constructorWithVararg.kt index be8f86f66a4..f293632dffa 100644 --- a/compiler/testData/codegen/box/enum/defaultCtor/constructorWithVararg.kt +++ b/compiler/testData/codegen/box/enum/defaultCtor/constructorWithVararg.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JS - enum class Test(vararg xs: Int) { OK; val values = xs diff --git a/compiler/testData/codegen/box/enum/defaultCtor/secondaryConstructorWithDefaultArguments.kt b/compiler/testData/codegen/box/enum/defaultCtor/secondaryConstructorWithDefaultArguments.kt index 58b0be6c9f0..fb08b98daab 100644 --- a/compiler/testData/codegen/box/enum/defaultCtor/secondaryConstructorWithDefaultArguments.kt +++ b/compiler/testData/codegen/box/enum/defaultCtor/secondaryConstructorWithDefaultArguments.kt @@ -1,6 +1,3 @@ -// IGNORE_BACKEND: JS -// see KT-14097 - enum class Test(val x: Int, val str: String) { OK; constructor(x: Int = 0) : this(x, "OK") diff --git a/compiler/testData/codegen/box/enum/defaultCtor/secondaryConstructorWithVararg.kt b/compiler/testData/codegen/box/enum/defaultCtor/secondaryConstructorWithVararg.kt index 9bee8603d4a..15c5ad34e9c 100644 --- a/compiler/testData/codegen/box/enum/defaultCtor/secondaryConstructorWithVararg.kt +++ b/compiler/testData/codegen/box/enum/defaultCtor/secondaryConstructorWithVararg.kt @@ -1,6 +1,3 @@ -// IGNORE_BACKEND: JS -// see KT-14097 - enum class Test(val x: Int, val str: String) { OK; constructor(vararg xs: Int) : this(xs.size + 42, "OK") diff --git a/compiler/testData/codegen/box/enum/emptyConstructor.kt b/compiler/testData/codegen/box/enum/emptyConstructor.kt index 412cf9a2801..c82a4ac41c3 100644 --- a/compiler/testData/codegen/box/enum/emptyConstructor.kt +++ b/compiler/testData/codegen/box/enum/emptyConstructor.kt @@ -1,6 +1,3 @@ -// TODO: muted automatically, investigate should it be ran for JS or not -// IGNORE_BACKEND: JS - package test enum class My(val s: String) { diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index e9803cd8a91..503a5214b6f 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -7743,13 +7743,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { @TestMetadata("emptyConstructor.kt") public void testEmptyConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/emptyConstructor.kt"); - try { - doTest(fileName); - } - catch (Throwable ignore) { - return; - } - throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + doTest(fileName); } @TestMetadata("emptyEnumValuesValueOf.kt") @@ -7913,37 +7907,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { @TestMetadata("constructorWithVararg.kt") public void testConstructorWithVararg() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/defaultCtor/constructorWithVararg.kt"); - try { - doTest(fileName); - } - catch (Throwable ignore) { - return; - } - throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + doTest(fileName); } @TestMetadata("secondaryConstructorWithDefaultArguments.kt") public void testSecondaryConstructorWithDefaultArguments() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/defaultCtor/secondaryConstructorWithDefaultArguments.kt"); - try { - doTest(fileName); - } - catch (Throwable ignore) { - return; - } - throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + doTest(fileName); } @TestMetadata("secondaryConstructorWithVararg.kt") public void testSecondaryConstructorWithVararg() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/defaultCtor/secondaryConstructorWithVararg.kt"); - try { - doTest(fileName); - } - catch (Throwable ignore) { - return; - } - throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + doTest(fileName); } } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.kt index 9d2204814a1..29041f4d150 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.kt @@ -66,8 +66,7 @@ class DeclarationBodyVisitor( val enumInstanceName = context.createGlobalName(enumName.ident + "_instance") assert(supertypes.size == 1) { "Simple Enum entry must have one supertype" } - val jsEnumEntryCreation = ClassInitializerTranslator - .generateEnumEntryInstanceCreation(context, supertypes[0], enumEntry, enumEntryOrdinal) + val jsEnumEntryCreation = ClassInitializerTranslator.generateEnumEntryInstanceCreation(context, enumEntry, enumEntryOrdinal) context.addDeclarationStatement(JsAstUtils.newVar(enumInstanceName, null)) enumInitializer.body.statements += JsAstUtils.assignment(pureFqn(enumInstanceName, null), jsEnumEntryCreation).makeStmt() diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/ClassInitializerTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/ClassInitializerTranslator.java index 5149b482d67..213541d21df 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/ClassInitializerTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/ClassInitializerTranslator.java @@ -40,13 +40,14 @@ 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.psi.psiUtil.PsiUtilsKt; import org.jetbrains.kotlin.resolve.DescriptorUtils; +import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt; 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; @@ -58,7 +59,6 @@ import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.*; import static org.jetbrains.kotlin.js.translate.utils.FunctionBodyTranslator.setDefaultValueForArguments; import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn; import static org.jetbrains.kotlin.js.translate.utils.PsiUtils.getPrimaryConstructorParameters; -import static org.jetbrains.kotlin.resolve.DescriptorUtils.getClassDescriptorForType; public final class ClassInitializerTranslator extends AbstractTranslator { @NotNull @@ -144,23 +144,21 @@ public final class ClassInitializerTranslator extends AbstractTranslator { @NotNull public static JsExpression generateEnumEntryInstanceCreation( @NotNull TranslationContext context, - @NotNull KotlinType enumClassType, - @NotNull KtClassOrObject classDeclaration, + @NotNull KtEnumEntry enumEntry, int ordinal ) { - ResolvedCall superCall = getSuperCall(context.bindingContext(), classDeclaration); + ResolvedCall resolvedCall = getSuperCall(context.bindingContext(), enumEntry); + if (resolvedCall == null) { + assert enumEntry.getInitializerList() == null : "Super call is missing on an enum entry with explicit initializer list " + + PsiUtilsKt.getTextWithLocation(enumEntry); + resolvedCall = CallUtilKt.getFunctionResolvedCallWithAssert(enumEntry, context.bindingContext()); + } - JsExpression nameArg = context.program().getStringLiteral(classDeclaration.getName()); + JsExpression nameArg = context.program().getStringLiteral(enumEntry.getName()); JsExpression ordinalArg = context.program().getNumberLiteral(ordinal); List additionalArgs = Arrays.asList(nameArg, ordinalArg); - if (superCall == null) { - ClassDescriptor classDescriptor = getClassDescriptorForType(enumClassType); - JsNameRef reference = context.getInnerReference(classDescriptor); - return new JsNew(reference, additionalArgs); - } - - JsExpression call = CallTranslator.translate(context, superCall); + JsExpression call = CallTranslator.translate(context, resolvedCall); if (call instanceof JsInvocation) { JsInvocation invocation = (JsInvocation) call; invocation.getArguments().addAll(0, additionalArgs);