diff --git a/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt b/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt index 70b869b1936..108424a8455 100644 --- a/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt +++ b/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.backend.konan.objcexport +import org.jetbrains.kotlin.backend.common.descriptors.allParameters import org.jetbrains.kotlin.backend.common.serialization.findSourceFile import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.enumEntries @@ -807,7 +808,7 @@ class ObjCExportTranslatorImpl( } else emptyList() val visibilityComments = visibilityComments(method.visibility, "method") - val paramComments = method.valueParameters.flatMap { parameterDescriptor -> + val paramComments = method.allParameters.flatMap { parameterDescriptor -> parameters.find { parameter -> parameter.origin?.name == parameterDescriptor.name }?.let { parameter -> mustBeDocumentedParamAttributeList(parameter, descriptor = parameterDescriptor) } ?: emptyList() diff --git a/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt b/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt index d4d6ec71878..b05b9196d4f 100644 --- a/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt +++ b/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt @@ -374,8 +374,6 @@ class ObjCExportLazyImpl( private val lazy: ObjCExportLazyImpl, ) : LazyObjCInterface(name = name.objCName, generics = emptyList(), categoryName = categoryName, attributes = emptyList()) { - override val origin: ObjCExportStubOrigin? = ObjCExportStubOrigin(classDescriptor) - override fun computeRealStub(): ObjCInterface = lazy.translator.translateExtensions( classDescriptor, declarations.mapNotNull { declaration -> @@ -403,6 +401,10 @@ private abstract class LazyObjCInterface( private val realStub by lazy { computeRealStub() } + override val origin: ObjCExportStubOrigin? by lazy { + realStub.origin + } + override val members: List get() = realStub.members diff --git a/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportStubFactories.kt b/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportStubFactories.kt index 14260a34595..e9949abb59f 100644 --- a/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportStubFactories.kt +++ b/native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportStubFactories.kt @@ -13,14 +13,18 @@ import org.jetbrains.kotlin.resolve.source.PsiSourceElement fun ObjCExportStubOrigin(descriptor: DeclarationDescriptor?): ObjCExportStubOrigin? { if (descriptor == null) return null + if (descriptor is DeserializedDescriptor) { + return ObjCExportStubOrigin.Binary(descriptor.name, descriptor.extractSerializedKdocString()) + } + if (descriptor is DeclarationDescriptorWithSource) { return ObjCExportStubOrigin.Source(descriptor.name, descriptor.findKDocString(), (descriptor.source as? PsiSourceElement)?.psi) } - assert(descriptor is DeserializedDescriptor) { "Expected '$descriptor' to implement ${DeserializedDescriptor::class.simpleName}" } return ObjCExportStubOrigin.Binary(descriptor.name, descriptor.extractSerializedKdocString()) } + fun ObjCProtocolImpl( name: String, descriptor: ClassDescriptor, 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 ad061019e1e..c99d237c448 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 @@ -115,6 +115,21 @@ class ObjCExportHeaderGeneratorTest(val generator: HeaderGenerator) { doTest(headersTestDataDir.resolve("kdocWithBlockTags")) } + @Test + fun `test - functionWithMustBeDocumentedAnnotation`() { + doTest(headersTestDataDir.resolve("functionWithMustBeDocumentedAnnotation")) + } + + @Test + fun `test - parameterWithMustBeDocumentedAnnotation`() { + doTest(headersTestDataDir.resolve("parameterWithMustBeDocumentedAnnotation")) + } + + @Test + fun `test - receiverWithMustBeDocumentedAnnotation`() { + doTest(headersTestDataDir.resolve("receiverWithMustBeDocumentedAnnotation")) + } + fun interface HeaderGenerator { fun generateHeaders(root: File): String } diff --git a/native/objcexport-header-generator/testData/headers/functionWithMustBeDocumentedAnnotation/!functionWithMustBeDocumentedAnnotation.h b/native/objcexport-header-generator/testData/headers/functionWithMustBeDocumentedAnnotation/!functionWithMustBeDocumentedAnnotation.h new file mode 100644 index 00000000000..088fe5cd498 --- /dev/null +++ b/native/objcexport-header-generator/testData/headers/functionWithMustBeDocumentedAnnotation/!functionWithMustBeDocumentedAnnotation.h @@ -0,0 +1,34 @@ +#import +#import +#import +#import +#import +#import +#import + +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 + + +/** + * @note annotations + * ImportantAnnotation +*/ +__attribute__((objc_subclassing_restricted)) +@interface Foo : Base +- (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/functionWithMustBeDocumentedAnnotation/Foo.kt b/native/objcexport-header-generator/testData/headers/functionWithMustBeDocumentedAnnotation/Foo.kt new file mode 100644 index 00000000000..d852a716637 --- /dev/null +++ b/native/objcexport-header-generator/testData/headers/functionWithMustBeDocumentedAnnotation/Foo.kt @@ -0,0 +1,5 @@ +@kotlin.annotation.MustBeDocumented +annotation class ImportantAnnotation + +@ImportantAnnotation +class Foo \ No newline at end of file diff --git a/native/objcexport-header-generator/testData/headers/parameterWithMustBeDocumentedAnnotation/!parameterWithMustBeDocumentedAnnotation.h b/native/objcexport-header-generator/testData/headers/parameterWithMustBeDocumentedAnnotation/!parameterWithMustBeDocumentedAnnotation.h new file mode 100644 index 00000000000..e33687145ae --- /dev/null +++ b/native/objcexport-header-generator/testData/headers/parameterWithMustBeDocumentedAnnotation/!parameterWithMustBeDocumentedAnnotation.h @@ -0,0 +1,33 @@ +#import +#import +#import +#import +#import +#import +#import + +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 + +__attribute__((objc_subclassing_restricted)) +@interface Foo : Base + +/** + * @param myPrameter annotations ImportantAnnotation +*/ +- (instancetype)initWithMyPrameter:(NSString *)myPrameter __attribute__((swift_name("init(myPrameter:)"))) __attribute__((objc_designated_initializer)); +@property (readonly) NSString *myPrameter __attribute__((swift_name("myPrameter"))); +@end + +#pragma pop_macro("_Nullable_result") +#pragma clang diagnostic pop +NS_ASSUME_NONNULL_END diff --git a/native/objcexport-header-generator/testData/headers/parameterWithMustBeDocumentedAnnotation/Foo.kt b/native/objcexport-header-generator/testData/headers/parameterWithMustBeDocumentedAnnotation/Foo.kt new file mode 100644 index 00000000000..00192a27c96 --- /dev/null +++ b/native/objcexport-header-generator/testData/headers/parameterWithMustBeDocumentedAnnotation/Foo.kt @@ -0,0 +1,4 @@ +@kotlin.annotation.MustBeDocumented +annotation class ImportantAnnotation + +class Foo(@param:ImportantAnnotation val myPrameter: String) \ No newline at end of file diff --git a/native/objcexport-header-generator/testData/headers/receiverWithMustBeDocumentedAnnotation/!receiverWithMustBeDocumentedAnnotation.h b/native/objcexport-header-generator/testData/headers/receiverWithMustBeDocumentedAnnotation/!receiverWithMustBeDocumentedAnnotation.h new file mode 100644 index 00000000000..7c19e62b0ef --- /dev/null +++ b/native/objcexport-header-generator/testData/headers/receiverWithMustBeDocumentedAnnotation/!receiverWithMustBeDocumentedAnnotation.h @@ -0,0 +1,32 @@ +#import +#import +#import +#import +#import +#import +#import + +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 + +__attribute__((objc_subclassing_restricted)) +@interface FooKt : Base + +/** + * @param receiver annotations ImportantAnnotation +*/ ++ (NSString *)foo:(id)receiver __attribute__((swift_name("foo(_:)"))); +@end + +#pragma pop_macro("_Nullable_result") +#pragma clang diagnostic pop +NS_ASSUME_NONNULL_END diff --git a/native/objcexport-header-generator/testData/headers/receiverWithMustBeDocumentedAnnotation/Foo.kt b/native/objcexport-header-generator/testData/headers/receiverWithMustBeDocumentedAnnotation/Foo.kt new file mode 100644 index 00000000000..f7f10cab327 --- /dev/null +++ b/native/objcexport-header-generator/testData/headers/receiverWithMustBeDocumentedAnnotation/Foo.kt @@ -0,0 +1,5 @@ +@Target(AnnotationTarget.VALUE_PARAMETER) +@MustBeDocumented +annotation class ImportantAnnotation + +fun @receiver:ImportantAnnotation Any.foo() = toString()