JS: fix translation of enum entries without parentheses that call secondary constructors, constructors with default parameters and varargs. See KT-15900, KT-14097
This commit is contained in:
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
enum class Test(vararg xs: Int) {
|
enum class Test(vararg xs: Int) {
|
||||||
OK;
|
OK;
|
||||||
val values = xs
|
val values = xs
|
||||||
|
|||||||
-3
@@ -1,6 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS
|
|
||||||
// see KT-14097
|
|
||||||
|
|
||||||
enum class Test(val x: Int, val str: String) {
|
enum class Test(val x: Int, val str: String) {
|
||||||
OK;
|
OK;
|
||||||
constructor(x: Int = 0) : this(x, "OK")
|
constructor(x: Int = 0) : this(x, "OK")
|
||||||
|
|||||||
-3
@@ -1,6 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS
|
|
||||||
// see KT-14097
|
|
||||||
|
|
||||||
enum class Test(val x: Int, val str: String) {
|
enum class Test(val x: Int, val str: String) {
|
||||||
OK;
|
OK;
|
||||||
constructor(vararg xs: Int) : this(xs.size + 42, "OK")
|
constructor(vararg xs: Int) : this(xs.size + 42, "OK")
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|
||||||
enum class My(val s: String) {
|
enum class My(val s: String) {
|
||||||
|
|||||||
+4
-28
@@ -7743,13 +7743,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
@TestMetadata("emptyConstructor.kt")
|
@TestMetadata("emptyConstructor.kt")
|
||||||
public void testEmptyConstructor() throws Exception {
|
public void testEmptyConstructor() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/emptyConstructor.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/emptyConstructor.kt");
|
||||||
try {
|
doTest(fileName);
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("emptyEnumValuesValueOf.kt")
|
@TestMetadata("emptyEnumValuesValueOf.kt")
|
||||||
@@ -7913,37 +7907,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
@TestMetadata("constructorWithVararg.kt")
|
@TestMetadata("constructorWithVararg.kt")
|
||||||
public void testConstructorWithVararg() throws Exception {
|
public void testConstructorWithVararg() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/defaultCtor/constructorWithVararg.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/defaultCtor/constructorWithVararg.kt");
|
||||||
try {
|
doTest(fileName);
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("secondaryConstructorWithDefaultArguments.kt")
|
@TestMetadata("secondaryConstructorWithDefaultArguments.kt")
|
||||||
public void testSecondaryConstructorWithDefaultArguments() throws Exception {
|
public void testSecondaryConstructorWithDefaultArguments() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/defaultCtor/secondaryConstructorWithDefaultArguments.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/defaultCtor/secondaryConstructorWithDefaultArguments.kt");
|
||||||
try {
|
doTest(fileName);
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("secondaryConstructorWithVararg.kt")
|
@TestMetadata("secondaryConstructorWithVararg.kt")
|
||||||
public void testSecondaryConstructorWithVararg() throws Exception {
|
public void testSecondaryConstructorWithVararg() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/defaultCtor/secondaryConstructorWithVararg.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/defaultCtor/secondaryConstructorWithVararg.kt");
|
||||||
try {
|
doTest(fileName);
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -66,8 +66,7 @@ class DeclarationBodyVisitor(
|
|||||||
val enumInstanceName = context.createGlobalName(enumName.ident + "_instance")
|
val enumInstanceName = context.createGlobalName(enumName.ident + "_instance")
|
||||||
|
|
||||||
assert(supertypes.size == 1) { "Simple Enum entry must have one supertype" }
|
assert(supertypes.size == 1) { "Simple Enum entry must have one supertype" }
|
||||||
val jsEnumEntryCreation = ClassInitializerTranslator
|
val jsEnumEntryCreation = ClassInitializerTranslator.generateEnumEntryInstanceCreation(context, enumEntry, enumEntryOrdinal)
|
||||||
.generateEnumEntryInstanceCreation(context, supertypes[0], enumEntry, enumEntryOrdinal)
|
|
||||||
context.addDeclarationStatement(JsAstUtils.newVar(enumInstanceName, null))
|
context.addDeclarationStatement(JsAstUtils.newVar(enumInstanceName, null))
|
||||||
enumInitializer.body.statements += JsAstUtils.assignment(pureFqn(enumInstanceName, null), jsEnumEntryCreation).makeStmt()
|
enumInitializer.body.statements += JsAstUtils.assignment(pureFqn(enumInstanceName, null), jsEnumEntryCreation).makeStmt()
|
||||||
|
|
||||||
|
|||||||
+11
-13
@@ -40,13 +40,14 @@ import org.jetbrains.kotlin.psi.KtClassOrObject;
|
|||||||
import org.jetbrains.kotlin.psi.KtEnumEntry;
|
import org.jetbrains.kotlin.psi.KtEnumEntry;
|
||||||
import org.jetbrains.kotlin.psi.KtExpression;
|
import org.jetbrains.kotlin.psi.KtExpression;
|
||||||
import org.jetbrains.kotlin.psi.KtParameter;
|
import org.jetbrains.kotlin.psi.KtParameter;
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
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.DefaultValueArgument;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument;
|
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
|
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
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.FunctionBodyTranslator.setDefaultValueForArguments;
|
||||||
import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn;
|
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.js.translate.utils.PsiUtils.getPrimaryConstructorParameters;
|
||||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getClassDescriptorForType;
|
|
||||||
|
|
||||||
public final class ClassInitializerTranslator extends AbstractTranslator {
|
public final class ClassInitializerTranslator extends AbstractTranslator {
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -144,23 +144,21 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static JsExpression generateEnumEntryInstanceCreation(
|
public static JsExpression generateEnumEntryInstanceCreation(
|
||||||
@NotNull TranslationContext context,
|
@NotNull TranslationContext context,
|
||||||
@NotNull KotlinType enumClassType,
|
@NotNull KtEnumEntry enumEntry,
|
||||||
@NotNull KtClassOrObject classDeclaration,
|
|
||||||
int ordinal
|
int ordinal
|
||||||
) {
|
) {
|
||||||
ResolvedCall<FunctionDescriptor> superCall = getSuperCall(context.bindingContext(), classDeclaration);
|
ResolvedCall<? extends FunctionDescriptor> 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);
|
JsExpression ordinalArg = context.program().getNumberLiteral(ordinal);
|
||||||
List<JsExpression> additionalArgs = Arrays.asList(nameArg, ordinalArg);
|
List<JsExpression> additionalArgs = Arrays.asList(nameArg, ordinalArg);
|
||||||
|
|
||||||
if (superCall == null) {
|
JsExpression call = CallTranslator.translate(context, resolvedCall);
|
||||||
ClassDescriptor classDescriptor = getClassDescriptorForType(enumClassType);
|
|
||||||
JsNameRef reference = context.getInnerReference(classDescriptor);
|
|
||||||
return new JsNew(reference, additionalArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
JsExpression call = CallTranslator.translate(context, superCall);
|
|
||||||
if (call instanceof JsInvocation) {
|
if (call instanceof JsInvocation) {
|
||||||
JsInvocation invocation = (JsInvocation) call;
|
JsInvocation invocation = (JsInvocation) call;
|
||||||
invocation.getArguments().addAll(0, additionalArgs);
|
invocation.getArguments().addAll(0, additionalArgs);
|
||||||
|
|||||||
Reference in New Issue
Block a user