From fcc4470b7430d428130d00d48302befe2520ef20 Mon Sep 17 00:00:00 2001 From: Artem Olkov Date: Thu, 14 Mar 2024 12:21:39 +0000 Subject: [PATCH] KT-65897: add exporting of kotlin constructors as Swift constructors #KT-65897 fixed Merge-request: KT-MR-14734 Merged-by: Artem Olkov --- .../sir/passes/builder/SirFromPsiBuilder.kt | 82 +++++++++- .../sir/printer/SirAsSwiftSourcesPrinter.kt | 61 +++++-- .../testData/class_with_init.golden.swift | 37 +++++ .../printer/SirAsSwiftSourcesPrinterTests.kt | 151 ++++++++++++++++++ .../gen/org/jetbrains/kotlin/sir/SirInit.kt | 34 ++++ .../kotlin/sir/builder/SirInitBuilder.kt | 66 ++++++++ .../jetbrains/kotlin/sir/impl/SirInitImpl.kt | 34 ++++ .../kotlin/sir/visitors/SirTransformer.kt | 8 + .../kotlin/sir/visitors/SirTransformerVoid.kt | 6 + .../kotlin/sir/visitors/SirVisitor.kt | 3 + .../kotlin/sir/visitors/SirVisitorVoid.kt | 8 + .../kotlin/sir/SirInitializerKind.kt | 12 ++ .../kotlin/sir/util/SirExtensions.kt | 3 +- .../kotlin/sir/tree/generator/SwiftIrTree.kt | 12 ++ .../kotlin/sir/tree/generator/Types.kt | 1 + .../classes/golden_result/result.swift | 37 +++++ .../testData/classes/input_root/classes.kt | 6 +- .../classes/input_root/should_be_ignored.kt | 2 +- 18 files changed, 544 insertions(+), 19 deletions(-) create mode 100644 native/swift/sir-printer/testData/class_with_init.golden.swift create mode 100644 native/swift/sir/gen/org/jetbrains/kotlin/sir/SirInit.kt create mode 100644 native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirInitBuilder.kt create mode 100644 native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirInitImpl.kt create mode 100644 native/swift/sir/src/org/jetbrains/kotlin/sir/SirInitializerKind.kt diff --git a/native/swift/sir-passes/src/org/jetbrains/sir/passes/builder/SirFromPsiBuilder.kt b/native/swift/sir-passes/src/org/jetbrains/sir/passes/builder/SirFromPsiBuilder.kt index f0099185a6e..b71ceb80eaa 100644 --- a/native/swift/sir-passes/src/org/jetbrains/sir/passes/builder/SirFromPsiBuilder.kt +++ b/native/swift/sir-passes/src/org/jetbrains/sir/passes/builder/SirFromPsiBuilder.kt @@ -34,6 +34,8 @@ private abstract class PsiToSirTranslation( ) : KtVisitor() { abstract override fun visitClassOrObject(classOrObject: KtClassOrObject, data: Unit?): T abstract override fun visitNamedFunction(function: KtNamedFunction, data: Unit?): T + abstract override fun visitPrimaryConstructor(constructor: KtPrimaryConstructor, data: Unit?): T + abstract override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor, data: Unit?): T abstract override fun visitProperty(property: KtProperty, data: Unit?): T } @@ -51,6 +53,14 @@ private class PsiToSirTranslationCollector( function.checkAndTranslate(null) } + override fun visitPrimaryConstructor(constructor: KtPrimaryConstructor) { + constructor.checkAndTranslate(null) + } + + override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor) { + constructor.checkAndTranslate(null) + } + override fun visitProperty(property: KtProperty) { property.checkAndTranslate(null) } @@ -82,9 +92,21 @@ private class PsiToSirTranslatableChecker( return functionIsPublicAndTopLevel && functionSymbolIsTranslatable } + override fun visitPrimaryConstructor(constructor: KtPrimaryConstructor, data: Unit?): Boolean { + return constructor.isConsumable() + } + + override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor, data: Unit?): Boolean { + return constructor.isConsumable() + } + override fun visitProperty(property: KtProperty, data: Unit?): Boolean { return property.isPublic } + + private fun KtConstructor<*>.isConsumable(): Boolean { + return isPublic + } } private class PsiToSirElementTranslation( @@ -99,6 +121,14 @@ private class PsiToSirElementTranslation( buildSirFunctionFromPsi(function) } + override fun visitPrimaryConstructor(constructor: KtPrimaryConstructor, data: Unit?): SirDeclaration = with(analysisSession) { + buildSirConstructorFromPsi(constructor) + } + + override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor, data: Unit?): SirDeclaration = with(analysisSession) { + buildSirConstructorFromPsi(constructor) + } + override fun visitProperty(property: KtProperty, data: Unit?): SirDeclaration = with(analysisSession) { buildSirVariableFromPsi(property) } @@ -118,6 +148,32 @@ internal fun buildSirClassFromPsi(classOrObject: KtClassOrObject): SirNamedDecla PsiToSirElementTranslation(analysisSession), ) ) + + // HACK to support default constructors. + // todo: We should rework builder from PSI to AnalysisApi during KT-66310 + val constructors = symbol.getMemberScope().getConstructors() + if (constructors.count() == 1 && constructors.first().psi == classOrObject) { + declarations.add( + 0, + buildInit { + val constructorSymbol = constructors.first() + origin = KotlinSource(constructorSymbol) + + kind = constructorSymbol.sirCallableKind + isFailable = false + initKind = SirInitializerKind.ORDINARY + + constructorSymbol.valueParameters.mapTo(parameters) { + SirParameter( + argumentName = it.name.asString(), + type = buildSirNominalType(it.returnType) + ) + } + + documentation = null + } + ) + } }.also { resultedClass -> resultedClass.declarations.forEach { decl -> decl.parent = resultedClass } } @@ -143,6 +199,25 @@ internal fun buildSirFunctionFromPsi(function: KtNamedFunction): SirFunction = b documentation = function.docComment?.text } +context(KtAnalysisSession) +internal fun buildSirConstructorFromPsi(function: KtConstructor<*>): SirInit = buildInit { + val symbol = function.getConstructorSymbol() + origin = KotlinSource(symbol) + + kind = symbol.sirCallableKind + isFailable = false + initKind = SirInitializerKind.ORDINARY + + symbol.valueParameters.mapTo(parameters) { + SirParameter( + argumentName = it.name.asString(), + type = buildSirNominalType(it.returnType) + ) + } + + documentation = function.docComment?.text +} + context(KtAnalysisSession) internal fun buildSirVariableFromPsi(variable: KtProperty): SirVariable = buildVariable { val symbol = variable.getVariableSymbol() @@ -213,8 +288,9 @@ private val KtCallableSymbol.sirCallableKind: SirCallableKind SirCallableKind.STATIC_METHOD } } - KtSymbolKind.CLASS_MEMBER, KtSymbolKind.ACCESSOR -> SirCallableKind.INSTANCE_METHOD + KtSymbolKind.CLASS_MEMBER, KtSymbolKind.ACCESSOR + -> SirCallableKind.INSTANCE_METHOD KtSymbolKind.LOCAL, - KtSymbolKind.SAM_CONSTRUCTOR -> - TODO("encountered callable kind($symbolKind) that is not translatable currently. Fix this crash during KT-65980.") + KtSymbolKind.SAM_CONSTRUCTOR + -> TODO("encountered callable kind($symbolKind) that is not translatable currently. Fix this crash during KT-65980.") } diff --git a/native/swift/sir-printer/src/org/jetbrains/sir/printer/SirAsSwiftSourcesPrinter.kt b/native/swift/sir-printer/src/org/jetbrains/sir/printer/SirAsSwiftSourcesPrinter.kt index 4ceba22fa5e..5d44522b7f1 100644 --- a/native/swift/sir-printer/src/org/jetbrains/sir/printer/SirAsSwiftSourcesPrinter.kt +++ b/native/swift/sir-printer/src/org/jetbrains/sir/printer/SirAsSwiftSourcesPrinter.kt @@ -102,19 +102,7 @@ public class SirAsSwiftSourcesPrinter(private val printer: SmartPrinter) : SirVi function.name.swiftIdentifier, "(" ) - if (function.parameters.isNotEmpty()) { - println() - withIndent { - function.parameters.forEachIndexed { index, sirParameter -> - print(sirParameter.swift) - if (index != function.parameters.lastIndex) { - println(",") - } else { - println() - } - } - } - } + printParameters(function.parameters) print( ")", " -> ", @@ -129,6 +117,26 @@ public class SirAsSwiftSourcesPrinter(private val printer: SmartPrinter) : SirVi println("}") } + override fun visitInit(init: SirInit): Unit = with(printer) { + init.documentation?.let { println(it) } + printVisibility(init) + printInitKind(init.initKind) + print("init") + "?".takeIf { init.isFailable }?.let { print(it) } + print("(") + printParameters(init.parameters) + print( + ")" + ) + println(" {") + withIndent { + printFunctionBody(init.body).forEach { + println(it) + } + } + println("}") + } + override fun visitEnum(enum: SirEnum): Unit = with(printer) { printVisibility(enum) println( @@ -184,6 +192,16 @@ internal fun SmartPrinter.printVisibility(decl: SirDeclaration) { ) } +internal fun SmartPrinter.printInitKind(decl: SirInitializerKind) { + print( + when (decl) { + SirInitializerKind.ORDINARY -> "" + SirInitializerKind.REQUIRED -> "required " + SirInitializerKind.CONVENIENCE -> "convenience " + } + ) +} + internal fun SmartPrinter.printCallableKind(callableKind: SirCallableKind) { print( when (callableKind) { @@ -194,3 +212,20 @@ internal fun SmartPrinter.printCallableKind(callableKind: SirCallableKind) { } ) } + +internal fun SmartPrinter.printParameters(params: List): Unit = params + .takeIf { it.isNotEmpty() } + ?.let { + println() + withIndent { + params.forEachIndexed { index, sirParameter -> + print(sirParameter.swift) + if (index != params.lastIndex) { + println(",") + } else { + println() + } + } + } + } + ?: Unit diff --git a/native/swift/sir-printer/testData/class_with_init.golden.swift b/native/swift/sir-printer/testData/class_with_init.golden.swift new file mode 100644 index 00000000000..c06d9980392 --- /dev/null +++ b/native/swift/sir-printer/testData/class_with_init.golden.swift @@ -0,0 +1,37 @@ +public class Foo { + public init?( + arg1: Swift.Bool, + arg2: Swift.Int8, + arg3: Swift.Int16, + arg4: Swift.Int32, + arg5: Swift.Int64, + arg6: Swift.Double, + arg7: Swift.Float + ) { + fatalError() + } + public init( + arg1: Swift.UInt8, + arg2: Swift.UInt16, + arg3: Swift.UInt32, + arg4: Swift.UInt64 + ) { + fatalError() + } + public required init( + arg1: Swift.UInt8, + arg2: Swift.UInt16, + arg3: Swift.UInt32, + arg4: Swift.UInt64 + ) { + fatalError() + } + public convenience init( + arg1: Swift.UInt8, + arg2: Swift.UInt16, + arg3: Swift.UInt32, + arg4: Swift.UInt64 + ) { + fatalError() + } +} \ No newline at end of file diff --git a/native/swift/sir-printer/tests/org/jetbrains/kotlin/sir/printer/SirAsSwiftSourcesPrinterTests.kt b/native/swift/sir-printer/tests/org/jetbrains/kotlin/sir/printer/SirAsSwiftSourcesPrinterTests.kt index 17f1aef6be7..d6fec34c5a5 100644 --- a/native/swift/sir-printer/tests/org/jetbrains/kotlin/sir/printer/SirAsSwiftSourcesPrinterTests.kt +++ b/native/swift/sir-printer/tests/org/jetbrains/kotlin/sir/printer/SirAsSwiftSourcesPrinterTests.kt @@ -460,6 +460,157 @@ class SirAsSwiftSourcesPrinterTests { ) } + @Test + fun `should print class with constructor`() { + + val module = buildModule { + name = "Test" + declarations.add( + buildClass { + origin = SirOrigin.Unknown + name = "Foo" + + declarations.add( + buildInit { + origin = SirOrigin.Unknown + kind = SirCallableKind.INSTANCE_METHOD + initKind = SirInitializerKind.ORDINARY + visibility = SirVisibility.PUBLIC + isFailable = true + parameters.addAll( + listOf( + SirParameter( + argumentName = "arg1", + type = SirNominalType(SirSwiftModule.bool) + ), + SirParameter( + argumentName = "arg2", + type = SirNominalType(SirSwiftModule.int8) + ), + SirParameter( + argumentName = "arg3", + type = SirNominalType(SirSwiftModule.int16) + ), + SirParameter( + argumentName = "arg4", + type = SirNominalType(SirSwiftModule.int32) + ), + SirParameter( + argumentName = "arg5", + type = SirNominalType(SirSwiftModule.int64) + ), + SirParameter( + argumentName = "arg6", + type = SirNominalType(SirSwiftModule.double) + ), + SirParameter( + argumentName = "arg7", + type = SirNominalType(SirSwiftModule.float) + ), + ) + ) + } + ) + + declarations.add( + buildInit { + origin = SirOrigin.Unknown + kind = SirCallableKind.INSTANCE_METHOD + initKind = SirInitializerKind.ORDINARY + visibility = SirVisibility.PUBLIC + isFailable = false + parameters.addAll( + listOf( + SirParameter( + argumentName = "arg1", + type = SirNominalType(SirSwiftModule.uint8) + ), + SirParameter( + argumentName = "arg2", + type = SirNominalType(SirSwiftModule.uint16) + ), + SirParameter( + argumentName = "arg3", + type = SirNominalType(SirSwiftModule.uint32) + ), + SirParameter( + argumentName = "arg4", + type = SirNominalType(SirSwiftModule.uint64) + ), + ) + ) + } + ) + + declarations.add( + buildInit { + origin = SirOrigin.Unknown + kind = SirCallableKind.INSTANCE_METHOD + initKind = SirInitializerKind.REQUIRED + visibility = SirVisibility.PUBLIC + isFailable = false + parameters.addAll( + listOf( + SirParameter( + argumentName = "arg1", + type = SirNominalType(SirSwiftModule.uint8) + ), + SirParameter( + argumentName = "arg2", + type = SirNominalType(SirSwiftModule.uint16) + ), + SirParameter( + argumentName = "arg3", + type = SirNominalType(SirSwiftModule.uint32) + ), + SirParameter( + argumentName = "arg4", + type = SirNominalType(SirSwiftModule.uint64) + ), + ) + ) + } + ) + + declarations.add( + buildInit { + origin = SirOrigin.Unknown + kind = SirCallableKind.INSTANCE_METHOD + initKind = SirInitializerKind.CONVENIENCE + visibility = SirVisibility.PUBLIC + isFailable = false + parameters.addAll( + listOf( + SirParameter( + argumentName = "arg1", + type = SirNominalType(SirSwiftModule.uint8) + ), + SirParameter( + argumentName = "arg2", + type = SirNominalType(SirSwiftModule.uint16) + ), + SirParameter( + argumentName = "arg3", + type = SirNominalType(SirSwiftModule.uint32) + ), + SirParameter( + argumentName = "arg4", + type = SirNominalType(SirSwiftModule.uint64) + ), + ) + ) + } + ) + } + ) + } + + runTest( + module, + "testData/class_with_init" + ) + } + @Test fun `should print class with variable`() { diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirInit.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirInit.kt new file mode 100644 index 00000000000..1a073727c70 --- /dev/null +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirInit.kt @@ -0,0 +1,34 @@ +/* + * 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. + */ + +// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md. +// DO NOT MODIFY IT MANUALLY. + +package org.jetbrains.kotlin.sir + +import org.jetbrains.kotlin.sir.visitors.SirTransformer +import org.jetbrains.kotlin.sir.visitors.SirVisitor + +/** + * Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.init] + */ +abstract class SirInit : SirCallable() { + abstract override val origin: SirOrigin + abstract override val visibility: SirVisibility + abstract override var parent: SirDeclarationParent + abstract override val kind: SirCallableKind + abstract override var body: SirFunctionBody? + abstract val isFailable: Boolean + abstract val parameters: List + abstract val initKind: SirInitializerKind + abstract var documentation: String? + + override fun accept(visitor: SirVisitor, data: D): R = + visitor.visitInit(this, data) + + @Suppress("UNCHECKED_CAST") + override fun transform(transformer: SirTransformer, data: D): E = + transformer.transformInit(this, data) as E +} diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirInitBuilder.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirInitBuilder.kt new file mode 100644 index 00000000000..95f08c1d348 --- /dev/null +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/builder/SirInitBuilder.kt @@ -0,0 +1,66 @@ +/* + * 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. + */ + +// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md. +// DO NOT MODIFY IT MANUALLY. + +@file:Suppress("DuplicatedCode", "unused") + +package org.jetbrains.kotlin.sir.builder + +import kotlin.contracts.* +import org.jetbrains.kotlin.sir.* +import org.jetbrains.kotlin.sir.impl.SirInitImpl + +@SirBuilderDsl +class SirInitBuilder { + var origin: SirOrigin = SirOrigin.Unknown + var visibility: SirVisibility = SirVisibility.PUBLIC + lateinit var kind: SirCallableKind + var body: SirFunctionBody? = null + var isFailable: Boolean by kotlin.properties.Delegates.notNull() + val parameters: MutableList = mutableListOf() + lateinit var initKind: SirInitializerKind + var documentation: String? = null + + fun build(): SirInit { + return SirInitImpl( + origin, + visibility, + kind, + body, + isFailable, + parameters, + initKind, + documentation, + ) + } + +} + +@OptIn(ExperimentalContracts::class) +inline fun buildInit(init: SirInitBuilder.() -> Unit): SirInit { + contract { + callsInPlace(init, InvocationKind.EXACTLY_ONCE) + } + return SirInitBuilder().apply(init).build() +} + +@OptIn(ExperimentalContracts::class) +inline fun buildInitCopy(original: SirInit, init: SirInitBuilder.() -> Unit): SirInit { + contract { + callsInPlace(init, InvocationKind.EXACTLY_ONCE) + } + val copyBuilder = SirInitBuilder() + copyBuilder.origin = original.origin + copyBuilder.visibility = original.visibility + copyBuilder.kind = original.kind + copyBuilder.body = original.body + copyBuilder.isFailable = original.isFailable + copyBuilder.parameters.addAll(original.parameters) + copyBuilder.initKind = original.initKind + copyBuilder.documentation = original.documentation + return copyBuilder.apply(init).build() +} diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirInitImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirInitImpl.kt new file mode 100644 index 00000000000..abb6aa03d58 --- /dev/null +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirInitImpl.kt @@ -0,0 +1,34 @@ +/* + * 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. + */ + +// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md. +// DO NOT MODIFY IT MANUALLY. + +@file:Suppress("DuplicatedCode") + +package org.jetbrains.kotlin.sir.impl + +import org.jetbrains.kotlin.sir.* +import org.jetbrains.kotlin.sir.visitors.SirTransformer +import org.jetbrains.kotlin.sir.visitors.SirVisitor + +internal class SirInitImpl( + override val origin: SirOrigin, + override val visibility: SirVisibility, + override val kind: SirCallableKind, + override var body: SirFunctionBody?, + override val isFailable: Boolean, + override val parameters: MutableList, + override val initKind: SirInitializerKind, + override var documentation: String?, +) : SirInit() { + override lateinit var parent: SirDeclarationParent + + override fun acceptChildren(visitor: SirVisitor, data: D) { + } + + override fun transformChildren(transformer: SirTransformer, data: D) { + } +} diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirTransformer.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirTransformer.kt index d48bdb7b9b0..18d3b9982ea 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirTransformer.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirTransformer.kt @@ -87,6 +87,14 @@ abstract class SirTransformer : SirVisitor() { return transformCallable(callable, data) } + open fun transformInit(init: SirInit, data: D): SirDeclaration { + return transformCallable(init, data) + } + + final override fun visitInit(init: SirInit, data: D): SirDeclaration { + return transformInit(init, data) + } + open fun transformFunction(function: SirFunction, data: D): SirDeclaration { return transformCallable(function, data) } diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirTransformerVoid.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirTransformerVoid.kt index f6c7a74ec2a..f930d6cef73 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirTransformerVoid.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirTransformerVoid.kt @@ -68,6 +68,12 @@ abstract class SirTransformerVoid : SirTransformer() { final override fun transformCallable(callable: SirCallable, data: Nothing?): SirDeclaration = transformCallable(callable) + open fun transformInit(init: SirInit): SirDeclaration = + transformCallable(init) + + final override fun transformInit(init: SirInit, data: Nothing?): SirDeclaration = + transformInit(init) + open fun transformFunction(function: SirFunction): SirDeclaration = transformCallable(function) diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirVisitor.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirVisitor.kt index f32935c2262..8ff0e907a2d 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirVisitor.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirVisitor.kt @@ -41,6 +41,9 @@ abstract class SirVisitor { open fun visitCallable(callable: SirCallable, data: D): R = visitDeclaration(callable, data) + open fun visitInit(init: SirInit, data: D): R = + visitCallable(init, data) + open fun visitFunction(function: SirFunction, data: D): R = visitCallable(function, data) diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirVisitorVoid.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirVisitorVoid.kt index bf23d173319..2c5edd51e1d 100644 --- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirVisitorVoid.kt +++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/visitors/SirVisitorVoid.kt @@ -86,6 +86,14 @@ abstract class SirVisitorVoid : SirVisitor() { visitDeclaration(callable) } + final override fun visitInit(init: SirInit, data: Nothing?) { + visitInit(init) + } + + open fun visitInit(init: SirInit) { + visitCallable(init) + } + final override fun visitFunction(function: SirFunction, data: Nothing?) { visitFunction(function) } diff --git a/native/swift/sir/src/org/jetbrains/kotlin/sir/SirInitializerKind.kt b/native/swift/sir/src/org/jetbrains/kotlin/sir/SirInitializerKind.kt new file mode 100644 index 00000000000..72ef2c98fa4 --- /dev/null +++ b/native/swift/sir/src/org/jetbrains/kotlin/sir/SirInitializerKind.kt @@ -0,0 +1,12 @@ +/* + * 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.sir + +enum class SirInitializerKind { + ORDINARY, + REQUIRED, + CONVENIENCE +} diff --git a/native/swift/sir/src/org/jetbrains/kotlin/sir/util/SirExtensions.kt b/native/swift/sir/src/org/jetbrains/kotlin/sir/util/SirExtensions.kt index 2b35b822126..cb9e02f89c6 100644 --- a/native/swift/sir/src/org/jetbrains/kotlin/sir/util/SirExtensions.kt +++ b/native/swift/sir/src/org/jetbrains/kotlin/sir/util/SirExtensions.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.sir.* val SirCallable.allParameters: List get() = when (this) { is SirFunction -> this.parameters + is SirInit -> this.parameters is SirSetter -> listOf(SirParameter(parameterName = parameterName, type = this.valueType)) is SirGetter -> listOf() } @@ -18,7 +19,7 @@ val SirCallable.returnType: SirType get() = when (this) { is SirFunction -> this.returnType is SirGetter -> this.valueType - is SirSetter -> SirNominalType(SirSwiftModule.void) + is SirSetter, is SirInit -> SirNominalType(SirSwiftModule.void) } val SirAccessor.valueType: SirType diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt index 480f182a600..9156c44ce5d 100644 --- a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt @@ -81,6 +81,18 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() { +field("body", functionBodyType, nullable = true, mutable = true) } + val init by element { + customParentInVisitor = callable + parent(callable) + + +field("isFailable", boolean) + +listField("parameters", parameterType) + + +field("initKind", initKind) + + +field(name = "documentation", string, nullable = true, mutable = true) + } + val function by element { customParentInVisitor = callable parent(callable) diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Types.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Types.kt index 55997f71df0..74a71556287 100644 --- a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Types.kt +++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Types.kt @@ -16,6 +16,7 @@ val typeType = type(BASE_PACKAGE, "SirType", TypeKind.Class) val enumCaseType = type(BASE_PACKAGE, "SirEnumCase", TypeKind.Class) val functionBodyType = type(BASE_PACKAGE, "SirFunctionBody", TypeKind.Class) val callableKind = type(BASE_PACKAGE, "SirCallableKind", TypeKind.Class) +val initKind = type(BASE_PACKAGE, "SirInitializerKind", TypeKind.Class) private const val VISITORS_PACKAGE = "$BASE_PACKAGE.visitors" diff --git a/native/swift/swift-export-standalone/testData/classes/golden_result/result.swift b/native/swift/swift-export-standalone/testData/classes/golden_result/result.swift index 86e891776a7..e14e6d812d4 100644 --- a/native/swift/swift-export-standalone/testData/classes/golden_result/result.swift +++ b/native/swift/swift-export-standalone/testData/classes/golden_result/result.swift @@ -4,10 +4,22 @@ import KotlinRuntime public enum namespace { public enum deeper { public class NAMESPACED_CLASS { + public init() { + fatalError() + } } public class Foo { + public init() { + fatalError() + } public class INSIDE_CLASS { + public init() { + fatalError() + } public class DEEPER_INSIDE_CLASS { + public init() { + fatalError() + } public func foo() -> Swift.Bool { fatalError() } @@ -61,9 +73,18 @@ public enum namespace { } } public class NAMESPACED_CLASS { + public init() { + fatalError() + } } public class Foo { + public init() { + fatalError() + } public class INSIDE_CLASS { + public init() { + fatalError() + } } public func foo() -> Swift.Bool { fatalError() @@ -84,8 +105,24 @@ public enum namespace { } } +public class ClassWithNonPublicConstructor { +} + public class Foo { + public init( + a: Swift.Int32 + ) { + fatalError() + } + public init( + f: Swift.Float + ) { + fatalError() + } public class INSIDE_CLASS { + public init() { + fatalError() + } public func my_func() -> Swift.Bool { fatalError() } diff --git a/native/swift/swift-export-standalone/testData/classes/input_root/classes.kt b/native/swift/swift-export-standalone/testData/classes/input_root/classes.kt index 848eb24305a..518efca4480 100644 --- a/native/swift/swift-export-standalone/testData/classes/input_root/classes.kt +++ b/native/swift/swift-export-standalone/testData/classes/input_root/classes.kt @@ -1,5 +1,9 @@ +public class ClassWithNonPublicConstructor internal constructor(public val a: Int) -class Foo { +class Foo (a: Int) { + constructor(f: Float) : this(f.toInt()) + + private constructor(d: Double) : this(d.toInt()) class INSIDE_CLASS { fun my_func(): Boolean = TODO() diff --git a/native/swift/swift-export-standalone/testData/classes/input_root/should_be_ignored.kt b/native/swift/swift-export-standalone/testData/classes/input_root/should_be_ignored.kt index 7fad1a22cad..965d8825884 100644 --- a/native/swift/swift-export-standalone/testData/classes/input_root/should_be_ignored.kt +++ b/native/swift/swift-export-standalone/testData/classes/input_root/should_be_ignored.kt @@ -29,4 +29,4 @@ abstract class ABSTRACT_CLASS sealed class SEALED { object O : SEALED() -} \ No newline at end of file +}