Skip to content

Commit 254c7f0

Browse files
committed
Add a test for the caching behavior of StabilityInferencer
1 parent c6702d6 commit 254c7f0

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

plugins/compose/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/ClassStabilityTransformTests.kt

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,17 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildClass
3232
import org.jetbrains.kotlin.ir.builders.declarations.buildReceiverParameter
3333
import org.jetbrains.kotlin.ir.declarations.IrClass
3434
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
35+
import org.jetbrains.kotlin.ir.declarations.IrFile
3536
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
3637
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
38+
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
3739
import org.jetbrains.kotlin.ir.expressions.IrExpression
3840
import org.jetbrains.kotlin.ir.expressions.IrReturn
3941
import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
4042
import org.jetbrains.kotlin.ir.types.IrType
4143
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
4244
import org.jetbrains.kotlin.ir.util.addChild
45+
import org.jetbrains.kotlin.ir.util.deepCopyWithoutPatchingParents
4346
import org.jetbrains.kotlin.ir.util.defaultType
4447
import org.jetbrains.kotlin.ir.util.file
4548
import org.jetbrains.kotlin.ir.util.statements
@@ -1872,6 +1875,54 @@ class ClassStabilityTransformTests(useFir: Boolean) : AbstractIrTransformTest(us
18721875
)
18731876
}
18741877

1878+
@Test
1879+
fun testStabilityCaching() {
1880+
val testFileSource = """
1881+
class A
1882+
class B(val a: A)
1883+
class C(val b: B)
1884+
class D(val c: C)
1885+
""".trimIndent()
1886+
1887+
val files = listOf(SourceFile("Test.kt", testFileSource))
1888+
val irModule = compileToIr(files, additionalPaths)
1889+
val stabilityInferencer = StabilityInferencer(isTargetJvm = true, irModule.descriptor, setOf())
1890+
1891+
val testIrFile = irModule.files.last()
1892+
val (aClass, bClass, cClass, dClass) = testIrFile.declarations.filterIsInstance<IrClass>()
1893+
1894+
// When a dependent in a different file requests the stability of a class defined in
1895+
// `testIrFile`, we expect the computed stability not to be cached. Note that
1896+
// `deepCopyWithoutPatchingParents` is used on the following line to obtain an object that
1897+
// is not referentially equal to `testIrFile`.
1898+
stabilityInferencer.stabilityOf(dClass.defaultType as IrType, testIrFile.deepCopyWithoutPatchingParents())
1899+
assertEquals(0, stabilityInferencer.cache.size)
1900+
1901+
// When `StabilityInferencer`'s cache is initially empty and `D`'s stability is requested,
1902+
// we expect the stability values of `A`, `B`, `C`, and `D` to each be computed and added to
1903+
// the cache.
1904+
val stabilityOfD = stabilityInferencer.stabilityOf(dClass.defaultType as IrType, testIrFile)
1905+
assertEquals(4, stabilityInferencer.cache.size)
1906+
1907+
// When the stability of a class is cached, we expect it to be returned from the cache, and
1908+
// we expect no cache modifications to happen.
1909+
1910+
assertEquals(
1911+
stabilityOfD,
1912+
stabilityInferencer.stabilityOf(dClass.defaultType as IrType, testIrFile)
1913+
)
1914+
assertEquals(4, stabilityInferencer.cache.size)
1915+
1916+
stabilityInferencer.stabilityOf(cClass.defaultType as IrType, testIrFile)
1917+
assertEquals(4, stabilityInferencer.cache.size)
1918+
1919+
stabilityInferencer.stabilityOf(bClass.defaultType as IrType, testIrFile)
1920+
assertEquals(4, stabilityInferencer.cache.size)
1921+
1922+
stabilityInferencer.stabilityOf(aClass.defaultType as IrType, testIrFile)
1923+
assertEquals(4, stabilityInferencer.cache.size)
1924+
}
1925+
18751926
private fun assertStability(
18761927
externalSrc: String,
18771928
localSrc: String,

plugins/compose/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/analysis/Stability.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package androidx.compose.compiler.plugins.kotlin.analysis
2121
import androidx.compose.compiler.plugins.kotlin.ComposeFqNames
2222
import androidx.compose.compiler.plugins.kotlin.lower.annotationClass
2323
import androidx.compose.compiler.plugins.kotlin.lower.isSyntheticComposableFunction
24+
import com.google.common.annotations.VisibleForTesting
2425
import org.jetbrains.kotlin.backend.jvm.ir.isInlineClassType
2526
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
2627
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
@@ -192,7 +193,8 @@ private fun IrAnnotationContainer.stabilityParamBitmask(): Int? =
192193
(annotations.findAnnotation(ComposeFqNames.StabilityInferred)?.arguments[0] as? IrConst)
193194
?.value as? Int
194195

195-
private data class SymbolForAnalysis(
196+
@VisibleForTesting
197+
data class SymbolForAnalysis(
196198
val symbol: IrClassifierSymbol,
197199
val typeParameters: List<IrTypeArgument?>,
198200
/**
@@ -214,7 +216,9 @@ class StabilityInferencer(
214216
) {
215217
private val externalTypeMatcherCollection = FqNameMatcherCollection(externalStableTypeMatchers)
216218

217-
private val cache = mutableMapOf<SymbolForAnalysis, Stability>()
219+
@VisibleForTesting
220+
var cache = mutableMapOf<SymbolForAnalysis, Stability>()
221+
private set
218222

219223
/**
220224
* Returns the stability of [irType].

0 commit comments

Comments
 (0)