add export from kotlin into swift of class content #KT-65896 fixed
Merge-request: KT-MR-14624 Merged-by: Artem Olkov <artem.olkov@jetbrains.com>
This commit is contained in:
+1
-4
@@ -5,9 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.sir.bridge.impl
|
||||
|
||||
import org.jetbrains.kotlin.sir.SirNominalType
|
||||
import org.jetbrains.kotlin.sir.SirParameter
|
||||
import org.jetbrains.kotlin.sir.SirType
|
||||
import org.jetbrains.kotlin.sir.*
|
||||
import org.jetbrains.kotlin.sir.bridge.*
|
||||
import org.jetbrains.kotlin.sir.util.*
|
||||
|
||||
@@ -181,4 +179,3 @@ internal enum class KotlinType(val repr: String) {
|
||||
Float("Float"),
|
||||
Double("Double"),
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -33,9 +33,10 @@ abstract class AbstractKotlinSirBridgeTest {
|
||||
val cBridgePrinter = createCBridgePrinter()
|
||||
|
||||
requests.forEach { request ->
|
||||
val bridge = generator.generate(request)
|
||||
kotlinBridgePrinter.add(bridge)
|
||||
cBridgePrinter.add(bridge)
|
||||
generator.generate(request)?.let {
|
||||
kotlinBridgePrinter.add(it)
|
||||
cBridgePrinter.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
val actualKotlinSrc = kotlinBridgePrinter.print().joinToString(separator = lineSeparator)
|
||||
|
||||
@@ -25,7 +25,7 @@ public fun KtAnalysisSession.buildSirDeclarationList(from: KtElement): List<SirD
|
||||
PsiToSirTranslationCollector(
|
||||
res,
|
||||
PsiToSirTranslatableChecker(this),
|
||||
PsiToSirElementTranslation(this)
|
||||
PsiToSirElementTranslation(this),
|
||||
)
|
||||
)
|
||||
return res.toList()
|
||||
@@ -43,10 +43,13 @@ private class PsiToSirTranslationCollector(
|
||||
private val res: MutableList<SirDeclaration>,
|
||||
private val checker: PsiToSirTranslation<Boolean>,
|
||||
private val translator: PsiToSirTranslation<SirDeclaration>,
|
||||
private val isFirstLevel: Boolean = true,
|
||||
) : KtTreeVisitorVoid() {
|
||||
|
||||
override fun visitClassOrObject(classOrObject: KtClassOrObject) {
|
||||
classOrObject.checkAndTranslate(null)
|
||||
if (isFirstLevel) {
|
||||
classOrObject.checkAndTranslate(null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitNamedFunction(function: KtNamedFunction) {
|
||||
@@ -72,7 +75,6 @@ private class PsiToSirTranslatableChecker(
|
||||
|
||||
override fun visitNamedFunction(function: KtNamedFunction, data: Unit?): Boolean = with(analysisSession) {
|
||||
val functionIsPublicAndTopLevel = function.isPublic
|
||||
&& function.isTopLevel
|
||||
&& !function.isAnonymous
|
||||
val functionSymbolIsTranslatable = (function.getFunctionLikeSymbol() as? KtFunctionSymbol)
|
||||
?.let { symbol ->
|
||||
@@ -87,7 +89,6 @@ private class PsiToSirTranslatableChecker(
|
||||
|
||||
override fun visitProperty(property: KtProperty, data: Unit?): Boolean {
|
||||
return property.isPublic
|
||||
&& property.isTopLevel
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,11 +111,21 @@ private class PsiToSirElementTranslation(
|
||||
|
||||
context(KtAnalysisSession)
|
||||
internal fun buildSirClassFromPsi(classOrObject: KtClassOrObject): SirNamedDeclaration {
|
||||
// if there is no symbol - it will be handled by `PsiToSirTranslatableChecker`
|
||||
val symbol = classOrObject.getNamedClassOrObjectSymbol()!!
|
||||
return buildClass {
|
||||
name = classOrObject.name ?: "UNKNOWN_CLASS" // todo: error handling strategy: KT-65980
|
||||
origin = KotlinSource(symbol)
|
||||
|
||||
classOrObject.acceptChildren(
|
||||
PsiToSirTranslationCollector(
|
||||
declarations,
|
||||
PsiToSirTranslatableChecker(analysisSession),
|
||||
PsiToSirElementTranslation(analysisSession),
|
||||
false
|
||||
)
|
||||
)
|
||||
}.also { resultedClass ->
|
||||
resultedClass.declarations.forEach { decl -> decl.parent = resultedClass }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
public class Foo {
|
||||
public func foo(
|
||||
arg1: Swift.Bool,
|
||||
arg2: Swift.Int8,
|
||||
arg3: Swift.Int16,
|
||||
arg4: Swift.Int32,
|
||||
arg5: Swift.Int64,
|
||||
arg6: Swift.Double,
|
||||
arg7: Swift.Float
|
||||
) -> Swift.Bool {
|
||||
fatalError()
|
||||
}
|
||||
public func bar(
|
||||
arg1: Swift.UInt8,
|
||||
arg2: Swift.UInt16,
|
||||
arg3: Swift.UInt32,
|
||||
arg4: Swift.UInt64
|
||||
) -> Swift.Bool {
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
public class Foo {
|
||||
public var my_variable1: Swift.Bool {
|
||||
get
|
||||
}
|
||||
public var my_variable2: Swift.Int8 {
|
||||
get
|
||||
}
|
||||
}
|
||||
+131
-4
@@ -6,10 +6,7 @@
|
||||
package org.jetbrains.kotlin.sir.printer
|
||||
|
||||
import org.jetbrains.kotlin.sir.*
|
||||
import org.jetbrains.kotlin.sir.builder.buildClass
|
||||
import org.jetbrains.kotlin.sir.builder.buildEnum
|
||||
import org.jetbrains.kotlin.sir.builder.buildFunction
|
||||
import org.jetbrains.kotlin.sir.builder.buildModule
|
||||
import org.jetbrains.kotlin.sir.builder.*
|
||||
import org.jetbrains.kotlin.sir.util.SirSwiftModule
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||
@@ -372,6 +369,136 @@ class SirAsSwiftSourcesPrinterTests {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should print class with function`() {
|
||||
|
||||
val module = buildModule {
|
||||
name = "Test"
|
||||
declarations.add(
|
||||
buildClass {
|
||||
origin = SirOrigin.Unknown
|
||||
name = "Foo"
|
||||
|
||||
declarations.add(
|
||||
buildFunction {
|
||||
origin = SirOrigin.Unknown
|
||||
kind = SirCallableKind.INSTANCE_METHOD
|
||||
visibility = SirVisibility.PUBLIC
|
||||
name = "foo"
|
||||
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)
|
||||
),
|
||||
)
|
||||
)
|
||||
returnType = SirNominalType(SirSwiftModule.bool)
|
||||
}
|
||||
)
|
||||
|
||||
declarations.add(
|
||||
buildFunction {
|
||||
origin = SirOrigin.Unknown
|
||||
kind = SirCallableKind.INSTANCE_METHOD
|
||||
visibility = SirVisibility.PUBLIC
|
||||
name = "bar"
|
||||
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)
|
||||
),
|
||||
)
|
||||
)
|
||||
returnType = SirNominalType(SirSwiftModule.bool)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
runTest(
|
||||
module,
|
||||
"testData/class_with_function"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should print class with variable`() {
|
||||
|
||||
val module = buildModule {
|
||||
name = "Test"
|
||||
declarations.add(
|
||||
buildClass {
|
||||
origin = SirOrigin.Unknown
|
||||
name = "Foo"
|
||||
|
||||
declarations.add(
|
||||
buildVariable {
|
||||
name = "my_variable1"
|
||||
type = SirNominalType(SirSwiftModule.bool)
|
||||
getter = buildGetter {
|
||||
kind = SirCallableKind.INSTANCE_METHOD
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
declarations.add(
|
||||
buildVariable {
|
||||
name = "my_variable2"
|
||||
type = SirNominalType(SirSwiftModule.int8)
|
||||
getter = buildGetter {
|
||||
kind = SirCallableKind.INSTANCE_METHOD
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
runTest(
|
||||
module,
|
||||
"testData/class_with_variable"
|
||||
)
|
||||
}
|
||||
|
||||
private fun runTest(module: SirModule, goldenDataFile: String) {
|
||||
val expectedSwiftSrc = File(KtTestUtil.getHomeDirectory()).resolve("$goldenDataFile.golden.swift")
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ sealed class SirAccessor : SirCallable() {
|
||||
abstract override val visibility: SirVisibility
|
||||
abstract override var parent: SirDeclarationParent
|
||||
abstract override val kind: SirCallableKind
|
||||
abstract var body: SirFunctionBody?
|
||||
abstract override var body: SirFunctionBody?
|
||||
|
||||
override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R =
|
||||
visitor.visitAccessor(this, data)
|
||||
|
||||
@@ -19,6 +19,7 @@ sealed class SirCallable : SirElementBase(), SirDeclaration {
|
||||
abstract override val visibility: SirVisibility
|
||||
abstract override var parent: SirDeclarationParent
|
||||
abstract val kind: SirCallableKind
|
||||
abstract var body: SirFunctionBody?
|
||||
|
||||
override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R =
|
||||
visitor.visitCallable(this, data)
|
||||
|
||||
@@ -19,10 +19,10 @@ abstract class SirFunction : SirCallable() {
|
||||
abstract override val visibility: SirVisibility
|
||||
abstract override var parent: SirDeclarationParent
|
||||
abstract override val kind: SirCallableKind
|
||||
abstract override var body: SirFunctionBody?
|
||||
abstract val name: String
|
||||
abstract val parameters: List<SirParameter>
|
||||
abstract val returnType: SirType
|
||||
abstract var body: SirFunctionBody?
|
||||
abstract var documentation: String?
|
||||
|
||||
override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R =
|
||||
|
||||
@@ -19,10 +19,10 @@ class SirFunctionBuilder {
|
||||
var origin: SirOrigin = SirOrigin.Unknown
|
||||
var visibility: SirVisibility = SirVisibility.PUBLIC
|
||||
lateinit var kind: SirCallableKind
|
||||
var body: SirFunctionBody? = null
|
||||
lateinit var name: String
|
||||
val parameters: MutableList<SirParameter> = mutableListOf()
|
||||
lateinit var returnType: SirType
|
||||
var body: SirFunctionBody? = null
|
||||
var documentation: String? = null
|
||||
|
||||
fun build(): SirFunction {
|
||||
@@ -30,10 +30,10 @@ class SirFunctionBuilder {
|
||||
origin,
|
||||
visibility,
|
||||
kind,
|
||||
body,
|
||||
name,
|
||||
parameters,
|
||||
returnType,
|
||||
body,
|
||||
documentation,
|
||||
)
|
||||
}
|
||||
@@ -57,10 +57,10 @@ inline fun buildFunctionCopy(original: SirFunction, init: SirFunctionBuilder.()
|
||||
copyBuilder.origin = original.origin
|
||||
copyBuilder.visibility = original.visibility
|
||||
copyBuilder.kind = original.kind
|
||||
copyBuilder.body = original.body
|
||||
copyBuilder.name = original.name
|
||||
copyBuilder.parameters.addAll(original.parameters)
|
||||
copyBuilder.returnType = original.returnType
|
||||
copyBuilder.body = original.body
|
||||
copyBuilder.documentation = original.documentation
|
||||
return copyBuilder.apply(init).build()
|
||||
}
|
||||
|
||||
@@ -18,10 +18,10 @@ internal class SirFunctionImpl(
|
||||
override val origin: SirOrigin,
|
||||
override val visibility: SirVisibility,
|
||||
override val kind: SirCallableKind,
|
||||
override var body: SirFunctionBody?,
|
||||
override val name: String,
|
||||
override val parameters: MutableList<SirParameter>,
|
||||
override val returnType: SirType,
|
||||
override var body: SirFunctionBody?,
|
||||
override var documentation: String?,
|
||||
) : SirFunction() {
|
||||
override lateinit var parent: SirDeclarationParent
|
||||
|
||||
+1
-3
@@ -78,6 +78,7 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() {
|
||||
parent(declaration)
|
||||
|
||||
+field("kind", callableKind)
|
||||
+field("body", functionBodyType, nullable = true, mutable = true)
|
||||
}
|
||||
|
||||
val function by element {
|
||||
@@ -87,7 +88,6 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() {
|
||||
+field("name", string)
|
||||
+listField("parameters", parameterType)
|
||||
+field("returnType", typeType)
|
||||
+field("body", functionBodyType, nullable = true, mutable = true)
|
||||
|
||||
+field(name = "documentation", string, nullable = true, mutable = true)
|
||||
}
|
||||
@@ -95,8 +95,6 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() {
|
||||
val accessor by sealedElement {
|
||||
customParentInVisitor = callable
|
||||
parent(callable)
|
||||
|
||||
+field("body", functionBodyType, nullable = true, mutable = true)
|
||||
}
|
||||
|
||||
val getter by element {
|
||||
|
||||
+35
-24
@@ -7,19 +7,12 @@ package org.jetbrains.kotlin.swiftexport.standalone.builders
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.psiSafe
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.sir.SirElement
|
||||
import org.jetbrains.kotlin.sir.SirFunction
|
||||
import org.jetbrains.kotlin.sir.SirVariable
|
||||
import org.jetbrains.kotlin.sir.SirAccessor
|
||||
import org.jetbrains.kotlin.sir.SirSetter
|
||||
import org.jetbrains.kotlin.sir.SirGetter
|
||||
import org.jetbrains.kotlin.sir.*
|
||||
import org.jetbrains.kotlin.sir.util.*
|
||||
import org.jetbrains.kotlin.sir.SirModule
|
||||
import org.jetbrains.kotlin.sir.bridge.BridgeRequest
|
||||
import org.jetbrains.kotlin.sir.bridge.createFunctionBodyFromRequest
|
||||
import org.jetbrains.kotlin.sir.visitors.SirVisitorVoid
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.sir.passes.SirPass
|
||||
import org.jetbrains.sir.passes.builder.KotlinSource
|
||||
import org.jetbrains.sir.passes.run
|
||||
@@ -46,15 +39,10 @@ private object BridgeGenerationPass : SirPass<SirElement, Nothing?, List<BridgeR
|
||||
?.callableIdIfNonLocal?.asSingleFqName()
|
||||
?.pathSegments()?.map { it.toString() }
|
||||
?: return
|
||||
val fqNameForBridge = fqName.forBridge
|
||||
|
||||
val bridgeRequest = BridgeRequest(
|
||||
function,
|
||||
fqNameForBridge.joinToString("_"),
|
||||
fqName
|
||||
requests.addIfNotNull(
|
||||
function.patchCallableBodyAndGenerateRequest(fqName)
|
||||
)
|
||||
requests += bridgeRequest
|
||||
function.body = createFunctionBodyFromRequest(bridgeRequest)
|
||||
}
|
||||
|
||||
override fun visitVariable(variable: SirVariable) {
|
||||
@@ -62,22 +50,45 @@ private object BridgeGenerationPass : SirPass<SirElement, Nothing?, List<BridgeR
|
||||
?.callableIdIfNonLocal?.asSingleFqName()
|
||||
?.pathSegments()?.map { it.toString() }
|
||||
?: return
|
||||
val fqNameForBridge = fqName.forBridge
|
||||
|
||||
variable.accessors.forEach {
|
||||
val suffix = it.bridgeSuffix
|
||||
val request = BridgeRequest(
|
||||
it,
|
||||
fqNameForBridge.joinToString("_") + "_$suffix",
|
||||
fqName
|
||||
requests.addIfNotNull(
|
||||
it.patchCallableBodyAndGenerateRequest(fqName)
|
||||
)
|
||||
requests += request
|
||||
it.body = createFunctionBodyFromRequest(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun SirCallable.patchCallableBodyAndGenerateRequest(
|
||||
fqName: List<String>,
|
||||
): BridgeRequest? = when (kind) {
|
||||
SirCallableKind.FUNCTION,
|
||||
SirCallableKind.STATIC_METHOD,
|
||||
-> {
|
||||
val suffix = bridgeSuffix
|
||||
val request = BridgeRequest(
|
||||
this,
|
||||
fqName.forBridge.joinToString("_") + suffix,
|
||||
fqName
|
||||
)
|
||||
body = createFunctionBodyFromRequest(request)
|
||||
request
|
||||
}
|
||||
SirCallableKind.INSTANCE_METHOD,
|
||||
SirCallableKind.CLASS_METHOD,
|
||||
-> {
|
||||
body = SirFunctionBody(listOf("fatalError()"))
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private val SirCallable.bridgeSuffix: String
|
||||
get() = when (this) {
|
||||
is SirAccessor -> "_$bridgeSuffix"
|
||||
else -> ""
|
||||
}
|
||||
|
||||
private val SirAccessor.bridgeSuffix: String
|
||||
get() = when (this) {
|
||||
is SirGetter -> "get"
|
||||
|
||||
+6
-5
@@ -38,11 +38,12 @@ private fun generateBridgeSources(requests: List<BridgeRequest>): BridgeSources
|
||||
val kotlinBridgePrinter = createKotlinBridgePrinter()
|
||||
val cBridgePrinter = createCBridgePrinter()
|
||||
|
||||
requests.forEach { request ->
|
||||
val bridge = generator.generate(request)
|
||||
kotlinBridgePrinter.add(bridge)
|
||||
cBridgePrinter.add(bridge)
|
||||
}
|
||||
requests
|
||||
.map(generator::generate)
|
||||
.forEach {
|
||||
kotlinBridgePrinter.add(it)
|
||||
cBridgePrinter.add(it)
|
||||
}
|
||||
|
||||
val actualKotlinSrc = kotlinBridgePrinter.print()
|
||||
val actualCHeader = cBridgePrinter.print()
|
||||
|
||||
+48
@@ -6,13 +6,61 @@ public enum namespace {
|
||||
public class NAMESPACED_CLASS {
|
||||
}
|
||||
public class Foo {
|
||||
public func foo() -> Swift.Bool {
|
||||
fatalError()
|
||||
}
|
||||
public var my_value: Swift.UInt32 {
|
||||
get {
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
public var my_variable: Swift.Int64 {
|
||||
get {
|
||||
fatalError()
|
||||
}
|
||||
set {
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public class NAMESPACED_CLASS {
|
||||
}
|
||||
public class Foo {
|
||||
public func foo() -> Swift.Bool {
|
||||
fatalError()
|
||||
}
|
||||
public var my_value: Swift.UInt32 {
|
||||
get {
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
public var my_variable: Swift.Int64 {
|
||||
get {
|
||||
fatalError()
|
||||
}
|
||||
set {
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Foo {
|
||||
public func foo() -> Swift.Bool {
|
||||
fatalError()
|
||||
}
|
||||
public var my_value: Swift.UInt32 {
|
||||
get {
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
public var my_variable: Swift.Int64 {
|
||||
get {
|
||||
fatalError()
|
||||
}
|
||||
set {
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+7
@@ -4,4 +4,11 @@ class NAMESPACED_CLASS
|
||||
|
||||
class Foo {
|
||||
class INSIDE_CLASS // this should be ignored currently
|
||||
|
||||
fun foo(): Boolean = TODO()
|
||||
|
||||
val my_value: UInt = 5u
|
||||
|
||||
var my_variable: Long = 5
|
||||
|
||||
}
|
||||
|
||||
+7
@@ -4,4 +4,11 @@ class NAMESPACED_CLASS
|
||||
|
||||
class Foo {
|
||||
class INSIDE_CLASS // this should be ignored currently
|
||||
|
||||
fun foo(): Boolean = TODO()
|
||||
|
||||
val my_value: UInt = 5u
|
||||
|
||||
var my_variable: Long = 5
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
|
||||
class Foo {
|
||||
class INSIDE_CLASS // this should be ignored currently
|
||||
|
||||
fun foo(): Boolean = TODO()
|
||||
|
||||
val my_value: UInt = 5u
|
||||
|
||||
var my_variable: Long = 5
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user