Remove KotlinSirOrigin hierarchy in favour of direct AA usage #KT-65335 Fixed

Merge-request: KT-MR-14229
Merged-by: Artem Olkov <artem.olkov@jetbrains.com>
This commit is contained in:
Artem Olkov
2024-02-09 18:34:52 +00:00
committed by Space Team
parent c2e0c8b2e9
commit b6c805bbb6
94 changed files with 548 additions and 1912 deletions
@@ -7,7 +7,6 @@ sourceSets {
} }
dependencies { dependencies {
implementation(projectTests(":native:swift:sir-analysis-api"))
implementation(projectTests(":native:swift:sir-compiler-bridge")) implementation(projectTests(":native:swift:sir-compiler-bridge"))
implementation(projectTests(":native:swift:swift-export-standalone")) implementation(projectTests(":native:swift:swift-export-standalone"))
implementation(projectTests(":generators:test-generator")) implementation(projectTests(":generators:test-generator"))
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.generators.tests.native.swift.sir 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.bridge.AbstractKotlinSirBridgeTest import org.jetbrains.kotlin.sir.bridge.AbstractKotlinSirBridgeTest
import org.jetbrains.kotlin.swiftexport.standalone.AbstractSwiftRunnerTest import org.jetbrains.kotlin.swiftexport.standalone.AbstractSwiftRunnerTest
@@ -14,16 +13,6 @@ import org.jetbrains.kotlin.swiftexport.standalone.AbstractSwiftRunnerTest
fun main() { fun main() {
System.setProperty("java.awt.headless", "true") System.setProperty("java.awt.headless", "true")
generateTestGroupSuiteWithJUnit5 { generateTestGroupSuiteWithJUnit5 {
testGroup(
"native/swift/sir-analysis-api/tests-gen/",
"native/swift/sir-analysis-api/testData"
) {
testClass<AbstractKotlinSirContextTest>(
suiteTestClassName = "SirAnalysisGeneratedTests"
) {
model("", recursive = false)
}
}
testGroup( testGroup(
"native/swift/sir-compiler-bridge/tests-gen/", "native/swift/sir-compiler-bridge/tests-gen/",
"native/swift/sir-compiler-bridge/testData" "native/swift/sir-compiler-bridge/testData"
@@ -24,6 +24,78 @@ public class TypeCheckSwiftExportGoldenData extends SwiftTypeCheckBaseTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData"), Pattern.compile("^(.+)\\.swift$"), null, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData"), Pattern.compile("^(.+)\\.swift$"), null, true);
} }
@Nested
@TestMetadata("native/swift/swift-export-standalone/testData/documentation")
@TestDataPath("$PROJECT_ROOT")
public class Documentation {
@Test
public void testAllFilesPresentInDocumentation() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/documentation"), Pattern.compile("^(.+)\\.swift$"), null, true);
}
@Nested
@TestMetadata("native/swift/swift-export-standalone/testData/documentation/golden_result")
@TestDataPath("$PROJECT_ROOT")
public class Golden_result {
@Test
public void testAllFilesPresentInGolden_result() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/documentation/golden_result"), Pattern.compile("^(.+)\\.swift$"), null, true);
}
@Test
@TestMetadata("result.swift")
public void testResult() throws Exception {
runTest("native/swift/swift-export-standalone/testData/documentation/golden_result/result.swift");
}
}
@Nested
@TestMetadata("native/swift/swift-export-standalone/testData/documentation/input_root")
@TestDataPath("$PROJECT_ROOT")
public class Input_root {
@Test
public void testAllFilesPresentInInput_root() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/documentation/input_root"), Pattern.compile("^(.+)\\.swift$"), null, true);
}
}
}
@Nested
@TestMetadata("native/swift/swift-export-standalone/testData/functions")
@TestDataPath("$PROJECT_ROOT")
public class Functions {
@Test
public void testAllFilesPresentInFunctions() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/functions"), Pattern.compile("^(.+)\\.swift$"), null, true);
}
@Nested
@TestMetadata("native/swift/swift-export-standalone/testData/functions/golden_result")
@TestDataPath("$PROJECT_ROOT")
public class Golden_result {
@Test
public void testAllFilesPresentInGolden_result() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/functions/golden_result"), Pattern.compile("^(.+)\\.swift$"), null, true);
}
@Test
@TestMetadata("result.swift")
public void testResult() throws Exception {
runTest("native/swift/swift-export-standalone/testData/functions/golden_result/result.swift");
}
}
@Nested
@TestMetadata("native/swift/swift-export-standalone/testData/functions/input_root")
@TestDataPath("$PROJECT_ROOT")
public class Input_root {
@Test
public void testAllFilesPresentInInput_root() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/functions/input_root"), Pattern.compile("^(.+)\\.swift$"), null, true);
}
}
}
@Nested @Nested
@TestMetadata("native/swift/swift-export-standalone/testData/no_package") @TestMetadata("native/swift/swift-export-standalone/testData/no_package")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@@ -60,42 +132,6 @@ public class TypeCheckSwiftExportGoldenData extends SwiftTypeCheckBaseTest {
} }
} }
@Nested
@TestMetadata("native/swift/swift-export-standalone/testData/simple")
@TestDataPath("$PROJECT_ROOT")
public class Simple {
@Test
public void testAllFilesPresentInSimple() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/simple"), Pattern.compile("^(.+)\\.swift$"), null, true);
}
@Nested
@TestMetadata("native/swift/swift-export-standalone/testData/simple/golden_result")
@TestDataPath("$PROJECT_ROOT")
public class Golden_result {
@Test
public void testAllFilesPresentInGolden_result() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/simple/golden_result"), Pattern.compile("^(.+)\\.swift$"), null, true);
}
@Test
@TestMetadata("result.swift")
public void testResult() throws Exception {
runTest("native/swift/swift-export-standalone/testData/simple/golden_result/result.swift");
}
}
@Nested
@TestMetadata("native/swift/swift-export-standalone/testData/simple/input_root")
@TestDataPath("$PROJECT_ROOT")
public class Input_root {
@Test
public void testAllFilesPresentInInput_root() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/swift-export-standalone/testData/simple/input_root"), Pattern.compile("^(.+)\\.swift$"), null, true);
}
}
}
@Nested @Nested
@TestMetadata("native/swift/swift-export-standalone/testData/variables") @TestMetadata("native/swift/swift-export-standalone/testData/variables")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
-3
View File
@@ -4,10 +4,7 @@ plugins {
tasks.register("sirAllTests") { tasks.register("sirAllTests") {
dependsOn( dependsOn(
":native:swift:sir:test",
":native:swift:sir-analysis-api:test",
":native:swift:sir-compiler-bridge:test", ":native:swift:sir-compiler-bridge:test",
":native:swift:sir-passes:test",
":native:swift:sir-printer:test", ":native:swift:sir-printer:test",
":native:swift:swift-export-standalone:test", ":native:swift:swift-export-standalone:test",
) )
-29
View File
@@ -1,29 +0,0 @@
# Build Swift IR from Analysis API
This module is responsible for populating SIR tree. It is the first step in Swift Export pipeline.
Input:
It should be possible to populate SIR from two types of artefacts:
1/ Kotlin Source Module
2/ KLib (currently not supported)
## Dev guide
### How to generate tests:
```bash
./gradlew :generators:sir-tests-generator:generateTests
```
this will generate test by their input files. Input files could be found and should be placed here - `native/swift/sir-analysis-api/testData`
The test expects to find `.sir` file, containing serialized SIR for the test-case. Name of the `.sir` file should be the same as a name of corresponding `.kt` file.
The project for the generator can be found here - `generators/sir-tests-generator/build.gradle.kts`
### How to run tests:
```bash
./gradlew :native:swift:sir-analysis-api:test --tests "*"
```
OR just open `SirAnalysisGeneratedTests` in IDEA and start them from gutter.
### Project Setup
No additional setup required to develop this project.
@@ -1,47 +0,0 @@
plugins {
kotlin("jvm")
}
description = "Build Swift IR from Analysis API"
kotlin {
explicitApi()
}
dependencies {
compileOnly(kotlinStdlib())
api(project(":native:swift:sir"))
api(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()
@@ -1,52 +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.sir.analysisapi
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtModifierListOwner
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
import org.jetbrains.kotlin.psi.psiUtil.isPublic
import org.jetbrains.kotlin.sir.SirDeclaration
import org.jetbrains.kotlin.sir.SirForeignFunction
import org.jetbrains.kotlin.sir.analysisapi.transformers.toForeignFunction
import org.jetbrains.kotlin.sir.analysisapi.transformers.toForeignVariable
/**
* A root interface for classes that produce Swift IR elements.
*/
public interface SirFactory {
public fun build(fromFile: KtFile): List<SirDeclaration>
}
public class SirGenerator : SirFactory {
override fun build(fromFile: KtFile): List<SirDeclaration> = analyze(fromFile) {
val res = mutableListOf<SirDeclaration>()
fromFile.accept(Visitor(res))
return res.toList()
}
private class Visitor(val res: MutableList<SirDeclaration>) : KtTreeVisitorVoid() {
override fun visitNamedFunction(function: KtNamedFunction) {
super.visitNamedFunction(function)
function.process(KtNamedFunction::toForeignFunction)
}
override fun visitProperty(property: KtProperty) {
super.visitProperty(property)
property.process(KtProperty::toForeignVariable)
}
private inline fun <T : KtDeclaration> T.process(converter: T.() -> SirDeclaration) {
this.takeIf { it.isPublic }
?.let(converter)
?.let { res.add(it) }
}
}
}
@@ -1,53 +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.sir.analysisapi.transformers
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.builder.buildForeignFunction
internal fun KtNamedFunction.toForeignFunction(): SirForeignFunction = buildForeignFunction {
origin = AAFunction(this@toForeignFunction)
}
private fun KtValueParameterSymbol.toSirParam(): SirKotlinOrigin.Parameter = AAParameter(
name = name.toString(),
type = AAKotlinType(name = returnType.toString())
)
private class AAFunction(
private val originalFunction: KtNamedFunction
) : SirKotlinOrigin.Function {
override val fqName: FqName
get() = originalFunction.fqName ?: FqName.fromSegments(emptyList())
override val parameters: List<SirKotlinOrigin.Parameter>
get() = analyze(originalFunction) {
val function = originalFunction.getFunctionLikeSymbol()
function.valueParameters.map { it.toSirParam() }
}
override val returnType: SirKotlinOrigin.Type
get() = analyze(originalFunction) {
val function = originalFunction.getFunctionLikeSymbol()
AAKotlinType(name = function.returnType.toString())
}
override val documentation: SirKotlinOrigin.Documentation?
get() = originalFunction.docComment?.let { AADocumentation(it) }
}
private data class AADocumentation(
private val kdoc: KDoc
) : SirKotlinOrigin.Documentation {
override val content: String
get() = kdoc.text
}
@@ -1,17 +0,0 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.sir.analysisapi.transformers
import org.jetbrains.kotlin.sir.SirKotlinOrigin
internal data class AAParameter(
override val name: String,
override val type: SirKotlinOrigin.Type
) : SirKotlinOrigin.Parameter
internal data class AAKotlinType(
override val name: String
) : SirKotlinOrigin.Type
@@ -1,31 +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.sir.analysisapi.transformers
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtVariableDeclaration
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.builder.buildForeignVariable
internal fun KtVariableDeclaration.toForeignVariable(): SirForeignVariable = buildForeignVariable {
origin = AAVariable(this@toForeignVariable)
}
private class AAVariable(
private val original: KtVariableDeclaration
) : SirKotlinOrigin.Property {
override val fqName: FqName
get() = original.fqName ?: FqName.fromSegments(emptyList())
override val type: SirKotlinOrigin.Type
get() = analyze(original) {
AAKotlinType(name = original.getReturnKtType().toString())
}
override val isWriteable: Boolean
get() = original.isVar
}
@@ -1 +0,0 @@
[foo] commented
@@ -1,12 +0,0 @@
// FILE: one.kt
package namespace
fun foo(arg1: Int) = println("")
fun foo(arg1: Double) = println("")
// FILE: two.kt
package other.namespace
fun foo(arg1: Int) = println("")
fun foo(arg1: Double) = println("")
@@ -1,4 +0,0 @@
[namespace, foo]
[namespace, foo]
[other, namespace, foo]
[other, namespace, foo]
@@ -1,12 +0,0 @@
// FILE: one.kt
package com.awesome.namespace
fun foo() = println("")
fun bar() = ""
// FILE: two.kt
package com.awesome.other.namespace
fun foo() = ""
@@ -1,3 +0,0 @@
[com, awesome, namespace, foo]
[com, awesome, namespace, bar]
[com, awesome, other, namespace, foo]
@@ -1,3 +0,0 @@
public fun foo_public() = println("")
internal fun foo_internal() = println("")
private fun foo_private() = println("")
@@ -1 +0,0 @@
[foo_public]
@@ -1 +0,0 @@
fun foo() = println("")
@@ -1 +0,0 @@
[foo]
@@ -1,56 +0,0 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.sir.analysisapi;
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/sir-analysis-api/testData")
@TestDataPath("$PROJECT_ROOT")
public class SirAnalysisGeneratedTests extends AbstractKotlinSirContextTest {
@Test
public void testAllFilesPresentInTestData() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/swift/sir-analysis-api/testData"), Pattern.compile("^(.+)\\.kt$"), null, false);
}
@Test
@TestMetadata("function_with_comment.kt")
public void testFunction_with_comment() throws Exception {
runTest("native/swift/sir-analysis-api/testData/function_with_comment.kt");
}
@Test
@TestMetadata("functions_overload.kt")
public void testFunctions_overload() throws Exception {
runTest("native/swift/sir-analysis-api/testData/functions_overload.kt");
}
@Test
@TestMetadata("namespaced_functions.kt")
public void testNamespaced_functions() throws Exception {
runTest("native/swift/sir-analysis-api/testData/namespaced_functions.kt");
}
@Test
@TestMetadata("should_ignore_not_public_functions.kt")
public void testShould_ignore_not_public_functions() throws Exception {
runTest("native/swift/sir-analysis-api/testData/should_ignore_not_public_functions.kt");
}
@Test
@TestMetadata("simple_function.kt")
public void testSimple_function() throws Exception {
runTest("native/swift/sir-analysis-api/testData/simple_function.kt");
}
}
@@ -1,56 +0,0 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.sir.analysisapi
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.AnalysisApiFirTestConfiguratorFactory
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedTest
import org.jetbrains.kotlin.analysis.test.framework.project.structure.allKtFiles
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.*
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind
import org.jetbrains.kotlin.sir.SirForeignFunction
import org.jetbrains.kotlin.sir.SirKotlinOrigin
import org.jetbrains.kotlin.sir.builder.buildModule
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
open class AbstractKotlinSirContextTest : AbstractKotlinSirContextTestBase() {
override val configurator: AnalysisApiTestConfigurator
get() = AnalysisApiFirTestConfiguratorFactory.createConfigurator(
AnalysisApiTestConfiguratorFactoryData(
FrontendKind.Fir,
TestModuleKind.Source,
AnalysisSessionMode.Normal,
AnalysisApiMode.Ide
)
);
}
abstract class AbstractKotlinSirContextTestBase : AbstractAnalysisApiBasedTest() {
override fun doTestByModuleStructure(moduleStructure: TestModuleStructure, testServices: TestServices) {
val ktFiles = testServices.allKtFiles()
val module = buildModule {
val sirFactory = SirGenerator()
ktFiles.forEach { file ->
name = "Test"
declarations += sirFactory.build(file)
}
}
val actual = buildString {
module.declarations
.filterIsInstance<SirForeignFunction>()
.forEach { sirForeignFunction ->
val function = sirForeignFunction.origin as SirKotlinOrigin.Function
val functionPath = "${function.path}"
val isCommented = function.documentation?.let { " commented" } ?: ""
appendLine("$functionPath$isCommented")
}
}
testServices.assertions.assertEqualsToTestDataFileSibling(actual, extension = ".sir")
}
}
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.sir.bridge
import org.jetbrains.kotlin.sir.SirCallable import org.jetbrains.kotlin.sir.SirCallable
import org.jetbrains.kotlin.sir.SirFunctionBody import org.jetbrains.kotlin.sir.SirFunctionBody
import org.jetbrains.kotlin.sir.SirNativeCallable import org.jetbrains.kotlin.sir.bridge.impl.*
import org.jetbrains.kotlin.sir.bridge.impl.BridgeGeneratorImpl import org.jetbrains.kotlin.sir.bridge.impl.BridgeGeneratorImpl
import org.jetbrains.kotlin.sir.bridge.impl.CBridgePrinter import org.jetbrains.kotlin.sir.bridge.impl.CBridgePrinter
import org.jetbrains.kotlin.sir.bridge.impl.KotlinBridgePrinter import org.jetbrains.kotlin.sir.bridge.impl.KotlinBridgePrinter
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.sir.util.returnType
* @param bridgeName C name of the bridge * @param bridgeName C name of the bridge
*/ */
public class BridgeRequest( public class BridgeRequest(
public val callable: SirNativeCallable, public val callable: SirCallable,
public val bridgeName: String, public val bridgeName: String,
public val fqName: List<String>, public val fqName: List<String>,
) )
@@ -35,7 +35,7 @@ public class BridgeRequest(
* @return the generated SirFunctionBody object representing the body of the function * @return the generated SirFunctionBody object representing the body of the function
*/ */
public fun createFunctionBodyFromRequest(request: BridgeRequest): SirFunctionBody { public fun createFunctionBodyFromRequest(request: BridgeRequest): SirFunctionBody {
val callee = request.bridgeName val callee = request.cDeclarationName()
val calleeArguments = request.callable.allParameters.map { it.name } val calleeArguments = request.callable.allParameters.map { it.name }
val callSite = "$callee(${calleeArguments.joinToString(separator = ", ")})" val callSite = "$callee(${calleeArguments.joinToString(separator = ", ")})"
val callStatement = if (request.callable.returnType.isVoid) callSite else "return $callSite" val callStatement = if (request.callable.returnType.isVoid) callSite else "return $callSite"
@@ -16,10 +16,10 @@ private const val stdintHeader = "stdint.h"
internal class BridgeGeneratorImpl : BridgeGenerator { internal class BridgeGeneratorImpl : BridgeGenerator {
override fun generate(request: BridgeRequest): FunctionBridge { override fun generate(request: BridgeRequest): FunctionBridge {
val (kotlinReturnType, cReturnType) = bridgeType(request.callable.returnType) val (kotlinReturnType, _) = bridgeType(request.callable.returnType)
val parameterBridges = request.callable.allParameters.mapIndexed { index, value -> bridgeParameter(value, index) } val parameterBridges = request.callable.allParameters.mapIndexed { index, value -> bridgeParameter(value, index) }
val cDeclaration = createCDeclaration(request.bridgeName, cReturnType, parameterBridges.map { it.c }) val cDeclaration = request.createCDeclaration()
val kotlinBridge = createKotlinBridge(request.bridgeName, request.fqName, kotlinReturnType, parameterBridges.map { it.kotlin }) val kotlinBridge = createKotlinBridge(request.bridgeName, request.fqName, kotlinReturnType, parameterBridges.map { it.kotlin })
return FunctionBridge( return FunctionBridge(
KotlinFunctionBridge(kotlinBridge, listOf(exportAnnotationFqName)), KotlinFunctionBridge(kotlinBridge, listOf(exportAnnotationFqName)),
@@ -28,6 +28,17 @@ internal class BridgeGeneratorImpl : BridgeGenerator {
} }
} }
// TODO: we need to mangle C name in more elegant way. KT-64970
// problems with this approach are:
// 1. there can be limit for declaration names in Clang compiler
// 1. this name will be UGLY in the debug session
internal fun BridgeRequest.cDeclarationName(): String {
val nameSuffixForOverloadSimulation = cParameters().joinToString(separator = "_", transform = { it.type.repr })
val suffixString = if (cParameters().isNotEmpty()) "__TypesOfArguments__${nameSuffixForOverloadSimulation}__" else ""
val result = "${bridgeName}${suffixString}"
return result
}
private fun createKotlinBridge( private fun createKotlinBridge(
bridgeName: String, bridgeName: String,
functionFqName: List<String>, functionFqName: List<String>,
@@ -61,12 +72,15 @@ private fun createKotlinDeclarationSignature(bridgeName: String, returnType: Kot
}): ${returnType.repr}" }): ${returnType.repr}"
} }
private fun createCDeclaration(bridgeName: String, returnType: CType, parameters: List<CBridgeParameter>): List<String> { private fun BridgeRequest.createCDeclaration(): List<String> {
val cParameters = parameters.joinToString(separator = ", ", transform = { "${it.type.repr} ${it.name}" }) val cParameters = cParameters().joinToString(separator = ", ", transform = { "${it.type.repr} ${it.name}" })
val declaration = "${returnType.repr} $bridgeName($cParameters);" val declaration = "${bridgeType(callable.returnType).second.repr} ${cDeclarationName()}($cParameters);"
return listOf(declaration) return listOf(declaration)
} }
private fun BridgeRequest.cParameters() = callable.allParameters
.mapIndexed { index, value -> bridgeParameter(value, index) }
.map { it.c }
private fun bridgeType(type: SirType): Pair<KotlinType, CType> { private fun bridgeType(type: SirType): Pair<KotlinType, CType> {
require(type is SirNominalType) require(type is SirNominalType)
@@ -76,16 +90,19 @@ private fun bridgeType(type: SirType): Pair<KotlinType, CType> {
SirSwiftModule.bool -> (KotlinType.Boolean to CType.Bool) SirSwiftModule.bool -> (KotlinType.Boolean to CType.Bool)
SirSwiftModule.int8 -> (KotlinType.Byte to CType.Int8) SirSwiftModule.int8 -> (KotlinType.Byte to CType.Int8)
SirSwiftModule.int16 -> (KotlinType.Short to CType.Int16)
SirSwiftModule.int32 -> (KotlinType.Int to CType.Int32) SirSwiftModule.int32 -> (KotlinType.Int to CType.Int32)
SirSwiftModule.int64 -> (KotlinType.Long to CType.Int64) SirSwiftModule.int64 -> (KotlinType.Long to CType.Int64)
SirSwiftModule.int16 -> (KotlinType.Short to CType.Int16)
SirSwiftModule.uint8 -> (KotlinType.UByte to CType.UInt8) SirSwiftModule.uint8 -> (KotlinType.UByte to CType.UInt8)
SirSwiftModule.uint16 -> (KotlinType.UShort to CType.UInt16)
SirSwiftModule.uint32 -> (KotlinType.UInt to CType.UInt32) SirSwiftModule.uint32 -> (KotlinType.UInt to CType.UInt32)
SirSwiftModule.uint64 -> (KotlinType.ULong to CType.UInt64) SirSwiftModule.uint64 -> (KotlinType.ULong to CType.UInt64)
SirSwiftModule.uint16 -> (KotlinType.UShort to CType.UInt16)
else -> error("Unsupported type: ${type.type}") SirSwiftModule.double -> (KotlinType.Double to CType.Double)
SirSwiftModule.float -> (KotlinType.Float to CType.Float)
else -> error("Unsupported type: ${type.type.name}")
} }
} }
@@ -129,6 +146,9 @@ public enum class CType(public val repr: String) {
UInt16("uint16_t"), UInt16("uint16_t"),
UInt32("uint32_t"), UInt32("uint32_t"),
UInt64("uint64_t"), UInt64("uint64_t"),
Float("float"),
Double("double"),
} }
internal data class KotlinBridgeParameter( internal data class KotlinBridgeParameter(
@@ -150,5 +170,8 @@ internal enum class KotlinType(val repr: String) {
UShort("UShort"), UShort("UShort"),
UInt("UInt"), UInt("UInt"),
ULong("ULong"), ULong("ULong"),
Float("Float"),
Double("Double"),
} }
@@ -1,6 +1,5 @@
#include <stdint.h> #include <stdint.h>
int32_t a_b_bar_bridge(int32_t param1, int64_t param2); int32_t a_b_bar_bridge__TypesOfArguments__int32_t_int64_t__(int32_t param1, int64_t param2);
_Bool a_b_foo_bridge(int32_t param1, int64_t param2);
_Bool a_b_foo_bridge__TypesOfArguments__int32_t_int64_t__(int32_t param1, int64_t param2);
@@ -1,7 +1,7 @@
#include <stdint.h> #include <stdint.h>
int32_t a(int8_t p0, int16_t p1, int32_t p2, int64_t p3); int32_t a__TypesOfArguments__int8_t_int16_t_int32_t_int64_t__(int8_t p0, int16_t p1, int32_t p2, int64_t p3);
uint32_t b(uint8_t p0, uint16_t p1, uint32_t p2, uint64_t p3); uint32_t b__TypesOfArguments__uint8_t_uint16_t_uint32_t_uint64_t__(uint8_t p0, uint16_t p1, uint32_t p2, uint64_t p3);
_Bool c(_Bool p0); _Bool c__TypesOfArguments___Bool__(_Bool p0);
@@ -2,4 +2,4 @@
_Bool getter_bridge(); _Bool getter_bridge();
void setter_bridge(_Bool newValue); void setter_bridge__TypesOfArguments___Bool__(_Bool newValue);
@@ -1,3 +1,3 @@
#include <stdint.h> #include <stdint.h>
int32_t a_b_foo_bridge(int32_t param1, int64_t param2); int32_t a_b_foo_bridge__TypesOfArguments__int32_t_int64_t__(int32_t param1, int64_t param2);
+7 -14
View File
@@ -13,23 +13,16 @@ dependencies {
api(project(":native:swift:sir")) api(project(":native:swift:sir"))
testImplementation(kotlin("test-junit5")) api(project(":compiler:psi"))
testImplementation(platform(libs.junit.bom)) api(project(":analysis:analysis-api"))
testImplementation(libs.junit.jupiter.api)
testRuntimeOnly(libs.junit.jupiter.engine)
testImplementation(projectTests(":native:swift:sir"))
testImplementation(projectTests(":compiler:tests-common"))
} }
sourceSets { sourceSets {
"main" { projectDefault() } "main" { projectDefault() }
"test" { projectDefault() }
} }
testsJar() tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
kotlinOptions {
projectTest(jUnitMode = JUnitMode.JUnit5) { freeCompilerArgs += "-Xcontext-receivers"
workingDir = rootDir }
useJUnitPlatform { } }
}
@@ -5,10 +5,12 @@
package org.jetbrains.sir.passes package org.jetbrains.sir.passes
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.sir.* import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.builder.buildEnum import org.jetbrains.kotlin.sir.builder.buildEnum
import org.jetbrains.kotlin.sir.builder.buildModule import org.jetbrains.kotlin.sir.builder.buildModule
import org.jetbrains.kotlin.sir.visitors.SirTransformer import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.sir.passes.builder.KotlinSource
/** /**
* Pass that for every occurring declaration in package x.y.z generates a mirroring type scope and puts it there. * Pass that for every occurring declaration in package x.y.z generates a mirroring type scope and puts it there.
@@ -53,15 +55,17 @@ public class SirInflatePackagesPass : SirModulePass {
name = module.name name = module.name
for (declaration in module.declarations) { for (declaration in module.declarations) {
if (declaration is SirForeignDeclaration) { val origin = declaration.origin as? KotlinSource
val origin = declaration.origin if (origin != null) {
if (origin is SirOrigin.Foreign) { // FIXME: for now we assume everything before the last dot is a package name.
// FIXME: for now we assume everything before the last dot is a package name. // This should change as we add type declarations into the mix
// This should change as we add type declarations into the mix val path = (origin.symbol as? KtCallableSymbol)
val path = origin.path.dropLast(1) ?.callableIdIfNonLocal?.packageName
data.root.getOrCreate(path).elements.add(declaration) ?.pathSegments()
continue ?.map { it.toString() }
} ?: emptyList()
data.root.getOrCreate(path).elements.add(declaration)
continue
} }
declarations += declaration declarations += declaration
} }
@@ -0,0 +1,136 @@
/*
* 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.sir.passes.builder
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.isPublic
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.builder.buildFunction
import org.jetbrains.kotlin.sir.builder.buildGetter
import org.jetbrains.kotlin.sir.builder.buildSetter
import org.jetbrains.kotlin.sir.builder.buildVariable
import org.jetbrains.kotlin.sir.util.SirSwiftModule
public fun KtAnalysisSession.buildSirDeclarationList(from: KtElement): List<SirDeclaration> {
val res = mutableListOf<SirDeclaration>()
from.accept(Visitor(res, this))
return res.toList()
}
private class Visitor(
private val res: MutableList<SirDeclaration>,
private val analysisSession: KtAnalysisSession
) : KtTreeVisitorVoid() {
override fun visitNamedFunction(function: KtNamedFunction) {
super.visitNamedFunction(function)
with(analysisSession) {
function.process {
buildSirFunctionFromPsi(function)
}
}
}
override fun visitProperty(property: KtProperty) {
super.visitProperty(property)
with(analysisSession) {
property.process {
buildSirVariableFromPsi(property)
}
}
}
private inline fun <T : KtDeclaration> T.process(converter: T.() -> SirDeclaration) {
this.takeIf { it.isPublic }
?.let(converter)
?.let { res.add(it) }
}
}
context(KtAnalysisSession)
internal fun buildSirFunctionFromPsi(function: KtNamedFunction): SirFunction = buildFunction {
val symbol = function.getFunctionLikeSymbol()
val callableId = symbol.callableIdIfNonLocal
origin = KotlinSource(symbol)
// this check is not ideal. We assume that there will be no further moves of the declaration,
// especially that there will be no changes in "static" quality.
// That is not fully true. For example, during KT-65127
// we may end up removing the whole enum structure at top of the declaration, and that will
// lift the need to keep it static.
// this problem will be addressed somewhere in the future
val isRootPackage = callableId?.packageName?.isRoot
isStatic = if (isRootPackage == true) false else function.isTopLevel
name = callableId?.callableName?.asString() ?: "UNKNOWN_FUNCTION_NAME"
symbol.valueParameters.mapTo(parameters) {
SirParameter(
argumentName = it.name.asString(),
type = buildSirNominalType(it.returnType)
)
}
returnType = buildSirNominalType(symbol.returnType)
documentation = function.docComment?.text
}
context(KtAnalysisSession)
internal fun buildSirVariableFromPsi(variable: KtProperty): SirVariable = buildVariable {
val symbol = variable.getVariableSymbol()
val callableId = symbol.callableIdIfNonLocal
origin = KotlinSource(symbol)
// this check is not ideal. We assume that there will be no further moves of the declaration,
// especially that there will be no changes in "static" quality.
// That is not fully true. For example, during KT-65127
// we may end up removing the whole enum structure at top of the declaration, and that will
// lift the need to keep it static.
// this problem will be addressed somewhere in the future
val isRootPackage = callableId?.packageName?.isRoot
isStatic = if (isRootPackage == true) false else variable.isTopLevel
name = callableId?.callableName?.asString() ?: "UNKNOWN_VARIABLE_NAME"
type = buildSirNominalType(symbol.returnType)
getter = buildGetter {}
setter = if (variable.isVar) buildSetter {} else null
}.also {
it.getter.parent = it
it.setter?.parent = it
}
public data class KotlinSource(
val symbol: KtSymbol,
) : SirOrigin.Foreign.SourceCode
context(KtAnalysisSession)
private fun buildSirNominalType(it: KtType): SirNominalType = SirNominalType(
when {
it.isUnit -> SirSwiftModule.void
it.isByte -> SirSwiftModule.int8
it.isShort -> SirSwiftModule.int16
it.isInt -> SirSwiftModule.int32
it.isLong -> SirSwiftModule.int64
it.isUByte -> SirSwiftModule.uint8
it.isUShort -> SirSwiftModule.uint16
it.isUInt -> SirSwiftModule.uint32
it.isULong -> SirSwiftModule.uint64
it.isBoolean -> SirSwiftModule.bool
it.isDouble -> SirSwiftModule.double
it.isFloat -> SirSwiftModule.float
else ->
throw IllegalArgumentException("Swift Export does not support argument type: ${it.asStringForDebugging()}")
}
)
@@ -1,97 +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.sir.passes.translation
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.builder.buildFunction
import org.jetbrains.kotlin.sir.builder.buildGetter
import org.jetbrains.kotlin.sir.builder.buildSetter
import org.jetbrains.kotlin.sir.builder.buildVariable
import org.jetbrains.kotlin.sir.util.SirSwiftModule
import org.jetbrains.kotlin.sir.constants.*
import org.jetbrains.kotlin.sir.visitors.SirTransformerVoid
import org.jetbrains.sir.passes.SirPass
import java.lang.IllegalStateException
/**
* Translates `SirForeign*` nodes into their regular "native" counterparts.
*/
public class ForeignTranslationPass : SirPass<SirElement, Nothing?, SirDeclaration> {
private class Transformer : SirTransformerVoid() {
override fun <E : SirElement> transformElement(element: E): E {
element.transformChildren(this)
return element
}
/**
* Works only with Nominal Types and top-level functions, currently.
* If received `element` of different type than `SirForeignFunction`,
* or `element` does not contain origin of type `SirOrigin.KotlinEntity.Function`,
* returns original element.
*/
override fun transformForeignFunction(function: SirForeignFunction): SirDeclaration {
val kotlinOrigin = function.origin as? SirKotlinOrigin.Function
?: return function
return buildFunction {
origin = function.origin
visibility = function.visibility
isStatic = function.parent is SirDeclaration
name = kotlinOrigin.path.last()
kotlinOrigin.parameters.mapTo(parameters) { it.toSir() }
returnType = kotlinOrigin.returnType.toSir()
documentation = kotlinOrigin.documentation?.content
}.apply {
parent = function.parent
}
}
override fun transformForeignVariable(variable: SirForeignVariable): SirDeclaration {
val kotlinOrigin = variable.origin as? SirKotlinOrigin.Property
?: return variable
return buildVariable {
origin = variable.origin
visibility = variable.visibility
isStatic = variable.parent is SirDeclaration
name = kotlinOrigin.path.last()
type = kotlinOrigin.type.toSir()
getter = buildGetter {}
setter = if (kotlinOrigin.isWriteable) buildSetter {} else null
}.also {
it.getter.parent = it
it.setter?.parent = it
}
}
}
override fun run(element: SirElement, data: Nothing?): SirDeclaration = element.transform(Transformer())
}
private fun SirKotlinOrigin.Parameter.toSir(): SirParameter = SirParameter(
argumentName = name,
type = type.toSir(),
)
private fun SirKotlinOrigin.Type.toSir(): SirType = SirNominalType(
type = when (this.name) {
UNIT -> SirSwiftModule.void
BYTE -> SirSwiftModule.int8
SHORT -> SirSwiftModule.int16
INT -> SirSwiftModule.int32
LONG -> SirSwiftModule.int64
BOOLEAN -> SirSwiftModule.bool
DOUBLE -> SirSwiftModule.double
FLOAT -> SirSwiftModule.float
else -> throw IllegalStateException("unknown externally defined type")
}
)
@@ -6,9 +6,7 @@
package org.jetbrains.sir.passes.utility package org.jetbrains.sir.passes.utility
import org.jetbrains.kotlin.sir.* import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.visitors.SirVisitor
import org.jetbrains.sir.passes.SirPass import org.jetbrains.sir.passes.SirPass
import org.jetbrains.sir.passes.utility.ValidationError.WrongForeignDeclarationOrigin
import org.jetbrains.sir.passes.utility.ValidationError.WrongParent import org.jetbrains.sir.passes.utility.ValidationError.WrongParent
import kotlin.collections.plusAssign import kotlin.collections.plusAssign
@@ -17,12 +15,10 @@ import kotlin.collections.plusAssign
*/ */
public sealed interface ValidationError { public sealed interface ValidationError {
public class WrongParent(public val declaration: SirDeclaration, public val expectedParent: SirDeclarationParent) : ValidationError public class WrongParent(public val declaration: SirDeclaration, public val expectedParent: SirDeclarationParent) : ValidationError
public class WrongForeignDeclarationOrigin(public val declaration: SirForeignDeclaration) : ValidationError
} }
public class SirValidatorConfig( public class SirValidatorConfig(
public val checkParents: Boolean = true, public val checkParents: Boolean = true,
public val checkForeignDeclarations: Boolean = true
) )
/** /**
@@ -41,7 +37,6 @@ public fun SirElement.assertValid() {
val messages = errors.map { val messages = errors.map {
when (it) { when (it) {
// TODO: better rendering of SIR elements. // TODO: better rendering of SIR elements.
is WrongForeignDeclarationOrigin -> "Wrong foreign declaration origin: ${it.declaration}"
is WrongParent -> "Wrong declaration parent of ${it.declaration}. Expected: ${it.expectedParent}. Got: ${it.declaration.parent}" is WrongParent -> "Wrong declaration parent of ${it.declaration}. Expected: ${it.expectedParent}. Got: ${it.declaration.parent}"
} }
} }
@@ -63,9 +58,6 @@ internal class SirValidator(private val config: SirValidatorConfig) : SirPass<Si
if (config.checkParents) { if (config.checkParents) {
element.accept(ParentValidator(handler), data) element.accept(ParentValidator(handler), data)
} }
if (config.checkForeignDeclarations) {
element.accept(ForeignDeclarationValidator(handler), data)
}
return errors return errors
} }
} }
@@ -77,16 +69,3 @@ private class ParentValidator(private val errorHandler: ErrorHandler) : Declarat
} }
} }
} }
private class ForeignDeclarationValidator(private val errorHandler: ErrorHandler) : SirVisitor<Unit, Nothing?>() {
override fun visitElement(element: SirElement, data: Nothing?) {
element.acceptChildren(this, data)
}
override fun visitForeignFunction(foreignFunction: SirForeignFunction, data: Nothing?) {
super.visitForeignFunction(foreignFunction, data)
if (foreignFunction.origin !is SirOrigin.Foreign) {
errorHandler.handle(WrongForeignDeclarationOrigin(foreignFunction))
}
}
}
@@ -1,214 +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.sir.passes
import org.jetbrains.kotlin.sir.SirModule
import org.jetbrains.kotlin.sir.SirOrigin
import org.jetbrains.kotlin.sir.builder.buildEnum
import org.jetbrains.kotlin.sir.builder.buildForeignFunction
import org.jetbrains.kotlin.sir.builder.buildModule
import org.jetbrains.kotlin.sir.builder.buildStruct
import org.jetbrains.kotlin.sir.util.SirComparator
import org.jetbrains.kotlin.sir.util.SirPrinter
import org.jetbrains.sir.passes.SirInflatePackagesPass
import org.jetbrains.sir.passes.run
import kotlin.test.Test
class SirPackageInflaterTests {
@Test
fun `should pass on empty module`() {
fun buildModule(): SirModule = buildModule {
name = "Root"
}
val actual = buildModule()
val expected = buildModule()
val pass = SirInflatePackagesPass()
pass.run(actual)
assertEqual(expected, actual)
}
@Test
fun `should collect entities into a single flat namespace`() {
val original = buildModule {
name = "Root"
declarations += listOf(
makeFunction("com.foo"),
makeFunction("com.bar"),
makeFunction("com.baz"),
)
}
val expected = buildModule {
name = "Root"
declarations += buildEnum {
name = "com"
origin = SirOrigin.Namespace(path = listOf("com"))
declarations += listOf(
makeFunction("com.foo"),
makeFunction("com.bar"),
makeFunction("com.baz"),
)
}
}
val pass = SirInflatePackagesPass()
val actual = pass.run(original)
assertEqual(expected, actual)
}
@Test
fun `should leave other declarations alone`() {
val original = buildModule {
name = "Root"
declarations += listOf(
buildStruct { name = "Orphan" },
makeFunction("com.foo"),
makeFunction("com.bar"),
)
}
val expected = buildModule {
name = "Root"
declarations += listOf(
buildStruct { name = "Orphan" },
buildEnum {
name = "com"
origin = SirOrigin.Namespace(path = listOf("com"))
declarations += listOf(
makeFunction("com.foo"),
makeFunction("com.bar"),
)
},
)
}
val pass = SirInflatePackagesPass()
val actual = pass.run(original)
assertEqual(expected, actual)
}
@Test
fun `should collect entities into multiple namespaces`() {
val original = buildModule {
name = "Root"
declarations += listOf(
makeFunction("com.foo"),
makeFunction("org.bar"),
makeFunction("com.baz"),
)
}
val expected = buildModule {
name = "Root"
declarations += buildEnum {
name = "com"
origin = SirOrigin.Namespace(path = listOf("com"))
declarations += listOf(
makeFunction("com.foo"),
makeFunction("com.baz"),
)
}
declarations += buildEnum {
name = "org"
origin = SirOrigin.Namespace(path = listOf("org"))
declarations += listOf(
makeFunction("org.bar"),
)
}
}
val pass = SirInflatePackagesPass()
val actual = pass.run(original)
assertEqual(expected, actual)
}
@Test
fun `should collect entities into multiple nested namespaces`() {
val original = buildModule {
name = "Root"
declarations += listOf(
makeFunction("orphan"),
makeFunction("com.foo"),
makeFunction("org.bar"),
makeFunction("com.baz"),
makeFunction("org.jetbrains.baz"),
makeFunction("org.jetbrains.mascots.kotlin.kodee"),
)
}
val expected = buildModule {
name = "Root"
declarations += listOf(
makeFunction("orphan"),
buildEnum {
name = "com"
origin = SirOrigin.Namespace(path = listOf("com"))
declarations += listOf(
makeFunction("com.foo"),
makeFunction("com.baz"),
)
},
buildEnum {
name = "org"
origin = SirOrigin.Namespace(path = listOf("org"))
declarations += listOf(
makeFunction("org.bar"),
buildEnum {
name = "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"))
declarations += buildEnum {
name = "kotlin"
origin = SirOrigin.Namespace(path = listOf("org", "jetbrains", "mascots", "kotlin"))
declarations += makeFunction("org.jetbrains.mascots.kotlin.kodee")
}
}
)
}
)
}
)
}
val pass = SirInflatePackagesPass()
val actual = pass.run(original)
assertEqual(expected, actual)
}
}
private fun makeFunction(fqName: String) = buildForeignFunction {
val path = fqName.split(".")
assert(path.isNotEmpty())
origin = SirOrigin.Foreign.Unknown(path)
}
private fun assertEqual(expected: SirModule, actual: SirModule) {
assert(SirComparator(options = setOf(SirComparator.Options.COMPARE_ORIGINS)).areEqual(expected, actual)) {
"\nExpected:\n\n${SirPrinter.toString(expected)}\n\nActual:\n\n${SirPrinter.toString(actual)}"
}
}
@@ -1,51 +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.sir.passes
import org.jetbrains.kotlin.sir.SirNominalType
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.util.SirSwiftModule
import org.jetbrains.sir.passes.utility.PatchDeclarationParentVisitor
import org.jetbrains.sir.passes.utility.SirValidatorConfig
import org.jetbrains.sir.passes.utility.ValidationError
import org.jetbrains.sir.passes.utility.validate
import kotlin.test.Test
import kotlin.test.assertTrue
/*
* 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.
*/
class SirParentPatcherTests {
@Test
fun `parent patcher should patch parents`() {
val wrongEnum = buildEnum { name = "wrongEnum" }
val function = buildFunction {
name = "foo"
returnType = SirNominalType(SirSwiftModule.bool)
isStatic = false
}
function.parent = wrongEnum
val wrongModule = buildModule { name = "wrongModule" }
val enum = buildEnum {
name = "e"
declarations += function
}
enum.parent = wrongModule
val module = buildModule {
name = "MyModule"
declarations += enum
}
val validationErrorsBefore = validate(module, SirValidatorConfig())
assertTrue(validationErrorsBefore.filterIsInstance<ValidationError.WrongParent>().count() == 2)
module.accept(PatchDeclarationParentVisitor(), null)
val validationErrorsAfter = validate(module, SirValidatorConfig())
assertTrue(validationErrorsAfter.filterIsInstance<ValidationError.WrongParent>().isEmpty())
}
}
@@ -1,195 +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.sir.passes
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.builder.*
import org.jetbrains.kotlin.sir.constants.*
import org.jetbrains.kotlin.sir.mock.MockDocumentation
import org.jetbrains.kotlin.sir.mock.MockFunction
import org.jetbrains.kotlin.sir.mock.MockKotlinType
import org.jetbrains.kotlin.sir.mock.MockParameter
import org.jetbrains.kotlin.sir.passes.asserts.assertSirFunctionsEquals
import org.jetbrains.kotlin.sir.passes.mocks.MockSirFunction
import org.jetbrains.kotlin.sir.passes.util.runWithAsserts
import org.jetbrains.kotlin.sir.util.SirSwiftModule
import org.jetbrains.sir.passes.translation.ForeignTranslationPass
import kotlin.test.Test
import kotlin.test.assertNotNull
class SirPassTests {
@Test
fun `foreign toplevel function without params should be translated`() {
val module = buildModule {
name = "demo"
}
val mySirElement = buildForeignFunction {
origin = MockFunction(
fqName = FqName.fromSegments(listOf("foo")),
parameters = emptyList(),
returnType = MockKotlinType(BOOLEAN),
)
visibility = SirVisibility.PUBLIC
}
mySirElement.parent = module
val myPass = ForeignTranslationPass()
val result = myPass.runWithAsserts(mySirElement, null) as? SirFunction
assertNotNull(result, "SirFunction should be produced")
val exp = MockSirFunction(
name = "foo",
parameters = emptyList(),
returnType = SirNominalType(SirSwiftModule.bool),
parent = module,
isStatic = false,
)
assertSirFunctionsEquals(actual = result, expected = exp)
}
@Test
fun `foreign toplevel function without params with package should be translated as static`() {
val module = buildModule {
name = "demo"
}
val mySirEnum = buildEnum {
name = "bar"
}
mySirEnum.parent = module
val mySirElement = buildForeignFunction {
origin = MockFunction(
fqName = FqName.fromSegments(listOf("bar", "foo")),
parameters = emptyList(),
returnType = MockKotlinType(BOOLEAN),
)
visibility = SirVisibility.PUBLIC
}
mySirElement.parent = mySirEnum
val myPass = ForeignTranslationPass()
val result = myPass.runWithAsserts(mySirElement, null) as? SirFunction
assertNotNull(result, "SirFunction should be produced")
val exp = MockSirFunction(
name = "foo",
parameters = emptyList(),
returnType = SirNominalType(SirSwiftModule.bool),
parent = mySirEnum,
isStatic = true,
)
assertSirFunctionsEquals(actual = result, expected = exp)
}
@Test
fun `foreign toplevel function with all params should be translated`() {
val module = buildModule {
name = "demo"
}
val mySirElement = buildForeignFunction {
origin = MockFunction(
fqName = FqName.fromSegments(listOf("foo")),
parameters = listOf(
MockParameter(
name = "arg1",
type = MockKotlinType(name = BYTE)
),
MockParameter(
name = "arg2",
type = MockKotlinType(name = SHORT)
),
MockParameter(
name = "arg3",
type = MockKotlinType(name = INT)
),
MockParameter(
name = "arg4",
type = MockKotlinType(name = LONG)
),
MockParameter(
name = "arg5",
type = MockKotlinType(name = DOUBLE)
),
MockParameter(
name = "arg6",
type = MockKotlinType(name = FLOAT)
),
MockParameter(
name = "arg7",
type = MockKotlinType(name = BOOLEAN)
)
),
returnType = MockKotlinType(name = BYTE),
)
visibility = SirVisibility.PUBLIC
}
mySirElement.parent = module
val myPass = ForeignTranslationPass()
val result = myPass.runWithAsserts(mySirElement, null) as? SirFunction
assertNotNull(result, "SirFunction should be produced")
val exp = MockSirFunction(
name = "foo",
parameters = listOf(
SirParameter(argumentName = "arg1", type = SirNominalType(SirSwiftModule.int8)),
SirParameter(argumentName = "arg2", type = SirNominalType(SirSwiftModule.int16)),
SirParameter(argumentName = "arg3", type = SirNominalType(SirSwiftModule.int32)),
SirParameter(argumentName = "arg4", type = SirNominalType(SirSwiftModule.int64)),
SirParameter(argumentName = "arg5", type = SirNominalType(SirSwiftModule.double)),
SirParameter(argumentName = "arg6", type = SirNominalType(SirSwiftModule.float)),
SirParameter(argumentName = "arg7", type = SirNominalType(SirSwiftModule.bool)),
),
returnType = SirNominalType(SirSwiftModule.int8),
parent = module,
isStatic = false,
)
assertSirFunctionsEquals(actual = result, expected = exp)
}
@Test
fun `foreign toplevel function with kdoc should be translated`() {
val module = buildModule {
name = "demo"
}
val mySirElement = buildForeignFunction {
origin = MockFunction(
fqName = FqName.fromSegments(listOf("foo")),
parameters = emptyList(),
returnType = MockKotlinType(BOOLEAN),
documentation = MockDocumentation(
"""
/**
* Function foo description
*
* @param p first Integer to consume
* @param p2 second Double to consume
* @return empty String
*/
""".trimIndent()
)
)
visibility = SirVisibility.PUBLIC
}
mySirElement.parent = module
val myPass = ForeignTranslationPass()
val result = myPass.runWithAsserts(mySirElement, null) as? SirFunction
assertNotNull(result, "SirFunction should be produced")
val exp = MockSirFunction(
name = "foo",
parameters = emptyList(),
returnType = SirNominalType(SirSwiftModule.bool),
parent = module,
isStatic = false,
documentation = """
/**
* Function foo description
*
* @param p first Integer to consume
* @param p2 second Double to consume
* @return empty String
*/
""".trimIndent()
)
assertSirFunctionsEquals(actual = result, expected = exp)
}
}
@@ -1,62 +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.sir.passes
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.sir.builder.buildForeignFunction
import org.jetbrains.kotlin.sir.builder.buildModule
import org.jetbrains.kotlin.sir.mock.MockFunction
import org.jetbrains.kotlin.sir.mock.MockKotlinType
import org.jetbrains.sir.passes.utility.SirValidatorConfig
import org.jetbrains.sir.passes.utility.ValidationError
import org.jetbrains.sir.passes.utility.validate
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class SirValidatorTests {
@Test
fun `validator should check foreign origins`() {
val module = buildModule {
name = "MyModule"
declarations += buildForeignFunction {
}
}
val config = SirValidatorConfig(checkParents = false)
val error = validate(module, config).first()
assertTrue(error is ValidationError.WrongForeignDeclarationOrigin)
assertEquals(module.declarations.first(), error.declaration)
}
@Test
fun `validatior should check declaration parents`() {
val wrongModule = buildModule {
name = "WrongModule"
}
val foreignFunction = buildForeignFunction {
val kotlinEntity = MockFunction(
fqName = FqName.fromSegments(listOf("foo")),
parameters = emptyList(),
returnType = MockKotlinType("kotlin/Byte"),
)
origin = kotlinEntity
}
foreignFunction.parent = wrongModule
val module = buildModule {
name = "MyModule"
declarations += foreignFunction
}
val config = SirValidatorConfig(
checkForeignDeclarations = false
)
val error = validate(module, config).first()
assertTrue(error is ValidationError.WrongParent)
assertEquals(foreignFunction, error.declaration)
assertEquals(module, error.expectedParent)
}
}
@@ -1,36 +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.sir.passes.asserts
import org.jetbrains.kotlin.sir.SirFunction
import kotlin.test.assertEquals
fun assertSirFunctionsEquals(expected: SirFunction, actual: SirFunction) {
assertEquals(
actual = actual.parent,
expected = expected.parent
)
assertEquals(
actual = actual.name,
expected = expected.name
)
assertEquals(
actual = actual.parameters,
expected = expected.parameters
)
assertEquals(
actual = actual.returnType,
expected = expected.returnType
)
assertEquals(
actual = actual.isStatic,
expected = expected.isStatic
)
assertEquals(
actual = actual.documentation,
expected = expected.documentation
)
}
@@ -1,27 +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.sir.passes.mocks
import org.jetbrains.kotlin.sir.SirFunctionBody
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
class MockSirFunction(
override val origin: SirOrigin = SirOrigin.Unknown,
override val isStatic: Boolean,
override val visibility: SirVisibility = SirVisibility.PUBLIC,
override var parent: SirDeclarationParent,
override val name: String,
override val parameters: List<SirParameter>,
override val returnType: SirType,
override var documentation: String? = null,
) : SirFunction() {
override fun <R, D> acceptChildren(visitor: SirVisitor<R, D>, data: D) = Unit
override fun <D> transformChildren(transformer: SirTransformer<D>, data: D) = Unit
override var body: SirFunctionBody? = null
}
@@ -1,19 +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.sir.passes.util
import org.jetbrains.kotlin.sir.SirElement
import org.jetbrains.sir.passes.SirPass
import org.jetbrains.sir.passes.utility.assertValid
fun <S : SirElement, R, T> SirPass<S, T, R>.runWithAsserts(element: S, data: T): R {
element.assertValid()
val result = run(element, data)
if (result is SirElement) {
result.assertValid()
}
return result
}
@@ -128,12 +128,6 @@ public class SirAsSwiftSourcesPrinter(private val printer: SmartPrinter) : SirVi
println("}") println("}")
} }
// we do not write foreign nodes
override fun visitForeignFunction(function: SirForeignFunction) {}
override fun visitForeignVariable(variable: SirForeignVariable) {}
override fun visitElement(element: SirElement): Unit = with(printer) { override fun visitElement(element: SirElement): Unit = with(printer) {
println("/* ERROR: unsupported element type: " + element.javaClass.simpleName + " */") println("/* ERROR: unsupported element type: " + element.javaClass.simpleName + " */")
} }
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.sir.printer package org.jetbrains.kotlin.sir.printer
import org.jetbrains.kotlin.sir.* import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.builder.buildForeignFunction
import org.jetbrains.kotlin.sir.builder.buildFunction import org.jetbrains.kotlin.sir.builder.buildFunction
import org.jetbrains.kotlin.sir.builder.buildModule import org.jetbrains.kotlin.sir.builder.buildModule
import org.jetbrains.kotlin.sir.util.SirSwiftModule import org.jetbrains.kotlin.sir.util.SirSwiftModule
@@ -17,18 +16,6 @@ import org.junit.jupiter.api.Test
import java.io.File import java.io.File
class SirAsSwiftSourcesPrinterTests { class SirAsSwiftSourcesPrinterTests {
@Test
fun `should ignore foreign elements`() {
val module = buildModule {
name = "Test"
declarations.add(foreignFunction())
}
runTest(
module,
"testData/empty"
)
}
@Test @Test
fun `should print simple function`() { fun `should print simple function`() {
@@ -146,7 +133,6 @@ class SirAsSwiftSourcesPrinterTests {
fun `should all types as parameter be handled`() { fun `should all types as parameter be handled`() {
val module = buildModule { val module = buildModule {
name = "Test" name = "Test"
declarations.add(foreignFunction())
declarations.add( declarations.add(
buildFunction { buildFunction {
@@ -295,9 +281,4 @@ class SirAsSwiftSourcesPrinterTests {
val actualSwiftSrc = SirAsSwiftSourcesPrinter().print(module) val actualSwiftSrc = SirAsSwiftSourcesPrinter().print(module)
JUnit5Assertions.assertEqualsToFile(expectedSwiftSrc, actualSwiftSrc) JUnit5Assertions.assertEqualsToFile(expectedSwiftSrc, actualSwiftSrc)
} }
private fun foreignFunction(): SirForeignFunction = buildForeignFunction {
origin = SirOrigin.Unknown
visibility = SirVisibility.PUBLIC
}
} }
-15
View File
@@ -9,23 +9,9 @@ description = "Swift Intermediate Representation"
dependencies { dependencies {
compileOnly(kotlinStdlib()) compileOnly(kotlinStdlib())
api(project(":core:compiler.common"))
if (kotlinBuildProperties.isInIdeaSync) { if (kotlinBuildProperties.isInIdeaSync) {
compileOnly(project("tree-generator")) // Provided, so that IDEA can recognize references to this module in KDoc. compileOnly(project("tree-generator")) // Provided, so that IDEA can recognize references to this module in KDoc.
} }
testImplementation(kotlin("test-junit5"))
testImplementation(platform(libs.junit.bom))
testImplementation(libs.junit.jupiter.api)
testRuntimeOnly(libs.junit.jupiter.engine)
}
testsJar()
projectTest(jUnitMode = JUnitMode.JUnit5) {
workingDir = rootDir
useJUnitPlatform { }
} }
val generatorClasspath by configurations.creating val generatorClasspath by configurations.creating
@@ -59,7 +45,6 @@ sourceSets {
projectDefault() projectDefault()
java.srcDir(generateTree) java.srcDir(generateTree)
} }
"test" { projectDefault() }
} }
if (kotlinBuildProperties.isInJpsBuildIdeaSync) { if (kotlinBuildProperties.isInJpsBuildIdeaSync) {
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.sir.visitors.SirVisitor
/** /**
* Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.accessor] * Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.accessor]
*/ */
sealed class SirAccessor : SirNativeCallable() { sealed class SirAccessor : SirCallable() {
abstract override val origin: SirOrigin abstract override val origin: SirOrigin
abstract override val visibility: SirVisibility abstract override val visibility: SirVisibility
abstract override var parent: SirDeclarationParent abstract override var parent: SirDeclarationParent
@@ -14,10 +14,10 @@ import org.jetbrains.kotlin.sir.visitors.SirVisitor
/** /**
* Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.callable] * Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.callable]
*/ */
sealed interface SirCallable : SirDeclaration { sealed class SirCallable : SirElementBase(), SirDeclaration {
override val origin: SirOrigin abstract override val origin: SirOrigin
override val visibility: SirVisibility abstract override val visibility: SirVisibility
override var parent: SirDeclarationParent abstract override var parent: SirDeclarationParent
override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R = override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R =
visitor.visitCallable(this, data) visitor.visitCallable(this, data)
@@ -1,28 +0,0 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
package org.jetbrains.kotlin.sir
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
/**
* Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.foreignDeclaration]
*/
sealed class SirForeignDeclaration : SirElementBase(), SirDeclaration {
abstract override val origin: SirOrigin
abstract override val visibility: SirVisibility
abstract override var parent: SirDeclarationParent
override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R =
visitor.visitForeignDeclaration(this, data)
@Suppress("UNCHECKED_CAST")
override fun <E : SirElement, D> transform(transformer: SirTransformer<D>, data: D): E =
transformer.transformForeignDeclaration(this, data) as E
}
@@ -1,28 +0,0 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
package org.jetbrains.kotlin.sir
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
/**
* Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.foreignFunction]
*/
abstract class SirForeignFunction : SirForeignDeclaration(), SirCallable {
abstract override val origin: SirOrigin
abstract override val visibility: SirVisibility
abstract override var parent: SirDeclarationParent
override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R =
visitor.visitForeignFunction(this, data)
@Suppress("UNCHECKED_CAST")
override fun <E : SirElement, D> transform(transformer: SirTransformer<D>, data: D): E =
transformer.transformForeignFunction(this, data) as E
}
@@ -1,28 +0,0 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
package org.jetbrains.kotlin.sir
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
/**
* Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.foreignVariable]
*/
abstract class SirForeignVariable : SirForeignDeclaration() {
abstract override val origin: SirOrigin
abstract override val visibility: SirVisibility
abstract override var parent: SirDeclarationParent
override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R =
visitor.visitForeignVariable(this, data)
@Suppress("UNCHECKED_CAST")
override fun <E : SirElement, D> transform(transformer: SirTransformer<D>, data: D): E =
transformer.transformForeignVariable(this, data) as E
}
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.sir.visitors.SirVisitor
/** /**
* Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.function] * Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.function]
*/ */
abstract class SirFunction : SirNativeCallable() { abstract class SirFunction : SirCallable() {
abstract override val origin: SirOrigin abstract override val origin: SirOrigin
abstract override val visibility: SirVisibility abstract override val visibility: SirVisibility
abstract override var parent: SirDeclarationParent abstract override var parent: SirDeclarationParent
@@ -1,28 +0,0 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
package org.jetbrains.kotlin.sir
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
/**
* Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.nativeCallable]
*/
sealed class SirNativeCallable : SirElementBase(), SirCallable {
abstract override val origin: SirOrigin
abstract override val visibility: SirVisibility
abstract override var parent: SirDeclarationParent
override fun <R, D> accept(visitor: SirVisitor<R, D>, data: D): R =
visitor.visitNativeCallable(this, data)
@Suppress("UNCHECKED_CAST")
override fun <E : SirElement, D> transform(transformer: SirTransformer<D>, data: D): E =
transformer.transformNativeCallable(this, data) as E
}
@@ -1,50 +0,0 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
@file:Suppress("DuplicatedCode", "unused")
package org.jetbrains.kotlin.sir.builder
import kotlin.contracts.*
import org.jetbrains.kotlin.sir.SirBuilderDsl
import org.jetbrains.kotlin.sir.SirForeignFunction
import org.jetbrains.kotlin.sir.SirOrigin
import org.jetbrains.kotlin.sir.SirVisibility
import org.jetbrains.kotlin.sir.impl.SirForeignFunctionImpl
@SirBuilderDsl
class SirForeignFunctionBuilder {
var origin: SirOrigin = SirOrigin.Unknown
var visibility: SirVisibility = SirVisibility.PUBLIC
fun build(): SirForeignFunction {
return SirForeignFunctionImpl(
origin,
visibility,
)
}
}
@OptIn(ExperimentalContracts::class)
inline fun buildForeignFunction(init: SirForeignFunctionBuilder.() -> Unit = {}): SirForeignFunction {
contract {
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
}
return SirForeignFunctionBuilder().apply(init).build()
}
@OptIn(ExperimentalContracts::class)
inline fun buildForeignFunctionCopy(original: SirForeignFunction, init: SirForeignFunctionBuilder.() -> Unit = {}): SirForeignFunction {
contract {
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
}
val copyBuilder = SirForeignFunctionBuilder()
copyBuilder.origin = original.origin
copyBuilder.visibility = original.visibility
return copyBuilder.apply(init).build()
}
@@ -1,50 +0,0 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
@file:Suppress("DuplicatedCode", "unused")
package org.jetbrains.kotlin.sir.builder
import kotlin.contracts.*
import org.jetbrains.kotlin.sir.SirBuilderDsl
import org.jetbrains.kotlin.sir.SirForeignVariable
import org.jetbrains.kotlin.sir.SirOrigin
import org.jetbrains.kotlin.sir.SirVisibility
import org.jetbrains.kotlin.sir.impl.SirForeignVariableImpl
@SirBuilderDsl
class SirForeignVariableBuilder {
var origin: SirOrigin = SirOrigin.Unknown
var visibility: SirVisibility = SirVisibility.PUBLIC
fun build(): SirForeignVariable {
return SirForeignVariableImpl(
origin,
visibility,
)
}
}
@OptIn(ExperimentalContracts::class)
inline fun buildForeignVariable(init: SirForeignVariableBuilder.() -> Unit = {}): SirForeignVariable {
contract {
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
}
return SirForeignVariableBuilder().apply(init).build()
}
@OptIn(ExperimentalContracts::class)
inline fun buildForeignVariableCopy(original: SirForeignVariable, init: SirForeignVariableBuilder.() -> Unit = {}): SirForeignVariable {
contract {
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
}
val copyBuilder = SirForeignVariableBuilder()
copyBuilder.origin = original.origin
copyBuilder.visibility = original.visibility
return copyBuilder.apply(init).build()
}
@@ -1,31 +0,0 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
@file:Suppress("DuplicatedCode", "unused")
package org.jetbrains.kotlin.sir.impl
import org.jetbrains.kotlin.sir.SirDeclarationParent
import org.jetbrains.kotlin.sir.SirForeignFunction
import org.jetbrains.kotlin.sir.SirOrigin
import org.jetbrains.kotlin.sir.SirVisibility
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
internal class SirForeignFunctionImpl(
override val origin: SirOrigin,
override val visibility: SirVisibility,
) : SirForeignFunction() {
override lateinit var parent: SirDeclarationParent
override fun <R, D> acceptChildren(visitor: SirVisitor<R, D>, data: D) {
}
override fun <D> transformChildren(transformer: SirTransformer<D>, data: D) {
}
}
@@ -1,31 +0,0 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
// This file was generated automatically. See native/swift/sir/tree-generator/Readme.md.
// DO NOT MODIFY IT MANUALLY.
@file:Suppress("DuplicatedCode", "unused")
package org.jetbrains.kotlin.sir.impl
import org.jetbrains.kotlin.sir.SirDeclarationParent
import org.jetbrains.kotlin.sir.SirForeignVariable
import org.jetbrains.kotlin.sir.SirOrigin
import org.jetbrains.kotlin.sir.SirVisibility
import org.jetbrains.kotlin.sir.visitors.SirTransformer
import org.jetbrains.kotlin.sir.visitors.SirVisitor
internal class SirForeignVariableImpl(
override val origin: SirOrigin,
override val visibility: SirVisibility,
) : SirForeignVariable() {
override lateinit var parent: SirDeclarationParent
override fun <R, D> acceptChildren(visitor: SirVisitor<R, D>, data: D) {
}
override fun <D> transformChildren(transformer: SirTransformer<D>, data: D) {
}
}
@@ -46,14 +46,6 @@ abstract class SirTransformer<in D> : SirVisitor<SirElement, D>() {
return transformDeclaration(declaration, data) return transformDeclaration(declaration, data)
} }
open fun transformForeignDeclaration(foreignDeclaration: SirForeignDeclaration, data: D): SirDeclaration {
return transformDeclaration(foreignDeclaration, data)
}
final override fun visitForeignDeclaration(declaration: SirForeignDeclaration, data: D): SirDeclaration {
return transformForeignDeclaration(declaration, data)
}
open fun transformNamedDeclaration(namedDeclaration: SirNamedDeclaration, data: D): SirDeclaration { open fun transformNamedDeclaration(namedDeclaration: SirNamedDeclaration, data: D): SirDeclaration {
return transformDeclaration(namedDeclaration, data) return transformDeclaration(namedDeclaration, data)
@@ -87,14 +79,6 @@ abstract class SirTransformer<in D> : SirVisitor<SirElement, D>() {
return transformCallable(callable, data) return transformCallable(callable, data)
} }
open fun transformNativeCallable(nativeCallable: SirNativeCallable, data: D): SirDeclaration {
return transformCallable(nativeCallable, data)
}
final override fun visitNativeCallable(nativeCallable: SirNativeCallable, data: D): SirDeclaration {
return transformNativeCallable(nativeCallable, data)
}
open fun transformFunction(function: SirFunction, data: D): SirDeclaration { open fun transformFunction(function: SirFunction, data: D): SirDeclaration {
return transformCallable(function, data) return transformCallable(function, data)
} }
@@ -103,14 +87,6 @@ abstract class SirTransformer<in D> : SirVisitor<SirElement, D>() {
return transformFunction(function, data) return transformFunction(function, data)
} }
open fun transformForeignFunction(foreignFunction: SirForeignFunction, data: D): SirDeclaration {
return transformCallable(foreignFunction, data)
}
final override fun visitForeignFunction(function: SirForeignFunction, data: D): SirDeclaration {
return transformForeignFunction(function, data)
}
open fun transformAccessor(accessor: SirAccessor, data: D): SirDeclaration { open fun transformAccessor(accessor: SirAccessor, data: D): SirDeclaration {
return transformCallable(accessor, data) return transformCallable(accessor, data)
} }
@@ -143,14 +119,6 @@ abstract class SirTransformer<in D> : SirVisitor<SirElement, D>() {
return transformVariable(variable, data) return transformVariable(variable, data)
} }
open fun transformForeignVariable(foreignVariable: SirForeignVariable, data: D): SirDeclaration {
return transformDeclaration(foreignVariable, data)
}
final override fun visitForeignVariable(variable: SirForeignVariable, data: D): SirDeclaration {
return transformForeignVariable(variable, data)
}
open fun transformImport(import: SirImport, data: D): SirDeclaration { open fun transformImport(import: SirImport, data: D): SirDeclaration {
return transformDeclaration(import, data) return transformDeclaration(import, data)
} }
@@ -38,12 +38,6 @@ abstract class SirTransformerVoid : SirTransformer<Nothing?>() {
final override fun transformDeclaration(declaration: SirDeclaration, data: Nothing?): SirDeclaration = final override fun transformDeclaration(declaration: SirDeclaration, data: Nothing?): SirDeclaration =
transformDeclaration(declaration) transformDeclaration(declaration)
open fun transformForeignDeclaration(declaration: SirForeignDeclaration): SirDeclaration =
transformDeclaration(declaration)
final override fun transformForeignDeclaration(declaration: SirForeignDeclaration, data: Nothing?): SirDeclaration =
transformForeignDeclaration(declaration)
open fun transformNamedDeclaration(declaration: SirNamedDeclaration): SirDeclaration = open fun transformNamedDeclaration(declaration: SirNamedDeclaration): SirDeclaration =
transformDeclaration(declaration) transformDeclaration(declaration)
@@ -68,24 +62,12 @@ abstract class SirTransformerVoid : SirTransformer<Nothing?>() {
final override fun transformCallable(callable: SirCallable, data: Nothing?): SirDeclaration = final override fun transformCallable(callable: SirCallable, data: Nothing?): SirDeclaration =
transformCallable(callable) transformCallable(callable)
open fun transformNativeCallable(nativeCallable: SirNativeCallable): SirDeclaration =
transformCallable(nativeCallable)
final override fun transformNativeCallable(nativeCallable: SirNativeCallable, data: Nothing?): SirDeclaration =
transformNativeCallable(nativeCallable)
open fun transformFunction(function: SirFunction): SirDeclaration = open fun transformFunction(function: SirFunction): SirDeclaration =
transformCallable(function) transformCallable(function)
final override fun transformFunction(function: SirFunction, data: Nothing?): SirDeclaration = final override fun transformFunction(function: SirFunction, data: Nothing?): SirDeclaration =
transformFunction(function) transformFunction(function)
open fun transformForeignFunction(function: SirForeignFunction): SirDeclaration =
transformCallable(function)
final override fun transformForeignFunction(function: SirForeignFunction, data: Nothing?): SirDeclaration =
transformForeignFunction(function)
open fun transformAccessor(accessor: SirAccessor): SirDeclaration = open fun transformAccessor(accessor: SirAccessor): SirDeclaration =
transformCallable(accessor) transformCallable(accessor)
@@ -110,12 +92,6 @@ abstract class SirTransformerVoid : SirTransformer<Nothing?>() {
final override fun transformVariable(variable: SirVariable, data: Nothing?): SirDeclaration = final override fun transformVariable(variable: SirVariable, data: Nothing?): SirDeclaration =
transformVariable(variable) transformVariable(variable)
open fun transformForeignVariable(variable: SirForeignVariable): SirDeclaration =
transformDeclaration(variable)
final override fun transformForeignVariable(variable: SirForeignVariable, data: Nothing?): SirDeclaration =
transformForeignVariable(variable)
open fun transformImport(import: SirImport): SirDeclaration = open fun transformImport(import: SirImport): SirDeclaration =
transformDeclaration(import) transformDeclaration(import)
@@ -26,9 +26,6 @@ abstract class SirVisitor<out R, in D> {
open fun visitDeclaration(declaration: SirDeclaration, data: D): R = open fun visitDeclaration(declaration: SirDeclaration, data: D): R =
visitElement(declaration, data) visitElement(declaration, data)
open fun visitForeignDeclaration(declaration: SirForeignDeclaration, data: D): R =
visitDeclaration(declaration, data)
open fun visitNamedDeclaration(declaration: SirNamedDeclaration, data: D): R = open fun visitNamedDeclaration(declaration: SirNamedDeclaration, data: D): R =
visitDeclaration(declaration, data) visitDeclaration(declaration, data)
@@ -41,15 +38,9 @@ abstract class SirVisitor<out R, in D> {
open fun visitCallable(callable: SirCallable, data: D): R = open fun visitCallable(callable: SirCallable, data: D): R =
visitDeclaration(callable, data) visitDeclaration(callable, data)
open fun visitNativeCallable(nativeCallable: SirNativeCallable, data: D): R =
visitCallable(nativeCallable, data)
open fun visitFunction(function: SirFunction, data: D): R = open fun visitFunction(function: SirFunction, data: D): R =
visitCallable(function, data) visitCallable(function, data)
open fun visitForeignFunction(function: SirForeignFunction, data: D): R =
visitCallable(function, data)
open fun visitAccessor(accessor: SirAccessor, data: D): R = open fun visitAccessor(accessor: SirAccessor, data: D): R =
visitCallable(accessor, data) visitCallable(accessor, data)
@@ -62,9 +53,6 @@ abstract class SirVisitor<out R, in D> {
open fun visitVariable(variable: SirVariable, data: D): R = open fun visitVariable(variable: SirVariable, data: D): R =
visitDeclaration(variable, data) visitDeclaration(variable, data)
open fun visitForeignVariable(variable: SirForeignVariable, data: D): R =
visitDeclaration(variable, data)
open fun visitImport(import: SirImport, data: D): R = open fun visitImport(import: SirImport, data: D): R =
visitDeclaration(import, data) visitDeclaration(import, data)
} }
@@ -46,14 +46,6 @@ abstract class SirVisitorVoid : SirVisitor<Unit, Nothing?>() {
visitElement(declaration) visitElement(declaration)
} }
final override fun visitForeignDeclaration(declaration: SirForeignDeclaration, data: Nothing?) {
visitForeignDeclaration(declaration)
}
open fun visitForeignDeclaration(declaration: SirForeignDeclaration) {
visitDeclaration(declaration)
}
final override fun visitNamedDeclaration(declaration: SirNamedDeclaration, data: Nothing?) { final override fun visitNamedDeclaration(declaration: SirNamedDeclaration, data: Nothing?) {
visitNamedDeclaration(declaration) visitNamedDeclaration(declaration)
} }
@@ -86,14 +78,6 @@ abstract class SirVisitorVoid : SirVisitor<Unit, Nothing?>() {
visitDeclaration(callable) visitDeclaration(callable)
} }
final override fun visitNativeCallable(nativeCallable: SirNativeCallable, data: Nothing?) {
visitNativeCallable(nativeCallable)
}
open fun visitNativeCallable(nativeCallable: SirNativeCallable) {
visitCallable(nativeCallable)
}
final override fun visitFunction(function: SirFunction, data: Nothing?) { final override fun visitFunction(function: SirFunction, data: Nothing?) {
visitFunction(function) visitFunction(function)
} }
@@ -102,14 +86,6 @@ abstract class SirVisitorVoid : SirVisitor<Unit, Nothing?>() {
visitCallable(function) visitCallable(function)
} }
final override fun visitForeignFunction(function: SirForeignFunction, data: Nothing?) {
visitForeignFunction(function)
}
open fun visitForeignFunction(function: SirForeignFunction) {
visitCallable(function)
}
final override fun visitAccessor(accessor: SirAccessor, data: Nothing?) { final override fun visitAccessor(accessor: SirAccessor, data: Nothing?) {
visitAccessor(accessor) visitAccessor(accessor)
} }
@@ -142,14 +118,6 @@ abstract class SirVisitorVoid : SirVisitor<Unit, Nothing?>() {
visitDeclaration(variable) visitDeclaration(variable)
} }
final override fun visitForeignVariable(variable: SirForeignVariable, data: Nothing?) {
visitForeignVariable(variable)
}
open fun visitForeignVariable(variable: SirForeignVariable) {
visitDeclaration(variable)
}
final override fun visitImport(import: SirImport, data: Nothing?) { final override fun visitImport(import: SirImport, data: Nothing?) {
visitImport(import) visitImport(import)
} }
@@ -1,39 +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.sir
import org.jetbrains.kotlin.name.FqName
sealed interface SirKotlinOrigin : SirOrigin.Foreign {
val fqName: FqName
override val path: List<String>
get() = fqName.pathSegments().map { it.asString() }
interface Function : SirKotlinOrigin {
val documentation: Documentation?
val parameters: List<Parameter>
val returnType: Type
}
interface Property : SirKotlinOrigin {
val type: Type
val isWriteable: Boolean
}
interface Parameter {
val name: String
val type: Type
}
interface Type {
val name: String
}
interface Documentation {
val content: String
}
}
@@ -13,10 +13,8 @@ sealed interface SirOrigin {
data class Namespace(val path: List<String>) : Synthetic data class Namespace(val path: List<String>) : Synthetic
sealed interface Foreign : SirOrigin { sealed interface Foreign : SirOrigin {
val path: List<String>
/** Value for nodes of origin unrepresentable or non-viable yet known to be foreign. */ interface SourceCode : Foreign
data class Unknown(override val path: List<String> = emptyList()) : Foreign
} }
/** /**
@@ -1,19 +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.sir.constants
private const val KOTLIN_PACKAGE = "kotlin"
private const val DELIMITER = "/"
private const val KOTLIN_BUILTIN_TYPE_PREFIX = "${KOTLIN_PACKAGE}${DELIMITER}"
const val UNIT = "${KOTLIN_BUILTIN_TYPE_PREFIX}Unit"
const val BYTE = "${KOTLIN_BUILTIN_TYPE_PREFIX}Byte"
const val SHORT = "${KOTLIN_BUILTIN_TYPE_PREFIX}Short"
const val INT = "${KOTLIN_BUILTIN_TYPE_PREFIX}Int"
const val LONG = "${KOTLIN_BUILTIN_TYPE_PREFIX}Long"
const val BOOLEAN = "${KOTLIN_BUILTIN_TYPE_PREFIX}Boolean"
const val DOUBLE = "${KOTLIN_BUILTIN_TYPE_PREFIX}Double"
const val FLOAT = "${KOTLIN_BUILTIN_TYPE_PREFIX}Float"
@@ -58,12 +58,6 @@ class SirComparator(val options: Set<Options> = emptySet()) : SirVisitor<Boolean
data.returnType == function.returnType && data.returnType == function.returnType &&
visitDeclaration(function, data) visitDeclaration(function, data)
} }
override fun visitForeignFunction(foreignFunction: SirForeignFunction, data: SirElement): Boolean {
return data is SirForeignFunction &&
areEqual(data.origin, foreignFunction.origin) &&
visitDeclaration(foreignFunction, data)
}
} }
private fun SirComparator.areEqual(lhs: List<SirElement>, rhs: List<SirElement>): Boolean { private fun SirComparator.areEqual(lhs: List<SirElement>, rhs: List<SirElement>): Boolean {
@@ -7,14 +7,14 @@ package org.jetbrains.kotlin.sir.util
import org.jetbrains.kotlin.sir.* import org.jetbrains.kotlin.sir.*
val SirNativeCallable.allParameters: List<SirParameter> val SirCallable.allParameters: List<SirParameter>
get() = when (this) { get() = when (this) {
is SirFunction -> this.parameters is SirFunction -> this.parameters
is SirSetter -> listOf(SirParameter(parameterName = parameterName, type = this.valueType)) is SirSetter -> listOf(SirParameter(parameterName = parameterName, type = this.valueType))
is SirGetter -> listOf() is SirGetter -> listOf()
} }
val SirNativeCallable.returnType: SirType val SirCallable.returnType: SirType
get() = when (this) { get() = when (this) {
is SirFunction -> this.returnType is SirFunction -> this.returnType
is SirGetter -> this.valueType is SirGetter -> this.valueType
@@ -15,53 +15,45 @@ object SirPrinter : SirVisitor<String, Unit>() {
return "UNKNOWN<${SirElement::class.simpleName}>($element)" return "UNKNOWN<${SirElement::class.simpleName}>($element)"
} }
override fun visitModule(element: SirModule, data: Unit): String = render( override fun visitModule(module: SirModule, data: Unit): String = render(
element, module,
listOf( listOf(
"name" to element.name "name" to module.name
), ),
element.declarations module.declarations
) )
override fun visitEnum(element: SirEnum, data: Unit): String = render( override fun visitEnum(enum: SirEnum, data: Unit): String = render(
element, enum,
listOf( listOf(
"origin" to element.origin, "origin" to enum.origin,
"visibility" to element.visibility, "visibility" to enum.visibility,
"name" to element.name, "name" to enum.name,
"cases" to element.cases "cases" to enum.cases
), ),
element.declarations enum.declarations
) )
override fun visitStruct(element: SirStruct, data: Unit): String = render( override fun visitStruct(struct: SirStruct, data: Unit): String = render(
element, struct,
listOf( listOf(
"origin" to element.origin, "origin" to struct.origin,
"visibility" to element.visibility, "visibility" to struct.visibility,
"name" to element.name "name" to struct.name
), ),
element.declarations struct.declarations
) )
override fun visitFunction(element: SirFunction, data: Unit): String = render( override fun visitFunction(function: SirFunction, data: Unit): String = render(
element, function,
listOf( listOf(
"origin" to element.origin, "origin" to function.origin,
"visibility" to element.visibility, "visibility" to function.visibility,
"name" to element.name, "name" to function.name,
"parameters" to element.parameters, "parameters" to function.parameters,
"returnType" to element.returnType, "returnType" to function.returnType,
) )
) )
override fun visitForeignFunction(element: SirForeignFunction, data: Unit): String = render(
element,
listOf(
"origin" to element.origin,
"visibility" to element.visibility,
),
)
} }
private fun render( private fun render(
@@ -1,34 +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.sir
import org.jetbrains.kotlin.sir.builder.buildEnum
import org.jetbrains.kotlin.sir.constants.BYTE
import org.jetbrains.kotlin.sir.mock.MockFunction
import org.jetbrains.kotlin.sir.mock.MockKotlinType
import org.jetbrains.kotlin.sir.mock.MockParameter
import kotlin.test.Test
import kotlin.test.assertTrue
class SirTest {
// TODO: Just a fake test to validate that everything is working. Feel free to delete.
@Test
fun exampleTest() {
val fakeElement = produceSwiftElement()
println(fakeElement)
assertTrue(fakeElement is SirElement)
}
private fun produceSwiftElement(): Any {
return buildEnum {
origin = SirOrigin.Unknown
name = "name"
visibility = SirVisibility.PUBLIC
}
}
}
@@ -1,28 +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.sir.mock
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.sir.SirKotlinOrigin
import org.jetbrains.kotlin.sir.SirOrigin
data class MockFunction(
override val fqName: FqName,
override val parameters: List<SirKotlinOrigin.Parameter>,
override val returnType: SirKotlinOrigin.Type,
override val documentation: SirKotlinOrigin.Documentation? = null,
) : SirKotlinOrigin.Function
data class MockParameter(
override val name: String,
override val type: SirKotlinOrigin.Type,
) : SirKotlinOrigin.Parameter
data class MockKotlinType(
override val name: String
) : SirKotlinOrigin.Type
data class MockDocumentation(override val content: String) : SirKotlinOrigin.Documentation
@@ -42,12 +42,6 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() {
} }
} }
val foreignDeclaration by sealedElement {
parent(declaration)
visitorParameterName = "declaration"
}
val named by sealedElement { val named by sealedElement {
+field("name", string) +field("name", string)
} }
@@ -78,15 +72,9 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() {
parent(declaration) parent(declaration)
} }
// Denotes "actual" callable node. (I.e. SirCallable & !SIRForeignDeclaration)
// TODO: remove along with foreign declaration (KT-65335); replace usages with just SIRCallable
val nativeCallable by sealedElement {
parent(callable)
}
val function by element { val function by element {
customParentInVisitor = callable customParentInVisitor = callable
parent(nativeCallable) parent(callable)
+field("isStatic", boolean) // todo: KT-65046 Method|function distinction in SIR +field("isStatic", boolean) // todo: KT-65046 Method|function distinction in SIR
+field("name", string) +field("name", string)
@@ -97,17 +85,9 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() {
+field(name = "documentation", string, nullable = true, mutable = true) +field(name = "documentation", string, nullable = true, mutable = true)
} }
val foreignFunction by element {
customParentInVisitor = callable
parent(callable)
parent(foreignDeclaration)
visitorParameterName = "function"
}
val accessor by sealedElement { val accessor by sealedElement {
customParentInVisitor = callable customParentInVisitor = callable
parent(nativeCallable) parent(callable)
+field("body", functionBodyType, nullable = true, mutable = true) +field("body", functionBodyType, nullable = true, mutable = true)
} }
@@ -119,7 +99,7 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() {
val setter by element { val setter by element {
parent(accessor) parent(accessor)
+field("parameterName", string, initializer = { }) +field("parameterName", string, initializer = { })
} }
val variable by element { val variable by element {
@@ -136,13 +116,6 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() {
+field("isStatic", boolean) // todo: KT-65046 Method|function distinction in SIR +field("isStatic", boolean) // todo: KT-65046 Method|function distinction in SIR
} }
val foreignVariable by element {
customParentInVisitor = declaration
parent(foreignDeclaration)
visitorParameterName = "variable"
}
val import by element { val import by element {
customParentInVisitor = declaration customParentInVisitor = declaration
parent(declaration) parent(declaration)
@@ -12,7 +12,6 @@ dependencies {
compileOnly(kotlinStdlib()) compileOnly(kotlinStdlib())
implementation(project(":native:swift:sir")) implementation(project(":native:swift:sir"))
implementation(project(":native:swift:sir-analysis-api"))
implementation(project(":native:swift:sir-compiler-bridge")) implementation(project(":native:swift:sir-compiler-bridge"))
implementation(project(":native:swift:sir-passes")) implementation(project(":native:swift:sir-passes"))
implementation(project(":native:swift:sir-printer")) implementation(project(":native:swift:sir-printer"))
@@ -5,7 +5,10 @@
package org.jetbrains.kotlin.swiftexport.standalone.builders package org.jetbrains.kotlin.swiftexport.standalone.builders
import org.jetbrains.kotlin.name.FqName 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.SirElement
import org.jetbrains.kotlin.sir.SirFunction import org.jetbrains.kotlin.sir.SirFunction
import org.jetbrains.kotlin.sir.SirVariable import org.jetbrains.kotlin.sir.SirVariable
@@ -13,12 +16,12 @@ import org.jetbrains.kotlin.sir.SirAccessor
import org.jetbrains.kotlin.sir.SirSetter import org.jetbrains.kotlin.sir.SirSetter
import org.jetbrains.kotlin.sir.SirGetter import org.jetbrains.kotlin.sir.SirGetter
import org.jetbrains.kotlin.sir.util.* import org.jetbrains.kotlin.sir.util.*
import org.jetbrains.kotlin.sir.SirKotlinOrigin
import org.jetbrains.kotlin.sir.SirModule import org.jetbrains.kotlin.sir.SirModule
import org.jetbrains.kotlin.sir.bridge.BridgeRequest import org.jetbrains.kotlin.sir.bridge.BridgeRequest
import org.jetbrains.kotlin.sir.bridge.createFunctionBodyFromRequest import org.jetbrains.kotlin.sir.bridge.createFunctionBodyFromRequest
import org.jetbrains.kotlin.sir.visitors.SirVisitorVoid import org.jetbrains.kotlin.sir.visitors.SirVisitorVoid
import org.jetbrains.sir.passes.SirPass import org.jetbrains.sir.passes.SirPass
import org.jetbrains.sir.passes.builder.KotlinSource
import org.jetbrains.sir.passes.run import org.jetbrains.sir.passes.run
internal fun SirModule.buildFunctionBridges(): List<BridgeRequest> { internal fun SirModule.buildFunctionBridges(): List<BridgeRequest> {
@@ -39,7 +42,9 @@ private object BridgeGenerationPass : SirPass<SirElement, Nothing?, List<BridgeR
} }
override fun visitFunction(function: SirFunction) { override fun visitFunction(function: SirFunction) {
val fqName = (function.origin as? SirKotlinOrigin.Function)?.path val fqName = ((function.origin as? KotlinSource)?.symbol as? KtFunctionLikeSymbol)
?.callableIdIfNonLocal?.asSingleFqName()
?.pathSegments()?.map { it.toString() }
?: return ?: return
val fqNameForBridge = fqName.forBridge val fqNameForBridge = fqName.forBridge
@@ -53,7 +58,9 @@ private object BridgeGenerationPass : SirPass<SirElement, Nothing?, List<BridgeR
} }
override fun visitVariable(variable: SirVariable) { override fun visitVariable(variable: SirVariable) {
val fqName = (variable.origin as? SirKotlinOrigin.Property)?.path?.forBridge val fqName = ((variable.origin as? KotlinSource)?.symbol as? KtVariableLikeSymbol)
?.callableIdIfNonLocal?.asSingleFqName()
?.pathSegments()?.map { it.toString() }
?: return ?: return
val fqNameForBridge = fqName.forBridge val fqNameForBridge = fqName.forBridge
@@ -71,13 +78,15 @@ private object BridgeGenerationPass : SirPass<SirElement, Nothing?, List<BridgeR
} }
} }
private val SirAccessor.bridgeSuffix: String get() = when(this) { private val SirAccessor.bridgeSuffix: String
is SirGetter -> "get" get() = when (this) {
is SirSetter -> "set" is SirGetter -> "get"
} is SirSetter -> "set"
}
private val List<String>.forBridge: List<String> get() = if (this.count() == 1) { private val List<String>.forBridge: List<String>
listOf("__root__", this.first()) // todo: should be changed with correct mangling KT-64970 get() = if (this.count() == 1) {
} else { listOf("__root__", this.first()) // todo: should be changed with correct mangling KT-64970
this } else {
} this
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.swiftexport.standalone.builders package org.jetbrains.kotlin.swiftexport.standalone.builders
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenProvider import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenProvider
import org.jetbrains.kotlin.analysis.api.standalone.KtAlwaysAccessibleLifetimeTokenProvider import org.jetbrains.kotlin.analysis.api.standalone.KtAlwaysAccessibleLifetimeTokenProvider
import org.jetbrains.kotlin.analysis.api.standalone.buildStandaloneAnalysisAPISession import org.jetbrains.kotlin.analysis.api.standalone.buildStandaloneAnalysisAPISession
@@ -13,10 +14,10 @@ import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtSourceModu
import org.jetbrains.kotlin.platform.konan.NativePlatforms import org.jetbrains.kotlin.platform.konan.NativePlatforms
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.sir.SirModule import org.jetbrains.kotlin.sir.SirModule
import org.jetbrains.kotlin.sir.analysisapi.SirGenerator
import org.jetbrains.kotlin.sir.builder.buildImport import org.jetbrains.kotlin.sir.builder.buildImport
import org.jetbrains.kotlin.sir.builder.buildModule import org.jetbrains.kotlin.sir.builder.buildModule
import org.jetbrains.kotlin.swiftexport.standalone.SwiftExportInput import org.jetbrains.kotlin.swiftexport.standalone.SwiftExportInput
import org.jetbrains.sir.passes.builder.buildSirDeclarationList
@OptIn(KtAnalysisApiInternals::class) @OptIn(KtAnalysisApiInternals::class)
internal fun buildSwiftModule( internal fun buildSwiftModule(
@@ -48,17 +49,17 @@ internal fun buildSwiftModule(
ktFiles = ktFiles.sortedBy { it.name } ktFiles = ktFiles.sortedBy { it.name }
} }
return analyze(sourceModule) {
return buildModule { buildModule {
name = sourceModule.moduleName name = sourceModule.moduleName
val sirFactory = SirGenerator() declarations += buildImport {
declarations += buildImport { moduleName = bridgeModuleName
moduleName = bridgeModuleName }
ktFiles.forEach { file ->
declarations += buildSirDeclarationList(file)
}
}.apply {
declarations.forEach { it.parent = this }
} }
ktFiles.forEach { file ->
declarations += sirFactory.build(file)
}
}.apply {
declarations.forEach { it.parent = this }
} }
} }
@@ -13,7 +13,6 @@ import org.jetbrains.sir.passes.SirInflatePackagesPass
import org.jetbrains.sir.passes.SirModulePass import org.jetbrains.sir.passes.SirModulePass
import org.jetbrains.sir.passes.SirPass import org.jetbrains.sir.passes.SirPass
import org.jetbrains.sir.passes.run import org.jetbrains.sir.passes.run
import org.jetbrains.sir.passes.translation.ForeignTranslationPass
internal fun SirModule.transformToSwift(): SirModule { internal fun SirModule.transformToSwift(): SirModule {
return SirPassesConfiguration.passes.fold(this) { module, pass -> return SirPassesConfiguration.passes.fold(this) { module, pass ->
@@ -24,9 +23,9 @@ internal fun SirModule.transformToSwift(): SirModule {
private object SirPassesConfiguration { private object SirPassesConfiguration {
val passes: List<SirModulePass> = listOf( val passes: List<SirModulePass> = listOf(
SirInflatePackagesPass(), SirInflatePackagesPass(),
WholeModuleTranslationByElementPass(ForeignTranslationPass()),
) )
@Suppress("Unused")
class WholeModuleTranslationByElementPass( class WholeModuleTranslationByElementPass(
val pass: SirPass<SirElement, Nothing?, SirDeclaration> val pass: SirPass<SirElement, Nothing?, SirDeclaration>
) : SirModulePass { ) : SirModulePass {
@@ -0,0 +1,4 @@
#include <stdint.h>
int16_t __root___foo__TypesOfArguments__int32_t_double__(int32_t p, double p2);
@@ -0,0 +1,8 @@
import kotlin.native.internal.ExportedBridge
@ExportedBridge("__root___foo")
public fun __root___foo(p: Int, p2: Double): Short {
val result = foo(p, p2)
return result
}
@@ -0,0 +1,15 @@
import KotlinBridges
/**
* Function foo description
*
* @param p first Integer to consume
* @param p2 second Double to consume
* @return Short, constant 1
*/
public func foo(
p: Swift.Int32,
p2: Swift.Double
) -> Swift.Int16 {
return __root___foo__TypesOfArguments__int32_t_double__(p, p2)
}
@@ -0,0 +1,18 @@
#include <stdint.h>
void namespace1_local_functions_foo();
int32_t namespace1_main_foobar__TypesOfArguments__int32_t__(int32_t param);
void namespace1_main_all_args__TypesOfArguments___Bool_int8_t_int16_t_int32_t_int64_t_float_double__(_Bool arg1, int8_t arg2, int16_t arg3, int32_t arg4, int64_t arg5, float arg10, double arg11);
int32_t namespace1_bar();
int32_t namespace2_foo__TypesOfArguments__int32_t__(int32_t arg1);
int32_t overload_foo__TypesOfArguments__int32_t__(int32_t arg1);
int32_t overload_foo__TypesOfArguments__double__(double arg1);
int32_t __root___foo();
@@ -0,0 +1,50 @@
import kotlin.native.internal.ExportedBridge
@ExportedBridge("namespace1_local_functions_foo")
public fun namespace1_local_functions_foo(): Unit {
val result = namespace1.local_functions.foo()
return result
}
@ExportedBridge("namespace1_main_foobar")
public fun namespace1_main_foobar(param: Int): Int {
val result = namespace1.main.foobar(param)
return result
}
@ExportedBridge("namespace1_main_all_args")
public fun namespace1_main_all_args(arg1: Boolean, arg2: Byte, arg3: Short, arg4: Int, arg5: Long, arg10: Float, arg11: Double): Unit {
val result = namespace1.main.all_args(arg1, arg2, arg3, arg4, arg5, arg10, arg11)
return result
}
@ExportedBridge("namespace1_bar")
public fun namespace1_bar(): Int {
val result = namespace1.bar()
return result
}
@ExportedBridge("namespace2_foo")
public fun namespace2_foo(arg1: Int): Int {
val result = namespace2.foo(arg1)
return result
}
@ExportedBridge("overload_foo")
public fun overload_foo(arg1: Int): Int {
val result = overload.foo(arg1)
return result
}
@ExportedBridge("overload_foo")
public fun overload_foo(arg1: Double): Int {
val result = overload.foo(arg1)
return result
}
@ExportedBridge("__root___foo")
public fun __root___foo(): Int {
val result = foo()
return result
}
@@ -0,0 +1,55 @@
import KotlinBridges
enum namespace1 {
enum local_functions {
public static func foo() -> Swift.Void {
namespace1_local_functions_foo()
}
}
enum main {
public static func foobar(
param: Swift.Int32
) -> Swift.Int32 {
return namespace1_main_foobar__TypesOfArguments__int32_t__(param)
}
public static func all_args(
arg1: Swift.Bool,
arg2: Swift.Int8,
arg3: Swift.Int16,
arg4: Swift.Int32,
arg5: Swift.Int64,
arg10: Swift.Float,
arg11: Swift.Double
) -> Swift.Void {
namespace1_main_all_args__TypesOfArguments___Bool_int8_t_int16_t_int32_t_int64_t_float_double__(arg1, arg2, arg3, arg4, arg5, arg10, arg11)
}
}
public static func bar() -> Swift.Int32 {
return namespace1_bar()
}
}
enum namespace2 {
public static func foo(
arg1: Swift.Int32
) -> Swift.Int32 {
return namespace2_foo__TypesOfArguments__int32_t__(arg1)
}
}
enum overload {
public static func foo(
arg1: Swift.Int32
) -> Swift.Int32 {
return overload_foo__TypesOfArguments__int32_t__(arg1)
}
public static func foo(
arg1: Swift.Double
) -> Swift.Int32 {
return overload_foo__TypesOfArguments__double__(arg1)
}
}
public func foo() -> Swift.Int32 {
return __root___foo()
}
@@ -0,0 +1,3 @@
package namespace2
fun foo(arg1: Int) = 123
@@ -0,0 +1,2 @@
internal fun foo_internal() = 123
@@ -0,0 +1,7 @@
package namespace1.local_functions
fun foo() {
fun bar() {
val baz = 0
}
}
@@ -0,0 +1,24 @@
package namespace1.main
import namespace1.*
import namespace2.*
fun foobar(param: Int): Int = foo() + bar() + param
fun all_args(
arg1: Boolean,
arg2: Byte,
arg3: Short,
arg4: Int,
arg5: Long,
// TODO: support kotlin Unsigned types - KT-65668
// arg6: UByte,
// arg7: UShort,
// arg8: UInt,
// arg9: ULong,
arg10: Float,
arg11: Double,
): Unit = Unit
@@ -0,0 +1,5 @@
package overload
fun foo(arg1: Int) = 123
fun foo(arg1: Double) = 321
@@ -1,9 +0,0 @@
#include <stdint.h>
int32_t namespace1_main_foobar(int32_t param);
int32_t namespace1_bar();
int32_t namespace2_foo();
int32_t __root___foo();
@@ -1,25 +0,0 @@
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
}
@@ -1,24 +0,0 @@
import KotlinBridges
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()
}
@@ -1,3 +0,0 @@
package namespace2
fun foo(): Int = 321
@@ -1,5 +0,0 @@
package namespace1.main
import namespace1.*
import namespace2.*
fun foobar(param: Int): Int = foo() + bar() + param
@@ -4,9 +4,9 @@ int32_t namespace_main_foo_get();
int32_t namespace_main_bar_get(); int32_t namespace_main_bar_get();
void namespace_main_bar_set(int32_t newValue); void namespace_main_bar_set__TypesOfArguments__int32_t__(int32_t newValue);
int32_t namespace_main_foobar(int32_t param); int32_t namespace_main_foobar__TypesOfArguments__int32_t__(int32_t param);
int32_t __root___baz(); int32_t __root___baz();
@@ -12,13 +12,13 @@ enum namespace {
return namespace_main_bar_get() return namespace_main_bar_get()
} }
set { set {
namespace_main_bar_set(newValue) namespace_main_bar_set__TypesOfArguments__int32_t__(newValue)
} }
} }
public static func foobar( public static func foobar(
param: Swift.Int32 param: Swift.Int32
) -> Swift.Int32 { ) -> Swift.Int32 {
return namespace_main_foobar(param) return namespace_main_foobar__TypesOfArguments__int32_t__(param)
} }
} }
} }
@@ -25,15 +25,21 @@ public class SwiftExportRunnerTest extends AbstractSwiftRunnerTest {
} }
@Test @Test
@TestMetadata("no_package") @TestMetadata("documentation")
public void testNo_package() throws Exception { public void testDocumentation() throws Exception {
runTest("native/swift/swift-export-standalone/testData/no_package/"); runTest("native/swift/swift-export-standalone/testData/documentation/");
} }
@Test @Test
@TestMetadata("simple") @TestMetadata("functions")
public void testSimple() throws Exception { public void testFunctions() throws Exception {
runTest("native/swift/swift-export-standalone/testData/simple/"); runTest("native/swift/swift-export-standalone/testData/functions/");
}
@Test
@TestMetadata("no_package")
public void testNo_package() throws Exception {
runTest("native/swift/swift-export-standalone/testData/no_package/");
} }
@Test @Test
-1
View File
@@ -422,7 +422,6 @@ include ":native:swift:sir",
":native:swift:sir:tree-generator", ":native:swift:sir:tree-generator",
":native:swift:sir-passes", ":native:swift:sir-passes",
":native:swift:sir-printer", ":native:swift:sir-printer",
":native:swift:sir-analysis-api",
":native:swift:sir-compiler-bridge", ":native:swift:sir-compiler-bridge",
":native:swift:swift-export-standalone", ":native:swift:swift-export-standalone",
":generators:sir-tests-generator" ":generators:sir-tests-generator"