[JS IR] Take into account the declaration annotations in IC hash

So the annotation modifications invalidate the caller.
This commit is contained in:
Alexander Korepanov
2022-12-02 18:47:34 +01:00
committed by Space Team
parent 0a35d84193
commit d21cbfe02e
14 changed files with 91 additions and 19 deletions
@@ -9,7 +9,9 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CrossModuleReferences
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
@@ -45,6 +47,18 @@ private class HashCalculatorForIC {
update(data.toByteArray())
}
fun update(irElement: IrElement) {
irElement.accept(
visitor = DumpIrTreeVisitor(
out = object : Appendable {
override fun append(csq: CharSequence) = this.apply { update(csq.toString().toByteArray()) }
override fun append(csq: CharSequence, start: Int, end: Int) = append(csq.subSequence(start, end))
override fun append(c: Char) = append(c.toString())
}
), data = ""
)
}
inline fun <T> updateForEach(collection: Collection<T>, f: (T) -> Unit) {
update(collection.size)
collection.forEach { f(it) }
@@ -90,16 +104,8 @@ internal fun CompilerConfiguration.configHashForIC() = HashCalculatorForIC().app
update(languageVersionSettings.toString())
}.finalize()
internal fun IrElement.irElementHashForIC() = HashCalculatorForIC().also {
accept(
visitor = DumpIrTreeVisitor(
out = object : Appendable {
override fun append(csq: CharSequence) = this.apply { it.update(csq.toString().toByteArray()) }
override fun append(csq: CharSequence, start: Int, end: Int) = append(csq.subSequence(start, end))
override fun append(c: Char) = append(c.toString())
}
), data = ""
)
internal fun IrSimpleFunction.irSimpleFunctionHashForIC() = HashCalculatorForIC().also {
it.update(this)
}.finalize()
internal fun IrSymbol.irSymbolHashForIC() = HashCalculatorForIC().also {
@@ -118,6 +124,11 @@ internal fun IrSymbol.irSymbolHashForIC() = HashCalculatorForIC().also {
it.update(functionParam.defaultValue?.let { 1 } ?: 0)
}
}
(owner as? IrAnnotationContainer)?.let { annotationContainer ->
it.updateForEach(annotationContainer.annotations) { annotation ->
it.update(annotation)
}
}
}.finalize()
internal fun String.stringHashForIC() = HashCalculatorForIC().also { it.update(this) }.finalize()
@@ -41,10 +41,10 @@ internal class IdSignatureHashCalculator {
}
flatHashes[declaration] = if (declaration.isFakeOverride) {
declaration.resolveFakeOverride()?.irElementHashForIC()
declaration.resolveFakeOverride()?.irSimpleFunctionHashForIC()
?: icError("can not resolve fake override for ${declaration.render()}")
} else {
declaration.irElementHashForIC()
declaration.irSimpleFunctionHashForIC()
}
}
// go deeper since local inline special declarations (like a reference adaptor) may appear
@@ -190,6 +190,11 @@ public class InvalidationTestGenerated extends AbstractInvalidationTest {
runTest("js/js.translator/testData/incremental/invalidation/inlineBecomeNonInline/");
}
@TestMetadata("inlineFunctionAnnotations")
public void testInlineFunctionAnnotations() throws Exception {
runTest("js/js.translator/testData/incremental/invalidation/inlineFunctionAnnotations/");
}
@TestMetadata("inlineFunctionAsFunctionReference")
public void testInlineFunctionAsFunctionReference() throws Exception {
runTest("js/js.translator/testData/incremental/invalidation/inlineFunctionAsFunctionReference/");
@@ -0,0 +1,3 @@
class MyClassA {
inline fun foo() = 42
}
@@ -0,0 +1,4 @@
@JsExport
class MyClassA {
inline fun foo() = 42
}
@@ -0,0 +1,5 @@
@JsExport
class MyClassA {
@JsName("bar")
inline fun foo() = 42
}
@@ -0,0 +1,5 @@
@JsExport
class MyClassA {
@JsName("baz")
inline fun foo() = 42
}
@@ -0,0 +1,5 @@
@JsExport
class MyClassA {
@JsName("baz")
inline fun foo() = 33
}
@@ -0,0 +1,20 @@
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
@@ -0,0 +1,8 @@
fun box(stepId: Int): String {
when (stepId) {
0, 1, 2, 3 -> if (MyClassA().foo() != 42) return "Fail"
4 -> if (MyClassA().foo() != 33) return "Fail"
else -> return "Unknown"
}
return "OK"
}
@@ -0,0 +1,6 @@
STEP 0:
dependencies: lib1
added file: m.kt
STEP 1..4:
dependencies: lib1
updated imports: m.kt
@@ -0,0 +1,5 @@
MODULES: lib1, main
STEP 0..4:
libs: lib1, main
dirty js: lib1, main
@@ -1,8 +1,6 @@
STEP 0:
dependencies: lib1
added file: m.kt
STEP 1..3:
STEP 1..6:
dependencies: lib1
updated imports: m.kt
STEP 4..6:
dependencies: lib1
@@ -1,8 +1,5 @@
MODULES: lib1, main
STEP 0..3:
STEP 0..6:
libs: lib1, main
dirty js: lib1, main
STEP 4..6:
libs: lib1, main
dirty js: lib1