[Commonizer] Implement SimpleCirSupertypesResolverTest
^KT-47430
This commit is contained in:
committed by
Space
parent
f64a0efa8b
commit
1e95717b8d
+170
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.commonizer.cir
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirClassifierIndex
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirProvided
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiersByModules
|
||||
import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot
|
||||
import org.jetbrains.kotlin.commonizer.utils.KtInlineSourceCommonizerTestCase
|
||||
import org.jetbrains.kotlin.commonizer.utils.createCirTree
|
||||
import org.jetbrains.kotlin.commonizer.utils.mockClassType
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class SimpleCirSupertypesResolverTest : KtInlineSourceCommonizerTestCase() {
|
||||
|
||||
fun `test single supertype from module`() {
|
||||
val module = createCirTreeFromSourceCode(
|
||||
"""
|
||||
interface A
|
||||
class X: A
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val root = CirTreeRoot(listOf(module))
|
||||
val index = CirClassifierIndex(root)
|
||||
val resolver = SimpleCirSupertypesResolver(index, CirProvidedClassifiers.EMPTY)
|
||||
val supertypes = resolver.supertypes(mockClassType("X"))
|
||||
kotlin.test.assertEquals(1, supertypes.size, "Expected single supertype. Found $supertypes")
|
||||
val supertype = supertypes.single()
|
||||
kotlin.test.assertEquals(CirEntityId.create("A"), supertype.classifierId)
|
||||
kotlin.test.assertNull(supertype.outerType, "Expected no outerType")
|
||||
kotlin.test.assertTrue(supertype.arguments.isEmpty(), "Expected no arguments. Found ${supertype.arguments}")
|
||||
kotlin.test.assertFalse(supertype.isMarkedNullable, "Expected supertype to be marked *not* nullable")
|
||||
}
|
||||
|
||||
fun `test outerType`() {
|
||||
val module = createCirTreeFromSourceCode(
|
||||
"""
|
||||
class Outer {
|
||||
open inner class Inner
|
||||
class X: Inner()
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val root = CirTreeRoot(listOf(module))
|
||||
val index = CirClassifierIndex(root)
|
||||
val resolver = SimpleCirSupertypesResolver(index, CirProvidedClassifiers.EMPTY)
|
||||
val supertypes = resolver.supertypes(mockClassType("/Outer.X"))
|
||||
kotlin.test.assertEquals(1, supertypes.size, "Expected single supertype. Found $supertypes")
|
||||
val supertype = supertypes.single()
|
||||
kotlin.test.assertEquals(CirEntityId.create("Outer.Inner"), supertype.classifierId)
|
||||
val outerType = kotlin.test.assertNotNull(supertype.outerType, "Expected outerType")
|
||||
kotlin.test.assertEquals(CirEntityId.create("Outer"), outerType.classifierId)
|
||||
}
|
||||
|
||||
fun `test hierarchy supertype from module`() {
|
||||
val module = createCirTreeFromSourceCode(
|
||||
"""
|
||||
interface A
|
||||
interface B: A
|
||||
interface C: A
|
||||
class X: B, C
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val root = CirTreeRoot(listOf(module))
|
||||
val index = CirClassifierIndex(root)
|
||||
val resolver = SimpleCirSupertypesResolver(index, CirProvidedClassifiers.EMPTY)
|
||||
val supertypes = resolver.supertypes(mockClassType("X"))
|
||||
|
||||
assertEquals(
|
||||
setOf("/B", "/C"), supertypes.map { it.safeAs<CirClassType>()?.classifierId.toString() }.toSet()
|
||||
)
|
||||
|
||||
supertypes.forEach { supertype ->
|
||||
kotlin.test.assertNull(supertype.outerType, "Expected no outerType")
|
||||
kotlin.test.assertTrue(supertype.arguments.isEmpty(), "Expected no arguments. Found ${supertype.arguments}")
|
||||
kotlin.test.assertFalse(supertype.isMarkedNullable, "Expected supertype to be marked *not* nullable")
|
||||
}
|
||||
}
|
||||
|
||||
fun `test single nullable supertype from module`() {
|
||||
val module = createCirTreeFromSourceCode(
|
||||
"""
|
||||
interface A
|
||||
class X: A
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val root = CirTreeRoot(listOf(module))
|
||||
val index = CirClassifierIndex(root)
|
||||
val resolver = SimpleCirSupertypesResolver(index, CirProvidedClassifiers.EMPTY)
|
||||
val supertypes = resolver.supertypes(mockClassType("X", nullable = true))
|
||||
kotlin.test.assertEquals(1, supertypes.size, "Expected single supertype. Found $supertypes")
|
||||
val supertype = supertypes.single()
|
||||
kotlin.test.assertEquals(CirEntityId.create("A"), supertype.classifierId)
|
||||
kotlin.test.assertTrue(supertype.isMarkedNullable, "Expected supertype to be marked nullable")
|
||||
}
|
||||
|
||||
fun `test single supertype from dependencies`() {
|
||||
val module = createCirTree {
|
||||
dependency { source("""interface A""") }
|
||||
source("""class X: A""")
|
||||
}
|
||||
|
||||
val root = CirTreeRoot(listOf(module))
|
||||
val index = CirClassifierIndex(root)
|
||||
val resolver = SimpleCirSupertypesResolver(
|
||||
index, CirProvidedClassifiersByModules(
|
||||
false, mapOf(
|
||||
CirEntityId.create("A") to CirProvided.RegularClass(
|
||||
typeParameters = emptyList(),
|
||||
supertypes = emptyList(),
|
||||
visibility = Visibilities.Public,
|
||||
kind = ClassKind.INTERFACE
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
val supertypes = resolver.supertypes(mockClassType("X"))
|
||||
kotlin.test.assertEquals(1, supertypes.size, "Expected single supertype. Found $supertypes")
|
||||
val supertype = supertypes.single()
|
||||
kotlin.test.assertEquals(CirEntityId.create("A"), supertype.classifierId)
|
||||
kotlin.test.assertNull(supertype.outerType, "Expected no outerType")
|
||||
kotlin.test.assertTrue(supertype.arguments.isEmpty(), "Expected no arguments. Found ${supertype.arguments}")
|
||||
kotlin.test.assertFalse(supertype.isMarkedNullable, "Expected supertype to be marked *not* nullable")
|
||||
}
|
||||
|
||||
fun `test single supertype from module and dependencies`() {
|
||||
val module = createCirTree {
|
||||
dependency { source("""interface A""") }
|
||||
source(
|
||||
"""
|
||||
interface B
|
||||
class X: A, B
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val root = CirTreeRoot(listOf(module))
|
||||
val index = CirClassifierIndex(root)
|
||||
val resolver = SimpleCirSupertypesResolver(
|
||||
index, CirProvidedClassifiersByModules(
|
||||
false, mapOf(
|
||||
CirEntityId.create("A") to CirProvided.RegularClass(
|
||||
typeParameters = emptyList(),
|
||||
supertypes = emptyList(),
|
||||
visibility = Visibilities.Public,
|
||||
kind = ClassKind.INTERFACE
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
val supertypes = resolver.supertypes(mockClassType("X"))
|
||||
kotlin.test.assertEquals(setOf("/A", "/B"), supertypes.map { it.safeAs<CirClassType>()?.classifierId.toString() }.toSet())
|
||||
|
||||
supertypes.forEach { supertype ->
|
||||
kotlin.test.assertNull(supertype.outerType, "Expected no outerType")
|
||||
kotlin.test.assertTrue(supertype.arguments.isEmpty(), "Expected no arguments. Found ${supertype.arguments}")
|
||||
kotlin.test.assertFalse(supertype.isMarkedNullable, "Expected supertype to be marked *not* nullable")
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
@@ -6,6 +6,8 @@
|
||||
package org.jetbrains.kotlin.commonizer.tree.deserializer
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirClassType
|
||||
import org.jetbrains.kotlin.commonizer.tree.CirTreeClass
|
||||
import org.jetbrains.kotlin.commonizer.util.transitiveClosure
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
@@ -117,6 +119,26 @@ class CirTreeClassDeserializerTest : AbstractCirTreeDeserializerTest() {
|
||||
|
||||
}
|
||||
|
||||
fun `test supertypes - supertype being nested`() {
|
||||
val module = createCirTreeFromSourceCode(
|
||||
"""
|
||||
class Outer {
|
||||
open inner class Inner
|
||||
inner class X: Outer.Inner()
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val pkg = module.assertSinglePackage()
|
||||
val xClass = pkg.classes.flatMap { transitiveClosure(it, CirTreeClass::classes) + it }
|
||||
.singleOrNull { it.clazz.name.toStrippedString() == "X" } ?: kotlin.test.fail("Missing class 'X'")
|
||||
val xSuperType = xClass.clazz.supertypes.singleOrNull()
|
||||
?: kotlin.test.fail("Expected single supertype for 'X'. Found ${xClass.clazz.supertypes}")
|
||||
val xClassSuperType = assertIs<CirClassType>(xSuperType, "Expected xSuperType to be class type")
|
||||
assertEquals("/Outer.Inner", xClassSuperType.classifierId.toString())
|
||||
assertEquals("/Outer", xClassSuperType.outerType?.classifierId.toString())
|
||||
}
|
||||
|
||||
fun `test abstract class`() {
|
||||
val module = createCirTreeFromSourceCode("abstract class X")
|
||||
val clazz = module.assertSingleClass()
|
||||
|
||||
@@ -47,7 +47,7 @@ internal fun mockClassType(
|
||||
)
|
||||
|
||||
private fun createValidClassifierId(classifierId: String): CirEntityId {
|
||||
check(classifierId.none { it == '.' || it == '\\' || it == '?' }) { "Malformed classifier ID: $classifierId" }
|
||||
check(classifierId.none { it == '\\' || it == '?' }) { "Malformed classifier ID: $classifierId" }
|
||||
return CirEntityId.create(classifierId)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user