[K/N] Make cinterop findObjCCategoriesInSameFilesAsClasses check TUs
findObjCCategoriesInSameFilesAsClasses iterates over translation units
containing encountered classes. The problem is that it is still a bit
fragile, because it is easy to have a disposed translation unit recorded
there.
As a way to make such problems easier to discover, this commit makes
findObjCCategoriesInSameFilesAsClasses check that all involved
translation units are still "valid" (= owned by a valid UnitsHolder).
^KT-56001
diff --git a/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt b/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt
index 2faeafa..e3ad74a 100644
--- a/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt
+++ b/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt
@@ -412,7 +412,7 @@
* NB: Current implementation is rather slow as it walks all the enclosing translation units.
*/
private fun includeCategoriesToObjCClasses() {
- val categoryCursors = findObjCCategoriesInSameFilesAsClasses(objCClassCursorsToIncludeCategories)
+ val categoryCursors = findObjCCategoriesInSameFilesAsClasses(objCClassCursorsToIncludeCategories, unitsHolder)
objCClassCursorsToIncludeCategories.clear()
for (cursor in categoryCursors) {
diff --git a/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/ObjCCategories.kt b/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/ObjCCategories.kt
index ccd05e6..db2d8ed 100644
--- a/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/ObjCCategories.kt
+++ b/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/ObjCCategories.kt
@@ -8,7 +8,14 @@
import clang.*
import kotlinx.cinterop.CValue
-internal fun findObjCCategoriesInSameFilesAsClasses(classCursors: List<CValue<CXCursor>>): List<CValue<CXCursor>> {
+internal fun findObjCCategoriesInSameFilesAsClasses(classCursors: List<CValue<CXCursor>>, unitsHolder: UnitsHolder): List<CValue<CXCursor>> {
+ val translationUnits = classCursors.asSequence().mapNotNull { clang_Cursor_getTranslationUnit(it) }.distinct().toList()
+
+ val validTranslationUnits = unitsHolder.validTranslationUnits.toSet()
+ translationUnits.forEach {
+ check(it in validTranslationUnits) { "Invalid translation unit found: $it" }
+ }
+
val fileToClassNames = mutableMapOf<CXFile, MutableSet<String>>()
for (cursor in classCursors) {
check(cursor.kind == CXCursorKind.CXCursor_ObjCInterfaceDecl) { cursor.kind }
@@ -19,8 +26,6 @@
val result = mutableListOf<CValue<CXCursor>>()
- val translationUnits = classCursors.asSequence().mapNotNull { clang_Cursor_getTranslationUnit(it) }.distinct()
-
for (translationUnit in translationUnits) {
// Accessing the whole translation unit (TU) is overkill, but it is the simplest solution which is doable.
// That's why we have to process all the classes in a single pass to avoid performance hit.
diff --git a/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Utils.kt b/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Utils.kt
index 3788fb0..6d9fb7e 100644
--- a/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Utils.kt
+++ b/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Utils.kt
@@ -703,6 +703,9 @@
private val unitByBinaryFile = mutableMapOf<String, CXTranslationUnit>()
private val allOwnedUnits = mutableListOf<CXTranslationUnit>()
+ internal val validTranslationUnits: List<CXTranslationUnit>
+ get() = allOwnedUnits
+
internal fun load(info: CXIdxImportedASTFileInfo): CXTranslationUnit {
val canonicalPath: String = info.file!!.canonicalPath
return unitByBinaryFile.getOrPut(canonicalPath) {