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:
@@ -386,7 +386,6 @@
|
|||||||
/plugins/power-assert/ "Kotlin Compiler Core"
|
/plugins/power-assert/ "Kotlin Compiler Core"
|
||||||
/plugins/sam-with-receiver/ "Kotlin Compiler Core"
|
/plugins/sam-with-receiver/ "Kotlin Compiler Core"
|
||||||
/plugins/scripting/ "Kotlin Compiler Core"
|
/plugins/scripting/ "Kotlin Compiler Core"
|
||||||
/plugins/swift-export/ "Kotlin Native"
|
|
||||||
|
|
||||||
/prepare/ "Kotlin Build Infrastructure"
|
/prepare/ "Kotlin Build Infrastructure"
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ sourceSets {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation(projectTests(":native:swift:sir-analysis-api"))
|
implementation(projectTests(":native:swift:sir-analysis-api"))
|
||||||
implementation(projectTests(":native:swift:sir-compiler-bridge"))
|
implementation(projectTests(":native:swift:sir-compiler-bridge"))
|
||||||
implementation(projectTests(":kotlin-swift-export-compiler-plugin"))
|
implementation(projectTests(":native:swift:swift-export-standalone"))
|
||||||
implementation(projectTests(":generators:test-generator"))
|
implementation(projectTests(":generators:test-generator"))
|
||||||
runtimeOnly(projectTests(":analysis:analysis-test-framework"))
|
runtimeOnly(projectTests(":analysis:analysis-test-framework"))
|
||||||
runtimeOnly(libs.junit.jupiter.api)
|
runtimeOnly(libs.junit.jupiter.api)
|
||||||
|
|||||||
+6
-6
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.generators.tests.native.swift.sir
|
|||||||
import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
|
import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
|
||||||
import org.jetbrains.kotlin.sir.analysisapi.AbstractKotlinSirContextTest
|
import org.jetbrains.kotlin.sir.analysisapi.AbstractKotlinSirContextTest
|
||||||
import org.jetbrains.kotlin.sir.bridge.AbstractKotlinSirBridgeTest
|
import org.jetbrains.kotlin.sir.bridge.AbstractKotlinSirBridgeTest
|
||||||
import org.jetbrains.kotlin.swiftexport.AbstractSwiftExportContextTest
|
import org.jetbrains.kotlin.swiftexport.standalone.AbstractSwiftRunnerTest
|
||||||
|
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
@@ -35,13 +35,13 @@ fun main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
testGroup(
|
testGroup(
|
||||||
"plugins/swift-export/tests-gen",
|
"native/swift/swift-export-standalone/tests-gen/",
|
||||||
"plugins/swift-export/testData"
|
"native/swift/swift-export-standalone/testData"
|
||||||
) {
|
) {
|
||||||
testClass<AbstractSwiftExportContextTest>(
|
testClass<AbstractSwiftRunnerTest>(
|
||||||
suiteTestClassName = "SwiftExportCompilerPluginTest"
|
suiteTestClassName = "SwiftExportRunnerTest"
|
||||||
) {
|
) {
|
||||||
model("", excludedPattern = ".*\\.golden\\.kt$", recursive = false)
|
model("", extension = null, recursive = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,5 +9,6 @@ tasks.register("sirAllTests") {
|
|||||||
":native:swift:sir-compiler-bridge:test",
|
":native:swift:sir-compiler-bridge:test",
|
||||||
":native:swift:sir-passes:test",
|
":native:swift:sir-passes:test",
|
||||||
":native:swift:sir-printer:test",
|
":native:swift:sir-printer:test",
|
||||||
|
":native:swift:swift-export-standalone:test",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-8
@@ -50,7 +50,7 @@ class SirPackageInflaterTests {
|
|||||||
|
|
||||||
declarations += buildEnum {
|
declarations += buildEnum {
|
||||||
name = "com"
|
name = "com"
|
||||||
origin = SirOrigin.Namespace(path = listOf("com"))
|
origin = SirOrigin.Namespace(path = listOf("com"))
|
||||||
declarations += listOf(
|
declarations += listOf(
|
||||||
makeFunction("com.foo"),
|
makeFunction("com.foo"),
|
||||||
makeFunction("com.bar"),
|
makeFunction("com.bar"),
|
||||||
@@ -84,7 +84,7 @@ class SirPackageInflaterTests {
|
|||||||
buildStruct { name = "Orphan" },
|
buildStruct { name = "Orphan" },
|
||||||
buildEnum {
|
buildEnum {
|
||||||
name = "com"
|
name = "com"
|
||||||
origin = SirOrigin.Namespace(path = listOf("com"))
|
origin = SirOrigin.Namespace(path = listOf("com"))
|
||||||
declarations += listOf(
|
declarations += listOf(
|
||||||
makeFunction("com.foo"),
|
makeFunction("com.foo"),
|
||||||
makeFunction("com.bar"),
|
makeFunction("com.bar"),
|
||||||
@@ -117,7 +117,7 @@ class SirPackageInflaterTests {
|
|||||||
|
|
||||||
declarations += buildEnum {
|
declarations += buildEnum {
|
||||||
name = "com"
|
name = "com"
|
||||||
origin = SirOrigin.Namespace(path = listOf("com"))
|
origin = SirOrigin.Namespace(path = listOf("com"))
|
||||||
declarations += listOf(
|
declarations += listOf(
|
||||||
makeFunction("com.foo"),
|
makeFunction("com.foo"),
|
||||||
makeFunction("com.baz"),
|
makeFunction("com.baz"),
|
||||||
@@ -162,7 +162,7 @@ class SirPackageInflaterTests {
|
|||||||
makeFunction("orphan"),
|
makeFunction("orphan"),
|
||||||
buildEnum {
|
buildEnum {
|
||||||
name = "com"
|
name = "com"
|
||||||
origin = SirOrigin.Namespace(path = listOf("com"))
|
origin = SirOrigin.Namespace(path = listOf("com"))
|
||||||
declarations += listOf(
|
declarations += listOf(
|
||||||
makeFunction("com.foo"),
|
makeFunction("com.foo"),
|
||||||
makeFunction("com.baz"),
|
makeFunction("com.baz"),
|
||||||
@@ -170,20 +170,20 @@ class SirPackageInflaterTests {
|
|||||||
},
|
},
|
||||||
buildEnum {
|
buildEnum {
|
||||||
name = "org"
|
name = "org"
|
||||||
origin = SirOrigin.Namespace(path = listOf("org"))
|
origin = SirOrigin.Namespace(path = listOf("org"))
|
||||||
declarations += listOf(
|
declarations += listOf(
|
||||||
makeFunction("org.bar"),
|
makeFunction("org.bar"),
|
||||||
buildEnum {
|
buildEnum {
|
||||||
name = "jetbrains"
|
name = "jetbrains"
|
||||||
origin = SirOrigin.Namespace(path = listOf("org", "jetbrains"))
|
origin = SirOrigin.Namespace(path = listOf("org", "jetbrains"))
|
||||||
declarations += listOf(
|
declarations += listOf(
|
||||||
makeFunction("org.jetbrains.baz"),
|
makeFunction("org.jetbrains.baz"),
|
||||||
buildEnum {
|
buildEnum {
|
||||||
name = "mascots"
|
name = "mascots"
|
||||||
origin = SirOrigin.Namespace(path = listOf("org", "jetbrains", "mascots"))
|
origin = SirOrigin.Namespace(path = listOf("org", "jetbrains", "mascots"))
|
||||||
declarations += buildEnum {
|
declarations += buildEnum {
|
||||||
name = "kotlin"
|
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")
|
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 {
|
private fun SirComparator.areEqual(lhs: List<SirElement>, rhs: List<SirElement>): Boolean {
|
||||||
return options.contains(SirComparator.Options.POSITIONAL) &&
|
return if (options.contains(SirComparator.Options.POSITIONAL)) {
|
||||||
lhs.size == rhs.size &&
|
lhs.size == rhs.size &&
|
||||||
lhs.zip(rhs).all { areEqual(it.first, it.second) } ||
|
lhs.zip(rhs).all { areEqual(it.first, it.second) }
|
||||||
areEqualNonPositionally(lhs, rhs)
|
} else {
|
||||||
|
areEqualNonPositionally(lhs, rhs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SirComparator.areEqual(lhs: SirOrigin, rhs: SirOrigin): Boolean {
|
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>)
|
||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
int32_t namespace1_main_foobar(int32_t param);
|
int32_t namespace1_main_foobar(int32_t param);
|
||||||
|
|
||||||
int32_t namespace1_foo();
|
int32_t namespace1_bar();
|
||||||
|
|
||||||
int32_t namespace2_bar();
|
int32_t namespace2_foo();
|
||||||
|
|
||||||
int32_t __root___foo();
|
int32_t __root___foo();
|
||||||
+6
-6
@@ -6,15 +6,15 @@ public fun namespace1_main_foobar(param: Int): Int {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExportedBridge("namespace1_foo")
|
@ExportedBridge("namespace1_bar")
|
||||||
public fun namespace1_foo(): Int {
|
public fun namespace1_bar(): Int {
|
||||||
val result = namespace1.foo()
|
val result = namespace1.bar()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExportedBridge("namespace2_bar")
|
@ExportedBridge("namespace2_foo")
|
||||||
public fun namespace2_bar(): Int {
|
public fun namespace2_foo(): Int {
|
||||||
val result = namespace2.bar()
|
val result = namespace2.foo()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
+4
-4
@@ -6,14 +6,14 @@ enum namespace1 {
|
|||||||
return namespace1_main_foobar(param)
|
return namespace1_main_foobar(param)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static func foo() -> Swift.Int32 {
|
public static func bar() -> Swift.Int32 {
|
||||||
return namespace1_foo()
|
return namespace1_bar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum namespace2 {
|
enum namespace2 {
|
||||||
public static func bar() -> Swift.Int32 {
|
public static func foo() -> Swift.Int32 {
|
||||||
return namespace2_bar()
|
return namespace2_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
|
||||||
+8
-9
@@ -3,11 +3,10 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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;
|
package org.jetbrains.kotlin.swiftexport.standalone;
|
||||||
|
|
||||||
import com.intellij.testFramework.TestDataPath;
|
import com.intellij.testFramework.TestDataPath;
|
||||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||||
import org.jetbrains.kotlin.test.TargetBackend;
|
|
||||||
import org.jetbrains.kotlin.test.TestMetadata;
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -17,23 +16,23 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.native.swift.sir.GenerateSirTestsKt}. DO NOT MODIFY MANUALLY */
|
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.native.swift.sir.GenerateSirTestsKt}. DO NOT MODIFY MANUALLY */
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
@TestMetadata("plugins/swift-export/testData")
|
@TestMetadata("native/swift/swift-export-standalone/testData")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
public class SwiftExportCompilerPluginTest extends AbstractSwiftExportContextTest {
|
public class SwiftExportRunnerTest extends AbstractSwiftRunnerTest {
|
||||||
@Test
|
@Test
|
||||||
public void testAllFilesPresentInTestData() throws Exception {
|
public void testAllFilesPresentInTestData() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/swift-export/testData"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile(".*\\.golden\\.kt$"), TargetBackend.JVM, false);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData"), Pattern.compile("^([^\\.]+)$"), null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("no_package.kt")
|
@TestMetadata("no_package")
|
||||||
public void testNo_package() throws Exception {
|
public void testNo_package() throws Exception {
|
||||||
runTest("plugins/swift-export/testData/no_package.kt");
|
runTest("native/swift/swift-export-standalone/testData/no_package/");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple")
|
||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
runTest("plugins/swift-export/testData/simple.kt");
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
# Swift Export Compiler Plugin
|
|
||||||
|
|
||||||
## Description
|
|
||||||
|
|
||||||
This module represents an entry point for the SwiftExport-Frontend functionality. It is implemented as a compiler plugin, without a direct CLI interface.
|
|
||||||
|
|
||||||
## Usage Guide
|
|
||||||
|
|
||||||
### How to build
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew kotlin-swift-export-compiler-plugin:build
|
|
||||||
```
|
|
||||||
|
|
||||||
This will produce the resulting jar (with all dependency embedded) at `%PATH_TO_KOTLIN_REPO%/plugins/swift-export/build/libs/kotlin-swift-export-compiler-plugin-%VERSION%.jar`
|
|
||||||
|
|
||||||
### Example usage
|
|
||||||
|
|
||||||
Given that:
|
|
||||||
1. there is a `kotlinc` installed at `$PATH`
|
|
||||||
2. sources are located in the `app.kt` file
|
|
||||||
3. the `$PLUGIN_PATH` variable contains the path to the jar received from the ["How to build"](#How-to-build) section
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kotlinc -language-version 2.0 app.kt -Xplugin=$PLUGIN_PATH -P plugin:org.jetbrains.kotlin.swiftexport:output_dir="~/my_awesome_directory/"
|
|
||||||
```
|
|
||||||
|
|
||||||
This will produce the following file tree:
|
|
||||||
```
|
|
||||||
~/my_awesome_directory/
|
|
||||||
|_result.swift
|
|
||||||
|_result.kt
|
|
||||||
|_result.h
|
|
||||||
```
|
|
||||||
|
|
||||||
`result.kt` - contains the kotlin bridge for the resulting module. It should be compiled against the `.klib` produced by kotlinc-native in order to receive the final binary.
|
|
||||||
`result.h` - contains C-header for final binary. The `result.swift` uses this header to talk to this compiled binary.
|
|
||||||
|
|
||||||
`result.swift` - contains the resulting Swift API for the compiled Kotlin/Native library.
|
|
||||||
|
|
||||||
### Supported Options
|
|
||||||
|
|
||||||
#### Output Directory
|
|
||||||
|
|
||||||
`output_dir` — Required parameter. Determines where the resulting artifacts will be placed.
|
|
||||||
|
|
||||||
#### Named
|
|
||||||
|
|
||||||
`named` — Optional parameter. Determines the names of the resulting files. By default — `result`.
|
|
||||||
|
|
||||||
## Dev guide
|
|
||||||
|
|
||||||
### 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 :kotlin-swift-export-compiler-plugin:test
|
|
||||||
```
|
|
||||||
OR just open `SwiftExportCompilerPluginTest` in IDEA and start them from gutter.
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
description = "Swift Export Compiler Plugin"
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
kotlin("jvm")
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
embedded(project(":kotlin-swift-export-compiler-plugin.backend")) { isTransitive = false }
|
|
||||||
embedded(project(":kotlin-swift-export-compiler-plugin.cli")) { isTransitive = false }
|
|
||||||
|
|
||||||
embedded(project(":native:swift:sir")) { isTransitive = false }
|
|
||||||
embedded(project(":native:swift:sir-analysis-api")) { isTransitive = false }
|
|
||||||
embedded(project(":native:swift:sir-compiler-bridge")) { isTransitive = false }
|
|
||||||
embedded(project(":native:swift:sir-passes")) { isTransitive = false }
|
|
||||||
embedded(project(":native:swift:sir-printer")) { isTransitive = false }
|
|
||||||
|
|
||||||
testApi(project(":kotlin-swift-export-compiler-plugin.cli"))
|
|
||||||
|
|
||||||
testApi(platform(libs.junit.bom))
|
|
||||||
testImplementation(libs.junit.jupiter.api)
|
|
||||||
testRuntimeOnly(libs.junit.jupiter.engine)
|
|
||||||
|
|
||||||
testImplementation(projectTests(":compiler:tests-common"))
|
|
||||||
testImplementation(projectTests(":compiler:tests-common-new"))
|
|
||||||
|
|
||||||
|
|
||||||
testApi(intellijCore())
|
|
||||||
}
|
|
||||||
|
|
||||||
optInToExperimentalCompilerApi()
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
"main" { none() }
|
|
||||||
"test" {
|
|
||||||
projectDefault()
|
|
||||||
generatedTestDir()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
optInToExperimentalCompilerApi()
|
|
||||||
|
|
||||||
if (project.kotlinBuildProperties.isSwiftExportPluginPublishingEnabled) {
|
|
||||||
// todo: is you are removing this check - don't forget to run tests in repo/artifacts-tests/src/test/kotlin/org/jetbrains/kotlin/code/ArtifactsTest.kt
|
|
||||||
publish()
|
|
||||||
}
|
|
||||||
|
|
||||||
runtimeJar()
|
|
||||||
sourcesJar()
|
|
||||||
javadocJar()
|
|
||||||
testsJar()
|
|
||||||
|
|
||||||
val testDataDir = projectDir.resolve("testData")
|
|
||||||
|
|
||||||
projectTest(parallel = true, jUnitMode = JUnitMode.JUnit5) {
|
|
||||||
workingDir = rootDir
|
|
||||||
dependsOn(":dist")
|
|
||||||
inputs.dir(testDataDir)
|
|
||||||
useJUnitPlatform()
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
description = "Swift Compiler Plugin (Backend)"
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
kotlin("jvm")
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly(project(":compiler:backend"))
|
|
||||||
compileOnly(project(":compiler:ir.backend.common"))
|
|
||||||
compileOnly(intellijCore())
|
|
||||||
|
|
||||||
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"))
|
|
||||||
|
|
||||||
compileOnly(commonDependency("org.jetbrains.intellij.deps:asm-all"))
|
|
||||||
implementation(kotlinStdlib())
|
|
||||||
}
|
|
||||||
|
|
||||||
optInToUnsafeDuringIrConstructionAPI()
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
"main" { projectDefault() }
|
|
||||||
"test" { none() }
|
|
||||||
}
|
|
||||||
|
|
||||||
runtimeJar()
|
|
||||||
sourcesJar()
|
|
||||||
javadocJar()
|
|
||||||
-184
@@ -1,184 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2023 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
|
|
||||||
|
|
||||||
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.config.CompilerConfiguration
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirAnalysisHandlerExtension
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
|
||||||
import org.jetbrains.kotlin.sir.*
|
|
||||||
import org.jetbrains.kotlin.sir.analysisapi.SirGenerator
|
|
||||||
import org.jetbrains.kotlin.sir.bridge.*
|
|
||||||
import org.jetbrains.kotlin.sir.builder.buildModule
|
|
||||||
import org.jetbrains.kotlin.sir.visitors.SirVisitorVoid
|
|
||||||
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
|
|
||||||
import org.jetbrains.sir.printer.SirAsSwiftSourcesPrinter
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class SwiftExportExtension(
|
|
||||||
private val destination: File,
|
|
||||||
private val outputFileName: String,
|
|
||||||
) : FirAnalysisHandlerExtension() {
|
|
||||||
override fun isApplicable(configuration: CompilerConfiguration): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun doAnalysis(configuration: CompilerConfiguration): Boolean {
|
|
||||||
val module = buildSwiftModule(configuration)
|
|
||||||
.transformToSwift()
|
|
||||||
val bridgeRequests = module.createFunctionBridges()
|
|
||||||
module.dumpResultToFiles(bridgeRequests)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun SirModule.createFunctionBridges(): List<BridgeRequest> {
|
|
||||||
return BridgeGenerationPass.run(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(KtAnalysisApiInternals::class)
|
|
||||||
private fun buildSwiftModule(configuration: CompilerConfiguration): SirModule {
|
|
||||||
val standaloneAnalysisAPISession =
|
|
||||||
buildStandaloneAnalysisAPISession(classLoader = SwiftExportExtension::class.java.classLoader) {
|
|
||||||
@Suppress("DEPRECATION") // TODO: KT-61319 Kapt: remove usages of deprecated buildKtModuleProviderByCompilerConfiguration
|
|
||||||
buildKtModuleProviderByCompilerConfiguration(configuration)
|
|
||||||
|
|
||||||
registerProjectService(KtLifetimeTokenProvider::class.java, KtAlwaysAccessibleLifetimeTokenProvider())
|
|
||||||
}
|
|
||||||
|
|
||||||
val (sourceModule, rawFiles) = standaloneAnalysisAPISession.modulesWithFiles.entries.single()
|
|
||||||
|
|
||||||
val ktFiles = rawFiles.filterIsInstance<KtFile>()
|
|
||||||
|
|
||||||
return buildModule {
|
|
||||||
name = sourceModule.moduleName
|
|
||||||
val sirFactory = SirGenerator()
|
|
||||||
ktFiles.forEach { file ->
|
|
||||||
declarations += sirFactory.build(file)
|
|
||||||
}
|
|
||||||
}.apply {
|
|
||||||
declarations.forEach { it.parent = this }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun SirModule.transformToSwift(): SirModule {
|
|
||||||
return SirPassesConfiguration.passes.fold(this) { module, pass ->
|
|
||||||
pass.run(module)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun SirModule.dumpResultToFiles(requests: List<BridgeRequest>) {
|
|
||||||
val destinationPath = destination.absolutePath
|
|
||||||
|
|
||||||
val cHeaderFile = File("${destinationPath}/${outputFileName}.h")
|
|
||||||
val ktBridgeFile = File("${destinationPath}/${outputFileName}.kt")
|
|
||||||
val swiftFile = File("${destinationPath}/${outputFileName}.swift")
|
|
||||||
|
|
||||||
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>)
|
|
||||||
|
|
||||||
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 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2023 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
|
|
||||||
|
|
||||||
object SwiftExportPluginNames {
|
|
||||||
const val PLUGIN_ID = "org.jetbrains.kotlin.swiftexport"
|
|
||||||
const val OUTPUT_DIR_KEY = "output_dir"
|
|
||||||
const val RESULT_NAME_KEY = "named"
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
description = "Swift Compiler Plugin (CLI)"
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
kotlin("jvm")
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation(project(":kotlin-swift-export-compiler-plugin.backend"))
|
|
||||||
|
|
||||||
compileOnly(project(":compiler:plugin-api"))
|
|
||||||
compileOnly(project(":compiler:fir:entrypoint"))
|
|
||||||
|
|
||||||
embedded(project(":analysis:analysis-api-standalone")) { isTransitive = false }
|
|
||||||
embedded(project(":analysis:analysis-api")) { isTransitive = false }
|
|
||||||
embedded(project(":analysis:analysis-api-fir")) { isTransitive = false }
|
|
||||||
embedded(project(":analysis:analysis-api-impl-base")) { isTransitive = false }
|
|
||||||
embedded(project(":analysis:analysis-api-impl-barebone")) { isTransitive = false }
|
|
||||||
embedded(project(":analysis:analysis-api-standalone:analysis-api-standalone-base")) { isTransitive = false }
|
|
||||||
embedded(project(":analysis:analysis-api-standalone:analysis-api-fir-standalone-base")) { isTransitive = false }
|
|
||||||
embedded(project(":analysis:analysis-internal-utils")) { isTransitive = false }
|
|
||||||
embedded(project(":analysis:low-level-api-fir")) { isTransitive = false }
|
|
||||||
embedded(project(":analysis:symbol-light-classes")) { isTransitive = false }
|
|
||||||
}
|
|
||||||
|
|
||||||
optInToExperimentalCompilerApi()
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
"main" { projectDefault() }
|
|
||||||
"test" { none() }
|
|
||||||
}
|
|
||||||
|
|
||||||
runtimeJar()
|
|
||||||
sourcesJar()
|
|
||||||
javadocJar()
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
org.jetbrains.kotlin.swiftexport.SwiftExportCommandLineProcessor
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
org.jetbrains.kotlin.swiftexport.SwiftExportComponentRegistrar
|
|
||||||
-68
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2023 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
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.compiler.plugin.*
|
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
|
||||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirAnalysisHandlerExtension
|
|
||||||
import org.jetbrains.kotlin.swiftexport.SwiftExportPluginNames.OUTPUT_DIR_KEY
|
|
||||||
import org.jetbrains.kotlin.swiftexport.SwiftExportPluginNames.PLUGIN_ID
|
|
||||||
import org.jetbrains.kotlin.swiftexport.SwiftExportPluginNames.RESULT_NAME_KEY
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
object SwiftExportConfigurationKeys {
|
|
||||||
val OUTPUT_DIR: CompilerConfigurationKey<String> = CompilerConfigurationKey.create(
|
|
||||||
"Destination directory for swift-export resulted files"
|
|
||||||
)
|
|
||||||
val RESULT_NAME: CompilerConfigurationKey<String> = CompilerConfigurationKey.create(
|
|
||||||
"Filenames for resulted files. There will be 3 files - %RESULT_NAME%.swift, %RESULT_NAME%.h and %RESULT_NAME%.kt."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
class SwiftExportCommandLineProcessor : CommandLineProcessor {
|
|
||||||
companion object {
|
|
||||||
val OUTPUT_DIR = CliOption(
|
|
||||||
OUTPUT_DIR_KEY, "output destination",
|
|
||||||
"Destination directory for swift-export resulted files",
|
|
||||||
required = true, allowMultipleOccurrences = false
|
|
||||||
)
|
|
||||||
val RESULT_NAME = CliOption(
|
|
||||||
RESULT_NAME_KEY, "Filenames for resulted files",
|
|
||||||
"Filenames for resulted files. By default - \"result\"",
|
|
||||||
required = false, allowMultipleOccurrences = false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val pluginId = PLUGIN_ID
|
|
||||||
override val pluginOptions = listOf(
|
|
||||||
OUTPUT_DIR, RESULT_NAME
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun processOption(option: AbstractCliOption, value: String, configuration: CompilerConfiguration) = when (option) {
|
|
||||||
OUTPUT_DIR -> configuration.put(SwiftExportConfigurationKeys.OUTPUT_DIR, value)
|
|
||||||
RESULT_NAME -> configuration.put(SwiftExportConfigurationKeys.RESULT_NAME, value)
|
|
||||||
else -> throw CliOptionProcessingException("Unknown option: ${option.optionName}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SwiftExportComponentRegistrar : CompilerPluginRegistrar() {
|
|
||||||
override val supportsK2: Boolean
|
|
||||||
get() = true
|
|
||||||
|
|
||||||
override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) {
|
|
||||||
val dir = File(
|
|
||||||
configuration.get(SwiftExportConfigurationKeys.OUTPUT_DIR)
|
|
||||||
?: throw IllegalArgumentException("output_dir is a required argument for org.jetbrains.kotlin.swiftexport")
|
|
||||||
)
|
|
||||||
|
|
||||||
val named = configuration.get(SwiftExportConfigurationKeys.RESULT_NAME)
|
|
||||||
?: "result"
|
|
||||||
FirAnalysisHandlerExtension.registerExtension(
|
|
||||||
SwiftExportExtension(dir, named)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id("org.jetbrains.kotlin.jvm")
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
embedded(project(":kotlin-swift-export-compiler-plugin")) { isTransitive = false }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project.kotlinBuildProperties.isSwiftExportPluginPublishingEnabled) {
|
|
||||||
// todo: is you are removing this check - don't forget to run tests in repo/artifacts-tests/src/test/kotlin/org/jetbrains/kotlin/code/ArtifactsTest.kt
|
|
||||||
publish {
|
|
||||||
artifactId = "kotlin-swift-export-compiler-plugin-embeddable"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
runtimeJar(rewriteDefaultJarDepsToShadedCompiler())
|
|
||||||
sourcesJarWithSourcesFromEmbedded(
|
|
||||||
project(":kotlin-swift-export-compiler-plugin").tasks.named<Jar>("sourcesJar")
|
|
||||||
)
|
|
||||||
javadocJarWithJavadocFromEmbedded(
|
|
||||||
project(":kotlin-swift-export-compiler-plugin").tasks.named<Jar>("javadocJar")
|
|
||||||
)
|
|
||||||
-111
@@ -1,111 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2023 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
|
|
||||||
|
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
|
||||||
import org.jetbrains.kotlin.cli.common.CLITool
|
|
||||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
|
||||||
import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
|
|
||||||
import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
|
||||||
import org.jetbrains.kotlin.test.CompilerTestUtil
|
|
||||||
import org.jetbrains.kotlin.test.model.*
|
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
|
||||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
|
||||||
import org.jetbrains.kotlin.test.services.getKtFilesForSourceFiles
|
|
||||||
import org.jetbrains.kotlin.test.services.sourceFileProvider
|
|
||||||
import java.io.File
|
|
||||||
import java.util.zip.ZipEntry
|
|
||||||
import java.util.zip.ZipOutputStream
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
import kotlin.test.assertEquals
|
|
||||||
|
|
||||||
internal class JvmCompilerWithSwiftExportPluginFacade(
|
|
||||||
private val testServices: TestServices,
|
|
||||||
) : AbstractTestFacade<ResultingArtifact.Source, SwiftExportArtifact>() {
|
|
||||||
override val inputKind: TestArtifactKind<ResultingArtifact.Source>
|
|
||||||
get() = SourcesKind
|
|
||||||
override val outputKind: TestArtifactKind<SwiftExportArtifact>
|
|
||||||
get() = SwiftExportArtifact.Kind
|
|
||||||
|
|
||||||
private val tmpDir = FileUtil.createTempDirectory("SwiftExportIntegrationTests", null, false)
|
|
||||||
|
|
||||||
override fun transform(module: TestModule, inputArtifact: ResultingArtifact.Source): SwiftExportArtifact {
|
|
||||||
val configurationProvider = testServices.compilerConfigurationProvider
|
|
||||||
val project = configurationProvider.getProject(module)
|
|
||||||
val ktFiles = testServices.sourceFileProvider.getKtFilesForSourceFiles(module.files, project, findViaVfs = true).values.toList()
|
|
||||||
|
|
||||||
val outputDirPath = tmpDir.absolutePath + "/" + "swift_export_output"
|
|
||||||
val outputDir = File(outputDirPath)
|
|
||||||
outputDir.mkdirs()
|
|
||||||
|
|
||||||
runTest(
|
|
||||||
K2JVMCompiler(),
|
|
||||||
ktFiles,
|
|
||||||
outputDir
|
|
||||||
)
|
|
||||||
|
|
||||||
return SwiftExportArtifact(
|
|
||||||
File(outputDir.absolutePath + "/result.swift"),
|
|
||||||
File(outputDir.absolutePath + "/result.h"),
|
|
||||||
File(outputDir.absolutePath + "/result.kt"),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun runTest(
|
|
||||||
compiler: CLITool<*>,
|
|
||||||
src: List<KtFile>,
|
|
||||||
outputDir: File,
|
|
||||||
) {
|
|
||||||
val sources = src.map {
|
|
||||||
tmpDir.resolve(it.name).apply {
|
|
||||||
writeText(it.text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val plugin = writePlugin(
|
|
||||||
SwiftExportCommandLineProcessor::class,
|
|
||||||
SwiftExportComponentRegistrar::class,
|
|
||||||
)
|
|
||||||
val args = listOf(
|
|
||||||
"-Xplugin=$plugin",
|
|
||||||
"-P", "plugin:org.jetbrains.kotlin.swiftexport:output_dir=${outputDir}"
|
|
||||||
) + sources.map { it.absolutePath }
|
|
||||||
|
|
||||||
val outputPath = listOf(
|
|
||||||
"-language-version", "2.0",
|
|
||||||
"-d", tmpDir.resolve("out").absolutePath
|
|
||||||
)
|
|
||||||
|
|
||||||
val (output, exitCode) = CompilerTestUtil.executeCompiler(
|
|
||||||
compiler,
|
|
||||||
args + outputPath
|
|
||||||
)
|
|
||||||
assertEquals(ExitCode.OK, exitCode, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun writePlugin(
|
|
||||||
cliProcessor: KClass<out CommandLineProcessor>,
|
|
||||||
registrarKClass: KClass<out CompilerPluginRegistrar>,
|
|
||||||
): String {
|
|
||||||
val jarFile = tmpDir.resolve("plugin.jar")
|
|
||||||
ZipOutputStream(jarFile.outputStream()).use {
|
|
||||||
val entryRegistry = ZipEntry("META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar")
|
|
||||||
it.putNextEntry(entryRegistry)
|
|
||||||
it.write(registrarKClass.java.name.toByteArray())
|
|
||||||
|
|
||||||
val entryCLI = ZipEntry("META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor")
|
|
||||||
it.putNextEntry(entryCLI)
|
|
||||||
it.write(cliProcessor.java.name.toByteArray())
|
|
||||||
}
|
|
||||||
return jarFile.absolutePath
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun shouldRunAnalysis(module: TestModule): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2023 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
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
|
||||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
|
||||||
import org.jetbrains.kotlin.test.model.*
|
|
||||||
import org.jetbrains.kotlin.test.runners.*
|
|
||||||
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
|
|
||||||
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
|
|
||||||
|
|
||||||
open class AbstractSwiftExportContextTest : AbstractSwiftExportContextTestBase(TargetBackend.JVM) {
|
|
||||||
override fun configure(builder: TestConfigurationBuilder) {
|
|
||||||
super.configure(builder)
|
|
||||||
builder.apply {
|
|
||||||
globalDefaults {
|
|
||||||
targetBackend = TargetBackend.JVM
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class AbstractSwiftExportContextTestBase(
|
|
||||||
targetBackend: TargetBackend
|
|
||||||
) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) {
|
|
||||||
|
|
||||||
override fun TestConfigurationBuilder.configuration() {
|
|
||||||
globalDefaults {
|
|
||||||
frontend = FrontendKinds.FIR
|
|
||||||
targetPlatform = JvmPlatforms.defaultJvmPlatform
|
|
||||||
dependencyKind = DependencyKind.Binary
|
|
||||||
}
|
|
||||||
|
|
||||||
useConfigurators(
|
|
||||||
::CommonEnvironmentConfigurator,
|
|
||||||
::JvmEnvironmentConfigurator,
|
|
||||||
)
|
|
||||||
|
|
||||||
facadeStep(::JvmCompilerWithSwiftExportPluginFacade)
|
|
||||||
|
|
||||||
handlersStep(SwiftExportArtifact.Kind) {
|
|
||||||
useHandlers(::SirExportHandler)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2023 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
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.test.model.AnalysisHandler
|
|
||||||
import org.jetbrains.kotlin.test.model.TestArtifactKind
|
|
||||||
import org.jetbrains.kotlin.test.model.TestModule
|
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
|
||||||
import org.jetbrains.kotlin.test.services.assertions
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
internal class SirExportHandler(testServices: TestServices) : AnalysisHandler<SwiftExportArtifact>(
|
|
||||||
testServices,
|
|
||||||
failureDisablesNextSteps = true,
|
|
||||||
doNotRunIfThereWerePreviousFailures = true
|
|
||||||
) {
|
|
||||||
override val artifactKind: TestArtifactKind<SwiftExportArtifact>
|
|
||||||
get() = SwiftExportArtifact.Kind
|
|
||||||
|
|
||||||
override fun processModule(module: TestModule, info: SwiftExportArtifact) {
|
|
||||||
val originalFile = module.files.first().originalFile
|
|
||||||
val originalFileName = originalFile.absolutePath.removeSuffix(".kt")
|
|
||||||
|
|
||||||
val expectedSwift = File("${originalFileName}.golden.swift")
|
|
||||||
val expectedCHeader = File("${originalFileName}.golden.h")
|
|
||||||
val expectedKotlinBridge = File("${originalFileName}.golden.kt")
|
|
||||||
|
|
||||||
testServices.assertions.assertEqualsToFile(expectedSwift, info.swift.readText())
|
|
||||||
testServices.assertions.assertEqualsToFile(expectedCHeader, info.cHeader.readText())
|
|
||||||
testServices.assertions.assertEqualsToFile(expectedKotlinBridge, info.ktBridge.readText())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2023 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
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.test.model.BinaryKind
|
|
||||||
import org.jetbrains.kotlin.test.model.ResultingArtifact
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
internal data class SwiftExportArtifact(
|
|
||||||
val swift: File,
|
|
||||||
val cHeader: File,
|
|
||||||
val ktBridge: File,
|
|
||||||
) : ResultingArtifact.Binary<SwiftExportArtifact>() {
|
|
||||||
object Kind : BinaryKind<SwiftExportArtifact>("SwiftExportArtifact")
|
|
||||||
|
|
||||||
override val kind: BinaryKind<SwiftExportArtifact>
|
|
||||||
get() = Kind
|
|
||||||
}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
// WITH_STDLIB
|
|
||||||
|
|
||||||
// FILE: no_package.kt
|
|
||||||
fun foo(): Int = 123
|
|
||||||
|
|
||||||
// FILE: foo.kt
|
|
||||||
package namespace1
|
|
||||||
fun foo(): Int = 123
|
|
||||||
|
|
||||||
// FILE: bar.kt
|
|
||||||
package namespace2
|
|
||||||
fun bar(): Int = 321
|
|
||||||
|
|
||||||
// FILE: main.kt
|
|
||||||
package namespace1.main
|
|
||||||
|
|
||||||
import namespace1
|
|
||||||
import namespace2
|
|
||||||
fun foobar(param: Int): Int = foo() + bar() + param
|
|
||||||
+1
-10
@@ -154,11 +154,6 @@ include ":kotlin-noarg-compiler-plugin",
|
|||||||
":kotlin-noarg-compiler-plugin.backend",
|
":kotlin-noarg-compiler-plugin.backend",
|
||||||
":kotlin-noarg-compiler-plugin.cli"
|
":kotlin-noarg-compiler-plugin.cli"
|
||||||
|
|
||||||
include ":kotlin-swift-export-compiler-plugin",
|
|
||||||
":kotlin-swift-export-compiler-plugin.embeddable",
|
|
||||||
":kotlin-swift-export-compiler-plugin.backend",
|
|
||||||
":kotlin-swift-export-compiler-plugin.cli"
|
|
||||||
|
|
||||||
include ":kotlin-sam-with-receiver-compiler-plugin",
|
include ":kotlin-sam-with-receiver-compiler-plugin",
|
||||||
":kotlin-sam-with-receiver-compiler-plugin.embeddable",
|
":kotlin-sam-with-receiver-compiler-plugin.embeddable",
|
||||||
":kotlin-sam-with-receiver-compiler-plugin.common",
|
":kotlin-sam-with-receiver-compiler-plugin.common",
|
||||||
@@ -423,6 +418,7 @@ include ":native:swift:sir",
|
|||||||
":native:swift:sir-printer",
|
":native:swift:sir-printer",
|
||||||
":native:swift:sir-analysis-api",
|
":native:swift:sir-analysis-api",
|
||||||
":native:swift:sir-compiler-bridge",
|
":native:swift:sir-compiler-bridge",
|
||||||
|
":native:swift:swift-export-standalone",
|
||||||
":generators:sir-tests-generator"
|
":generators:sir-tests-generator"
|
||||||
|
|
||||||
void intellij(String imlPath) {
|
void intellij(String imlPath) {
|
||||||
@@ -738,11 +734,6 @@ project(':kotlin-noarg-compiler-plugin.k2').projectDir = "$rootDir/plugins/noarg
|
|||||||
project(':kotlin-noarg-compiler-plugin.backend').projectDir = "$rootDir/plugins/noarg/noarg.backend" as File
|
project(':kotlin-noarg-compiler-plugin.backend').projectDir = "$rootDir/plugins/noarg/noarg.backend" as File
|
||||||
project(':kotlin-noarg-compiler-plugin.cli').projectDir = "$rootDir/plugins/noarg/noarg.cli" as File
|
project(':kotlin-noarg-compiler-plugin.cli').projectDir = "$rootDir/plugins/noarg/noarg.cli" as File
|
||||||
|
|
||||||
project(':kotlin-swift-export-compiler-plugin').projectDir = "$rootDir/plugins/swift-export" as File
|
|
||||||
project(':kotlin-swift-export-compiler-plugin.embeddable').projectDir = "$rootDir/plugins/swift-export/swift-export.embeddable" as File
|
|
||||||
project(':kotlin-swift-export-compiler-plugin.backend').projectDir = "$rootDir/plugins/swift-export/swift-export.backend" as File
|
|
||||||
project(':kotlin-swift-export-compiler-plugin.cli').projectDir = "$rootDir/plugins/swift-export/swift-export.cli" as File
|
|
||||||
|
|
||||||
project(':kotlin-sam-with-receiver-compiler-plugin').projectDir = "$rootDir/plugins/sam-with-receiver" as File
|
project(':kotlin-sam-with-receiver-compiler-plugin').projectDir = "$rootDir/plugins/sam-with-receiver" as File
|
||||||
project(':kotlin-sam-with-receiver-compiler-plugin.embeddable').projectDir = "$rootDir/plugins/sam-with-receiver/sam-with-receiver.embeddable" as File
|
project(':kotlin-sam-with-receiver-compiler-plugin.embeddable').projectDir = "$rootDir/plugins/sam-with-receiver/sam-with-receiver.embeddable" as File
|
||||||
project(':kotlin-sam-with-receiver-compiler-plugin.common').projectDir = "$rootDir/plugins/sam-with-receiver/sam-with-receiver.common" as File
|
project(':kotlin-sam-with-receiver-compiler-plugin.common').projectDir = "$rootDir/plugins/sam-with-receiver/sam-with-receiver.common" as File
|
||||||
|
|||||||
Reference in New Issue
Block a user