[JS IR] Don't check an interface method default impl during JS translation

We do not need to check a default implementation of the interface during
 the translation to JS because it must be checked before.

 Moreover, this check breaks the produced JS code
 if IR is partial loaded, e.g. during the incremental rebuild.

^KT-55716 Fixed
This commit is contained in:
Alexander Korepanov
2023-01-02 16:47:07 +01:00
committed by Space Team
parent 155777e3fa
commit 5f10e605a9
20 changed files with 281 additions and 2 deletions
@@ -194,8 +194,9 @@ fun translateCall(
Pair(function, superQualifier.owner)
}
val callRef = if (klass.isInterface && target.body != null) {
JsNameRef(Namer.CALL_FUNCTION, JsNameRef(context.getNameForStaticDeclaration(target)))
val callRef = if (klass.isInterface) {
val nameForStaticDeclaration = context.getNameForStaticDeclaration(target)
JsNameRef(Namer.CALL_FUNCTION, JsNameRef(nameForStaticDeclaration))
} else {
val qualifierName = context.getNameForClass(klass).makeRef()
val targetName = context.getNameForMemberFunction(target)
@@ -215,6 +215,11 @@ public class InvalidationTestGenerated extends AbstractInvalidationTest {
runTest("js/js.translator/testData/incremental/invalidation/inlineFunctionWithObject/");
}
@TestMetadata("interfaceSuperUsage")
public void testInterfaceSuperUsage() throws Exception {
runTest("js/js.translator/testData/incremental/invalidation/interfaceSuperUsage/");
}
@TestMetadata("interfaceWithDefaultParams")
public void testInterfaceWithDefaultParams() throws Exception {
runTest("js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/");
@@ -0,0 +1,7 @@
class ClassA : Interface {
override var someVar: Int?
get() = super.someVar
set(value) {
super.someVar = value
}
}
@@ -0,0 +1,12 @@
class ClassA : Interface {
override var someVar: Int?
get() = 1
set(value) {
super.someVar = value
}
override val someValue: Int
get() = super.someValue
override fun someFunction(): Int = super.someFunction()
}
@@ -0,0 +1,9 @@
class ClassB : Interface {
override var someVar: Int?
get() = super.someVar
set(value) {
super.someVar = value
}
val x = 1
}
@@ -0,0 +1,3 @@
class ClassB : Interface {
val x = 3
}
@@ -0,0 +1,6 @@
class ClassB : Interface {
val x = 3
override val someValue: Int
get() = super.someValue + 1
}
@@ -0,0 +1,8 @@
class ClassB : Interface {
val x = 3
override val someValue: Int
get() = super.someValue + 1
override fun someFunction(): Int = super.someFunction() + 1
}
@@ -0,0 +1,9 @@
private var myProperty: Int? = null
interface Interface {
var someVar: Int?
get() = myProperty
set(value) {
myProperty = value
}
}
@@ -0,0 +1,15 @@
private var myProperty: Int? = null
interface Interface {
var someVar: Int?
get() = myProperty?.let {
if (it == 1) {
it + 1
} else {
it
}
}
set(value) {
myProperty = value
}
}
@@ -0,0 +1,20 @@
private var myProperty: Int? = null
interface Interface {
var someVar: Int?
get() = myProperty?.let {
if (it == 1 || it == 3) {
it + 1
} else {
it
}
}
set(value) {
myProperty = value
}
val someValue: Int
get() = 1
fun someFunction(): Int = someValue
}
@@ -0,0 +1,38 @@
STEP 0:
modifications:
U : ClassA.0.kt -> ClassA.kt
U : ClassB.0.kt -> ClassB.kt
U : Interface.0.kt -> Interface.kt
added file: ClassA.kt, ClassB.kt, Interface.kt
STEP 1:
updated exports: ClassB.kt
STEP 2:
modifications:
U : Interface.2.kt -> Interface.kt
modified ir: Interface.kt
STEP 3:
modifications:
U : ClassB.3.kt -> ClassB.kt
modified ir: ClassB.kt
updated exports: ClassB.kt
STEP 4:
modifications:
U : Interface.4.kt -> Interface.kt
modified ir: Interface.kt
STEP 5:
updated exports: Interface.kt, ClassB.kt
STEP 6:
modifications:
U : ClassB.6.kt -> ClassB.kt
modified ir: ClassB.kt
updated exports: Interface.kt
STEP 7:
modifications:
U : ClassB.7.kt -> ClassB.kt
modified ir: ClassB.kt
STEP 8:
modifications:
U : ClassA.8.kt -> ClassA.kt
modified ir: ClassA.kt
STEP 9..10:
updated exports: ClassA.kt
@@ -0,0 +1,7 @@
fun box(stepId: Int): String {
val x = test()
if (x != stepId) {
return "Fail: $x != $stepId"
}
return "OK"
}
@@ -0,0 +1,39 @@
STEP 0:
dependencies: lib1
modifications:
U : test.0.kt -> test.kt
added file: m.kt, test.kt
STEP 1:
dependencies: lib1
modifications:
U : test.1.kt -> test.kt
modified ir: test.kt
STEP 2:
dependencies: lib1
STEP 3:
dependencies: lib1
updated imports: test.kt
STEP 4:
dependencies: lib1
STEP 5:
dependencies: lib1
modifications:
U : test.5.kt -> test.kt
modified ir: test.kt
STEP 6:
dependencies: lib1
STEP 7:
dependencies: lib1
updated imports: test.kt
STEP 8:
dependencies: lib1
STEP 9:
dependencies: lib1
modifications:
U : test.9.kt -> test.kt
modified ir: test.kt
STEP 10:
dependencies: lib1
modifications:
U : test.10.kt -> test.kt
modified ir: test.kt
@@ -0,0 +1,9 @@
private fun testClassA(): Int {
val a = ClassA()
a.someVar = 0
return a.someVar!!
}
fun test(): Int {
return testClassA()
}
@@ -0,0 +1,17 @@
private fun testClassA(): Int {
val a = ClassA()
a.someVar = 0
return a.someVar!!
}
private fun testClassB(): Int {
val b = ClassB()
b.someVar = b.x
return b.someVar!!
}
fun test(): Int {
val b = testClassB()
val a = testClassA()
return b + a
}
@@ -0,0 +1,17 @@
private fun testClassA(): Int {
val a = ClassA()
a.someVar = 0
return a.someVar!! + a.someFunction() + a.someValue
}
private fun testClassB(): Int {
val b = ClassB()
b.someVar = b.x
return b.someVar!! + b.someFunction()
}
fun test(): Int {
val b = testClassB()
val a = testClassA()
return b + a
}
@@ -0,0 +1,17 @@
private fun testClassA(): Int {
val a = ClassA()
a.someVar = 0
return a.someVar!!
}
private fun testClassB(): Int {
val b = ClassB()
b.someVar = b.x
return b.someVar!! + b.someFunction()
}
fun test(): Int {
val b = testClassB()
val a = testClassA()
return b + a
}
@@ -0,0 +1,17 @@
private fun testClassA(): Int {
val a = ClassA()
a.someVar = 0
return a.someVar!! + a.someFunction()
}
private fun testClassB(): Int {
val b = ClassB()
b.someVar = b.x
return b.someVar!! + b.someFunction()
}
fun test(): Int {
val b = testClassB()
val a = testClassA()
return b + a
}
@@ -0,0 +1,23 @@
MODULES: lib1, main
STEP 0..3:
libs: lib1, main
dirty js: lib1, main
STEP 4:
libs: lib1, main
dirty js: lib1
STEP 5:
libs: lib1, main
dirty js: lib1, main
STEP 6:
libs: lib1, main
dirty js: lib1
STEP 7:
libs: lib1, main
dirty js: lib1, main
STEP 8:
libs: lib1, main
dirty js: lib1
STEP 9..10:
libs: lib1, main
dirty js: lib1, main