[JS IR] IC: Propagate dependencies from nested declaration to parent

JsIrLinker can't load nested declarations,
 therefore it is required to load their parent.
 This patch adds a dependency in the incremental cache graph
 between nested declaration user and nested declaration parent.

^KT-53931 Fixed
^KT-54120 Fixed
This commit is contained in:
Alexander Korepanov
2022-09-23 18:55:08 +02:00
committed by Space
parent bd085fbf43
commit 252dc01dd5
34 changed files with 372 additions and 13 deletions
@@ -0,0 +1,5 @@
class MyClass1 {
companion object {
inline fun companionMethod() = 0
}
}
@@ -0,0 +1,5 @@
class MyClass1 {
companion object {
inline fun companionMethod() = 1
}
}
@@ -0,0 +1,7 @@
class MyClass1 {
class InternalClass {
companion object {
inline fun companionMethod() = 2
}
}
}
@@ -0,0 +1,7 @@
class MyClass1 {
class InternalClass {
companion object {
inline fun companionMethod() = 3
}
}
}
@@ -0,0 +1,19 @@
STEP 0:
modifications:
U : l1.0.kt -> l1.kt
added file: l1.kt
STEP 1:
modifications:
U : l1.1.kt -> l1.kt
modified ir: l1.kt
STEP 2:
modifications:
U : l1.2.kt -> l1.kt
modified ir: l1.kt
STEP 3:
modifications:
U : l1.3.kt -> l1.kt
modified ir: l1.kt
STEP 4:
STEP 5:
updated exports: l1.kt
@@ -0,0 +1 @@
inline fun foo() = MyClass1.companionMethod()
@@ -0,0 +1 @@
inline fun foo() = MyClass1.InternalClass.companionMethod()
@@ -0,0 +1,6 @@
inline fun foo(): Int {
bar(null)
return MyClass1.InternalClass.companionMethod() + 1
}
fun bar(x: Any?): Any = (x as? MyClass1) ?: 1
@@ -0,0 +1,6 @@
inline fun foo(): Int {
bar(null)
return MyClass1.InternalClass.companionMethod() + 1
}
fun bar(x: Any?): Any = x ?: MyClass1()
@@ -0,0 +1,27 @@
STEP 0:
dependencies: lib1
modifications:
U : l2.0.kt -> l2.kt
added file: l2.kt
STEP 1:
dependencies: lib1
updated imports: l2.kt
STEP 2:
dependencies: lib1
modifications:
U : l2.2.kt -> l2.kt
modified ir: l2.kt
STEP 3:
dependencies: lib1
updated imports: l2.kt
STEP 4:
dependencies: lib1
modifications:
U : l2.4.kt -> l2.kt
modified ir: l2.kt
STEP 5:
dependencies: lib1
modifications:
U : l2.5.kt -> l2.kt
modified ir: l2.kt
@@ -0,0 +1,8 @@
fun box(stepId: Int): String {
when (stepId) {
0, 1, 2, 3, 4 -> if (foo() != stepId) return "Fail"
5 -> if (foo() != 4) return "Fail"
else -> return "Unkown"
}
return "OK"
}
@@ -0,0 +1,8 @@
STEP 0:
dependencies: lib1, lib2
added file: m.kt
STEP 1..4:
dependencies: lib1, lib2
updated imports: m.kt
STEP 5:
dependencies: lib1, lib2
@@ -0,0 +1,8 @@
MODULES: lib1, lib2, main
STEP 0..4:
libs: lib1, lib2, main
dirty js: lib1, lib2, main
STEP 5:
libs: lib1, lib2, main
dirty js: lib1, lib2
@@ -0,0 +1,15 @@
class MyClass1 {
companion object {
fun companionMethod(v: Int): Int {
return v.countTrailingZeroBits()
}
}
}
class MyClass2 {
companion object {
fun companionMethod(v: Int): Int {
return v.countTrailingZeroBits()
}
}
}
@@ -0,0 +1,7 @@
class MyClass1 {
companion object {
fun companionMethod(v: Int): Int {
return v.countTrailingZeroBits()
}
}
}
@@ -0,0 +1,13 @@
STEP 0:
modifications:
U : l1.0.kt -> l1.kt
added file: l1.kt
STEP 1:
modifications:
U : l1.1.kt -> l1.kt
modified ir: l1.kt
STEP 2:
modifications:
U : l1.0.kt -> l1.kt
modified ir: l1.kt
STEP 3:
@@ -0,0 +1,5 @@
fun test(x: Int): Int {
val y = MyClass1.companionMethod(x)
return y.countTrailingZeroBits()
}
@@ -0,0 +1,5 @@
fun test(x: Int): Int {
val y = MyClass1.companionMethod(x)
return y
}
@@ -0,0 +1,11 @@
fun box(stepId: Int): String {
val x = test(stepId)
when (stepId) {
0 -> if (x != 5) return "Fail, x == $x"
1 -> if (x != 32) return "Fail, x == $x"
2 -> if (x != 0) return "Fail, x == $x"
3 -> if (x != 0) return "Fail, x == $x"
else -> return "Unkown"
}
return "OK"
}
@@ -0,0 +1,12 @@
STEP 0:
dependencies: lib1
modifications:
U : f.0.kt -> f.kt
added file: m.kt, f.kt
STEP 1..2:
dependencies: lib1
STEP 3:
dependencies: lib1
modifications:
U : f.3.kt -> f.kt
modified ir: f.kt
@@ -0,0 +1,11 @@
MODULES: lib1, main
STEP 0:
libs: lib1, main
dirty js: lib1, main
STEP 1..2:
libs: lib1, main
dirty js: lib1
STEP 3:
libs: lib1, main
dirty js: main
@@ -0,0 +1,5 @@
class MyClass {
class NestedClass {
inline fun foo() = 0
}
}
@@ -0,0 +1,5 @@
class MyClass {
class NestedClass {
inline fun foo() = 1
}
}
@@ -0,0 +1,7 @@
class MyClass {
class NestedClass {
inline fun foo() = 1
}
fun unusedFunction() = -1
}
@@ -0,0 +1,7 @@
data class MyClass(val unusedField: String) {
class NestedClass {
inline fun foo() = 1
}
fun unusedFunction() = -1
}
@@ -0,0 +1,9 @@
data class MyClass(val unusedField: String) {
class NestedClass {
inline fun foo() = 1
val field = 5
}
fun unusedFunction() = -1
}
@@ -0,0 +1,9 @@
data class MyClass(val unusedField: String) {
class NestedClass {
inline fun foo() = field
val field = 5
}
fun unusedFunction() = -1
}
@@ -0,0 +1,9 @@
data class MyClass(val unusedField: String) {
class NestedClass {
inline fun foo() = field
val field = 6
}
fun unusedFunction() = -1
}
@@ -0,0 +1,28 @@
STEP 0:
modifications:
U : l1.0.kt -> l1.kt
added file: l1.kt
STEP 1:
modifications:
U : l1.1.kt -> l1.kt
modified ir: l1.kt
STEP 2:
modifications:
U : l1.2.kt -> l1.kt
modified ir: l1.kt
STEP 3:
modifications:
U : l1.3.kt -> l1.kt
modified ir: l1.kt
STEP 4:
modifications:
U : l1.4.kt -> l1.kt
modified ir: l1.kt
STEP 5:
modifications:
U : l1.5.kt -> l1.kt
modified ir: l1.kt
STEP 6:
modifications:
U : l1.6.kt -> l1.kt
modified ir: l1.kt
@@ -0,0 +1,8 @@
fun box(stepId: Int): String {
when (stepId) {
0, 1, 5, 6 -> if (MyClass.NestedClass().foo() != stepId) return "Fail"
2, 3, 4 -> if (MyClass.NestedClass().foo() != 1) return "Fail"
else -> return "Unknown"
}
return "OK"
}
@@ -0,0 +1,18 @@
STEP 0:
dependencies: lib1
added file: m.kt
STEP 1:
dependencies: lib1
updated imports: m.kt
STEP 2:
dependencies: lib1
STEP 3:
dependencies: lib1
updated imports: m.kt
STEP 4:
dependencies: lib1
STEP 5:
dependencies: lib1
updated imports: m.kt
STEP 6:
dependencies: lib1
@@ -0,0 +1,20 @@
MODULES: lib1, main
STEP 0..1:
libs: lib1, main
dirty js: lib1, main
STEP 2:
libs: lib1, main
dirty js: lib1
STEP 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