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
This commit is contained in:
Svyatoslav Scherbina
2018-09-17 10:08:26 +03:00
committed by SvyatoslavScherbina
parent 446bacbe7a
commit 4ec1ec05cf
2 changed files with 33 additions and 16 deletions
@@ -122,10 +122,6 @@ internal class NativeIndexImpl(val library: NativeLibrary) : NativeIndex() {
return library.headerToIdMapper.getHeaderId(filePath)
}
private fun getContainingFile(cursor: CValue<CXCursor>): CXFile? {
return clang_getCursorLocation(cursor).getContainingFile()
}
private fun getLocation(cursor: CValue<CXCursor>): 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<CXCursor>) {
if (isAvailable(cursor)) {
getObjCClassAt(cursor)
}
}
fun indexObjCProtocol(cursor: CValue<CXCursor>) {
if (isAvailable(cursor)) {
getObjCProtocolAt(cursor)
}
}
private fun getFunction(cursor: CValue<CXCursor>): 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)
}
@@ -545,6 +545,11 @@ internal fun CValue<CXSourceLocation>.getContainingFile(): CXFile? = memScoped {
fileVar.value
}
@JvmName("getFileContainingCursor")
internal fun getContainingFile(cursor: CValue<CXCursor>): CXFile? {
return clang_getCursorLocation(cursor).getContainingFile()
}
private fun createVfsOverlayFileContents(virtualPathToReal: Map<Path, Path>): ByteArray {
val overlay = clang_VirtualFileOverlay_create(0)