[Swift Export]: KT-63280: Package inflation

Merge-request: KT-MR-13331
Merged-by: Gleb Lukianets <Gleb.Lukianets@jetbrains.com>
This commit is contained in:
Gleb Lukianets
2023-12-12 16:05:22 +00:00
committed by Space Team
parent 0b1c4b836a
commit 64ebec7955
17 changed files with 644 additions and 116 deletions
@@ -1,23 +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
sealed interface KotlinEntity
interface KotlinFunction : KotlinEntity {
val fqName: List<String>
val parameters: List<KotlinParameter>
val returnType: KotlinType
}
interface KotlinParameter : KotlinEntity {
val name: String
val type: KotlinType
}
interface KotlinType : KotlinEntity {
val name: String
}
@@ -8,4 +8,22 @@ package org.jetbrains.kotlin.sir
class SirEnumCase(
val name: String,
val parameters: List<SirParameter>
)
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other != null && this::class != other::class) return false
other as SirEnumCase
if (name != other.name) return false
if (parameters != other.parameters) return false
return true
}
override fun hashCode(): Int {
var result = name.hashCode()
result = 31 * result + parameters.hashCode()
return result
}
}
@@ -0,0 +1,27 @@
/*
* 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
sealed interface SirKotlinOrigin : SirOrigin.Foreign {
val fqName: List<String>
override val path: List<String>
get() = fqName
interface Function : SirKotlinOrigin {
val parameters: List<Parameter>
val returnType: Type
}
interface Parameter {
val name: String
val type: Type
}
interface Type {
val name: String
}
}
@@ -10,11 +10,18 @@ sealed interface SirOrigin {
data class ExternallyDefined(val name: String) : Synthetic
data class ForeignEntity(val entity: KotlinEntity): 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
}
/**
* Value for nodes of unknown or non-viable origin
* (e.g. objects created in/for tests)
*/
data object Unknown : SirOrigin
}
}
@@ -5,9 +5,29 @@
package org.jetbrains.kotlin.sir
data class SirParameter(
class SirParameter(
val argumentName: String? = null, // external function parameter (argument) name
val parameterName: String? = null, // internal function parameter name
val type: SirType,
/* TODO: val defaultValue: Expression? = null, */
)
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other != null && this::class != other::class) return false
other as SirParameter
if (argumentName != other.argumentName) return false
if (parameterName != other.parameterName) return false
if (type != other.type) return false
return true
}
override fun hashCode(): Int {
var result = argumentName?.hashCode() ?: 0
result = 31 * result + (parameterName?.hashCode() ?: 0)
result = 31 * result + type.hashCode()
return result
}
}
@@ -13,7 +13,9 @@ class SirNominalType(
) : SirType {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is SirNominalType) return false
if (other != null && this::class != other::class) return false
other as SirNominalType
if (type != other.type) return false
if (parent != other.parent) return false
@@ -30,4 +32,14 @@ class SirNominalType(
class SirExistentialType(
// TODO: Protocols. For now, only `any Any` is supported
) : SirType
) : SirType {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other != null && this::class != other::class) return false
return true
}
override fun hashCode(): Int {
return this::class.hashCode()
}
}
@@ -0,0 +1,97 @@
/*
* 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.util
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.visitors.SirVisitor
class SirComparator(val options: Set<Options> = emptySet()) : SirVisitor<Boolean, SirElement>() {
enum class Options {
POSITIONAL,
COMPARE_ORIGINS,
}
fun areEqual(lhs: SirElement, rhs: SirElement): Boolean = lhs.accept(this, rhs)
override fun visitElement(element: SirElement, data: SirElement): Boolean {
error("Comparison of ${element::class.simpleName} is unsupported")
}
override fun visitModule(module: SirModule, data: SirElement): Boolean {
return data is SirModule &&
module.name == data.name &&
visitDeclarationContainer(module, data)
}
override fun visitDeclarationContainer(declarationContainer: SirDeclarationContainer, data: SirElement): Boolean {
return data is SirDeclarationContainer && areEqual(declarationContainer.declarations, data.declarations)
}
override fun visitDeclaration(declaration: SirDeclaration, data: SirElement): Boolean {
return data is SirDeclaration &&
areEqual(data.origin, declaration.origin) &&
data.visibility == declaration.visibility
}
override fun visitEnum(enum: SirEnum, data: SirElement): Boolean {
return data is SirEnum &&
data.name == enum.name &&
data.cases == enum.cases &&
visitDeclaration(enum, data) &&
visitDeclarationContainer(enum, data)
}
override fun visitStruct(struct: SirStruct, data: SirElement): Boolean {
return data is SirStruct &&
data.name == struct.name &&
visitDeclaration(struct, data) &&
visitDeclarationContainer(struct, data)
}
override fun visitFunction(function: SirFunction, data: SirElement): Boolean {
return data is SirFunction &&
data.name == function.name &&
data.parameters == function.parameters &&
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 {
return options.contains(SirComparator.Options.POSITIONAL) &&
lhs.size == rhs.size &&
lhs.zip(rhs).all { areEqual(it.first, it.second) } ||
areEqualNonPositionally(lhs, rhs)
}
private fun SirComparator.areEqual(lhs: SirOrigin, rhs: SirOrigin): Boolean {
return !options.contains(SirComparator.Options.COMPARE_ORIGINS) || lhs == rhs
}
private fun SirComparator.areEqualNonPositionally(lhs: List<SirElement>, rhs: List<SirElement>): Boolean {
// FIXME: in the worst case scenario, this function is quadratic
if (lhs.size != rhs.size)
return false
val probedIndices = rhs.indices.toMutableSet()
lloop@ for (i in lhs.indices) {
for (j in probedIndices) {
if (areEqual(lhs[i], rhs[j])) {
probedIndices.remove(j)
continue@lloop
}
}
return false
}
return true
}
@@ -0,0 +1,85 @@
/*
* 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.util
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.visitors.SirVisitor
object SirPrinter : SirVisitor<String, Unit>() {
fun toString(element: SirElement): String = element.accept(this, Unit)
override fun visitElement(element: SirElement, data: Unit): String {
return "UNKNOWN<${SirElement::class.simpleName}>($element)"
}
override fun visitModule(element: SirModule, data: Unit): String = render(
element,
listOf(
"name" to element.name
),
element.declarations
)
override fun visitEnum(element: SirEnum, data: Unit): String = render(
element,
listOf(
"origin" to element.origin,
"visibility" to element.visibility,
"name" to element.name,
"cases" to element.cases
),
element.declarations
)
override fun visitStruct(element: SirStruct, data: Unit): String = render(
element,
listOf(
"origin" to element.origin,
"visibility" to element.visibility,
"name" to element.name
),
element.declarations
)
override fun visitFunction(element: SirFunction, data: Unit): String = render(
element,
listOf(
"origin" to element.origin,
"visibility" to element.visibility,
"name" to element.name,
"parameters" to element.parameters,
"returnType" to element.returnType,
)
)
override fun visitForeignFunction(element: SirForeignFunction, data: Unit): String = render(
element,
listOf(
"origin" to element.origin,
"visibility" to element.visibility,
),
)
}
private fun render(
base: SirElement,
attributes: List<Pair<String, Any?>> = emptyList(),
children: List<SirElement> = emptyList(),
): String {
return "${base::class.simpleName}${attributes.renderAsAttributres()} ${children.renderAsChildren()}"
}
private fun List<SirElement>.renderAsChildren(): String {
return this.takeIf { isNotEmpty() }?.joinToString(prefix = "{\n", separator = "\n", postfix = "\n}") {
SirPrinter.toString(it).prependIndent(" ")
} ?: "{}"
}
private fun List<Pair<String, Any?>>.renderAsAttributres(): String {
return this.takeIf { isNotEmpty() }?.joinToString(prefix = "(\n", separator = "\n", postfix = "\n)") {
" ${it.first}: ${it.second}"
} ?: "()"
}
@@ -26,20 +26,9 @@ class SirTest {
private fun produceSwiftElement(): Any {
return buildEnum {
origin = SirOrigin.ForeignEntity(
MockFunction(
fqName = listOf("foo"),
parameters = listOf(
MockParameter(
name = "arg1",
type = MockKotlinType(BYTE),
)
),
returnType = MockKotlinType("kotlin/Byte")
)
)
name = "MyEnum"
origin = SirOrigin.Unknown
name = "name"
visibility = SirVisibility.PUBLIC
}
}
}
}
@@ -5,21 +5,19 @@
package org.jetbrains.kotlin.sir.mock
import org.jetbrains.kotlin.sir.KotlinFunction
import org.jetbrains.kotlin.sir.KotlinType
import org.jetbrains.kotlin.sir.KotlinParameter
import org.jetbrains.kotlin.sir.SirKotlinOrigin
data class MockFunction(
override val fqName: List<String>,
override val parameters: List<KotlinParameter>,
override val returnType: KotlinType,
) : KotlinFunction
override val parameters: List<SirKotlinOrigin.Parameter>,
override val returnType: SirKotlinOrigin.Type,
) : SirKotlinOrigin.Function
data class MockParameter(
override val name: String,
override val type: KotlinType,
) : KotlinParameter
override val type: SirKotlinOrigin.Type,
) : SirKotlinOrigin.Parameter
data class MockKotlinType(
override val name: String
) : KotlinType
) : SirKotlinOrigin.Type