diff --git a/kmp-nativecoroutines-compiler/src/main/kotlin/com/rickclephas/kmp/nativecoroutines/compiler/classic/utils/ObjCRefinement.kt b/kmp-nativecoroutines-compiler/src/main/kotlin/com/rickclephas/kmp/nativecoroutines/compiler/classic/utils/ObjCRefinement.kt index 001581a6..5ceb9e67 100644 --- a/kmp-nativecoroutines-compiler/src/main/kotlin/com/rickclephas/kmp/nativecoroutines/compiler/classic/utils/ObjCRefinement.kt +++ b/kmp-nativecoroutines-compiler/src/main/kotlin/com/rickclephas/kmp/nativecoroutines/compiler/classic/utils/ObjCRefinement.kt @@ -8,7 +8,12 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass internal val DeclarationDescriptor.isRefined: Boolean get() = annotations.any { annotation -> !annotation.isNativeCoroutinesAnnotation && annotation.isRefinementAnnotation - } + } || (containingDeclaration?.isHiddenFromObjC ?: false) + +private val DeclarationDescriptor.isHiddenFromObjC: Boolean + get() = annotations.any { annotation -> + annotation.isHiddenFromObjCAnnotation + } || (containingDeclaration?.isHiddenFromObjC ?: false) @Suppress("UnstableApiUsage") private val AnnotationDescriptor.isRefinementAnnotation: Boolean @@ -16,3 +21,8 @@ private val AnnotationDescriptor.isRefinementAnnotation: Boolean val fqName = metaAnnotation.fqName fqName == FqNames.hidesFromObjC || fqName == FqNames.refinesInSwift } ?: false + +private val AnnotationDescriptor.isHiddenFromObjCAnnotation: Boolean + get() = annotationClass?.annotations?.any { metaAnnotation -> + metaAnnotation.fqName == FqNames.hidesFromObjC + } ?: false diff --git a/kmp-nativecoroutines-compiler/src/main/kotlin/com/rickclephas/kmp/nativecoroutines/compiler/fir/utils/ObjCRefinement.kt b/kmp-nativecoroutines-compiler/src/main/kotlin/com/rickclephas/kmp/nativecoroutines/compiler/fir/utils/ObjCRefinement.kt index 75ad4b5c..54657038 100644 --- a/kmp-nativecoroutines-compiler/src/main/kotlin/com/rickclephas/kmp/nativecoroutines/compiler/fir/utils/ObjCRefinement.kt +++ b/kmp-nativecoroutines-compiler/src/main/kotlin/com/rickclephas/kmp/nativecoroutines/compiler/fir/utils/ObjCRefinement.kt @@ -3,17 +3,31 @@ package com.rickclephas.kmp.nativecoroutines.compiler.fir.utils import com.rickclephas.kmp.nativecoroutines.compiler.utils.ClassIds import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration +import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId import org.jetbrains.kotlin.fir.declarations.toAnnotationClassLikeSymbol import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.resolve.getContainingClass +import org.jetbrains.kotlin.fir.resolve.getContainingDeclaration internal fun FirCallableDeclaration.isRefined(session: FirSession): Boolean = annotations.any { annotation -> !annotation.isNativeCoroutinesAnnotation(session) && annotation.isRefinementAnnotation(session) - } + } || (getContainingClass()?.isHiddenFromObjC(session) ?: false) + +private fun FirClassLikeDeclaration.isHiddenFromObjC(session: FirSession): Boolean = + annotations.any { annotation -> + annotation.isHidingFromObjCAnnotation(session) + } || (getContainingDeclaration(session)?.isHiddenFromObjC(session) ?: false) private fun FirAnnotation.isRefinementAnnotation(session: FirSession): Boolean = toAnnotationClassLikeSymbol(session)?.resolvedAnnotationsWithClassIds.orEmpty().any { metaAnnotation -> val classId = metaAnnotation.toAnnotationClassId(session) classId == ClassIds.hidesFromObjC || classId == ClassIds.refinesInSwift } + +private fun FirAnnotation.isHidingFromObjCAnnotation(session: FirSession): Boolean = + toAnnotationClassLikeSymbol(session)?.resolvedAnnotationsWithClassIds.orEmpty().any { metaAnnotation -> + val classId = metaAnnotation.toAnnotationClassId(session) + classId == ClassIds.hidesFromObjC + } diff --git a/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedAnnotated.kt b/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedAnnotated.kt index 6e54122c..0f65cc59 100644 --- a/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedAnnotated.kt +++ b/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedAnnotated.kt @@ -77,6 +77,20 @@ interface TestInterface { val flowInterfaceProperty: Flow } +@OptIn(ExperimentalObjCRefinement::class) +@HiddenFromObjC +interface TestHiddenFromObjCInterface { + suspend fun suspendInterfaceFunction(): Int + + val flowInterfaceProperty: Flow + + class Nested { + suspend fun suspendInterfaceFunction(): Int = 0 + + val flowInterfaceProperty: Flow = throw Throwable() + } +} + class TestClassA: TestInterface { override suspend fun suspendInterfaceFunction(): Int = 0 @@ -120,3 +134,19 @@ actual class TestClassC { actual val flowProperty: Flow get() = throw Throwable() } + +class TestClassD { + @NativeCoroutines + suspend fun suspendInterfaceFunction(): Int = 0 + + @NativeCoroutines + val flowInterfaceProperty: Flow = throw Throwable() + + @OptIn(ExperimentalObjCRefinement::class) + @HiddenFromObjC + interface Nested { + suspend fun suspendInterfaceFunction(): Int + + val flowInterfaceProperty: Flow + } +} diff --git a/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedError.kt b/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedError.kt index 16989ee6..6d79b93a 100644 --- a/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedError.kt +++ b/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedError.kt @@ -59,6 +59,20 @@ interface TestInterface { val flowInterfaceProperty: Flow } +@OptIn(ExperimentalObjCRefinement::class) +@HiddenFromObjC +interface TestHiddenFromObjCInterface { + suspend fun suspendInterfaceFunction(): Int + + val flowInterfaceProperty: Flow + + class Nested { + suspend fun suspendInterfaceFunction(): Int = 0 + + val flowInterfaceProperty: Flow = throw Throwable() + } +} + class TestClassA: TestInterface { override suspend fun suspendInterfaceFunction(): Int = 0 @@ -96,3 +110,17 @@ actual class TestClassC { actual val flowProperty: Flow get() = throw Throwable() } + +class TestClassD { + suspend fun suspendInterfaceFunction(): Int = 0 + + val flowInterfaceProperty: Flow = throw Throwable() + + @OptIn(ExperimentalObjCRefinement::class) + @HiddenFromObjC + interface Nested { + suspend fun suspendInterfaceFunction(): Int + + val flowInterfaceProperty: Flow + } +} diff --git a/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedNone.kt b/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedNone.kt index da4c7804..bbbaf47f 100644 --- a/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedNone.kt +++ b/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedNone.kt @@ -59,6 +59,20 @@ interface TestInterface { val flowInterfaceProperty: Flow } +@OptIn(ExperimentalObjCRefinement::class) +@HiddenFromObjC +interface TestHiddenFromObjCInterface { + suspend fun suspendInterfaceFunction(): Int + + val flowInterfaceProperty: Flow + + class Nested { + suspend fun suspendInterfaceFunction(): Int = 0 + + val flowInterfaceProperty: Flow = throw Throwable() + } +} + class TestClassA: TestInterface { override suspend fun suspendInterfaceFunction(): Int = 0 @@ -96,3 +110,17 @@ actual class TestClassC { actual val flowProperty: Flow get() = throw Throwable() } + +class TestClassD { + suspend fun suspendInterfaceFunction(): Int = 0 + + val flowInterfaceProperty: Flow = throw Throwable() + + @OptIn(ExperimentalObjCRefinement::class) + @HiddenFromObjC + interface Nested { + suspend fun suspendInterfaceFunction(): Int + + val flowInterfaceProperty: Flow + } +} diff --git a/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedWarning.kt b/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedWarning.kt index 9d4ce7b1..29451620 100644 --- a/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedWarning.kt +++ b/kmp-nativecoroutines-compiler/src/testData/diagnostics/exposedWarning.kt @@ -59,6 +59,20 @@ interface TestInterface { val flowInterfaceProperty: Flow } +@OptIn(ExperimentalObjCRefinement::class) +@HiddenFromObjC +interface TestHiddenFromObjCInterface { + suspend fun suspendInterfaceFunction(): Int + + val flowInterfaceProperty: Flow + + class Nested { + suspend fun suspendInterfaceFunction(): Int = 0 + + val flowInterfaceProperty: Flow = throw Throwable() + } +} + class TestClassA: TestInterface { override suspend fun suspendInterfaceFunction(): Int = 0 @@ -96,3 +110,17 @@ actual class TestClassC { actual val flowProperty: Flow get() = throw Throwable() } + +class TestClassD { + suspend fun suspendInterfaceFunction(): Int = 0 + + val flowInterfaceProperty: Flow = throw Throwable() + + @OptIn(ExperimentalObjCRefinement::class) + @HiddenFromObjC + interface Nested { + suspend fun suspendInterfaceFunction(): Int + + val flowInterfaceProperty: Flow + } +}