[ObjCExport] Translate superClass and superClass generics for class and objects
^KT-65384 Verification Pending
This commit is contained in:
committed by
Space Team
parent
c22149c642
commit
5b11308d1b
+1
-1
@@ -25,4 +25,4 @@ internal fun KtClassOrObjectSymbol.getDeclaredSuperInterfaceSymbols(): List<KtCl
|
|||||||
.filter { !it.isCloneable } // TODO: Write unit test for this
|
.filter { !it.isCloneable } // TODO: Write unit test for this
|
||||||
.filter { superInterface -> superInterface.classKind == KtClassKind.INTERFACE }
|
.filter { superInterface -> superInterface.classKind == KtClassKind.INTERFACE }
|
||||||
.toList()
|
.toList()
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-15
@@ -7,9 +7,7 @@ package org.jetbrains.kotlin.objcexport.analysisApiUtils
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtClassErrorType
|
import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtClassType
|
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to find the superclass [KtClassOrObjectSymbol] symbol which is *not* kotlin.Any
|
* Tries to find the superclass [KtClassOrObjectSymbol] symbol which is *not* kotlin.Any
|
||||||
@@ -28,20 +26,32 @@ import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier
|
|||||||
*/
|
*/
|
||||||
context(KtAnalysisSession)
|
context(KtAnalysisSession)
|
||||||
internal fun KtClassOrObjectSymbol.getSuperClassSymbolNotAny(): KtClassOrObjectSymbol? {
|
internal fun KtClassOrObjectSymbol.getSuperClassSymbolNotAny(): KtClassOrObjectSymbol? {
|
||||||
|
return getSuperClassTypeNotAny()?.expandedClassSymbol
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to find the supertype of this [KtClassOrObjectSymbol] which is a superclass (not Any)
|
||||||
|
* ```kotlin
|
||||||
|
* abstract class A
|
||||||
|
*
|
||||||
|
* class B: A
|
||||||
|
*
|
||||||
|
* fun example() {
|
||||||
|
* val symbolOfB = // ...
|
||||||
|
* val typeRepresentingA = symbolOfB.getSuperClassTypeNotAny()
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
context(KtAnalysisSession)
|
||||||
|
internal fun KtClassOrObjectSymbol.getSuperClassTypeNotAny(): KtNonErrorClassType? {
|
||||||
return superTypes.firstNotNullOfOrNull find@{ superType ->
|
return superTypes.firstNotNullOfOrNull find@{ superType ->
|
||||||
if (superType.isAny) return@find null
|
if (superType.isAny || superType.isError) return@find null
|
||||||
if (superType.isError && superType is KtClassErrorType) {
|
if (superType is KtNonErrorClassType) {
|
||||||
//Header should have just a Base type in case unresolved super type
|
val classSymbol = superType.expandedClassSymbol ?: return@find null
|
||||||
return@find null
|
if (classSymbol.classKind.isClass) {
|
||||||
}
|
return superType
|
||||||
if (superType is KtClassType) {
|
|
||||||
val classifier = superType.qualifiers.firstNotNullOfOrNull { qualifier ->
|
|
||||||
(qualifier as? KtClassTypeQualifier.KtResolvedClassTypeQualifier)?.symbol
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classifier is KtClassOrObjectSymbol && classifier.classKind.isClass) return@find classifier
|
|
||||||
}
|
}
|
||||||
|
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2024 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
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||||
|
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
|
||||||
|
import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType
|
||||||
|
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportClassOrProtocolName
|
||||||
|
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCNonNullReferenceType
|
||||||
|
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getDefaultSuperClassOrProtocolName
|
||||||
|
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getSuperClassTypeNotAny
|
||||||
|
|
||||||
|
internal data class KtObjCSuperClassTranslation(
|
||||||
|
val superClassName: ObjCExportClassOrProtocolName,
|
||||||
|
val superClassGenerics: List<ObjCNonNullReferenceType>,
|
||||||
|
)
|
||||||
|
|
||||||
|
context(KtAnalysisSession, KtObjCExportSession)
|
||||||
|
internal fun KtClassOrObjectSymbol.translateSuperClass(): KtObjCSuperClassTranslation {
|
||||||
|
val superClassType = getSuperClassTypeNotAny()
|
||||||
|
val superClassName = superClassType?.getSuperClassName() ?: getDefaultSuperClassOrProtocolName()
|
||||||
|
|
||||||
|
val superClassGenerics: List<ObjCNonNullReferenceType> = superTypes
|
||||||
|
.filterIsInstance<KtNonErrorClassType>()
|
||||||
|
.find { type ->
|
||||||
|
val classSymbol = type.classSymbol as? KtClassOrObjectSymbol ?: return@find false
|
||||||
|
classSymbol.classKind.isClass
|
||||||
|
}
|
||||||
|
?.ownTypeArguments
|
||||||
|
.orEmpty()
|
||||||
|
.mapNotNull { typeProjection -> typeProjection.type?.mapToReferenceTypeIgnoringNullability() }
|
||||||
|
|
||||||
|
return KtObjCSuperClassTranslation(superClassName, superClassGenerics)
|
||||||
|
}
|
||||||
-18
@@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2024 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
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
|
|
||||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCProtocol
|
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getDeclaredSuperInterfaceSymbols
|
|
||||||
|
|
||||||
context(KtAnalysisSession, KtObjCExportSession)
|
|
||||||
internal fun KtClassOrObjectSymbol.translateSuperInterfaces(): List<ObjCProtocol> {
|
|
||||||
return getDeclaredSuperInterfaceSymbols().mapNotNull { superInterfaceSymbol ->
|
|
||||||
superInterfaceSymbol.translateToObjCProtocol()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+25
-23
@@ -4,10 +4,10 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
|||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind
|
import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithModality
|
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithModality
|
||||||
|
import org.jetbrains.kotlin.analysis.api.symbols.nameOrAnonymous
|
||||||
|
import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType
|
||||||
import org.jetbrains.kotlin.backend.konan.objcexport.*
|
import org.jetbrains.kotlin.backend.konan.objcexport.*
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getDefaultSuperClassOrProtocolName
|
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getSuperClassSymbolNotAny
|
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isVisibleInObjC
|
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isVisibleInObjC
|
||||||
|
|
||||||
context(KtAnalysisSession, KtObjCExportSession)
|
context(KtAnalysisSession, KtObjCExportSession)
|
||||||
@@ -15,9 +15,6 @@ fun KtClassOrObjectSymbol.translateToObjCClass(): ObjCClass? {
|
|||||||
require(classKind == KtClassKind.CLASS)
|
require(classKind == KtClassKind.CLASS)
|
||||||
if (!isVisibleInObjC()) return null
|
if (!isVisibleInObjC()) return null
|
||||||
|
|
||||||
val superClass = getSuperClassSymbolNotAny()
|
|
||||||
val kotlinAnyName = getDefaultSuperClassOrProtocolName()
|
|
||||||
val superName = if (superClass == null) kotlinAnyName else getSuperClassName()
|
|
||||||
val enumKind = this.classKind == KtClassKind.ENUM_CLASS
|
val enumKind = this.classKind == KtClassKind.ENUM_CLASS
|
||||||
val final = if (this is KtSymbolWithModality) this.modality == Modality.FINAL else false
|
val final = if (this is KtSymbolWithModality) this.modality == Modality.FINAL else false
|
||||||
val attributes = if (enumKind || final) listOf(OBJC_SUBCLASSING_RESTRICTED) else emptyList()
|
val attributes = if (enumKind || final) listOf(OBJC_SUBCLASSING_RESTRICTED) else emptyList()
|
||||||
@@ -25,6 +22,8 @@ fun KtClassOrObjectSymbol.translateToObjCClass(): ObjCClass? {
|
|||||||
val name = getObjCClassOrProtocolName()
|
val name = getObjCClassOrProtocolName()
|
||||||
val comment: ObjCComment? = annotationsList.translateToObjCComment()
|
val comment: ObjCComment? = annotationsList.translateToObjCComment()
|
||||||
val origin: ObjCExportStubOrigin = getObjCExportStubOrigin()
|
val origin: ObjCExportStubOrigin = getObjCExportStubOrigin()
|
||||||
|
|
||||||
|
val superClass = translateSuperClass()
|
||||||
val superProtocols: List<String> = superProtocols()
|
val superProtocols: List<String> = superProtocols()
|
||||||
|
|
||||||
val members: List<ObjCExportStub> = getMemberScope().getCallableSymbols().plus(getMemberScope().getConstructors())
|
val members: List<ObjCExportStub> = getMemberScope().getCallableSymbols().plus(getMemberScope().getConstructors())
|
||||||
@@ -33,20 +32,25 @@ fun KtClassOrObjectSymbol.translateToObjCClass(): ObjCClass? {
|
|||||||
.toList()
|
.toList()
|
||||||
|
|
||||||
val categoryName: String? = null
|
val categoryName: String? = null
|
||||||
val generics: List<ObjCGenericTypeDeclaration> = emptyList()
|
|
||||||
val superClassGenerics: List<ObjCNonNullReferenceType> = emptyList()
|
val generics: List<ObjCGenericTypeDeclaration> = typeParameters.map { typeParameter ->
|
||||||
|
ObjCGenericTypeParameterDeclaration(
|
||||||
|
typeParameter.nameOrAnonymous.asString().toValidObjCSwiftIdentifier(),
|
||||||
|
ObjCVariance.fromKotlinVariance(typeParameter.variance)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return ObjCInterfaceImpl(
|
return ObjCInterfaceImpl(
|
||||||
name.objCName,
|
name = name.objCName,
|
||||||
comment,
|
comment = comment,
|
||||||
origin,
|
origin = origin,
|
||||||
attributes,
|
attributes = attributes,
|
||||||
superProtocols,
|
superProtocols = superProtocols,
|
||||||
members,
|
members = members,
|
||||||
categoryName,
|
categoryName = categoryName,
|
||||||
generics,
|
generics = generics,
|
||||||
superName.objCName,
|
superClass = superClass.superClassName.objCName,
|
||||||
superClassGenerics
|
superClassGenerics = superClass.superClassGenerics
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,10 +64,8 @@ private fun abbreviate(name: String): String {
|
|||||||
return normalizedName
|
return normalizedName
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
context(KtAnalysisSession, KtObjCExportSession)
|
||||||
* See issue KT-65384
|
internal fun KtNonErrorClassType.getSuperClassName(): ObjCExportClassOrProtocolName? {
|
||||||
* And K1 implementation [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportTranslatorImpl.translateClass]
|
val classSymbol = expandedClassSymbol ?: return null
|
||||||
*/
|
return classSymbol.getObjCClassOrProtocolName()
|
||||||
private fun KtClassOrObjectSymbol.getSuperClassName(): ObjCExportClassOrProtocolName {
|
|
||||||
return ObjCExportClassOrProtocolName("UnimplementedSwiftName", "UnimplementedObjCName")
|
|
||||||
}
|
}
|
||||||
+5
-6
@@ -47,7 +47,6 @@ fun translateToObjCHeader(files: List<KtFile>): ObjCHeader {
|
|||||||
|
|
||||||
/* Add the classId to already processed classIds and do not redo if already processed */
|
/* Add the classId to already processed classIds and do not redo if already processed */
|
||||||
val stub = translatedClassifiers.getOrPut(classId) {
|
val stub = translatedClassifiers.getOrPut(classId) {
|
||||||
|
|
||||||
val translatedObjCClassOrProtocol = when (symbol.classKind) {
|
val translatedObjCClassOrProtocol = when (symbol.classKind) {
|
||||||
KtClassKind.INTERFACE -> symbol.translateToObjCProtocol()
|
KtClassKind.INTERFACE -> symbol.translateToObjCProtocol()
|
||||||
KtClassKind.CLASS -> symbol.translateToObjCClass()
|
KtClassKind.CLASS -> symbol.translateToObjCClass()
|
||||||
@@ -56,7 +55,11 @@ fun translateToObjCHeader(files: List<KtFile>): ObjCHeader {
|
|||||||
} ?: return result
|
} ?: return result
|
||||||
|
|
||||||
symbol.getDeclaredSuperInterfaceSymbols().forEach { superInterfaceSymbol ->
|
symbol.getDeclaredSuperInterfaceSymbols().forEach { superInterfaceSymbol ->
|
||||||
result.addAll(process(superInterfaceSymbol))
|
result.addAll(process(superInterfaceSymbol, true))
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol.getSuperClassSymbolNotAny()?.let { superClassSymbol ->
|
||||||
|
process(superClassSymbol, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
result.add(translatedObjCClassOrProtocol)
|
result.add(translatedObjCClassOrProtocol)
|
||||||
@@ -123,10 +126,6 @@ fun translateToObjCHeader(files: List<KtFile>): ObjCHeader {
|
|||||||
classForwardDeclarations.add(errorForwardClass)
|
classForwardDeclarations.add(errorForwardClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
protocolForwardDeclarations += stubs
|
|
||||||
.filterIsInstance<ObjCClass>()
|
|
||||||
.flatMap { it.superProtocols }
|
|
||||||
|
|
||||||
return ObjCHeader(
|
return ObjCHeader(
|
||||||
stubs = stubs,
|
stubs = stubs,
|
||||||
classForwardDeclarations = classForwardDeclarations,
|
classForwardDeclarations = classForwardDeclarations,
|
||||||
|
|||||||
+12
-16
@@ -6,8 +6,6 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
|
|||||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithModality
|
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithModality
|
||||||
import org.jetbrains.kotlin.backend.konan.objcexport.*
|
import org.jetbrains.kotlin.backend.konan.objcexport.*
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getDefaultSuperClassOrProtocolName
|
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getSuperClassSymbolNotAny
|
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isVisibleInObjC
|
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isVisibleInObjC
|
||||||
|
|
||||||
context(KtAnalysisSession, KtObjCExportSession)
|
context(KtAnalysisSession, KtObjCExportSession)
|
||||||
@@ -15,9 +13,6 @@ fun KtClassOrObjectSymbol.translateToObjCObject(): ObjCClass? {
|
|||||||
require(classKind == KtClassKind.OBJECT)
|
require(classKind == KtClassKind.OBJECT)
|
||||||
if (!isVisibleInObjC()) return null
|
if (!isVisibleInObjC()) return null
|
||||||
|
|
||||||
val superClass = getSuperClassSymbolNotAny()
|
|
||||||
val kotlinAnyName = getDefaultSuperClassOrProtocolName()
|
|
||||||
val superName = if (superClass == null) kotlinAnyName else throw RuntimeException("Super class translation isn't implemented yet")
|
|
||||||
val enumKind = this.classKind == KtClassKind.ENUM_CLASS
|
val enumKind = this.classKind == KtClassKind.ENUM_CLASS
|
||||||
val final = if (this is KtSymbolWithModality) this.modality == Modality.FINAL else false
|
val final = if (this is KtSymbolWithModality) this.modality == Modality.FINAL else false
|
||||||
val attributes = if (enumKind || final) listOf(OBJC_SUBCLASSING_RESTRICTED) else emptyList()
|
val attributes = if (enumKind || final) listOf(OBJC_SUBCLASSING_RESTRICTED) else emptyList()
|
||||||
@@ -28,25 +23,26 @@ fun KtClassOrObjectSymbol.translateToObjCObject(): ObjCClass? {
|
|||||||
val superProtocols: List<String> = superProtocols()
|
val superProtocols: List<String> = superProtocols()
|
||||||
val categoryName: String? = null
|
val categoryName: String? = null
|
||||||
val generics: List<ObjCGenericTypeDeclaration> = emptyList()
|
val generics: List<ObjCGenericTypeDeclaration> = emptyList()
|
||||||
val superClassGenerics: List<ObjCNonNullReferenceType> = emptyList()
|
|
||||||
val objectMembers = getDefaultMembers()
|
val objectMembers = getDefaultMembers()
|
||||||
|
|
||||||
|
val superClass = translateSuperClass()
|
||||||
|
|
||||||
getMemberScope().getCallableSymbols()
|
getMemberScope().getCallableSymbols()
|
||||||
.sortedWith(StableCallableOrder)
|
.sortedWith(StableCallableOrder)
|
||||||
.flatMap { it.translateToObjCExportStubs() }
|
.flatMap { it.translateToObjCExportStubs() }
|
||||||
.forEach { objectMembers.add(it) }
|
.forEach { objectMembers.add(it) }
|
||||||
|
|
||||||
return ObjCInterfaceImpl(
|
return ObjCInterfaceImpl(
|
||||||
name.objCName,
|
name = name.objCName,
|
||||||
comment,
|
comment = comment,
|
||||||
origin,
|
origin = origin,
|
||||||
attributes,
|
attributes = attributes,
|
||||||
superProtocols,
|
superProtocols = superProtocols,
|
||||||
objectMembers,
|
members = objectMembers,
|
||||||
categoryName,
|
categoryName = categoryName,
|
||||||
generics,
|
generics = generics,
|
||||||
superName.objCName,
|
superClass = superClass.superClassName.objCName,
|
||||||
superClassGenerics
|
superClassGenerics = superClass.superClassGenerics
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-2
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.backend.konan.objcexport.ObjCProtocol
|
|||||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCProtocolImpl
|
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCProtocolImpl
|
||||||
import org.jetbrains.kotlin.backend.konan.objcexport.toNameAttributes
|
import org.jetbrains.kotlin.backend.konan.objcexport.toNameAttributes
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getDeclaredSuperInterfaceSymbols
|
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getDeclaredSuperInterfaceSymbols
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isCloneable
|
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isVisibleInObjC
|
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isVisibleInObjC
|
||||||
|
|
||||||
context(KtAnalysisSession, KtObjCExportSession)
|
context(KtAnalysisSession, KtObjCExportSession)
|
||||||
@@ -45,7 +44,6 @@ fun KtClassOrObjectSymbol.translateToObjCProtocol(): ObjCProtocol? {
|
|||||||
context(KtAnalysisSession, KtObjCExportSession)
|
context(KtAnalysisSession, KtObjCExportSession)
|
||||||
internal fun KtClassOrObjectSymbol.superProtocols(): List<String> {
|
internal fun KtClassOrObjectSymbol.superProtocols(): List<String> {
|
||||||
return getDeclaredSuperInterfaceSymbols()
|
return getDeclaredSuperInterfaceSymbols()
|
||||||
.filter { superInterface -> !superInterface.isCloneable }
|
|
||||||
.map { superInterface -> superInterface.getObjCClassOrProtocolName().objCName }
|
.map { superInterface -> superInterface.getObjCClassOrProtocolName().objCName }
|
||||||
.toList()
|
.toList()
|
||||||
}
|
}
|
||||||
+1
-1
@@ -60,7 +60,7 @@ internal fun KtType.translateToObjCReferenceType(): ObjCReferenceType {
|
|||||||
* [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportTranslatorImpl.mapReferenceTypeIgnoringNullability]
|
* [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportTranslatorImpl.mapReferenceTypeIgnoringNullability]
|
||||||
*/
|
*/
|
||||||
context(KtAnalysisSession, KtObjCExportSession)
|
context(KtAnalysisSession, KtObjCExportSession)
|
||||||
private fun KtType.mapToReferenceTypeIgnoringNullability(): ObjCNonNullReferenceType {
|
internal fun KtType.mapToReferenceTypeIgnoringNullability(): ObjCNonNullReferenceType {
|
||||||
val fullyExpandedType = fullyExpandedType
|
val fullyExpandedType = fullyExpandedType
|
||||||
val classId = (fullyExpandedType as? KtNonErrorClassType)?.classId
|
val classId = (fullyExpandedType as? KtNonErrorClassType)?.classId
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -63,7 +63,7 @@ class ForwardedClassesAndProtocolsDependenciesTest(
|
|||||||
fun getInterface(): InterfaceB = error("error")
|
fun getInterface(): InterfaceB = error("error")
|
||||||
""",
|
""",
|
||||||
protocols = setOf("InterfaceB", "InterfaceA"),
|
protocols = setOf("InterfaceB", "InterfaceA"),
|
||||||
classes = setOf("ClassB")
|
classes = setOf("ClassB", "ClassA")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
@@ -233,6 +233,21 @@ class ObjCExportHeaderGeneratorTest(private val generator: HeaderGenerator) {
|
|||||||
doTest(headersTestDataDir.resolve("extensionFunctions"))
|
doTest(headersTestDataDir.resolve("extensionFunctions"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test - classWithGenerics`() {
|
||||||
|
doTest(headersTestDataDir.resolve("classWithGenerics"))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* - init method missing
|
||||||
|
* - 'new constructor' missing
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@TodoAnalysisApi
|
||||||
|
fun `test - objectWithGenericSuperclass`() {
|
||||||
|
doTest(headersTestDataDir.resolve("objectWithGenericSuperclass"))
|
||||||
|
}
|
||||||
|
|
||||||
private fun doTest(root: File, configuration: Configuration = Configuration()) {
|
private fun doTest(root: File, configuration: Configuration = Configuration()) {
|
||||||
if (!root.isDirectory) fail("Expected ${root.absolutePath} to be directory")
|
if (!root.isDirectory) fail("Expected ${root.absolutePath} to be directory")
|
||||||
val generatedHeaders = generator.generateHeaders(root, configuration).toString()
|
val generatedHeaders = generator.generateHeaders(root, configuration).toString()
|
||||||
|
|||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
#import <Foundation/NSArray.h>
|
||||||
|
#import <Foundation/NSDictionary.h>
|
||||||
|
#import <Foundation/NSError.h>
|
||||||
|
#import <Foundation/NSObject.h>
|
||||||
|
#import <Foundation/NSSet.h>
|
||||||
|
#import <Foundation/NSString.h>
|
||||||
|
#import <Foundation/NSValue.h>
|
||||||
|
|
||||||
|
@class A<T1, T2>;
|
||||||
|
|
||||||
|
@protocol I1, I2;
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wunknown-warning-option"
|
||||||
|
#pragma clang diagnostic ignored "-Wincompatible-property-type"
|
||||||
|
#pragma clang diagnostic ignored "-Wnullability"
|
||||||
|
|
||||||
|
#pragma push_macro("_Nullable_result")
|
||||||
|
#if !__has_feature(nullability_nullable_result)
|
||||||
|
#undef _Nullable_result
|
||||||
|
#define _Nullable_result _Nullable
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@interface A<T1, T2> : Base
|
||||||
|
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
|
||||||
|
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
|
||||||
|
@end
|
||||||
|
|
||||||
|
@protocol I1
|
||||||
|
@required
|
||||||
|
@end
|
||||||
|
|
||||||
|
@protocol I2
|
||||||
|
@required
|
||||||
|
@end
|
||||||
|
|
||||||
|
__attribute__((objc_subclassing_restricted))
|
||||||
|
@interface Foo<T> : A<T, NSString *> <I1, I2>
|
||||||
|
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
|
||||||
|
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma pop_macro("_Nullable_result")
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
open class A<T1, T2>
|
||||||
|
|
||||||
|
interface I1<T>
|
||||||
|
interface I2<T>
|
||||||
|
|
||||||
|
class Foo<T> : I1<T>, I2<String>, A<T, String>()
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
#import <Foundation/NSArray.h>
|
||||||
|
#import <Foundation/NSDictionary.h>
|
||||||
|
#import <Foundation/NSError.h>
|
||||||
|
#import <Foundation/NSObject.h>
|
||||||
|
#import <Foundation/NSSet.h>
|
||||||
|
#import <Foundation/NSString.h>
|
||||||
|
#import <Foundation/NSValue.h>
|
||||||
|
|
||||||
|
@class A<T1, T2>, Foo;
|
||||||
|
|
||||||
|
@protocol I;
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wunknown-warning-option"
|
||||||
|
#pragma clang diagnostic ignored "-Wincompatible-property-type"
|
||||||
|
#pragma clang diagnostic ignored "-Wnullability"
|
||||||
|
|
||||||
|
#pragma push_macro("_Nullable_result")
|
||||||
|
#if !__has_feature(nullability_nullable_result)
|
||||||
|
#undef _Nullable_result
|
||||||
|
#define _Nullable_result _Nullable
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@interface A<T1, T2> : Base
|
||||||
|
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
|
||||||
|
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
|
||||||
|
@end
|
||||||
|
|
||||||
|
@protocol I
|
||||||
|
@required
|
||||||
|
@end
|
||||||
|
|
||||||
|
__attribute__((objc_subclassing_restricted))
|
||||||
|
@interface Foo : A<Int *, NSString *> <I>
|
||||||
|
+ (instancetype)alloc __attribute__((unavailable));
|
||||||
|
+ (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable));
|
||||||
|
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable));
|
||||||
|
+ (instancetype)new __attribute__((unavailable));
|
||||||
|
+ (instancetype)foo __attribute__((swift_name("init()")));
|
||||||
|
@property (class, readonly, getter=shared) Foo *shared __attribute__((swift_name("shared")));
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma pop_macro("_Nullable_result")
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
abstract class A<T1, T2>
|
||||||
|
interface I<T>
|
||||||
|
|
||||||
|
object Foo : A<Int, String>(), I<String>
|
||||||
Reference in New Issue
Block a user