[ObjCExport] Implement getSuperClassSymbolNotAny util
KT-64226
This commit is contained in:
committed by
Space Team
parent
9909940b24
commit
66533141b8
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.objcexport.analysisApiUtils
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtClassType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier
|
||||
|
||||
/**
|
||||
* Tries to find the superclass [KtClassOrObjectSymbol] symbol which is *not* kotlin.Any
|
||||
*
|
||||
* e.g.
|
||||
* ```kotlin
|
||||
* abstract class A
|
||||
*
|
||||
* class B: A
|
||||
*
|
||||
* fun example() {
|
||||
* val symbolOfB = // ...
|
||||
* val symbolOfA = symbolOfB.getSuperClassSymbolNotAny()
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
context(KtAnalysisSession)
|
||||
internal fun KtClassOrObjectSymbol.getSuperClassSymbolNotAny(): KtClassOrObjectSymbol? {
|
||||
return superTypes.firstNotNullOfOrNull find@{ superType ->
|
||||
if (superType.isAny) return@find null
|
||||
if (superType is KtClassType) {
|
||||
val classifier = superType.qualifiers.firstNotNullOfOrNull { qualifier ->
|
||||
(qualifier as? KtClassTypeQualifier.KtResolvedClassTypeQualifier)?.symbol
|
||||
}
|
||||
|
||||
if (classifier is KtClassOrObjectSymbol && classifier.classKind.isClass) return@find classifier
|
||||
}
|
||||
|
||||
null
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.objcexport.tests
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.analyze
|
||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getSuperClassSymbolNotAny
|
||||
import org.jetbrains.kotlin.objcexport.testUtils.InlineSourceCodeAnalysis
|
||||
import org.jetbrains.kotlin.objcexport.testUtils.getClassOrFail
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNull
|
||||
|
||||
class GetSuperClassSymbolNotAnyTest(
|
||||
private val inlineSourceCodeAnalysis: InlineSourceCodeAnalysis,
|
||||
) {
|
||||
|
||||
@Test
|
||||
fun `test - no declared superclass - returns null`() {
|
||||
val file = inlineSourceCodeAnalysis.createKtFile("""class Foo""")
|
||||
analyze(file) {
|
||||
val foo = file.getClassOrFail("Foo")
|
||||
assertNull(foo.getSuperClassSymbolNotAny())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - single abstract super class`() {
|
||||
val file = inlineSourceCodeAnalysis.createKtFile(
|
||||
"""
|
||||
abstract class Bar
|
||||
class Foo: Bar()
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
analyze(file) {
|
||||
val fooSymbol = file.getClassOrFail("Foo")
|
||||
val barSymbol = fooSymbol.getSuperClassSymbolNotAny()
|
||||
assertEquals(barSymbol, file.getClassOrFail("Bar"))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - multiple abstract classes`() {
|
||||
val file = inlineSourceCodeAnalysis.createKtFile(
|
||||
"""
|
||||
abstract class A
|
||||
abstract class B: A()
|
||||
class C: B()
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
analyze(file) {
|
||||
val aSymbol = file.getClassOrFail("A")
|
||||
val bSymbol = file.getClassOrFail("B")
|
||||
val cSymbol = file.getClassOrFail("C")
|
||||
|
||||
assertEquals(cSymbol.getSuperClassSymbolNotAny(), bSymbol)
|
||||
assertEquals(bSymbol.getSuperClassSymbolNotAny(), aSymbol)
|
||||
assertNull(aSymbol.getSuperClassSymbolNotAny())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - abstract class and interfaces`() {
|
||||
val file = inlineSourceCodeAnalysis.createKtFile(
|
||||
"""
|
||||
abstract class A
|
||||
interface I1
|
||||
interface I2
|
||||
class Foo: I1, I2, A()
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
analyze(file) {
|
||||
val aSymbol = file.getClassOrFail("A")
|
||||
val i1Symbol = file.getClassOrFail("I1")
|
||||
val i2Symbol = file.getClassOrFail("I2")
|
||||
val fooSymbol = file.getClassOrFail("Foo")
|
||||
|
||||
assertEquals(fooSymbol.getSuperClassSymbolNotAny(), aSymbol)
|
||||
assertNull(i1Symbol.getSuperClassSymbolNotAny())
|
||||
assertNull(i2Symbol.getSuperClassSymbolNotAny())
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user