From 4ec1ec05cf443580b20aaf238474c3276b94be3d Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Mon, 17 Sep 2018 10:08:26 +0300 Subject: [PATCH] Properly support interop with headers generated by Swift These headers contain `external_source_symbol(..., generated_declaration)` attributes, making clang indexer to ignore the declarations. Add an additional AST pass to ensure that all Objective-C classes and protocols get found. See https://github.com/JetBrains/kotlin-native/issues/1841#issuecomment-411346727 --- .../kotlin/native/interop/indexer/Indexer.kt | 44 ++++++++++++------- .../kotlin/native/interop/indexer/Utils.kt | 5 +++ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt b/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt index 07e672b9295..169095d229e 100644 --- a/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt +++ b/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt @@ -122,10 +122,6 @@ internal class NativeIndexImpl(val library: NativeLibrary) : NativeIndex() { return library.headerToIdMapper.getHeaderId(filePath) } - private fun getContainingFile(cursor: CValue): CXFile? { - return clang_getCursorLocation(cursor).getContainingFile() - } - private fun getLocation(cursor: CValue): Location { val headerId = getHeaderId(getContainingFile(cursor)) return Location(headerId) @@ -737,12 +733,8 @@ internal class NativeIndexImpl(val library: NativeLibrary) : NativeIndex() { } } - CXIdxEntity_ObjCClass -> { - if (isAvailable(cursor) && - cursor.kind != CXCursorKind.CXCursor_ObjCClassRef /* not a forward declaration */) { - - getObjCClassAt(cursor) - } + CXIdxEntity_ObjCClass -> if (cursor.kind != CXCursorKind.CXCursor_ObjCClassRef /* not a forward declaration */) { + indexObjCClass(cursor) } CXIdxEntity_ObjCCategory -> { @@ -751,12 +743,8 @@ internal class NativeIndexImpl(val library: NativeLibrary) : NativeIndex() { } } - CXIdxEntity_ObjCProtocol -> { - if (isAvailable(cursor) && - cursor.kind != CXCursorKind.CXCursor_ObjCProtocolRef /* not a forward declaration */) { - - getObjCProtocolAt(cursor) - } + CXIdxEntity_ObjCProtocol -> if (cursor.kind != CXCursorKind.CXCursor_ObjCProtocolRef /* not a forward declaration */) { + indexObjCProtocol(cursor) } CXIdxEntity_ObjCProperty -> { @@ -791,6 +779,18 @@ internal class NativeIndexImpl(val library: NativeLibrary) : NativeIndex() { } } + fun indexObjCClass(cursor: CValue) { + if (isAvailable(cursor)) { + getObjCClassAt(cursor) + } + } + + fun indexObjCProtocol(cursor: CValue) { + if (isAvailable(cursor)) { + getObjCProtocolAt(cursor) + } + } + private fun getFunction(cursor: CValue): FunctionDecl { val name = clang_getCursorSpelling(cursor).convertAndDispose() val returnType = convertType(clang_getCursorResultType(cursor), clang_getCursorResultTypeAttributes(cursor)) @@ -920,6 +920,18 @@ private fun indexDeclarations(nativeIndex: NativeIndexImpl) { } } }) + + visitChildren(clang_getTranslationUnitCursor(translationUnit)) { cursor, _ -> + val file = getContainingFile(cursor) + if (file in headers && nativeIndex.library.includesDeclaration(cursor)) { + when (cursor.kind) { + CXCursorKind.CXCursor_ObjCInterfaceDecl -> nativeIndex.indexObjCClass(cursor) + CXCursorKind.CXCursor_ObjCProtocolDecl -> nativeIndex.indexObjCProtocol(cursor) + else -> {} + } + } + CXChildVisitResult.CXChildVisit_Continue + } } finally { clang_disposeTranslationUnit(translationUnit) } diff --git a/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Utils.kt b/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Utils.kt index 247a109e725..94e50f61a0c 100644 --- a/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Utils.kt +++ b/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Utils.kt @@ -545,6 +545,11 @@ internal fun CValue.getContainingFile(): CXFile? = memScoped { fileVar.value } +@JvmName("getFileContainingCursor") +internal fun getContainingFile(cursor: CValue): CXFile? { + return clang_getCursorLocation(cursor).getContainingFile() +} + private fun createVfsOverlayFileContents(virtualPathToReal: Map): ByteArray { val overlay = clang_VirtualFileOverlay_create(0)