KT-4107 Data objects

This commit is contained in:
Pavel Mikhailovskii
2022-06-28 09:51:57 +02:00
parent 6c31dc90e4
commit c3c09aa95a
75 changed files with 1183 additions and 134 deletions
@@ -10116,6 +10116,34 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/dataObjects")
@TestDataPath("$PROJECT_ROOT")
public class DataObjects {
@Test
public void testAllFilesPresentInDataObjects() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/dataObjects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
}
@Test
@TestMetadata("equals.kt")
public void testEquals() throws Exception {
runTest("compiler/testData/codegen/box/dataObjects/equals.kt");
}
@Test
@TestMetadata("hashCode.kt")
public void testHashCode() throws Exception {
runTest("compiler/testData/codegen/box/dataObjects/hashCode.kt");
}
@Test
@TestMetadata("toString.kt")
public void testToString() throws Exception {
runTest("compiler/testData/codegen/box/dataObjects/toString.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/deadCodeElimination")
@TestDataPath("$PROJECT_ROOT")
@@ -10158,6 +10158,34 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/dataObjects")
@TestDataPath("$PROJECT_ROOT")
public class DataObjects {
@Test
public void testAllFilesPresentInDataObjects() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/dataObjects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("equals.kt")
public void testEquals() throws Exception {
runTest("compiler/testData/codegen/box/dataObjects/equals.kt");
}
@Test
@TestMetadata("hashCode.kt")
public void testHashCode() throws Exception {
runTest("compiler/testData/codegen/box/dataObjects/hashCode.kt");
}
@Test
@TestMetadata("toString.kt")
public void testToString() throws Exception {
runTest("compiler/testData/codegen/box/dataObjects/toString.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/deadCodeElimination")
@TestDataPath("$PROJECT_ROOT")
@@ -8996,6 +8996,34 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
}
}
@TestMetadata("compiler/testData/codegen/box/dataObjects")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class DataObjects extends AbstractIrCodegenBoxWasmTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
}
public void testAllFilesPresentInDataObjects() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/dataObjects"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
}
@TestMetadata("equals.kt")
public void testEquals() throws Exception {
runTest("compiler/testData/codegen/box/dataObjects/equals.kt");
}
@TestMetadata("hashCode.kt")
public void testHashCode() throws Exception {
runTest("compiler/testData/codegen/box/dataObjects/hashCode.kt");
}
@TestMetadata("toString.kt")
public void testToString() throws Exception {
runTest("compiler/testData/codegen/box/dataObjects/toString.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/deadCodeElimination")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -16,7 +16,9 @@ import org.jetbrains.kotlin.js.backend.ast.*;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
import org.jetbrains.kotlin.js.translate.utils.UtilsKt;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.KtClassOrObject;
import org.jetbrains.kotlin.psi.KtObjectDeclaration;
import org.jetbrains.kotlin.psi.KtParameter;
import org.jetbrains.kotlin.resolve.source.PsiSourceElementKt;
@@ -35,6 +37,11 @@ abstract class JsEqualsHashcodeToStringGenerator extends DataClassMethodGenerato
@Override
public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> classProperties) {
if (getDeclaration() instanceof KtObjectDeclaration) {
generateJsMethod(function).getBody().getStatements().add(new JsReturn(new JsStringLiteral(getDeclaration().getName())));
return;
}
// TODO: relax this limitation, with the data generation logic fixed.
assert !classProperties.isEmpty();
JsFunction functionObj = generateJsMethod(function);
@@ -65,6 +72,14 @@ abstract class JsEqualsHashcodeToStringGenerator extends DataClassMethodGenerato
@Override
public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> classProperties) {
JsFunction functionObj = generateJsMethod(function);
if (classProperties.isEmpty()) {
FqName fqName = getDeclaration().getFqName();
JsExpression returnExpression = new JsIntLiteral(fqName != null ? fqName.hashCode() : 0);
JsReturn returnStatement = new JsReturn(returnExpression);
returnStatement.setSource(getDeclaration());
functionObj.getBody().getStatements().add(returnStatement);
return;
}
List<JsStatement> statements = functionObj.getBody().getStatements();
@@ -92,8 +107,8 @@ abstract class JsEqualsHashcodeToStringGenerator extends DataClassMethodGenerato
@Override
public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> classProperties) {
assert !classProperties.isEmpty();
JsFunction functionObj = generateJsMethod(function);
JsFunctionScope funScope = functionObj.getScope();
JsName paramName = funScope.declareName("other");
@@ -120,9 +135,8 @@ abstract class JsEqualsHashcodeToStringGenerator extends DataClassMethodGenerato
fieldChain = and(fieldChain, next);
}
}
assert fieldChain != null;
JsExpression returnExpression = or(referenceEqual, and(isNotNull, and(otherIsObject, and(prototypeEqual, fieldChain))));
JsExpression returnExpression = or(referenceEqual, and(isNotNull, and(otherIsObject, fieldChain != null ? and(prototypeEqual, fieldChain) : prototypeEqual)));
JsReturn returnStatement = new JsReturn(returnExpression);
returnStatement.setSource(getDeclaration());
functionObj.getBody().getStatements().add(returnStatement);