From 5b11308d1be978f20788084b00158641a5c37cd7 Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Wed, 7 Feb 2024 10:49:42 +0100 Subject: [PATCH] [ObjCExport] Translate superClass and superClass generics for class and objects ^KT-65384 Verification Pending --- .../getDeclaredSuperInterfaceSymbols.kt | 2 +- ...SymbolNotAny.kt => getSuperClassNotAny.kt} | 40 ++++++++++------ .../kotlin/objcexport/translateSuperClass.kt | 37 ++++++++++++++ .../objcexport/translateSuperInterfaces.kt | 18 ------- .../kotlin/objcexport/translateToObjCClass.kt | 48 ++++++++++--------- .../objcexport/translateToObjCHeader.kt | 11 ++--- .../objcexport/translateToObjCObject.kt | 28 +++++------ .../objcexport/translateToObjCProtocol.kt | 2 - .../kotlin/objcexport/translateToObjCType.kt | 2 +- ...rdedClassesAndProtocolsDependenciesTest.kt | 2 +- .../tests/ObjCExportHeaderGeneratorTest.kt | 15 ++++++ .../classWithGenerics/!classWithGenerics.h | 46 ++++++++++++++++++ .../testData/headers/classWithGenerics/Foo.kt | 6 +++ .../!objectWithGenericSuperclass.h | 46 ++++++++++++++++++ .../objectWithGenericSuperclass/Foo.kt | 4 ++ 15 files changed, 224 insertions(+), 83 deletions(-) rename native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/analysisApiUtils/{getSuperClassSymbolNotAny.kt => getSuperClassNotAny.kt} (53%) create mode 100644 native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateSuperClass.kt delete mode 100644 native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateSuperInterfaces.kt create mode 100644 native/objcexport-header-generator/testData/headers/classWithGenerics/!classWithGenerics.h create mode 100644 native/objcexport-header-generator/testData/headers/classWithGenerics/Foo.kt create mode 100644 native/objcexport-header-generator/testData/headers/objectWithGenericSuperclass/!objectWithGenericSuperclass.h create mode 100644 native/objcexport-header-generator/testData/headers/objectWithGenericSuperclass/Foo.kt diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/analysisApiUtils/getDeclaredSuperInterfaceSymbols.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/analysisApiUtils/getDeclaredSuperInterfaceSymbols.kt index 6cdc207cccb..e6efabb90d0 100644 --- a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/analysisApiUtils/getDeclaredSuperInterfaceSymbols.kt +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/analysisApiUtils/getDeclaredSuperInterfaceSymbols.kt @@ -25,4 +25,4 @@ internal fun KtClassOrObjectSymbol.getDeclaredSuperInterfaceSymbols(): List superInterface.classKind == KtClassKind.INTERFACE } .toList() -} \ No newline at end of file +} diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/analysisApiUtils/getSuperClassSymbolNotAny.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/analysisApiUtils/getSuperClassNotAny.kt similarity index 53% rename from native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/analysisApiUtils/getSuperClassSymbolNotAny.kt rename to native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/analysisApiUtils/getSuperClassNotAny.kt index 2978fb6a402..407edea6b82 100644 --- a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/analysisApiUtils/getSuperClassSymbolNotAny.kt +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/analysisApiUtils/getSuperClassNotAny.kt @@ -7,9 +7,7 @@ package org.jetbrains.kotlin.objcexport.analysisApiUtils import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol -import org.jetbrains.kotlin.analysis.api.types.KtClassErrorType -import org.jetbrains.kotlin.analysis.api.types.KtClassType -import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier +import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType /** * 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) 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 -> - if (superType.isAny) return@find null - if (superType.isError && superType is KtClassErrorType) { - //Header should have just a Base type in case unresolved super type - return@find null - } - if (superType is KtClassType) { - val classifier = superType.qualifiers.firstNotNullOfOrNull { qualifier -> - (qualifier as? KtClassTypeQualifier.KtResolvedClassTypeQualifier)?.symbol + if (superType.isAny || superType.isError) return@find null + if (superType is KtNonErrorClassType) { + val classSymbol = superType.expandedClassSymbol ?: return@find null + if (classSymbol.classKind.isClass) { + return superType } - - if (classifier is KtClassOrObjectSymbol && classifier.classKind.isClass) return@find classifier } - null } -} \ No newline at end of file +} diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateSuperClass.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateSuperClass.kt new file mode 100644 index 00000000000..b1d2c12a9f9 --- /dev/null +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateSuperClass.kt @@ -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, +) + +context(KtAnalysisSession, KtObjCExportSession) +internal fun KtClassOrObjectSymbol.translateSuperClass(): KtObjCSuperClassTranslation { + val superClassType = getSuperClassTypeNotAny() + val superClassName = superClassType?.getSuperClassName() ?: getDefaultSuperClassOrProtocolName() + + val superClassGenerics: List = superTypes + .filterIsInstance() + .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) +} \ No newline at end of file diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateSuperInterfaces.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateSuperInterfaces.kt deleted file mode 100644 index 0dcd3c930a2..00000000000 --- a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateSuperInterfaces.kt +++ /dev/null @@ -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 { - return getDeclaredSuperInterfaceSymbols().mapNotNull { superInterfaceSymbol -> - superInterfaceSymbol.translateToObjCProtocol() - } -} \ No newline at end of file diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCClass.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCClass.kt index 232e042d3f0..64e2836ed8d 100644 --- a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCClass.kt +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCClass.kt @@ -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.KtClassOrObjectSymbol 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.descriptors.Modality -import org.jetbrains.kotlin.objcexport.analysisApiUtils.getDefaultSuperClassOrProtocolName -import org.jetbrains.kotlin.objcexport.analysisApiUtils.getSuperClassSymbolNotAny import org.jetbrains.kotlin.objcexport.analysisApiUtils.isVisibleInObjC context(KtAnalysisSession, KtObjCExportSession) @@ -15,9 +15,6 @@ fun KtClassOrObjectSymbol.translateToObjCClass(): ObjCClass? { require(classKind == KtClassKind.CLASS) 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 final = if (this is KtSymbolWithModality) this.modality == Modality.FINAL else false val attributes = if (enumKind || final) listOf(OBJC_SUBCLASSING_RESTRICTED) else emptyList() @@ -25,6 +22,8 @@ fun KtClassOrObjectSymbol.translateToObjCClass(): ObjCClass? { val name = getObjCClassOrProtocolName() val comment: ObjCComment? = annotationsList.translateToObjCComment() val origin: ObjCExportStubOrigin = getObjCExportStubOrigin() + + val superClass = translateSuperClass() val superProtocols: List = superProtocols() val members: List = getMemberScope().getCallableSymbols().plus(getMemberScope().getConstructors()) @@ -33,20 +32,25 @@ fun KtClassOrObjectSymbol.translateToObjCClass(): ObjCClass? { .toList() val categoryName: String? = null - val generics: List = emptyList() - val superClassGenerics: List = emptyList() + + val generics: List = typeParameters.map { typeParameter -> + ObjCGenericTypeParameterDeclaration( + typeParameter.nameOrAnonymous.asString().toValidObjCSwiftIdentifier(), + ObjCVariance.fromKotlinVariance(typeParameter.variance) + ) + } return ObjCInterfaceImpl( - name.objCName, - comment, - origin, - attributes, - superProtocols, - members, - categoryName, - generics, - superName.objCName, - superClassGenerics + name = name.objCName, + comment = comment, + origin = origin, + attributes = attributes, + superProtocols = superProtocols, + members = members, + categoryName = categoryName, + generics = generics, + superClass = superClass.superClassName.objCName, + superClassGenerics = superClass.superClassGenerics ) } @@ -60,10 +64,8 @@ private fun abbreviate(name: String): String { return normalizedName } -/** - * See issue KT-65384 - * And K1 implementation [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportTranslatorImpl.translateClass] - */ -private fun KtClassOrObjectSymbol.getSuperClassName(): ObjCExportClassOrProtocolName { - return ObjCExportClassOrProtocolName("UnimplementedSwiftName", "UnimplementedObjCName") +context(KtAnalysisSession, KtObjCExportSession) +internal fun KtNonErrorClassType.getSuperClassName(): ObjCExportClassOrProtocolName? { + val classSymbol = expandedClassSymbol ?: return null + return classSymbol.getObjCClassOrProtocolName() } \ No newline at end of file diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCHeader.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCHeader.kt index af32e45084d..73158fdfb20 100644 --- a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCHeader.kt +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCHeader.kt @@ -47,7 +47,6 @@ fun translateToObjCHeader(files: List): ObjCHeader { /* Add the classId to already processed classIds and do not redo if already processed */ val stub = translatedClassifiers.getOrPut(classId) { - val translatedObjCClassOrProtocol = when (symbol.classKind) { KtClassKind.INTERFACE -> symbol.translateToObjCProtocol() KtClassKind.CLASS -> symbol.translateToObjCClass() @@ -56,7 +55,11 @@ fun translateToObjCHeader(files: List): ObjCHeader { } ?: return result symbol.getDeclaredSuperInterfaceSymbols().forEach { superInterfaceSymbol -> - result.addAll(process(superInterfaceSymbol)) + result.addAll(process(superInterfaceSymbol, true)) + } + + symbol.getSuperClassSymbolNotAny()?.let { superClassSymbol -> + process(superClassSymbol, true) } result.add(translatedObjCClassOrProtocol) @@ -123,10 +126,6 @@ fun translateToObjCHeader(files: List): ObjCHeader { classForwardDeclarations.add(errorForwardClass) } - protocolForwardDeclarations += stubs - .filterIsInstance() - .flatMap { it.superProtocols } - return ObjCHeader( stubs = stubs, classForwardDeclarations = classForwardDeclarations, diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCObject.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCObject.kt index da773b00599..ba4869ddd71 100644 --- a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCObject.kt +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCObject.kt @@ -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.backend.konan.objcexport.* 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 context(KtAnalysisSession, KtObjCExportSession) @@ -15,9 +13,6 @@ fun KtClassOrObjectSymbol.translateToObjCObject(): ObjCClass? { require(classKind == KtClassKind.OBJECT) 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 final = if (this is KtSymbolWithModality) this.modality == Modality.FINAL else false val attributes = if (enumKind || final) listOf(OBJC_SUBCLASSING_RESTRICTED) else emptyList() @@ -28,25 +23,26 @@ fun KtClassOrObjectSymbol.translateToObjCObject(): ObjCClass? { val superProtocols: List = superProtocols() val categoryName: String? = null val generics: List = emptyList() - val superClassGenerics: List = emptyList() val objectMembers = getDefaultMembers() + val superClass = translateSuperClass() + getMemberScope().getCallableSymbols() .sortedWith(StableCallableOrder) .flatMap { it.translateToObjCExportStubs() } .forEach { objectMembers.add(it) } return ObjCInterfaceImpl( - name.objCName, - comment, - origin, - attributes, - superProtocols, - objectMembers, - categoryName, - generics, - superName.objCName, - superClassGenerics + name = name.objCName, + comment = comment, + origin = origin, + attributes = attributes, + superProtocols = superProtocols, + members = objectMembers, + categoryName = categoryName, + generics = generics, + superClass = superClass.superClassName.objCName, + superClassGenerics = superClass.superClassGenerics ) } diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCProtocol.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCProtocol.kt index 68adf5f36cb..127ffc66e3d 100644 --- a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCProtocol.kt +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCProtocol.kt @@ -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.toNameAttributes import org.jetbrains.kotlin.objcexport.analysisApiUtils.getDeclaredSuperInterfaceSymbols -import org.jetbrains.kotlin.objcexport.analysisApiUtils.isCloneable import org.jetbrains.kotlin.objcexport.analysisApiUtils.isVisibleInObjC context(KtAnalysisSession, KtObjCExportSession) @@ -45,7 +44,6 @@ fun KtClassOrObjectSymbol.translateToObjCProtocol(): ObjCProtocol? { context(KtAnalysisSession, KtObjCExportSession) internal fun KtClassOrObjectSymbol.superProtocols(): List { return getDeclaredSuperInterfaceSymbols() - .filter { superInterface -> !superInterface.isCloneable } .map { superInterface -> superInterface.getObjCClassOrProtocolName().objCName } .toList() } \ No newline at end of file diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCType.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCType.kt index ddc8a32793b..b1965c70a6a 100644 --- a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCType.kt +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/translateToObjCType.kt @@ -60,7 +60,7 @@ internal fun KtType.translateToObjCReferenceType(): ObjCReferenceType { * [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportTranslatorImpl.mapReferenceTypeIgnoringNullability] */ context(KtAnalysisSession, KtObjCExportSession) -private fun KtType.mapToReferenceTypeIgnoringNullability(): ObjCNonNullReferenceType { +internal fun KtType.mapToReferenceTypeIgnoringNullability(): ObjCNonNullReferenceType { val fullyExpandedType = fullyExpandedType val classId = (fullyExpandedType as? KtNonErrorClassType)?.classId diff --git a/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/tests/ForwardedClassesAndProtocolsDependenciesTest.kt b/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/tests/ForwardedClassesAndProtocolsDependenciesTest.kt index 941cae767e2..6e6a0c4b14b 100644 --- a/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/tests/ForwardedClassesAndProtocolsDependenciesTest.kt +++ b/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/tests/ForwardedClassesAndProtocolsDependenciesTest.kt @@ -63,7 +63,7 @@ class ForwardedClassesAndProtocolsDependenciesTest( fun getInterface(): InterfaceB = error("error") """, protocols = setOf("InterfaceB", "InterfaceA"), - classes = setOf("ClassB") + classes = setOf("ClassB", "ClassA") ) } diff --git a/native/objcexport-header-generator/test/org/jetbrains/kotlin/backend/konan/tests/ObjCExportHeaderGeneratorTest.kt b/native/objcexport-header-generator/test/org/jetbrains/kotlin/backend/konan/tests/ObjCExportHeaderGeneratorTest.kt index b0550065fb4..2c910e1a520 100644 --- a/native/objcexport-header-generator/test/org/jetbrains/kotlin/backend/konan/tests/ObjCExportHeaderGeneratorTest.kt +++ b/native/objcexport-header-generator/test/org/jetbrains/kotlin/backend/konan/tests/ObjCExportHeaderGeneratorTest.kt @@ -233,6 +233,21 @@ class ObjCExportHeaderGeneratorTest(private val generator: HeaderGenerator) { 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()) { if (!root.isDirectory) fail("Expected ${root.absolutePath} to be directory") val generatedHeaders = generator.generateHeaders(root, configuration).toString() diff --git a/native/objcexport-header-generator/testData/headers/classWithGenerics/!classWithGenerics.h b/native/objcexport-header-generator/testData/headers/classWithGenerics/!classWithGenerics.h new file mode 100644 index 00000000000..b652853d32e --- /dev/null +++ b/native/objcexport-header-generator/testData/headers/classWithGenerics/!classWithGenerics.h @@ -0,0 +1,46 @@ +#import +#import +#import +#import +#import +#import +#import + +@class A; + +@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 : 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 : A +- (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 diff --git a/native/objcexport-header-generator/testData/headers/classWithGenerics/Foo.kt b/native/objcexport-header-generator/testData/headers/classWithGenerics/Foo.kt new file mode 100644 index 00000000000..0191bd736a4 --- /dev/null +++ b/native/objcexport-header-generator/testData/headers/classWithGenerics/Foo.kt @@ -0,0 +1,6 @@ +open class A + +interface I1 +interface I2 + +class Foo : I1, I2, A() \ No newline at end of file diff --git a/native/objcexport-header-generator/testData/headers/objectWithGenericSuperclass/!objectWithGenericSuperclass.h b/native/objcexport-header-generator/testData/headers/objectWithGenericSuperclass/!objectWithGenericSuperclass.h new file mode 100644 index 00000000000..c5908c62576 --- /dev/null +++ b/native/objcexport-header-generator/testData/headers/objectWithGenericSuperclass/!objectWithGenericSuperclass.h @@ -0,0 +1,46 @@ +#import +#import +#import +#import +#import +#import +#import + +@class A, 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 : 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 ++ (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 diff --git a/native/objcexport-header-generator/testData/headers/objectWithGenericSuperclass/Foo.kt b/native/objcexport-header-generator/testData/headers/objectWithGenericSuperclass/Foo.kt new file mode 100644 index 00000000000..99e8bab04de --- /dev/null +++ b/native/objcexport-header-generator/testData/headers/objectWithGenericSuperclass/Foo.kt @@ -0,0 +1,4 @@ +abstract class A +interface I + +object Foo : A(), I \ No newline at end of file