[ObjCExport] Implement isObjCBaseCallable util
KT-64226
This commit is contained in:
committed by
Space Team
parent
b5bcfaa2e3
commit
e0383282b5
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.KtCallableSymbol
|
||||
|
||||
/**
|
||||
* Check that given [descriptor] is a so-called "base method", i.e. method
|
||||
* that doesn't override anything in a generated Objective-C interface.
|
||||
* Note that it does not mean that it has no "override" keyword.
|
||||
* Consider example:
|
||||
* ```kotlin
|
||||
* private interface I {
|
||||
* fun f()
|
||||
* }
|
||||
*
|
||||
* class C : I {
|
||||
* override fun f() {}
|
||||
* }
|
||||
* ```
|
||||
* Interface `I` is not exposed to the generated header, so C#f is considered to be a base method even though it has an "override" keyword.
|
||||
*/
|
||||
context(KtAnalysisSession)
|
||||
fun KtCallableSymbol.isObjCBaseCallable(): Boolean {
|
||||
return getAllOverriddenSymbols().none { overriddenSymbol ->
|
||||
overriddenSymbol.isVisibleInObjC()
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.isObjCBaseCallable
|
||||
import org.jetbrains.kotlin.objcexport.testUtils.InlineSourceCodeAnalysis
|
||||
import org.jetbrains.kotlin.objcexport.testUtils.getClassOrFail
|
||||
import org.jetbrains.kotlin.objcexport.testUtils.getFunctionOrFail
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class IsObjCBaseCallableTest(
|
||||
private val inlineSourceCodeAnalysis: InlineSourceCodeAnalysis,
|
||||
) {
|
||||
@Test
|
||||
fun `test - top level function`() {
|
||||
val file = inlineSourceCodeAnalysis.createKtFile("fun foo() = Unit")
|
||||
analyze(file) {
|
||||
val fooSymbol = file.getFunctionOrFail("foo")
|
||||
assertTrue(fooSymbol.isObjCBaseCallable())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - function overriding abstract function`() {
|
||||
val file = inlineSourceCodeAnalysis.createKtFile(
|
||||
"""
|
||||
abstract class Bar {
|
||||
abstract fun x()
|
||||
}
|
||||
|
||||
class Foo : Bar() {
|
||||
override fun x() = Unit
|
||||
}
|
||||
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
analyze(file) {
|
||||
val fooSymbol = file.getClassOrFail("Foo")
|
||||
val xSymbol = fooSymbol.getMemberScope().getFunctionOrFail("x")
|
||||
assertFalse(xSymbol.isObjCBaseCallable())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - function overriding private interface function`() {
|
||||
val file = inlineSourceCodeAnalysis.createKtFile(
|
||||
"""
|
||||
private interface I {
|
||||
fun x()
|
||||
}
|
||||
class Foo: I {
|
||||
override fun x() = Unit
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
analyze(file) {
|
||||
val fooSymbol = file.getClassOrFail("Foo")
|
||||
val xSymbol = fooSymbol.getMemberScope().getFunctionOrFail("x")
|
||||
assertTrue(xSymbol.isObjCBaseCallable())
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user