[JS IR IC] Load only top level signatures for function type interfaces
The dependency signature may refer to function type interface properties (e.g. name) or methods. It is impossible to detect (without hacks) which binary symbol for loading is required. However, when loading a property or a method the entire function type interface is loaded. And vice versa, a loading of function type interface loads properties and methods as well. Therefore, load the top level signature only, it must be the signature of function type interface. ^KT-56582 Fixed
This commit is contained in:
committed by
Space Team
parent
f367541393
commit
121c920099
+7
-1
@@ -189,7 +189,13 @@ internal class JsIrLinkerLoader(
|
||||
for (loadingSrcFileSignatures in loadingSrcFiles.values) {
|
||||
for (loadingSignature in loadingSrcFileSignatures.getExportedSignatures()) {
|
||||
if (checkIsFunctionInterface(loadingSignature)) {
|
||||
moduleDeserializer.tryDeserializeIrSymbol(loadingSignature, BinarySymbolData.SymbolKind.CLASS_SYMBOL)
|
||||
// The signature may refer to function type interface properties (e.g. name) or methods.
|
||||
// It is impossible to detect (without hacks) here which binary symbol is required.
|
||||
// However, when loading a property or a method the entire function type interface is loaded.
|
||||
// And vice versa, a loading of function type interface loads properties and methods as well.
|
||||
// Therefore, load the top level signature only - it must be the signature of function type interface.
|
||||
val topLevelSignature = loadingSignature.topLevelSignature()
|
||||
moduleDeserializer.tryDeserializeIrSymbol(topLevelSignature, BinarySymbolData.SymbolKind.CLASS_SYMBOL)
|
||||
} else if (loadingSignature in moduleDeserializer) {
|
||||
moduleDeserializer.addModuleReachableTopLevel(loadingSignature)
|
||||
}
|
||||
|
||||
Generated
+5
@@ -175,6 +175,11 @@ public class JsIrES6InvalidationTestGenerated extends AbstractJsIrES6Invalidatio
|
||||
runTest("js/js.translator/testData/incremental/invalidation/functionTypeInterface/");
|
||||
}
|
||||
|
||||
@TestMetadata("functionTypeInterfaceReflect")
|
||||
public void testFunctionTypeInterfaceReflect() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/functionTypeInterfaceReflect/");
|
||||
}
|
||||
|
||||
@TestMetadata("genericFunctions")
|
||||
public void testGenericFunctions() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/genericFunctions/");
|
||||
|
||||
+5
@@ -175,6 +175,11 @@ public class JsIrInvalidationTestGenerated extends AbstractJsIrInvalidationTest
|
||||
runTest("js/js.translator/testData/incremental/invalidation/functionTypeInterface/");
|
||||
}
|
||||
|
||||
@TestMetadata("functionTypeInterfaceReflect")
|
||||
public void testFunctionTypeInterfaceReflect() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/functionTypeInterfaceReflect/");
|
||||
}
|
||||
|
||||
@TestMetadata("genericFunctions")
|
||||
public void testGenericFunctions() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/genericFunctions/");
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
object A {
|
||||
public fun testFunction() { }
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
object B {
|
||||
public fun testFunction(x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) { }
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
object C {
|
||||
public fun testFunction(x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) { }
|
||||
}
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
STEP 0:
|
||||
modifications:
|
||||
U : A.0.kt -> A.kt
|
||||
U : B.0.kt -> B.kt
|
||||
U : C.0.kt -> C.kt
|
||||
added file: A.kt, B.kt, C.kt
|
||||
STEP 1:
|
||||
updated exports: A.kt, B.kt
|
||||
STEP 2:
|
||||
updated exports: A.kt
|
||||
STEP 3:
|
||||
updated exports: C.kt
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fun box(stepId: Int): String {
|
||||
val s = test()
|
||||
when (stepId) {
|
||||
0 -> if (s != "class A - testFunction") return "Fail, got '$s'"
|
||||
1 -> if (s != "class B - testFunction") return "Fail, got '$s'"
|
||||
2 -> if (s != "class A - testFunction, class B - testFunction") return "Fail, got '$s'"
|
||||
3 -> if (s != "class A - testFunction, class B - testFunction, class C - testFunction") return "Fail, got '$s'"
|
||||
else -> return "Unknown"
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
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
|
||||
modifications:
|
||||
U : test.2.kt -> test.kt
|
||||
modified ir: test.kt
|
||||
STEP 3:
|
||||
dependencies: lib1
|
||||
modifications:
|
||||
U : test.3.kt -> test.kt
|
||||
modified ir: test.kt
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
private fun nameToString(
|
||||
kClass: KClass<*>,
|
||||
methodName: String
|
||||
) = "$kClass - $methodName"
|
||||
|
||||
internal fun test(): String {
|
||||
return nameToString(A::class, A::testFunction.name)
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
private fun nameToString(
|
||||
kClass: KClass<*>,
|
||||
methodName: String
|
||||
) = "$kClass - $methodName"
|
||||
|
||||
internal fun test(): String {
|
||||
return nameToString(B::class, B::testFunction.name)
|
||||
}
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
private fun nameToString(
|
||||
kClass: KClass<*>,
|
||||
methodName: String
|
||||
) = "$kClass - $methodName"
|
||||
|
||||
internal fun test(): String {
|
||||
return "${nameToString(A::class, A::testFunction.name)}, " +
|
||||
"${nameToString(B::class, B::testFunction.name)}"
|
||||
}
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
private fun nameToString(
|
||||
kClass: KClass<*>,
|
||||
methodName: String
|
||||
) = "$kClass - $methodName"
|
||||
|
||||
internal fun test(): String {
|
||||
return "${nameToString(A::class, A::testFunction.name)}, " +
|
||||
"${nameToString(B::class, B::testFunction.name)}, " +
|
||||
"${nameToString(C::class, C::testFunction.name)}"
|
||||
}
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
MODULES: lib1, main
|
||||
|
||||
STEP 0..3:
|
||||
libs: lib1, main
|
||||
dirty js: lib1, main
|
||||
Reference in New Issue
Block a user