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:
Alexey Andreev
2017-01-25 17:39:15 +03:00
parent 0f87320f9e
commit 1c8478e46b
7 changed files with 16 additions and 54 deletions
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: JS
enum class Test(vararg xs: Int) {
OK;
val values = xs
@@ -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")
@@ -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")
@@ -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) {
@@ -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);
}
}
}
@@ -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()
@@ -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<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);
List<JsExpression> 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);