KT-65123: move Swift Export Compiler Plugin into swift-export-standalone module
Merge-request: KT-MR-14031 Merged-by: Artem Olkov <artem.olkov@jetbrains.com>
This commit is contained in:
@@ -9,5 +9,6 @@ tasks.register("sirAllTests") {
|
||||
":native:swift:sir-compiler-bridge:test",
|
||||
":native:swift:sir-passes:test",
|
||||
":native:swift:sir-printer:test",
|
||||
":native:swift:swift-export-standalone:test",
|
||||
)
|
||||
}
|
||||
|
||||
+8
-8
@@ -50,7 +50,7 @@ class SirPackageInflaterTests {
|
||||
|
||||
declarations += buildEnum {
|
||||
name = "com"
|
||||
origin = SirOrigin.Namespace(path = listOf("com"))
|
||||
origin = SirOrigin.Namespace(path = listOf("com"))
|
||||
declarations += listOf(
|
||||
makeFunction("com.foo"),
|
||||
makeFunction("com.bar"),
|
||||
@@ -84,7 +84,7 @@ class SirPackageInflaterTests {
|
||||
buildStruct { name = "Orphan" },
|
||||
buildEnum {
|
||||
name = "com"
|
||||
origin = SirOrigin.Namespace(path = listOf("com"))
|
||||
origin = SirOrigin.Namespace(path = listOf("com"))
|
||||
declarations += listOf(
|
||||
makeFunction("com.foo"),
|
||||
makeFunction("com.bar"),
|
||||
@@ -117,7 +117,7 @@ class SirPackageInflaterTests {
|
||||
|
||||
declarations += buildEnum {
|
||||
name = "com"
|
||||
origin = SirOrigin.Namespace(path = listOf("com"))
|
||||
origin = SirOrigin.Namespace(path = listOf("com"))
|
||||
declarations += listOf(
|
||||
makeFunction("com.foo"),
|
||||
makeFunction("com.baz"),
|
||||
@@ -162,7 +162,7 @@ class SirPackageInflaterTests {
|
||||
makeFunction("orphan"),
|
||||
buildEnum {
|
||||
name = "com"
|
||||
origin = SirOrigin.Namespace(path = listOf("com"))
|
||||
origin = SirOrigin.Namespace(path = listOf("com"))
|
||||
declarations += listOf(
|
||||
makeFunction("com.foo"),
|
||||
makeFunction("com.baz"),
|
||||
@@ -170,20 +170,20 @@ class SirPackageInflaterTests {
|
||||
},
|
||||
buildEnum {
|
||||
name = "org"
|
||||
origin = SirOrigin.Namespace(path = listOf("org"))
|
||||
origin = SirOrigin.Namespace(path = listOf("org"))
|
||||
declarations += listOf(
|
||||
makeFunction("org.bar"),
|
||||
buildEnum {
|
||||
name = "jetbrains"
|
||||
origin = SirOrigin.Namespace(path = listOf("org", "jetbrains"))
|
||||
origin = SirOrigin.Namespace(path = listOf("org", "jetbrains"))
|
||||
declarations += listOf(
|
||||
makeFunction("org.jetbrains.baz"),
|
||||
buildEnum {
|
||||
name = "mascots"
|
||||
origin = SirOrigin.Namespace(path = listOf("org", "jetbrains", "mascots"))
|
||||
origin = SirOrigin.Namespace(path = listOf("org", "jetbrains", "mascots"))
|
||||
declarations += buildEnum {
|
||||
name = "kotlin"
|
||||
origin = SirOrigin.Namespace(path = listOf("org", "jetbrains", "mascots", "kotlin"))
|
||||
origin = SirOrigin.Namespace(path = listOf("org", "jetbrains", "mascots", "kotlin"))
|
||||
declarations += makeFunction("org.jetbrains.mascots.kotlin.kodee")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,10 +67,12 @@ class SirComparator(val options: Set<Options> = emptySet()) : SirVisitor<Boolean
|
||||
}
|
||||
|
||||
private fun SirComparator.areEqual(lhs: List<SirElement>, rhs: List<SirElement>): Boolean {
|
||||
return options.contains(SirComparator.Options.POSITIONAL) &&
|
||||
lhs.size == rhs.size &&
|
||||
lhs.zip(rhs).all { areEqual(it.first, it.second) } ||
|
||||
areEqualNonPositionally(lhs, rhs)
|
||||
return if (options.contains(SirComparator.Options.POSITIONAL)) {
|
||||
lhs.size == rhs.size &&
|
||||
lhs.zip(rhs).all { areEqual(it.first, it.second) }
|
||||
} else {
|
||||
areEqualNonPositionally(lhs, rhs)
|
||||
}
|
||||
}
|
||||
|
||||
private fun SirComparator.areEqual(lhs: SirOrigin, rhs: SirOrigin): Boolean {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Swift Export Runner
|
||||
|
||||
## Description
|
||||
|
||||
This module represents an entry point for the SwiftExport-Frontend functionality. It is implemented as a kotlin library and should be consumed by Build Tooling or IDE.
|
||||
|
||||
### How to generate tests:
|
||||
```bash
|
||||
./gradlew :generators:sir-tests-generator:generateTests
|
||||
```
|
||||
this will generate tests from the input files. The input files can be found and should be placed here: `plugins/swift-export/testData`
|
||||
|
||||
The test expects to find the `.golden.swift`, `.golden.kt` and `.golden.h` files that contain the resulting bridges. The name of the `.golden.*` file should be the same as the name of the corresponding `.kt` file.
|
||||
|
||||
The project for the generator can be found here — `generators/sir-tests-generator/build.gradle.kts`
|
||||
|
||||
### How to run the tests:
|
||||
```bash
|
||||
./gradlew :native:swift:sirAllTests
|
||||
```
|
||||
this command will run all tests for Swift Export.
|
||||
@@ -0,0 +1,52 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
}
|
||||
|
||||
description = "Runner for Swift Export"
|
||||
|
||||
kotlin {
|
||||
explicitApi()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(kotlinStdlib())
|
||||
|
||||
implementation(project(":native:swift:sir"))
|
||||
implementation(project(":native:swift:sir-analysis-api"))
|
||||
implementation(project(":native:swift:sir-compiler-bridge"))
|
||||
implementation(project(":native:swift:sir-passes"))
|
||||
implementation(project(":native:swift:sir-printer"))
|
||||
|
||||
implementation(project(":analysis:analysis-api"))
|
||||
implementation(project(":analysis:analysis-api-standalone"))
|
||||
|
||||
testApi(platform(libs.junit.bom))
|
||||
testRuntimeOnly(libs.junit.jupiter.engine)
|
||||
testImplementation(libs.junit.jupiter.api)
|
||||
|
||||
testRuntimeOnly(projectTests(":analysis:low-level-api-fir"))
|
||||
testRuntimeOnly(projectTests(":analysis:analysis-api-impl-base"))
|
||||
testImplementation(projectTests(":analysis:analysis-api-fir"))
|
||||
testImplementation(projectTests(":analysis:analysis-test-framework"))
|
||||
testImplementation(projectTests(":compiler:tests-common"))
|
||||
testImplementation(projectTests(":compiler:tests-common-new"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" {
|
||||
projectDefault()
|
||||
generatedTestDir()
|
||||
}
|
||||
}
|
||||
|
||||
val testDataDir = projectDir.resolve("testData")
|
||||
|
||||
projectTest(jUnitMode = JUnitMode.JUnit5) {
|
||||
inputs.dir(testDataDir)
|
||||
dependsOn(":dist")
|
||||
workingDir = rootDir
|
||||
useJUnitPlatform { }
|
||||
}
|
||||
|
||||
testsJar()
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.swiftexport.standalone
|
||||
|
||||
import org.jetbrains.kotlin.swiftexport.standalone.SwiftExportConfig.Companion.DEBUG_MODE_ENABLED
|
||||
import org.jetbrains.kotlin.swiftexport.standalone.builders.buildFunctionBridges
|
||||
import org.jetbrains.kotlin.swiftexport.standalone.builders.buildSwiftModule
|
||||
import org.jetbrains.kotlin.swiftexport.standalone.transformation.transformToSwift
|
||||
import org.jetbrains.kotlin.swiftexport.standalone.writer.dumpResultToFiles
|
||||
import java.nio.file.Path
|
||||
|
||||
public data class SwiftExportConfig(
|
||||
val settings: Map<String, String>
|
||||
) {
|
||||
public companion object {
|
||||
public const val DEBUG_MODE_ENABLED: String = "DEBUG_MODE_ENABLED"
|
||||
}
|
||||
}
|
||||
|
||||
public data class SwiftExportInput(
|
||||
val sourceRoot: Path, // todo: we do not support multi-modules currently. see KT-65220
|
||||
val libraries: List<Path> = emptyList(), // todo: not supported currently. see KT-65221
|
||||
)
|
||||
|
||||
public data class SwiftExportOutput(
|
||||
val swiftApi: Path,
|
||||
val kotlinBridges: Path,
|
||||
val cHeaderBridges: Path,
|
||||
)
|
||||
|
||||
/**
|
||||
* A root function for running Swift Export from build tool
|
||||
*/
|
||||
public fun runSwiftExport(
|
||||
input: SwiftExportInput,
|
||||
config: SwiftExportConfig = SwiftExportConfig(emptyMap()),
|
||||
output: SwiftExportOutput,
|
||||
) {
|
||||
val module = buildSwiftModule(input, config.settings.containsKey(DEBUG_MODE_ENABLED))
|
||||
.transformToSwift()
|
||||
val bridgeRequests = module.buildFunctionBridges()
|
||||
module.dumpResultToFiles(bridgeRequests, output)
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.swiftexport.standalone.builders
|
||||
|
||||
import org.jetbrains.kotlin.sir.SirElement
|
||||
import org.jetbrains.kotlin.sir.SirFunction
|
||||
import org.jetbrains.kotlin.sir.SirKotlinOrigin
|
||||
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.sir.passes.SirPass
|
||||
import org.jetbrains.sir.passes.run
|
||||
|
||||
internal fun SirModule.buildFunctionBridges(): List<BridgeRequest> {
|
||||
return BridgeGenerationPass.run(this)
|
||||
}
|
||||
|
||||
private object BridgeGenerationPass : SirPass<SirElement, Nothing?, List<BridgeRequest>> {
|
||||
override fun run(element: SirElement, data: Nothing?): List<BridgeRequest> {
|
||||
val requests = mutableListOf<BridgeRequest>()
|
||||
element.accept(Visitor(requests))
|
||||
return requests.toList()
|
||||
}
|
||||
|
||||
private class Visitor(val requests: MutableList<BridgeRequest>) : SirVisitorVoid() {
|
||||
|
||||
override fun visitElement(element: SirElement) {
|
||||
element.acceptChildren(this)
|
||||
}
|
||||
|
||||
override fun visitFunction(function: SirFunction) {
|
||||
val fqName = (function.origin as? SirKotlinOrigin.Function)?.path
|
||||
?: return
|
||||
val fqNameForBridge = if (fqName.count() == 1) {
|
||||
listOf("__root__", fqName.first()) // todo: should be changed with correct mangling KT-64970
|
||||
} else {
|
||||
fqName
|
||||
}
|
||||
val bridgeRequest = BridgeRequest(
|
||||
function,
|
||||
fqNameForBridge.joinToString("_"),
|
||||
fqName
|
||||
)
|
||||
requests += bridgeRequest
|
||||
function.body = createFunctionBodyFromRequest(bridgeRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.swiftexport.standalone.builders
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenProvider
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.KtAlwaysAccessibleLifetimeTokenProvider
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.buildStandaloneAnalysisAPISession
|
||||
import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtSourceModule
|
||||
import org.jetbrains.kotlin.platform.konan.NativePlatforms
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.sir.SirModule
|
||||
import org.jetbrains.kotlin.sir.analysisapi.SirGenerator
|
||||
import org.jetbrains.kotlin.sir.builder.buildModule
|
||||
import org.jetbrains.kotlin.swiftexport.standalone.SwiftExportInput
|
||||
|
||||
@OptIn(KtAnalysisApiInternals::class)
|
||||
internal fun buildSwiftModule(input: SwiftExportInput, shouldSortInputFiles: Boolean): SirModule {
|
||||
val session = buildStandaloneAnalysisAPISession {
|
||||
registerProjectService(KtLifetimeTokenProvider::class.java, KtAlwaysAccessibleLifetimeTokenProvider())
|
||||
|
||||
buildKtModuleProvider {
|
||||
platform = NativePlatforms.unspecifiedNativePlatform
|
||||
|
||||
addModule(
|
||||
buildKtSourceModule {
|
||||
addSourceRoot(input.sourceRoot)
|
||||
platform = NativePlatforms.unspecifiedNativePlatform
|
||||
moduleName = "main"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val (sourceModule, rawFiles) = session.modulesWithFiles.entries.single()
|
||||
|
||||
var ktFiles = rawFiles.filterIsInstance<KtFile>()
|
||||
|
||||
if (shouldSortInputFiles) {
|
||||
ktFiles = ktFiles.sortedBy { it.name }
|
||||
}
|
||||
|
||||
return buildModule {
|
||||
name = sourceModule.moduleName
|
||||
val sirFactory = SirGenerator()
|
||||
ktFiles.forEach { file ->
|
||||
declarations += sirFactory.build(file)
|
||||
}
|
||||
}.apply {
|
||||
declarations.forEach { it.parent = this }
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.swiftexport.standalone.transformation
|
||||
|
||||
import org.jetbrains.kotlin.sir.SirDeclaration
|
||||
import org.jetbrains.kotlin.sir.SirElement
|
||||
import org.jetbrains.kotlin.sir.SirModule
|
||||
import org.jetbrains.kotlin.sir.builder.buildModule
|
||||
import org.jetbrains.sir.passes.SirInflatePackagesPass
|
||||
import org.jetbrains.sir.passes.SirModulePass
|
||||
import org.jetbrains.sir.passes.SirPass
|
||||
import org.jetbrains.sir.passes.run
|
||||
import org.jetbrains.sir.passes.translation.ForeignIntoSwiftFunctionTranslationPass
|
||||
|
||||
internal fun SirModule.transformToSwift(): SirModule {
|
||||
return SirPassesConfiguration.passes.fold(this) { module, pass ->
|
||||
pass.run(module)
|
||||
}
|
||||
}
|
||||
|
||||
private object SirPassesConfiguration {
|
||||
val passes: List<SirModulePass> = listOf(
|
||||
SirInflatePackagesPass(),
|
||||
WholeModuleTranslationByElementPass(ForeignIntoSwiftFunctionTranslationPass()),
|
||||
)
|
||||
|
||||
class WholeModuleTranslationByElementPass(
|
||||
val pass: SirPass<SirElement, Nothing?, SirDeclaration>
|
||||
) : SirModulePass {
|
||||
override fun run(element: SirModule, data: Nothing?): SirModule {
|
||||
return buildModule {
|
||||
name = element.name
|
||||
element.declarations.forEach {
|
||||
val newDecl = pass.run(it)
|
||||
declarations.add(newDecl)
|
||||
}
|
||||
}.apply {
|
||||
declarations.forEach { it.parent = this }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+66
@@ -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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.swiftexport.standalone.writer
|
||||
|
||||
import org.jetbrains.kotlin.sir.SirModule
|
||||
import org.jetbrains.kotlin.sir.bridge.BridgeRequest
|
||||
import org.jetbrains.kotlin.sir.bridge.createBridgeGenerator
|
||||
import org.jetbrains.kotlin.sir.bridge.createCBridgePrinter
|
||||
import org.jetbrains.kotlin.sir.bridge.createKotlinBridgePrinter
|
||||
import org.jetbrains.kotlin.swiftexport.standalone.SwiftExportOutput
|
||||
import org.jetbrains.sir.printer.SirAsSwiftSourcesPrinter
|
||||
import java.io.File
|
||||
|
||||
|
||||
internal fun SirModule.dumpResultToFiles(requests: List<BridgeRequest>, output: SwiftExportOutput) {
|
||||
val cHeaderFile = output.cHeaderBridges.toFile()
|
||||
val ktBridgeFile = output.kotlinBridges.toFile()
|
||||
val swiftFile = output.swiftApi.toFile()
|
||||
|
||||
val bridges = generateBridgeSources(requests)
|
||||
val swiftSrc = generateSwiftSrc()
|
||||
|
||||
dumpTextAtFile(bridges.ktSrc, ktBridgeFile)
|
||||
dumpTextAtFile(bridges.cSrc, cHeaderFile)
|
||||
dumpTextAtFile(sequenceOf(swiftSrc), swiftFile)
|
||||
}
|
||||
|
||||
private fun SirModule.generateSwiftSrc(): String {
|
||||
return SirAsSwiftSourcesPrinter().print(this)
|
||||
}
|
||||
|
||||
private fun generateBridgeSources(requests: List<BridgeRequest>): BridgeSources {
|
||||
|
||||
val generator = createBridgeGenerator()
|
||||
val kotlinBridgePrinter = createKotlinBridgePrinter()
|
||||
val cBridgePrinter = createCBridgePrinter()
|
||||
|
||||
requests.forEach { request ->
|
||||
val bridge = generator.generate(request)
|
||||
kotlinBridgePrinter.add(bridge)
|
||||
cBridgePrinter.add(bridge)
|
||||
}
|
||||
|
||||
val actualKotlinSrc = kotlinBridgePrinter.print()
|
||||
val actualCHeader = cBridgePrinter.print()
|
||||
|
||||
return BridgeSources(ktSrc = actualKotlinSrc, cSrc = actualCHeader)
|
||||
}
|
||||
|
||||
private fun dumpTextAtFile(text: Sequence<String>, file: File) {
|
||||
if (!file.exists()) {
|
||||
file.parentFile.mkdirs()
|
||||
file.createNewFile()
|
||||
}
|
||||
val writer = file.printWriter()
|
||||
for (t in text) {
|
||||
writer.println(t)
|
||||
}
|
||||
writer.close()
|
||||
}
|
||||
|
||||
|
||||
private data class BridgeSources(val ktSrc: Sequence<String>, val cSrc: Sequence<String>)
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
#include <stdint.h>
|
||||
|
||||
int32_t __root___meaningOfLife();
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import kotlin.native.internal.ExportedBridge
|
||||
|
||||
@ExportedBridge("__root___meaningOfLife")
|
||||
public fun __root___meaningOfLife(): Int {
|
||||
val result = meaningOfLife()
|
||||
return result
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
public func meaningOfLife() -> Swift.Int32 {
|
||||
return __root___meaningOfLife()
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
fun meaningOfLife(): Int = 420
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <stdint.h>
|
||||
|
||||
int32_t namespace1_main_foobar(int32_t param);
|
||||
|
||||
int32_t namespace1_bar();
|
||||
|
||||
int32_t namespace2_foo();
|
||||
|
||||
int32_t __root___foo();
|
||||
@@ -0,0 +1,25 @@
|
||||
import kotlin.native.internal.ExportedBridge
|
||||
|
||||
@ExportedBridge("namespace1_main_foobar")
|
||||
public fun namespace1_main_foobar(param: Int): Int {
|
||||
val result = namespace1.main.foobar(param)
|
||||
return result
|
||||
}
|
||||
|
||||
@ExportedBridge("namespace1_bar")
|
||||
public fun namespace1_bar(): Int {
|
||||
val result = namespace1.bar()
|
||||
return result
|
||||
}
|
||||
|
||||
@ExportedBridge("namespace2_foo")
|
||||
public fun namespace2_foo(): Int {
|
||||
val result = namespace2.foo()
|
||||
return result
|
||||
}
|
||||
|
||||
@ExportedBridge("__root___foo")
|
||||
public fun __root___foo(): Int {
|
||||
val result = foo()
|
||||
return result
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
enum namespace1 {
|
||||
enum main {
|
||||
public static func foobar(
|
||||
param: Swift.Int32
|
||||
) -> Swift.Int32 {
|
||||
return namespace1_main_foobar(param)
|
||||
}
|
||||
}
|
||||
public static func bar() -> Swift.Int32 {
|
||||
return namespace1_bar()
|
||||
}
|
||||
}
|
||||
|
||||
enum namespace2 {
|
||||
public static func foo() -> Swift.Int32 {
|
||||
return namespace2_foo()
|
||||
}
|
||||
}
|
||||
|
||||
public func foo() -> Swift.Int32 {
|
||||
return __root___foo()
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package namespace1
|
||||
|
||||
fun bar(): Int = 123
|
||||
@@ -0,0 +1,3 @@
|
||||
package namespace2
|
||||
|
||||
fun foo(): Int = 321
|
||||
@@ -0,0 +1,5 @@
|
||||
package namespace1.main
|
||||
|
||||
import namespace1.*
|
||||
import namespace2.*
|
||||
fun foobar(param: Int): Int = foo() + bar() + param
|
||||
@@ -0,0 +1 @@
|
||||
fun foo(): Int = 123
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.swiftexport.standalone;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.native.swift.sir.GenerateSirTestsKt}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("native/swift/swift-export-standalone/testData")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class SwiftExportRunnerTest extends AbstractSwiftRunnerTest {
|
||||
@Test
|
||||
public void testAllFilesPresentInTestData() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData"), Pattern.compile("^([^\\.]+)$"), null, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("no_package")
|
||||
public void testNo_package() throws Exception {
|
||||
runTest("native/swift/swift-export-standalone/testData/no_package/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("native/swift/swift-export-standalone/testData/simple/");
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.swiftexport.standalone
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import kotlin.io.path.*
|
||||
|
||||
open class AbstractSwiftRunnerTest : AbstractSwiftRunnerTestBase()
|
||||
|
||||
abstract class AbstractSwiftRunnerTestBase {
|
||||
|
||||
private val tmpdir = FileUtil.createTempDirectory("SwiftExportIntegrationTests", null, false)
|
||||
|
||||
fun runTest(testPathString: String) {
|
||||
val path = Path(testPathString)
|
||||
val expectedFiles = path / "golden_result/"
|
||||
val moduleRoot = path / "input_root/"
|
||||
assert(expectedFiles.isDirectory() && moduleRoot.isDirectory()) { "setup for $path is incorrect" }
|
||||
|
||||
val expectedSwift = expectedFiles / "result.swift"
|
||||
val expectedCHeader = expectedFiles / "result.h"
|
||||
val expectedKotlinBridge = expectedFiles / "result.kt"
|
||||
|
||||
val output = SwiftExportOutput(
|
||||
swiftApi = tmpdir.resolve("result.swift").toPath(),
|
||||
kotlinBridges = tmpdir.resolve("result.kt").toPath(),
|
||||
cHeaderBridges = tmpdir.resolve("result.c").toPath()
|
||||
)
|
||||
|
||||
runSwiftExport(
|
||||
input = SwiftExportInput(
|
||||
sourceRoot = moduleRoot,
|
||||
),
|
||||
output = output,
|
||||
config = SwiftExportConfig(
|
||||
settings = mapOf(
|
||||
SwiftExportConfig.DEBUG_MODE_ENABLED to "true"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(expectedSwift, output.swiftApi.readText())
|
||||
KotlinTestUtils.assertEqualsToFile(expectedCHeader, output.cHeaderBridges.readText())
|
||||
KotlinTestUtils.assertEqualsToFile(expectedKotlinBridge, output.kotlinBridges.readText())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user