[JS IR] Do not copy interface method if base class inherits it

^KT-58599 Fixed
This commit is contained in:
Alexander Korepanov
2023-05-30 08:22:43 +00:00
committed by Space Team
parent 9ca9fc9c68
commit 8066f1b7d2
54 changed files with 886 additions and 8 deletions
@@ -277,6 +277,12 @@ public class JsFirInvalidationTestGenerated extends AbstractJsFirInvalidationTes
runTest("js/js.translator/testData/incremental/invalidation/interfaceOpenMethods/");
}
@Test
@TestMetadata("interfaceOpenMethodsInOpenClass")
public void testInterfaceOpenMethodsInOpenClass() throws Exception {
runTest("js/js.translator/testData/incremental/invalidation/interfaceOpenMethodsInOpenClass/");
}
@Test
@TestMetadata("interfaceSuperUsage")
public void testInterfaceSuperUsage() throws Exception {
@@ -277,6 +277,12 @@ public class JsIrES6InvalidationTestGenerated extends AbstractJsIrES6Invalidatio
runTest("js/js.translator/testData/incremental/invalidation/interfaceOpenMethods/");
}
@Test
@TestMetadata("interfaceOpenMethodsInOpenClass")
public void testInterfaceOpenMethodsInOpenClass() throws Exception {
runTest("js/js.translator/testData/incremental/invalidation/interfaceOpenMethodsInOpenClass/");
}
@Test
@TestMetadata("interfaceSuperUsage")
public void testInterfaceSuperUsage() throws Exception {
@@ -277,6 +277,12 @@ public class JsIrInvalidationTestGenerated extends AbstractJsIrInvalidationTest
runTest("js/js.translator/testData/incremental/invalidation/interfaceOpenMethods/");
}
@Test
@TestMetadata("interfaceOpenMethodsInOpenClass")
public void testInterfaceOpenMethodsInOpenClass() throws Exception {
runTest("js/js.translator/testData/incremental/invalidation/interfaceOpenMethodsInOpenClass/");
}
@Test
@TestMetadata("interfaceSuperUsage")
public void testInterfaceSuperUsage() throws Exception {
@@ -1169,6 +1169,16 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/dce")
@TestDataPath("$PROJECT_ROOT")
public class Dce {
@Test
public void testAllFilesPresentInDce() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/dce"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/defaultArguments")
@TestDataPath("$PROJECT_ROOT")
@@ -15241,6 +15241,24 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inference/noCoercionToUnitWithEqualityConstraintForNullableReturnType.kt");
}
@Test
@TestMetadata("overrideDefaultMethod.kt")
public void testOverrideDefaultMethod() throws Exception {
runTest("compiler/testData/codegen/box/inference/overrideDefaultMethod.kt");
}
@Test
@TestMetadata("overrideDefaultProperty.kt")
public void testOverrideDefaultProperty() throws Exception {
runTest("compiler/testData/codegen/box/inference/overrideDefaultProperty.kt");
}
@Test
@TestMetadata("overrideGenericDefaultMethod.kt")
public void testOverrideGenericDefaultMethod() throws Exception {
runTest("compiler/testData/codegen/box/inference/overrideGenericDefaultMethod.kt");
}
@Test
@TestMetadata("plusAssignInsideLambda.kt")
public void testPlusAssignInsideLambda() throws Exception {
@@ -1233,6 +1233,22 @@ public class FirJsBoxTestGenerated extends AbstractFirJsBoxTest {
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/dce")
@TestDataPath("$PROJECT_ROOT")
public class Dce {
@Test
public void testAllFilesPresentInDce() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/dce"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("removeUnusedOverride.kt")
public void testRemoveUnusedOverride() throws Exception {
runTest("js/js.translator/testData/box/dce/removeUnusedOverride.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/defaultArguments")
@TestDataPath("$PROJECT_ROOT")
@@ -15259,6 +15259,24 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inference/noCoercionToUnitWithEqualityConstraintForNullableReturnType.kt");
}
@Test
@TestMetadata("overrideDefaultMethod.kt")
public void testOverrideDefaultMethod() throws Exception {
runTest("compiler/testData/codegen/box/inference/overrideDefaultMethod.kt");
}
@Test
@TestMetadata("overrideDefaultProperty.kt")
public void testOverrideDefaultProperty() throws Exception {
runTest("compiler/testData/codegen/box/inference/overrideDefaultProperty.kt");
}
@Test
@TestMetadata("overrideGenericDefaultMethod.kt")
public void testOverrideGenericDefaultMethod() throws Exception {
runTest("compiler/testData/codegen/box/inference/overrideGenericDefaultMethod.kt");
}
@Test
@TestMetadata("plusAssignInsideLambda.kt")
public void testPlusAssignInsideLambda() throws Exception {
@@ -35206,6 +35224,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
public void testAllFilesPresentInSize() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/size"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("removeUnusedOverride.kt")
public void testRemoveUnusedOverride() throws Exception {
runTest("compiler/testData/codegen/box/size/removeUnusedOverride.kt");
}
}
@Nested
@@ -1233,6 +1233,22 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/dce")
@TestDataPath("$PROJECT_ROOT")
public class Dce {
@Test
public void testAllFilesPresentInDce() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/dce"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
@Test
@TestMetadata("removeUnusedOverride.kt")
public void testRemoveUnusedOverride() throws Exception {
runTest("js/js.translator/testData/box/dce/removeUnusedOverride.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/defaultArguments")
@TestDataPath("$PROJECT_ROOT")
@@ -1233,6 +1233,22 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/dce")
@TestDataPath("$PROJECT_ROOT")
public class Dce {
@Test
public void testAllFilesPresentInDce() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/dce"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("removeUnusedOverride.kt")
public void testRemoveUnusedOverride() throws Exception {
runTest("js/js.translator/testData/box/dce/removeUnusedOverride.kt");
}
}
@Nested
@TestMetadata("js/js.translator/testData/box/defaultArguments")
@TestDataPath("$PROJECT_ROOT")
@@ -15259,6 +15259,24 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inference/noCoercionToUnitWithEqualityConstraintForNullableReturnType.kt");
}
@Test
@TestMetadata("overrideDefaultMethod.kt")
public void testOverrideDefaultMethod() throws Exception {
runTest("compiler/testData/codegen/box/inference/overrideDefaultMethod.kt");
}
@Test
@TestMetadata("overrideDefaultProperty.kt")
public void testOverrideDefaultProperty() throws Exception {
runTest("compiler/testData/codegen/box/inference/overrideDefaultProperty.kt");
}
@Test
@TestMetadata("overrideGenericDefaultMethod.kt")
public void testOverrideGenericDefaultMethod() throws Exception {
runTest("compiler/testData/codegen/box/inference/overrideGenericDefaultMethod.kt");
}
@Test
@TestMetadata("plusAssignInsideLambda.kt")
public void testPlusAssignInsideLambda() throws Exception {
@@ -35206,6 +35224,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
public void testAllFilesPresentInSize() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/size"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("removeUnusedOverride.kt")
public void testRemoveUnusedOverride() throws Exception {
runTest("compiler/testData/codegen/box/size/removeUnusedOverride.kt");
}
}
@Nested
@@ -15259,6 +15259,24 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
runTest("compiler/testData/codegen/box/inference/noCoercionToUnitWithEqualityConstraintForNullableReturnType.kt");
}
@Test
@TestMetadata("overrideDefaultMethod.kt")
public void testOverrideDefaultMethod() throws Exception {
runTest("compiler/testData/codegen/box/inference/overrideDefaultMethod.kt");
}
@Test
@TestMetadata("overrideDefaultProperty.kt")
public void testOverrideDefaultProperty() throws Exception {
runTest("compiler/testData/codegen/box/inference/overrideDefaultProperty.kt");
}
@Test
@TestMetadata("overrideGenericDefaultMethod.kt")
public void testOverrideGenericDefaultMethod() throws Exception {
runTest("compiler/testData/codegen/box/inference/overrideGenericDefaultMethod.kt");
}
@Test
@TestMetadata("plusAssignInsideLambda.kt")
public void testPlusAssignInsideLambda() throws Exception {
@@ -35206,6 +35224,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
public void testAllFilesPresentInSize() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/size"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
@Test
@TestMetadata("removeUnusedOverride.kt")
public void testRemoveUnusedOverride() throws Exception {
runTest("compiler/testData/codegen/box/size/removeUnusedOverride.kt");
}
}
@Nested
@@ -0,0 +1,55 @@
// TARGET_BACKEND: JS_IR
// ONLY_IR_DCE
// RUN_PLAIN_BOX_FUNCTION
// INFER_MAIN_MODULE
// MODULE: remove_unused_override
// FILE: lib.kt
interface I {
fun foo() = "OK"
}
abstract class A : I
class B : A()
class C : A() {
override fun foo(): String {
return "C::foo"
}
}
@JsExport
fun makeB(): A {
val b = B()
b.foo()
return b
}
@JsExport
fun makeC(): A {
return C()
}
// FILE: test.js
function box() {
var b = this["remove_unused_override"].makeB()
var c = this["remove_unused_override"].makeC()
var cnt = 0
for(var prop in b) {
if (typeof b[prop] === 'function' && prop != 'constructor') {
++cnt
if (b[prop].call(b) != "OK") return "expect inherited method"
}
}
for(var prop in c) {
if (typeof c[prop] === 'function' && prop != 'constructor') {
++cnt
if (c[prop].call(c) != "OK") return "override C::foo() should be removed by DCE"
}
}
return cnt == 2 ? "OK" : ("Expected 2 calls, got " + cnt)
}
@@ -0,0 +1,8 @@
interface A {
fun testA1() = 2
fun testA2() = 3
val testA3: Int
get() = 1
}
@@ -12,3 +12,11 @@ STEP 1:
updated imports: InterfaceB.kt, InterfaceC.kt
STEP 2:
updated exports: InterfaceB.kt, InterfaceC.kt
STEP 3:
modifications:
U : InterfaceA.3.kt -> InterfaceA.kt
modified ir: InterfaceA.kt
updated exports: InterfaceA.kt
updated imports: InterfaceB.kt, InterfaceC.kt
STEP 4:
updated exports: InterfaceB.kt, InterfaceC.kt, InterfaceA.kt
@@ -6,3 +6,8 @@ STEP 1:
updated imports: MyClass.kt, GetB.kt, GetC.kt, GetA.kt
STEP 2:
dependencies: lib1
STEP 3:
dependencies: lib1
updated imports: MyClass.kt, GetB.kt, GetC.kt, GetA.kt
STEP 4:
dependencies: lib1
@@ -3,6 +3,8 @@ fun box(stepId: Int): String {
0 -> 10
1 -> 13
2 -> 16
3 -> 22
4 -> 25
else -> return "Unknown"
}
@@ -11,3 +11,11 @@ STEP 2:
modifications:
U : test.2.kt -> test.kt
modified ir: test.kt
STEP 3:
dependencies: lib1, lib2
updated imports: test.kt
STEP 4:
dependencies: lib1, lib2
modifications:
U : test.4.kt -> test.kt
modified ir: test.kt
@@ -0,0 +1,9 @@
fun test(): Int {
val a = getObjectA()
val b = getObjectB()
val c = getObjectC()
return a.testA1() + a.testA2() + a.testA3 +
b.testA1() + b.testA2() + b.testB1() + b.testA3 +
c.testA1() + c.testA2() + c.testB1() + c.testC1() + c.testA3
}
@@ -6,3 +6,9 @@ STEP 0..1:
STEP 2:
libs: lib1, lib2, main
dirty js: lib1, main
STEP 3:
libs: lib1, lib2, main
dirty js: lib1, lib2, main
STEP 4:
libs: lib1, lib2, main
dirty js: lib1, main
@@ -0,0 +1,2 @@
open class B : A<Int> {
}
@@ -0,0 +1,3 @@
open class B : A<Int> {
override fun test() = 1
}
@@ -0,0 +1,5 @@
open class B : A<Int> {
override fun test() = 1
override val testProp: Int = 3
}
@@ -0,0 +1,7 @@
open class B : A<Int> {
override fun test() = 1
override val testProp: Int = 3
override fun testWithDefault(x: Int) = x + 1
}
@@ -0,0 +1,9 @@
open class B : A<Int> {
override fun test() = 1
override val testProp: Int = 3
override fun testWithDefault(x: Int) = x + 1
override fun testGeneric(x: Int) = x + 1
}
@@ -0,0 +1,12 @@
interface A<T> {
fun test() = 0
val testProp: Int
get() = 2
fun testWithDefault(x: Int = 1) = x
fun testGeneric(x: T) = 1
fun unused() = 1
}
@@ -0,0 +1,12 @@
interface A<T> {
fun test() = 0
val testProp: Int
get() = 2
fun testWithDefault(x: Int) = x + 1
fun testGeneric(x: T) = 1
fun unused() = 1
}
@@ -0,0 +1,33 @@
STEP 0:
modifications:
U : InterfaceA.0.kt -> InterfaceA.kt
U : ClassB.0.kt -> ClassB.kt
added file: InterfaceA.kt, ClassB.kt
STEP 1:
modifications:
U : ClassB.1.kt -> ClassB.kt
modified ir: ClassB.kt
STEP 2:
modifications:
U : ClassB.2.kt -> ClassB.kt
modified ir: ClassB.kt
updated exports: ClassB.kt
STEP 3:
modifications:
U : ClassB.3.kt -> ClassB.kt
modified ir: ClassB.kt
STEP 4:
STEP 5:
modifications:
U : InterfaceA.5.kt -> InterfaceA.kt
modified ir: InterfaceA.kt
updated imports: ClassB.kt
STEP 6:
modifications:
U : ClassB.6.kt -> ClassB.kt
modified ir: ClassB.kt
STEP 7:
modifications:
U : ClassB.0.kt -> ClassB.kt
modified ir: ClassB.kt
updated exports: ClassB.kt
@@ -0,0 +1,3 @@
fun getObjectA() : A<Int> {
return myObject
}
@@ -0,0 +1,3 @@
fun getObjectB() : B {
return myObject
}
@@ -0,0 +1,4 @@
private class MyClass : B() {
}
internal val myObject: B = MyClass()
@@ -0,0 +1,13 @@
STEP 0:
dependencies: lib1
added file: MyClass.kt, GetB.kt, GetA.kt
STEP 1..4:
dependencies: lib1
STEP 5:
dependencies: lib1
updated imports: GetA.kt, MyClass.kt
STEP 6:
dependencies: lib1
STEP 7:
dependencies: lib1
updated imports: MyClass.kt
@@ -0,0 +1,19 @@
fun box(stepId: Int): String {
val expected = when (stepId) {
0 -> 9
1 -> 11
2 -> 13
3 -> 15
4, 5 -> 16
6 -> 16 + 177
7 -> 12
else -> return "Unknown"
}
val x = test()
if (expected != x) {
return "Fail $expected != $x"
}
return "OK"
}
@@ -0,0 +1,16 @@
STEP 0:
dependencies: lib1, lib2
modifications:
U : test.0.kt -> test.kt
added file: m.kt, test.kt
STEP 1..3:
dependencies: lib1, lib2
updated imports: test.kt
STEP 4:
dependencies: lib1, lib2
modifications:
U : test.4.kt -> test.kt
modified ir: test.kt
STEP 5..7:
dependencies: lib1, lib2
updated imports: test.kt
@@ -0,0 +1,6 @@
fun test(): Int {
val b = getObjectB()
val a = getObjectA()
return b.test() + b.testProp + b.testWithDefault(2) + b.testGeneric(100) +
a.test() + a.testProp + a.testWithDefault() + a.testGeneric(77)
}
@@ -0,0 +1,6 @@
fun test(): Int {
val b = getObjectB()
val a = getObjectA()
return b.test() + b.testProp + b.testWithDefault(2) + b.testGeneric(100) +
a.test() + a.testProp + a.testWithDefault(2) + a.testGeneric(77)
}
@@ -0,0 +1,14 @@
MODULES: lib1, lib2, main
STEP 0:
libs: lib1, lib2, main
dirty js: lib1, lib2, main
STEP 1..3:
libs: lib1, lib2, main
dirty js: lib1, main
STEP 4:
libs: lib1, lib2, main
dirty js: main
STEP 5..7:
libs: lib1, lib2, main
dirty js: lib1, lib2, main