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:
@@ -7,7 +7,6 @@ sourceSets {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projectTests(":native:swift:sir-analysis-api"))
|
||||
implementation(projectTests(":native:swift:sir-compiler-bridge"))
|
||||
implementation(projectTests(":native:swift:swift-export-standalone"))
|
||||
implementation(projectTests(":generators:test-generator"))
|
||||
|
||||
-11
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.generators.tests.native.swift.sir
|
||||
|
||||
import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
|
||||
import org.jetbrains.kotlin.sir.analysisapi.AbstractKotlinSirContextTest
|
||||
import org.jetbrains.kotlin.sir.bridge.AbstractKotlinSirBridgeTest
|
||||
import org.jetbrains.kotlin.swiftexport.standalone.AbstractSwiftRunnerTest
|
||||
|
||||
@@ -14,16 +13,6 @@ import org.jetbrains.kotlin.swiftexport.standalone.AbstractSwiftRunnerTest
|
||||
fun main() {
|
||||
System.setProperty("java.awt.headless", "true")
|
||||
generateTestGroupSuiteWithJUnit5 {
|
||||
testGroup(
|
||||
"native/swift/sir-analysis-api/tests-gen/",
|
||||
"native/swift/sir-analysis-api/testData"
|
||||
) {
|
||||
testClass<AbstractKotlinSirContextTest>(
|
||||
suiteTestClassName = "SirAnalysisGeneratedTests"
|
||||
) {
|
||||
model("", recursive = false)
|
||||
}
|
||||
}
|
||||
testGroup(
|
||||
"native/swift/sir-compiler-bridge/tests-gen/",
|
||||
"native/swift/sir-compiler-bridge/testData"
|
||||
|
||||
+72
-36
@@ -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);
|
||||
}
|
||||
|
||||
@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
|
||||
@TestMetadata("native/swift/swift-export-standalone/testData/no_package")
|
||||
@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
|
||||
@TestMetadata("native/swift/swift-export-standalone/testData/variables")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
@@ -4,10 +4,7 @@ plugins {
|
||||
|
||||
tasks.register("sirAllTests") {
|
||||
dependsOn(
|
||||
":native:swift:sir:test",
|
||||
":native:swift:sir-analysis-api:test",
|
||||
":native:swift:sir-compiler-bridge:test",
|
||||
":native:swift:sir-passes:test",
|
||||
":native:swift:sir-printer:test",
|
||||
":native:swift:swift-export-standalone:test",
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
-52
@@ -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) }
|
||||
}
|
||||
}
|
||||
}
|
||||
-53
@@ -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
|
||||
}
|
||||
-17
@@ -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
|
||||
-31
@@ -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]
|
||||
-56
@@ -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");
|
||||
}
|
||||
}
|
||||
-56
@@ -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")
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.sir.bridge
|
||||
|
||||
import org.jetbrains.kotlin.sir.SirCallable
|
||||
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.CBridgePrinter
|
||||
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
|
||||
*/
|
||||
public class BridgeRequest(
|
||||
public val callable: SirNativeCallable,
|
||||
public val callable: SirCallable,
|
||||
public val bridgeName: String,
|
||||
public val fqName: List<String>,
|
||||
)
|
||||
@@ -35,7 +35,7 @@ public class BridgeRequest(
|
||||
* @return the generated SirFunctionBody object representing the body of the function
|
||||
*/
|
||||
public fun createFunctionBodyFromRequest(request: BridgeRequest): SirFunctionBody {
|
||||
val callee = request.bridgeName
|
||||
val callee = request.cDeclarationName()
|
||||
val calleeArguments = request.callable.allParameters.map { it.name }
|
||||
val callSite = "$callee(${calleeArguments.joinToString(separator = ", ")})"
|
||||
val callStatement = if (request.callable.returnType.isVoid) callSite else "return $callSite"
|
||||
|
||||
+31
-8
@@ -16,10 +16,10 @@ private const val stdintHeader = "stdint.h"
|
||||
|
||||
internal class BridgeGeneratorImpl : BridgeGenerator {
|
||||
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 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 })
|
||||
return FunctionBridge(
|
||||
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(
|
||||
bridgeName: String,
|
||||
functionFqName: List<String>,
|
||||
@@ -61,12 +72,15 @@ private fun createKotlinDeclarationSignature(bridgeName: String, returnType: Kot
|
||||
}): ${returnType.repr}"
|
||||
}
|
||||
|
||||
private fun createCDeclaration(bridgeName: String, returnType: CType, parameters: List<CBridgeParameter>): List<String> {
|
||||
val cParameters = parameters.joinToString(separator = ", ", transform = { "${it.type.repr} ${it.name}" })
|
||||
val declaration = "${returnType.repr} $bridgeName($cParameters);"
|
||||
private fun BridgeRequest.createCDeclaration(): List<String> {
|
||||
val cParameters = cParameters().joinToString(separator = ", ", transform = { "${it.type.repr} ${it.name}" })
|
||||
val declaration = "${bridgeType(callable.returnType).second.repr} ${cDeclarationName()}($cParameters);"
|
||||
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> {
|
||||
require(type is SirNominalType)
|
||||
@@ -76,16 +90,19 @@ private fun bridgeType(type: SirType): Pair<KotlinType, CType> {
|
||||
SirSwiftModule.bool -> (KotlinType.Boolean to CType.Bool)
|
||||
|
||||
SirSwiftModule.int8 -> (KotlinType.Byte to CType.Int8)
|
||||
SirSwiftModule.int16 -> (KotlinType.Short to CType.Int16)
|
||||
SirSwiftModule.int32 -> (KotlinType.Int to CType.Int32)
|
||||
SirSwiftModule.int64 -> (KotlinType.Long to CType.Int64)
|
||||
SirSwiftModule.int16 -> (KotlinType.Short to CType.Int16)
|
||||
|
||||
SirSwiftModule.uint8 -> (KotlinType.UByte to CType.UInt8)
|
||||
SirSwiftModule.uint16 -> (KotlinType.UShort to CType.UInt16)
|
||||
SirSwiftModule.uint32 -> (KotlinType.UInt to CType.UInt32)
|
||||
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"),
|
||||
UInt32("uint32_t"),
|
||||
UInt64("uint64_t"),
|
||||
|
||||
Float("float"),
|
||||
Double("double"),
|
||||
}
|
||||
|
||||
internal data class KotlinBridgeParameter(
|
||||
@@ -150,5 +170,8 @@ internal enum class KotlinType(val repr: String) {
|
||||
UShort("UShort"),
|
||||
UInt("UInt"),
|
||||
ULong("ULong"),
|
||||
|
||||
Float("Float"),
|
||||
Double("Double"),
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <stdint.h>
|
||||
|
||||
int32_t a_b_bar_bridge(int32_t param1, int64_t param2);
|
||||
|
||||
_Bool a_b_foo_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__TypesOfArguments__int32_t_int64_t__(int32_t param1, int64_t param2);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#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();
|
||||
|
||||
void setter_bridge(_Bool newValue);
|
||||
void setter_bridge__TypesOfArguments___Bool__(_Bool newValue);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#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);
|
||||
|
||||
@@ -13,23 +13,16 @@ dependencies {
|
||||
|
||||
api(project(":native:swift:sir"))
|
||||
|
||||
testImplementation(kotlin("test-junit5"))
|
||||
testImplementation(platform(libs.junit.bom))
|
||||
testImplementation(libs.junit.jupiter.api)
|
||||
testRuntimeOnly(libs.junit.jupiter.engine)
|
||||
|
||||
testImplementation(projectTests(":native:swift:sir"))
|
||||
testImplementation(projectTests(":compiler:tests-common"))
|
||||
api(project(":compiler:psi"))
|
||||
api(project(":analysis:analysis-api"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
testsJar()
|
||||
|
||||
projectTest(jUnitMode = JUnitMode.JUnit5) {
|
||||
workingDir = rootDir
|
||||
useJUnitPlatform { }
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs += "-Xcontext-receivers"
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,12 @@
|
||||
|
||||
package org.jetbrains.sir.passes
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.sir.*
|
||||
import org.jetbrains.kotlin.sir.builder.buildEnum
|
||||
import org.jetbrains.kotlin.sir.builder.buildModule
|
||||
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.
|
||||
@@ -53,16 +55,18 @@ public class SirInflatePackagesPass : SirModulePass {
|
||||
name = module.name
|
||||
|
||||
for (declaration in module.declarations) {
|
||||
if (declaration is SirForeignDeclaration) {
|
||||
val origin = declaration.origin
|
||||
if (origin is SirOrigin.Foreign) {
|
||||
val origin = declaration.origin as? KotlinSource
|
||||
if (origin != null) {
|
||||
// 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
|
||||
val path = origin.path.dropLast(1)
|
||||
val path = (origin.symbol as? KtCallableSymbol)
|
||||
?.callableIdIfNonLocal?.packageName
|
||||
?.pathSegments()
|
||||
?.map { it.toString() }
|
||||
?: emptyList()
|
||||
data.root.getOrCreate(path).elements.add(declaration)
|
||||
continue
|
||||
}
|
||||
}
|
||||
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()}")
|
||||
}
|
||||
)
|
||||
-97
@@ -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
|
||||
|
||||
import org.jetbrains.kotlin.sir.*
|
||||
import org.jetbrains.kotlin.sir.visitors.SirVisitor
|
||||
import org.jetbrains.sir.passes.SirPass
|
||||
import org.jetbrains.sir.passes.utility.ValidationError.WrongForeignDeclarationOrigin
|
||||
import org.jetbrains.sir.passes.utility.ValidationError.WrongParent
|
||||
import kotlin.collections.plusAssign
|
||||
|
||||
@@ -17,12 +15,10 @@ import kotlin.collections.plusAssign
|
||||
*/
|
||||
public sealed interface 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 val checkParents: Boolean = true,
|
||||
public val checkForeignDeclarations: Boolean = true
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -41,7 +37,6 @@ public fun SirElement.assertValid() {
|
||||
val messages = errors.map {
|
||||
when (it) {
|
||||
// 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}"
|
||||
}
|
||||
}
|
||||
@@ -63,9 +58,6 @@ internal class SirValidator(private val config: SirValidatorConfig) : SirPass<Si
|
||||
if (config.checkParents) {
|
||||
element.accept(ParentValidator(handler), data)
|
||||
}
|
||||
if (config.checkForeignDeclarations) {
|
||||
element.accept(ForeignDeclarationValidator(handler), data)
|
||||
}
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
-214
@@ -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)}"
|
||||
}
|
||||
}
|
||||
-51
@@ -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)
|
||||
}
|
||||
}
|
||||
-36
@@ -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
|
||||
)
|
||||
}
|
||||
-27
@@ -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
|
||||
}
|
||||
-19
@@ -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("}")
|
||||
}
|
||||
|
||||
// we do not write foreign nodes
|
||||
|
||||
override fun visitForeignFunction(function: SirForeignFunction) {}
|
||||
|
||||
override fun visitForeignVariable(variable: SirForeignVariable) {}
|
||||
|
||||
override fun visitElement(element: SirElement): Unit = with(printer) {
|
||||
println("/* ERROR: unsupported element type: " + element.javaClass.simpleName + " */")
|
||||
}
|
||||
|
||||
-19
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.sir.printer
|
||||
|
||||
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.buildModule
|
||||
import org.jetbrains.kotlin.sir.util.SirSwiftModule
|
||||
@@ -17,18 +16,6 @@ import org.junit.jupiter.api.Test
|
||||
import java.io.File
|
||||
|
||||
class SirAsSwiftSourcesPrinterTests {
|
||||
@Test
|
||||
fun `should ignore foreign elements`() {
|
||||
val module = buildModule {
|
||||
name = "Test"
|
||||
declarations.add(foreignFunction())
|
||||
}
|
||||
|
||||
runTest(
|
||||
module,
|
||||
"testData/empty"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should print simple function`() {
|
||||
@@ -146,7 +133,6 @@ class SirAsSwiftSourcesPrinterTests {
|
||||
fun `should all types as parameter be handled`() {
|
||||
val module = buildModule {
|
||||
name = "Test"
|
||||
declarations.add(foreignFunction())
|
||||
|
||||
declarations.add(
|
||||
buildFunction {
|
||||
@@ -295,9 +281,4 @@ class SirAsSwiftSourcesPrinterTests {
|
||||
val actualSwiftSrc = SirAsSwiftSourcesPrinter().print(module)
|
||||
JUnit5Assertions.assertEqualsToFile(expectedSwiftSrc, actualSwiftSrc)
|
||||
}
|
||||
|
||||
private fun foreignFunction(): SirForeignFunction = buildForeignFunction {
|
||||
origin = SirOrigin.Unknown
|
||||
visibility = SirVisibility.PUBLIC
|
||||
}
|
||||
}
|
||||
@@ -9,23 +9,9 @@ description = "Swift Intermediate Representation"
|
||||
dependencies {
|
||||
compileOnly(kotlinStdlib())
|
||||
|
||||
api(project(":core:compiler.common"))
|
||||
|
||||
if (kotlinBuildProperties.isInIdeaSync) {
|
||||
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
|
||||
@@ -59,7 +45,6 @@ sourceSets {
|
||||
projectDefault()
|
||||
java.srcDir(generateTree)
|
||||
}
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
if (kotlinBuildProperties.isInJpsBuildIdeaSync) {
|
||||
|
||||
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.sir.visitors.SirVisitor
|
||||
/**
|
||||
* 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 visibility: SirVisibility
|
||||
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]
|
||||
*/
|
||||
sealed interface SirCallable : SirDeclaration {
|
||||
override val origin: SirOrigin
|
||||
override val visibility: SirVisibility
|
||||
override var parent: SirDeclarationParent
|
||||
sealed class SirCallable : 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.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]
|
||||
*/
|
||||
abstract class SirFunction : SirNativeCallable() {
|
||||
abstract class SirFunction : SirCallable() {
|
||||
abstract override val origin: SirOrigin
|
||||
abstract override val visibility: SirVisibility
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
return transformDeclaration(namedDeclaration, data)
|
||||
@@ -87,14 +79,6 @@ abstract class SirTransformer<in D> : SirVisitor<SirElement, D>() {
|
||||
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 {
|
||||
return transformCallable(function, data)
|
||||
}
|
||||
@@ -103,14 +87,6 @@ abstract class SirTransformer<in D> : SirVisitor<SirElement, D>() {
|
||||
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 {
|
||||
return transformCallable(accessor, data)
|
||||
}
|
||||
@@ -143,14 +119,6 @@ abstract class SirTransformer<in D> : SirVisitor<SirElement, D>() {
|
||||
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 {
|
||||
return transformDeclaration(import, data)
|
||||
}
|
||||
|
||||
@@ -38,12 +38,6 @@ abstract class SirTransformerVoid : SirTransformer<Nothing?>() {
|
||||
final override fun transformDeclaration(declaration: SirDeclaration, data: Nothing?): SirDeclaration =
|
||||
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 =
|
||||
transformDeclaration(declaration)
|
||||
|
||||
@@ -68,24 +62,12 @@ abstract class SirTransformerVoid : SirTransformer<Nothing?>() {
|
||||
final override fun transformCallable(callable: SirCallable, data: Nothing?): SirDeclaration =
|
||||
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 =
|
||||
transformCallable(function)
|
||||
|
||||
final override fun transformFunction(function: SirFunction, data: Nothing?): SirDeclaration =
|
||||
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 =
|
||||
transformCallable(accessor)
|
||||
|
||||
@@ -110,12 +92,6 @@ abstract class SirTransformerVoid : SirTransformer<Nothing?>() {
|
||||
final override fun transformVariable(variable: SirVariable, data: Nothing?): SirDeclaration =
|
||||
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 =
|
||||
transformDeclaration(import)
|
||||
|
||||
|
||||
@@ -26,9 +26,6 @@ abstract class SirVisitor<out R, in D> {
|
||||
open fun visitDeclaration(declaration: SirDeclaration, data: D): R =
|
||||
visitElement(declaration, data)
|
||||
|
||||
open fun visitForeignDeclaration(declaration: SirForeignDeclaration, data: D): R =
|
||||
visitDeclaration(declaration, data)
|
||||
|
||||
open fun visitNamedDeclaration(declaration: SirNamedDeclaration, data: D): R =
|
||||
visitDeclaration(declaration, data)
|
||||
|
||||
@@ -41,15 +38,9 @@ abstract class SirVisitor<out R, in D> {
|
||||
open fun visitCallable(callable: SirCallable, data: D): R =
|
||||
visitDeclaration(callable, data)
|
||||
|
||||
open fun visitNativeCallable(nativeCallable: SirNativeCallable, data: D): R =
|
||||
visitCallable(nativeCallable, data)
|
||||
|
||||
open fun visitFunction(function: SirFunction, data: D): R =
|
||||
visitCallable(function, data)
|
||||
|
||||
open fun visitForeignFunction(function: SirForeignFunction, data: D): R =
|
||||
visitCallable(function, data)
|
||||
|
||||
open fun visitAccessor(accessor: SirAccessor, data: D): R =
|
||||
visitCallable(accessor, data)
|
||||
|
||||
@@ -62,9 +53,6 @@ abstract class SirVisitor<out R, in D> {
|
||||
open fun visitVariable(variable: SirVariable, data: D): R =
|
||||
visitDeclaration(variable, data)
|
||||
|
||||
open fun visitForeignVariable(variable: SirForeignVariable, data: D): R =
|
||||
visitDeclaration(variable, data)
|
||||
|
||||
open fun visitImport(import: SirImport, data: D): R =
|
||||
visitDeclaration(import, data)
|
||||
}
|
||||
|
||||
@@ -46,14 +46,6 @@ abstract class SirVisitorVoid : SirVisitor<Unit, Nothing?>() {
|
||||
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?) {
|
||||
visitNamedDeclaration(declaration)
|
||||
}
|
||||
@@ -86,14 +78,6 @@ abstract class SirVisitorVoid : SirVisitor<Unit, Nothing?>() {
|
||||
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?) {
|
||||
visitFunction(function)
|
||||
}
|
||||
@@ -102,14 +86,6 @@ abstract class SirVisitorVoid : SirVisitor<Unit, Nothing?>() {
|
||||
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?) {
|
||||
visitAccessor(accessor)
|
||||
}
|
||||
@@ -142,14 +118,6 @@ abstract class SirVisitorVoid : SirVisitor<Unit, Nothing?>() {
|
||||
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?) {
|
||||
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
|
||||
|
||||
sealed interface Foreign : SirOrigin {
|
||||
val path: List<String>
|
||||
|
||||
/** Value for nodes of origin unrepresentable or non-viable yet known to be foreign. */
|
||||
data class Unknown(override val path: List<String> = emptyList()) : Foreign
|
||||
interface SourceCode : 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 &&
|
||||
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 {
|
||||
|
||||
@@ -7,14 +7,14 @@ package org.jetbrains.kotlin.sir.util
|
||||
|
||||
import org.jetbrains.kotlin.sir.*
|
||||
|
||||
val SirNativeCallable.allParameters: List<SirParameter>
|
||||
val SirCallable.allParameters: List<SirParameter>
|
||||
get() = when (this) {
|
||||
is SirFunction -> this.parameters
|
||||
is SirSetter -> listOf(SirParameter(parameterName = parameterName, type = this.valueType))
|
||||
is SirGetter -> listOf()
|
||||
}
|
||||
|
||||
val SirNativeCallable.returnType: SirType
|
||||
val SirCallable.returnType: SirType
|
||||
get() = when (this) {
|
||||
is SirFunction -> this.returnType
|
||||
is SirGetter -> this.valueType
|
||||
|
||||
@@ -15,53 +15,45 @@ object SirPrinter : SirVisitor<String, Unit>() {
|
||||
return "UNKNOWN<${SirElement::class.simpleName}>($element)"
|
||||
}
|
||||
|
||||
override fun visitModule(element: SirModule, data: Unit): String = render(
|
||||
element,
|
||||
override fun visitModule(module: SirModule, data: Unit): String = render(
|
||||
module,
|
||||
listOf(
|
||||
"name" to element.name
|
||||
"name" to module.name
|
||||
),
|
||||
element.declarations
|
||||
module.declarations
|
||||
)
|
||||
|
||||
override fun visitEnum(element: SirEnum, data: Unit): String = render(
|
||||
element,
|
||||
override fun visitEnum(enum: SirEnum, data: Unit): String = render(
|
||||
enum,
|
||||
listOf(
|
||||
"origin" to element.origin,
|
||||
"visibility" to element.visibility,
|
||||
"name" to element.name,
|
||||
"cases" to element.cases
|
||||
"origin" to enum.origin,
|
||||
"visibility" to enum.visibility,
|
||||
"name" to enum.name,
|
||||
"cases" to enum.cases
|
||||
),
|
||||
element.declarations
|
||||
enum.declarations
|
||||
)
|
||||
|
||||
override fun visitStruct(element: SirStruct, data: Unit): String = render(
|
||||
element,
|
||||
override fun visitStruct(struct: SirStruct, data: Unit): String = render(
|
||||
struct,
|
||||
listOf(
|
||||
"origin" to element.origin,
|
||||
"visibility" to element.visibility,
|
||||
"name" to element.name
|
||||
"origin" to struct.origin,
|
||||
"visibility" to struct.visibility,
|
||||
"name" to struct.name
|
||||
),
|
||||
element.declarations
|
||||
struct.declarations
|
||||
)
|
||||
|
||||
override fun visitFunction(element: SirFunction, data: Unit): String = render(
|
||||
element,
|
||||
override fun visitFunction(function: SirFunction, data: Unit): String = render(
|
||||
function,
|
||||
listOf(
|
||||
"origin" to element.origin,
|
||||
"visibility" to element.visibility,
|
||||
"name" to element.name,
|
||||
"parameters" to element.parameters,
|
||||
"returnType" to element.returnType,
|
||||
"origin" to function.origin,
|
||||
"visibility" to function.visibility,
|
||||
"name" to function.name,
|
||||
"parameters" to function.parameters,
|
||||
"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(
|
||||
|
||||
@@ -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
|
||||
+2
-29
@@ -42,12 +42,6 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() {
|
||||
}
|
||||
}
|
||||
|
||||
val foreignDeclaration by sealedElement {
|
||||
parent(declaration)
|
||||
|
||||
visitorParameterName = "declaration"
|
||||
}
|
||||
|
||||
val named by sealedElement {
|
||||
+field("name", string)
|
||||
}
|
||||
@@ -78,15 +72,9 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() {
|
||||
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 {
|
||||
customParentInVisitor = callable
|
||||
parent(nativeCallable)
|
||||
parent(callable)
|
||||
|
||||
+field("isStatic", boolean) // todo: KT-65046 Method|function distinction in SIR
|
||||
+field("name", string)
|
||||
@@ -97,17 +85,9 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() {
|
||||
+field(name = "documentation", string, nullable = true, mutable = true)
|
||||
}
|
||||
|
||||
val foreignFunction by element {
|
||||
customParentInVisitor = callable
|
||||
parent(callable)
|
||||
parent(foreignDeclaration)
|
||||
|
||||
visitorParameterName = "function"
|
||||
}
|
||||
|
||||
val accessor by sealedElement {
|
||||
customParentInVisitor = callable
|
||||
parent(nativeCallable)
|
||||
parent(callable)
|
||||
|
||||
+field("body", functionBodyType, nullable = true, mutable = true)
|
||||
}
|
||||
@@ -136,13 +116,6 @@ object SwiftIrTree : AbstractSwiftIrTreeBuilder() {
|
||||
+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 {
|
||||
customParentInVisitor = declaration
|
||||
parent(declaration)
|
||||
|
||||
@@ -12,7 +12,6 @@ dependencies {
|
||||
compileOnly(kotlinStdlib())
|
||||
|
||||
implementation(project(":native:swift:sir"))
|
||||
implementation(project(":native:swift:sir-analysis-api"))
|
||||
implementation(project(":native:swift:sir-compiler-bridge"))
|
||||
implementation(project(":native:swift:sir-passes"))
|
||||
implementation(project(":native:swift:sir-printer"))
|
||||
|
||||
+18
-9
@@ -5,7 +5,10 @@
|
||||
|
||||
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.SirFunction
|
||||
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.SirGetter
|
||||
import org.jetbrains.kotlin.sir.util.*
|
||||
import org.jetbrains.kotlin.sir.SirKotlinOrigin
|
||||
import org.jetbrains.kotlin.sir.SirModule
|
||||
import org.jetbrains.kotlin.sir.bridge.BridgeRequest
|
||||
import org.jetbrains.kotlin.sir.bridge.createFunctionBodyFromRequest
|
||||
import org.jetbrains.kotlin.sir.visitors.SirVisitorVoid
|
||||
import org.jetbrains.sir.passes.SirPass
|
||||
import org.jetbrains.sir.passes.builder.KotlinSource
|
||||
import org.jetbrains.sir.passes.run
|
||||
|
||||
internal fun SirModule.buildFunctionBridges(): List<BridgeRequest> {
|
||||
@@ -39,7 +42,9 @@ private object BridgeGenerationPass : SirPass<SirElement, Nothing?, List<BridgeR
|
||||
}
|
||||
|
||||
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
|
||||
val fqNameForBridge = fqName.forBridge
|
||||
|
||||
@@ -53,7 +58,9 @@ private object BridgeGenerationPass : SirPass<SirElement, Nothing?, List<BridgeR
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
get() = when (this) {
|
||||
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>
|
||||
get() = if (this.count() == 1) {
|
||||
listOf("__root__", this.first()) // todo: should be changed with correct mangling KT-64970
|
||||
} else {
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
+6
-5
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.swiftexport.standalone.builders
|
||||
|
||||
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.standalone.KtAlwaysAccessibleLifetimeTokenProvider
|
||||
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.psi.KtFile
|
||||
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.buildModule
|
||||
import org.jetbrains.kotlin.swiftexport.standalone.SwiftExportInput
|
||||
import org.jetbrains.sir.passes.builder.buildSirDeclarationList
|
||||
|
||||
@OptIn(KtAnalysisApiInternals::class)
|
||||
internal fun buildSwiftModule(
|
||||
@@ -48,17 +49,17 @@ internal fun buildSwiftModule(
|
||||
ktFiles = ktFiles.sortedBy { it.name }
|
||||
}
|
||||
|
||||
|
||||
return buildModule {
|
||||
return analyze(sourceModule) {
|
||||
buildModule {
|
||||
name = sourceModule.moduleName
|
||||
val sirFactory = SirGenerator()
|
||||
declarations += buildImport {
|
||||
moduleName = bridgeModuleName
|
||||
}
|
||||
ktFiles.forEach { file ->
|
||||
declarations += sirFactory.build(file)
|
||||
declarations += buildSirDeclarationList(file)
|
||||
}
|
||||
}.apply {
|
||||
declarations.forEach { it.parent = this }
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -13,7 +13,6 @@ import org.jetbrains.sir.passes.SirInflatePackagesPass
|
||||
import org.jetbrains.sir.passes.SirModulePass
|
||||
import org.jetbrains.sir.passes.SirPass
|
||||
import org.jetbrains.sir.passes.run
|
||||
import org.jetbrains.sir.passes.translation.ForeignTranslationPass
|
||||
|
||||
internal fun SirModule.transformToSwift(): SirModule {
|
||||
return SirPassesConfiguration.passes.fold(this) { module, pass ->
|
||||
@@ -24,9 +23,9 @@ internal fun SirModule.transformToSwift(): SirModule {
|
||||
private object SirPassesConfiguration {
|
||||
val passes: List<SirModulePass> = listOf(
|
||||
SirInflatePackagesPass(),
|
||||
WholeModuleTranslationByElementPass(ForeignTranslationPass()),
|
||||
)
|
||||
|
||||
@Suppress("Unused")
|
||||
class WholeModuleTranslationByElementPass(
|
||||
val pass: SirPass<SirElement, Nothing?, SirDeclaration>
|
||||
) : SirModulePass {
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
#include <stdint.h>
|
||||
|
||||
int16_t __root___foo__TypesOfArguments__int32_t_double__(int32_t p, double p2);
|
||||
|
||||
+8
@@ -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
|
||||
}
|
||||
|
||||
+15
@@ -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)
|
||||
}
|
||||
+18
@@ -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();
|
||||
|
||||
+50
@@ -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
|
||||
}
|
||||
|
||||
+55
@@ -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
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
|
||||
internal fun foo_internal() = 123
|
||||
+7
@@ -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
|
||||
+5
@@ -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
|
||||
}
|
||||
-24
@@ -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
|
||||
+2
-2
@@ -4,9 +4,9 @@ int32_t namespace_main_foo_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();
|
||||
|
||||
|
||||
+2
-2
@@ -12,13 +12,13 @@ enum namespace {
|
||||
return namespace_main_bar_get()
|
||||
}
|
||||
set {
|
||||
namespace_main_bar_set(newValue)
|
||||
namespace_main_bar_set__TypesOfArguments__int32_t__(newValue)
|
||||
}
|
||||
}
|
||||
public static func foobar(
|
||||
param: Swift.Int32
|
||||
) -> Swift.Int32 {
|
||||
return namespace_main_foobar(param)
|
||||
return namespace_main_foobar__TypesOfArguments__int32_t__(param)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-6
@@ -25,15 +25,21 @@ public class SwiftExportRunnerTest extends AbstractSwiftRunnerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("no_package")
|
||||
public void testNo_package() throws Exception {
|
||||
runTest("native/swift/swift-export-standalone/testData/no_package/");
|
||||
@TestMetadata("documentation")
|
||||
public void testDocumentation() throws Exception {
|
||||
runTest("native/swift/swift-export-standalone/testData/documentation/");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("native/swift/swift-export-standalone/testData/simple/");
|
||||
@TestMetadata("functions")
|
||||
public void testFunctions() throws Exception {
|
||||
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
|
||||
|
||||
@@ -422,7 +422,6 @@ include ":native:swift:sir",
|
||||
":native:swift:sir:tree-generator",
|
||||
":native:swift:sir-passes",
|
||||
":native:swift:sir-printer",
|
||||
":native:swift:sir-analysis-api",
|
||||
":native:swift:sir-compiler-bridge",
|
||||
":native:swift:swift-export-standalone",
|
||||
":generators:sir-tests-generator"
|
||||
|
||||
Reference in New Issue
Block a user