[Commonizer] Create approximation keys based on Cir instead of metadata
This commit is contained in:
committed by
Space
parent
09f9a1ce5b
commit
f3ff9814a8
@@ -82,7 +82,7 @@ data class CirPropertyImpl(
|
|||||||
override val kind: CallableMemberDescriptor.Kind,
|
override val kind: CallableMemberDescriptor.Kind,
|
||||||
override val isVar: Boolean,
|
override val isVar: Boolean,
|
||||||
override val isLateInit: Boolean,
|
override val isLateInit: Boolean,
|
||||||
override var isConst: Boolean,
|
override val isConst: Boolean,
|
||||||
override val isDelegate: Boolean,
|
override val isDelegate: Boolean,
|
||||||
override val getter: CirPropertyGetter?,
|
override val getter: CirPropertyGetter?,
|
||||||
override val setter: CirPropertySetter?,
|
override val setter: CirPropertySetter?,
|
||||||
|
|||||||
+47
-5
@@ -8,9 +8,7 @@ package org.jetbrains.kotlin.commonizer.core
|
|||||||
import org.jetbrains.kotlin.commonizer.cir.*
|
import org.jetbrains.kotlin.commonizer.cir.*
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirConstantValue.*
|
import org.jetbrains.kotlin.commonizer.cir.CirConstantValue.*
|
||||||
import org.jetbrains.kotlin.commonizer.core.AnnotationsCommonizer.Companion.FALLBACK_MESSAGE
|
import org.jetbrains.kotlin.commonizer.core.AnnotationsCommonizer.Companion.FALLBACK_MESSAGE
|
||||||
import org.jetbrains.kotlin.commonizer.utils.DEPRECATED_ANNOTATION_CLASS_ID
|
import org.jetbrains.kotlin.commonizer.utils.*
|
||||||
import org.jetbrains.kotlin.commonizer.utils.compactMap
|
|
||||||
import org.jetbrains.kotlin.commonizer.utils.compactMapOf
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import kotlin.DeprecationLevel.WARNING
|
import kotlin.DeprecationLevel.WARNING
|
||||||
|
|
||||||
@@ -19,15 +17,38 @@ import kotlin.DeprecationLevel.WARNING
|
|||||||
*/
|
*/
|
||||||
class AnnotationsCommonizer : AbstractStandardCommonizer<List<CirAnnotation>, List<CirAnnotation>>() {
|
class AnnotationsCommonizer : AbstractStandardCommonizer<List<CirAnnotation>, List<CirAnnotation>>() {
|
||||||
private var deprecatedAnnotationCommonizer: DeprecatedAnnotationCommonizer? = null
|
private var deprecatedAnnotationCommonizer: DeprecatedAnnotationCommonizer? = null
|
||||||
|
private var deprecatedAnnotationCommonizerHasResult: Boolean = true
|
||||||
|
|
||||||
|
private val objCInteropCallableAnnotationCommonizer = ObjCInteropCallableAnnotationCommonizer.asCommonizer()
|
||||||
|
private var objCInteropCallableAnnotationCommonizerHasResult = true
|
||||||
|
|
||||||
override fun commonizationResult(): List<CirAnnotation> {
|
override fun commonizationResult(): List<CirAnnotation> {
|
||||||
val deprecatedAnnotation = deprecatedAnnotationCommonizer?.result ?: return emptyList()
|
val deprecatedAnnotation = if (deprecatedAnnotationCommonizerHasResult)
|
||||||
return listOf(deprecatedAnnotation)
|
deprecatedAnnotationCommonizer?.result else null
|
||||||
|
|
||||||
|
val objCInteropCallableAnnotations = if (objCInteropCallableAnnotationCommonizerHasResult)
|
||||||
|
objCInteropCallableAnnotationCommonizer.result else emptyList()
|
||||||
|
|
||||||
|
return if (deprecatedAnnotation != null) {
|
||||||
|
objCInteropCallableAnnotations.plus(deprecatedAnnotation)
|
||||||
|
} else objCInteropCallableAnnotations
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun initialize(first: List<CirAnnotation>) = Unit
|
override fun initialize(first: List<CirAnnotation>) = Unit
|
||||||
|
|
||||||
override fun doCommonizeWith(next: List<CirAnnotation>): Boolean {
|
override fun doCommonizeWith(next: List<CirAnnotation>): Boolean {
|
||||||
|
if (deprecatedAnnotationCommonizerHasResult) {
|
||||||
|
deprecatedAnnotationCommonizerHasResult = doCommonizeDeprecatedAnnotation(next)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objCInteropCallableAnnotationCommonizerHasResult) {
|
||||||
|
objCInteropCallableAnnotationCommonizerHasResult = objCInteropCallableAnnotationCommonizer.commonizeWith(next)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doCommonizeDeprecatedAnnotation(next: List<CirAnnotation>): Boolean {
|
||||||
val nextDeprecatedAnnotation = next.firstOrNull { it.type.classifierId == DEPRECATED_ANNOTATION_CLASS_ID } ?: return true
|
val nextDeprecatedAnnotation = next.firstOrNull { it.type.classifierId == DEPRECATED_ANNOTATION_CLASS_ID } ?: return true
|
||||||
|
|
||||||
val deprecatedAnnotationCommonizer = deprecatedAnnotationCommonizer
|
val deprecatedAnnotationCommonizer = deprecatedAnnotationCommonizer
|
||||||
@@ -41,6 +62,27 @@ class AnnotationsCommonizer : AbstractStandardCommonizer<List<CirAnnotation>, Li
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object ObjCInteropCallableAnnotationCommonizer : AssociativeCommonizer<List<CirAnnotation>> {
|
||||||
|
override fun commonize(first: List<CirAnnotation>, second: List<CirAnnotation>): List<CirAnnotation> {
|
||||||
|
return if (first.any { it.type.classifierId.isObjCInteropCallableAnnotation } &&
|
||||||
|
second.any { it.type.classifierId.isObjCInteropCallableAnnotation }
|
||||||
|
) {
|
||||||
|
objCCallableAnnotationList
|
||||||
|
} else emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val objCCallableAnnotation = CirAnnotation.createInterned(
|
||||||
|
CirClassType.createInterned(
|
||||||
|
classId = COMMONIZER_OBJC_INTEROP_CALLABLE_ANNOTATION_ID,
|
||||||
|
outerType = null, visibility = Visibilities.Public, arguments = emptyList(), isMarkedNullable = false
|
||||||
|
),
|
||||||
|
constantValueArguments = emptyMap(),
|
||||||
|
annotationValueArguments = emptyMap()
|
||||||
|
)
|
||||||
|
|
||||||
|
private val objCCallableAnnotationList = listOf(objCCallableAnnotation)
|
||||||
|
}
|
||||||
|
|
||||||
private class DeprecatedAnnotationCommonizer : Commonizer<CirAnnotation, CirAnnotation> {
|
private class DeprecatedAnnotationCommonizer : Commonizer<CirAnnotation, CirAnnotation> {
|
||||||
private var level: DeprecationLevel? = null // null level means that state is empty
|
private var level: DeprecationLevel? = null // null level means that state is empty
|
||||||
private var message: String? = null // null -> message is not equal
|
private var message: String? = null // null -> message is not equal
|
||||||
|
|||||||
+3
-1
@@ -18,13 +18,14 @@ class ClassConstructorCommonizer(
|
|||||||
private val visibility = VisibilityCommonizer.equalizing()
|
private val visibility = VisibilityCommonizer.equalizing()
|
||||||
private val typeParameters = TypeParameterListCommonizer(classifiers)
|
private val typeParameters = TypeParameterListCommonizer(classifiers)
|
||||||
private val valueParameters = CallableValueParametersCommonizer(classifiers)
|
private val valueParameters = CallableValueParametersCommonizer(classifiers)
|
||||||
|
private val annotationsCommonizer = AnnotationsCommonizer()
|
||||||
|
|
||||||
override fun commonizationResult(): CirClassConstructor {
|
override fun commonizationResult(): CirClassConstructor {
|
||||||
val valueParameters = valueParameters.result
|
val valueParameters = valueParameters.result
|
||||||
valueParameters.patchCallables()
|
valueParameters.patchCallables()
|
||||||
|
|
||||||
return CirClassConstructor.create(
|
return CirClassConstructor.create(
|
||||||
annotations = emptyList(),
|
annotations = annotationsCommonizer.result,
|
||||||
typeParameters = typeParameters.result,
|
typeParameters = typeParameters.result,
|
||||||
visibility = visibility.result,
|
visibility = visibility.result,
|
||||||
containingClass = CONTAINING_CLASS_DOES_NOT_MATTER, // does not matter
|
containingClass = CONTAINING_CLASS_DOES_NOT_MATTER, // does not matter
|
||||||
@@ -45,6 +46,7 @@ class ClassConstructorCommonizer(
|
|||||||
&& visibility.commonizeWith(next)
|
&& visibility.commonizeWith(next)
|
||||||
&& typeParameters.commonizeWith(next.typeParameters)
|
&& typeParameters.commonizeWith(next.typeParameters)
|
||||||
&& valueParameters.commonizeWith(next)
|
&& valueParameters.commonizeWith(next)
|
||||||
|
&& annotationsCommonizer.commonizeWith(next.annotations)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.commonizer.mergedtree
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirClass
|
||||||
|
|
||||||
|
internal class CirMemberContext private constructor(val classes: List<CirClass>) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val empty = CirMemberContext(emptyList())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun withContextOf(clazz: CirClass) = CirMemberContext(classes = classes + clazz)
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
other as CirMemberContext
|
||||||
|
if (classes != other.classes) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return classes.hashCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
+168
-41
@@ -3,50 +3,61 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("FunctionName")
|
||||||
|
|
||||||
package org.jetbrains.kotlin.commonizer.mergedtree
|
package org.jetbrains.kotlin.commonizer.mergedtree
|
||||||
|
|
||||||
import kotlinx.metadata.*
|
import gnu.trove.TIntHashSet
|
||||||
import kotlinx.metadata.klib.annotations
|
import org.jetbrains.kotlin.commonizer.cir.*
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirName
|
import org.jetbrains.kotlin.commonizer.utils.Interner
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirTypeSignature
|
|
||||||
import org.jetbrains.kotlin.commonizer.core.Commonizer
|
|
||||||
import org.jetbrains.kotlin.commonizer.metadata.CirTypeParameterResolver
|
|
||||||
import org.jetbrains.kotlin.commonizer.utils.appendHashCode
|
import org.jetbrains.kotlin.commonizer.utils.appendHashCode
|
||||||
import org.jetbrains.kotlin.commonizer.utils.computeSignature
|
|
||||||
import org.jetbrains.kotlin.commonizer.utils.hashCode
|
import org.jetbrains.kotlin.commonizer.utils.hashCode
|
||||||
import org.jetbrains.kotlin.commonizer.utils.isObjCInteropCallableAnnotation
|
import org.jetbrains.kotlin.commonizer.utils.isObjCInteropCallableAnnotation
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
|
|
||||||
|
typealias ObjCFunctionApproximation = Int
|
||||||
|
|
||||||
/** Used for approximation of [KmProperty]s before running concrete [Commonizer]s */
|
|
||||||
data class PropertyApproximationKey(
|
data class PropertyApproximationKey(
|
||||||
val name: CirName,
|
val name: CirName,
|
||||||
val extensionReceiverParameterType: CirTypeSignature?
|
val extensionReceiverParameterType: CirTypeSignature?
|
||||||
) {
|
) {
|
||||||
constructor(property: KmProperty, typeParameterResolver: CirTypeParameterResolver) : this(
|
companion object {
|
||||||
CirName.create(property.name),
|
internal fun create(context: CirMemberContext, property: CirProperty): PropertyApproximationKey {
|
||||||
property.receiverParameterType?.computeSignature(typeParameterResolver)
|
return PropertyApproximationKey(
|
||||||
)
|
name = property.name,
|
||||||
|
extensionReceiverParameterType = property.extensionReceiver
|
||||||
|
?.let { buildApproximationSignature(SignatureBuildingContext.create(context, property), it.type) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Used for approximation of [KmFunction]s before running concrete [Commonizer]s */
|
|
||||||
data class FunctionApproximationKey(
|
data class FunctionApproximationKey(
|
||||||
val name: CirName,
|
val name: CirName,
|
||||||
val valueParametersTypes: Array<CirTypeSignature>,
|
val valueParametersTypes: Array<CirTypeSignature>,
|
||||||
private val additionalValueParametersNamesHash: Int,
|
val extensionReceiverParameterType: CirTypeSignature?,
|
||||||
val extensionReceiverParameterType: CirTypeSignature?
|
val objCFunctionApproximation: ObjCFunctionApproximation
|
||||||
) {
|
) {
|
||||||
constructor(function: KmFunction, typeParameterResolver: CirTypeParameterResolver) : this(
|
|
||||||
CirName.create(function.name),
|
companion object {
|
||||||
function.valueParameters.computeSignatures(typeParameterResolver),
|
internal fun create(context: CirMemberContext, function: CirFunction): FunctionApproximationKey {
|
||||||
additionalValueParameterNamesHash(function.annotations, function.valueParameters),
|
return FunctionApproximationKey(
|
||||||
function.receiverParameterType?.computeSignature(typeParameterResolver)
|
name = function.name,
|
||||||
)
|
valueParametersTypes = valueParameterTypes(context, function),
|
||||||
|
extensionReceiverParameterType = function.extensionReceiver
|
||||||
|
?.let { buildApproximationSignature(SignatureBuildingContext.create(context, function), it.type) },
|
||||||
|
objCFunctionApproximation = objCFunctionApproximation(function)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is FunctionApproximationKey)
|
if (other !is FunctionApproximationKey)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
return name == other.name
|
return name == other.name
|
||||||
&& additionalValueParametersNamesHash == other.additionalValueParametersNamesHash
|
&& objCFunctionApproximation == other.objCFunctionApproximation
|
||||||
&& valueParametersTypes.contentEquals(other.valueParametersTypes)
|
&& valueParametersTypes.contentEquals(other.valueParametersTypes)
|
||||||
&& extensionReceiverParameterType == other.extensionReceiverParameterType
|
&& extensionReceiverParameterType == other.extensionReceiverParameterType
|
||||||
}
|
}
|
||||||
@@ -54,39 +65,155 @@ data class FunctionApproximationKey(
|
|||||||
override fun hashCode() = hashCode(name)
|
override fun hashCode() = hashCode(name)
|
||||||
.appendHashCode(valueParametersTypes)
|
.appendHashCode(valueParametersTypes)
|
||||||
.appendHashCode(extensionReceiverParameterType)
|
.appendHashCode(extensionReceiverParameterType)
|
||||||
.appendHashCode(additionalValueParametersNamesHash)
|
.appendHashCode(objCFunctionApproximation)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Used for approximation of [KmConstructor]s before running concrete [Commonizer]s */
|
|
||||||
data class ConstructorApproximationKey(
|
data class ConstructorApproximationKey(
|
||||||
val valueParametersTypes: Array<CirTypeSignature>,
|
val valueParametersTypes: Array<CirTypeSignature>,
|
||||||
private val additionalValueParametersNamesHash: Int
|
private val objCFunctionApproximation: ObjCFunctionApproximation
|
||||||
) {
|
) {
|
||||||
constructor(constructor: KmConstructor, typeParameterResolver: CirTypeParameterResolver) : this(
|
|
||||||
constructor.valueParameters.computeSignatures(typeParameterResolver),
|
companion object {
|
||||||
additionalValueParameterNamesHash(constructor.annotations, constructor.valueParameters)
|
internal fun create(context: CirMemberContext, constructor: CirClassConstructor): ConstructorApproximationKey {
|
||||||
)
|
return ConstructorApproximationKey(
|
||||||
|
valueParametersTypes = valueParameterTypes(context, constructor),
|
||||||
|
objCFunctionApproximation = objCFunctionApproximation(constructor)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is ConstructorApproximationKey)
|
if (other !is ConstructorApproximationKey)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
return additionalValueParametersNamesHash == other.additionalValueParametersNamesHash
|
return objCFunctionApproximation == other.objCFunctionApproximation
|
||||||
&& valueParametersTypes.contentEquals(other.valueParametersTypes)
|
&& valueParametersTypes.contentEquals(other.valueParametersTypes)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode() = hashCode(valueParametersTypes)
|
override fun hashCode() = hashCode(valueParametersTypes)
|
||||||
.appendHashCode(additionalValueParametersNamesHash)
|
.appendHashCode(objCFunctionApproximation)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
private fun <T> objCFunctionApproximation(value: T): ObjCFunctionApproximation
|
||||||
private inline fun List<KmValueParameter>.computeSignatures(typeParameterResolver: CirTypeParameterResolver): Array<CirTypeSignature> =
|
where T : CirHasAnnotations, T : CirCallableMemberWithParameters {
|
||||||
if (isEmpty()) emptyArray() else Array(size) { index -> this[index].type?.computeSignature(typeParameterResolver).orEmpty() }
|
return if (value.annotations.any { it.type.classifierId.isObjCInteropCallableAnnotation }) {
|
||||||
|
value.valueParameters.fold(0) { acc, next -> acc.appendHashCode(next.name) }
|
||||||
private fun additionalValueParameterNamesHash(annotations: List<KmAnnotation>, valueParameters: List<KmValueParameter>): Int {
|
} else 0
|
||||||
// TODO: add more precise checks when more languages than C & ObjC are supported
|
}
|
||||||
if (annotations.none { it.isObjCInteropCallableAnnotation })
|
|
||||||
return 0 // do not calculate hash for non-ObjC callables
|
private fun <T> valueParameterTypes(context: CirMemberContext, callable: T): Array<CirTypeSignature>
|
||||||
|
where T : CirHasTypeParameters, T : CirCallableMemberWithParameters, T : CirMaybeCallableMemberOfClass {
|
||||||
return valueParameters.fold(0) { acc, next -> acc.appendHashCode(next.name) }
|
if (callable.valueParameters.isEmpty()) return emptyArray()
|
||||||
|
return Array(callable.valueParameters.size) { index ->
|
||||||
|
val parameter = callable.valueParameters[index]
|
||||||
|
buildApproximationSignature(SignatureBuildingContext.create(context, callable), parameter.returnType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val typeSignatureInterner = Interner<CirTypeSignature>()
|
||||||
|
|
||||||
|
internal fun buildApproximationSignature(context: SignatureBuildingContext, type: CirType): CirTypeSignature {
|
||||||
|
return typeSignatureInterner.intern(StringBuilder().apply { appendTypeApproximationSignature(context, type) }.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun StringBuilder.appendTypeApproximationSignature(context: SignatureBuildingContext, type: CirType) {
|
||||||
|
return when (type) {
|
||||||
|
is CirFlexibleType -> appendFlexibleTypeApproximationSignature(context, type)
|
||||||
|
is CirTypeParameterType -> appendTypeParameterTypeApproximationSignature(context.forTypeParameterTypes(), type)
|
||||||
|
is CirClassOrTypeAliasType -> appendClassOrTypeAliasTypeApproximationSignature(context, type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun StringBuilder.appendClassOrTypeAliasTypeApproximationSignature(
|
||||||
|
context: SignatureBuildingContext, type: CirClassOrTypeAliasType
|
||||||
|
) {
|
||||||
|
append(type.classifierId.toString())
|
||||||
|
if (type.arguments.isNotEmpty()) {
|
||||||
|
append("<")
|
||||||
|
type.arguments.forEachIndexed { index, argument ->
|
||||||
|
when (argument) {
|
||||||
|
is CirRegularTypeProjection -> {
|
||||||
|
when (argument.projectionKind) {
|
||||||
|
Variance.INVARIANT -> Unit
|
||||||
|
Variance.IN_VARIANCE -> append("in ")
|
||||||
|
Variance.OUT_VARIANCE -> append("out ")
|
||||||
|
}
|
||||||
|
appendTypeApproximationSignature(context, argument.type)
|
||||||
|
}
|
||||||
|
is CirStarTypeProjection -> append("*")
|
||||||
|
}
|
||||||
|
if (index != type.arguments.lastIndex) {
|
||||||
|
append(", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
append(">")
|
||||||
|
}
|
||||||
|
if (type.isMarkedNullable) append("?")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun StringBuilder.appendTypeParameterTypeApproximationSignature(
|
||||||
|
context: TypeParameterTypeSignatureBuildingContext, type: CirTypeParameterType
|
||||||
|
) {
|
||||||
|
val typeParameter = context.resolveTypeParameter(type.index)
|
||||||
|
append(typeParameter.name)
|
||||||
|
if (context.isVisitedFirstTime(type.index)) {
|
||||||
|
append(" : [")
|
||||||
|
typeParameter.upperBounds.forEachIndexed { index, upperBound ->
|
||||||
|
appendTypeApproximationSignature(context, upperBound)
|
||||||
|
if (index != typeParameter.upperBounds.lastIndex) append(", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
append("]")
|
||||||
|
if (type.isMarkedNullable) append("?")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun StringBuilder.appendFlexibleTypeApproximationSignature(
|
||||||
|
context: SignatureBuildingContext, type: CirFlexibleType
|
||||||
|
) {
|
||||||
|
appendTypeApproximationSignature(context, type.lowerBound)
|
||||||
|
append("..")
|
||||||
|
appendTypeApproximationSignature(context, type.upperBound)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed interface SignatureBuildingContext {
|
||||||
|
companion object {
|
||||||
|
fun create(memberContext: CirMemberContext, functionOrPropertyOrConstructor: CirHasTypeParameters): SignatureBuildingContext {
|
||||||
|
return DefaultSignatureBuildingContext(memberContext, functionOrPropertyOrConstructor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun SignatureBuildingContext.forTypeParameterTypes(): TypeParameterTypeSignatureBuildingContext = when (this) {
|
||||||
|
is DefaultSignatureBuildingContext -> TypeParameterTypeSignatureBuildingContext(memberContext, functionOrPropertyOrConstructor)
|
||||||
|
is TypeParameterTypeSignatureBuildingContext -> this
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DefaultSignatureBuildingContext(
|
||||||
|
val memberContext: CirMemberContext,
|
||||||
|
val functionOrPropertyOrConstructor: CirHasTypeParameters
|
||||||
|
) : SignatureBuildingContext
|
||||||
|
|
||||||
|
private class TypeParameterTypeSignatureBuildingContext(
|
||||||
|
private val memberContext: CirMemberContext,
|
||||||
|
private val functionOrPropertyOrConstructor: CirHasTypeParameters
|
||||||
|
) : SignatureBuildingContext {
|
||||||
|
|
||||||
|
private val alreadyVisitedParameterTypeIndices = TIntHashSet()
|
||||||
|
|
||||||
|
fun isVisitedFirstTime(typeParameterIndex: Int): Boolean {
|
||||||
|
return alreadyVisitedParameterTypeIndices.add(typeParameterIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resolveTypeParameter(index: Int): CirTypeParameter {
|
||||||
|
var indexOffset = 0
|
||||||
|
memberContext.classes.forEach { clazz ->
|
||||||
|
val indexInClass = index - indexOffset
|
||||||
|
if (indexInClass >= 0 && indexInClass <= clazz.typeParameters.lastIndex) {
|
||||||
|
return clazz.typeParameters[indexInClass]
|
||||||
|
}
|
||||||
|
indexOffset += clazz.typeParameters.size
|
||||||
|
}
|
||||||
|
|
||||||
|
return functionOrPropertyOrConstructor.typeParameters[index - indexOffset]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,22 +21,12 @@ data class CirTreeModule(
|
|||||||
|
|
||||||
data class CirTreePackage(
|
data class CirTreePackage(
|
||||||
val pkg: CirPackage,
|
val pkg: CirPackage,
|
||||||
val properties: List<CirTreeProperty> = emptyList(),
|
val properties: List<CirProperty> = emptyList(),
|
||||||
val functions: List<CirTreeFunction> = emptyList(),
|
val functions: List<CirFunction> = emptyList(),
|
||||||
val classes: List<CirTreeClass> = emptyList(),
|
val classes: List<CirTreeClass> = emptyList(),
|
||||||
val typeAliases: List<CirTreeTypeAlias> = emptyList()
|
val typeAliases: List<CirTreeTypeAlias> = emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
data class CirTreeProperty(
|
|
||||||
val approximationKey: PropertyApproximationKey,
|
|
||||||
val property: CirProperty
|
|
||||||
)
|
|
||||||
|
|
||||||
data class CirTreeFunction(
|
|
||||||
val approximationKey: FunctionApproximationKey,
|
|
||||||
val function: CirFunction
|
|
||||||
)
|
|
||||||
|
|
||||||
sealed interface CirTreeClassifier {
|
sealed interface CirTreeClassifier {
|
||||||
val id: CirEntityId
|
val id: CirEntityId
|
||||||
}
|
}
|
||||||
@@ -49,14 +39,10 @@ data class CirTreeTypeAlias(
|
|||||||
data class CirTreeClass(
|
data class CirTreeClass(
|
||||||
override val id: CirEntityId,
|
override val id: CirEntityId,
|
||||||
val clazz: CirClass,
|
val clazz: CirClass,
|
||||||
val properties: List<CirTreeProperty> = emptyList(),
|
val properties: List<CirProperty> = emptyList(),
|
||||||
val functions: List<CirTreeFunction> = emptyList(),
|
val functions: List<CirFunction> = emptyList(),
|
||||||
val constructors: List<CirTreeClassConstructor> = emptyList(),
|
val constructors: List<CirClassConstructor> = emptyList(),
|
||||||
val classes: List<CirTreeClass> = emptyList(),
|
val classes: List<CirTreeClass> = emptyList(),
|
||||||
) : CirTreeClassifier
|
) : CirTreeClassifier
|
||||||
|
|
||||||
class CirTreeClassConstructor(
|
|
||||||
val approximationKey: ConstructorApproximationKey,
|
|
||||||
val constructor: CirClassConstructor
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ internal fun CirPackageNode.assembleCirTree(): CirTreePackage? {
|
|||||||
|
|
||||||
return CirTreePackage(
|
return CirTreePackage(
|
||||||
pkg = commonizedPackage,
|
pkg = commonizedPackage,
|
||||||
properties = properties.mapNotNull { (key, property) -> property.assembleCirTree(key) },
|
properties = properties.mapNotNull { (key, property) -> property.commonDeclaration() },
|
||||||
functions = functions.mapNotNull { (key, function) -> function.assembleCirTree(key) },
|
functions = functions.mapNotNull { (key, function) -> function.commonDeclaration() },
|
||||||
typeAliases = commonizedTypeAliases.filterIsInstance<CirTreeTypeAlias>(),
|
typeAliases = commonizedTypeAliases.filterIsInstance<CirTreeTypeAlias>(),
|
||||||
classes = classes.mapNotNull { (_, clazz) -> clazz.assembleCirTree() } + commonizedTypeAliases.filterIsInstance<CirTreeClass>()
|
classes = classes.mapNotNull { (_, clazz) -> clazz.assembleCirTree() } + commonizedTypeAliases.filterIsInstance<CirTreeClass>()
|
||||||
)
|
)
|
||||||
@@ -39,9 +39,9 @@ internal fun CirClassNode.assembleCirTree(): CirTreeClass? {
|
|||||||
return CirTreeClass(
|
return CirTreeClass(
|
||||||
id = id,
|
id = id,
|
||||||
clazz = commonDeclaration() ?: return null,
|
clazz = commonDeclaration() ?: return null,
|
||||||
properties = properties.mapNotNull { (key, property) -> property.assembleCirTree(key) },
|
properties = properties.mapNotNull { (key, property) -> property.commonDeclaration() },
|
||||||
functions = functions.mapNotNull { (key, function) -> function.assembleCirTree(key) },
|
functions = functions.mapNotNull { (key, function) -> function.commonDeclaration() },
|
||||||
constructors = constructors.mapNotNull { (key, constructor) -> constructor.assembleCirTree(key) },
|
constructors = constructors.mapNotNull { (key, constructor) -> constructor.commonDeclaration() },
|
||||||
classes = classes.mapNotNull { (_, clazz) -> clazz.assembleCirTree() }
|
classes = classes.mapNotNull { (_, clazz) -> clazz.assembleCirTree() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -54,24 +54,3 @@ internal fun CirTypeAliasNode.assembleCirTree(): CirTreeClassifier? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun CirPropertyNode.assembleCirTree(approximationKey: PropertyApproximationKey): CirTreeProperty? {
|
|
||||||
return CirTreeProperty(
|
|
||||||
approximationKey = approximationKey,
|
|
||||||
property = commonDeclaration() ?: return null,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun CirFunctionNode.assembleCirTree(approximationKey: FunctionApproximationKey): CirTreeFunction? {
|
|
||||||
return CirTreeFunction(
|
|
||||||
approximationKey = approximationKey,
|
|
||||||
function = commonDeclaration() ?: return null,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun CirClassConstructorNode.assembleCirTree(approximationKey: ConstructorApproximationKey): CirTreeClassConstructor? {
|
|
||||||
return CirTreeClassConstructor(
|
|
||||||
approximationKey = approximationKey,
|
|
||||||
constructor = commonDeclaration() ?: return null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
+6
-10
@@ -6,23 +6,19 @@
|
|||||||
package org.jetbrains.kotlin.commonizer.tree.deserializer
|
package org.jetbrains.kotlin.commonizer.tree.deserializer
|
||||||
|
|
||||||
import kotlinx.metadata.KmConstructor
|
import kotlinx.metadata.KmConstructor
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirClassConstructor
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirContainingClass
|
import org.jetbrains.kotlin.commonizer.cir.CirContainingClass
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.ConstructorApproximationKey
|
|
||||||
import org.jetbrains.kotlin.commonizer.metadata.CirDeserializers
|
import org.jetbrains.kotlin.commonizer.metadata.CirDeserializers
|
||||||
import org.jetbrains.kotlin.commonizer.metadata.CirTypeResolver
|
import org.jetbrains.kotlin.commonizer.metadata.CirTypeResolver
|
||||||
import org.jetbrains.kotlin.commonizer.tree.CirTreeClassConstructor
|
|
||||||
|
|
||||||
internal object CirTreeClassConstructorDeserializer {
|
internal object CirTreeClassConstructorDeserializer {
|
||||||
operator fun invoke(
|
operator fun invoke(
|
||||||
constructor: KmConstructor, containingClass: CirContainingClass, typeResolver: CirTypeResolver
|
constructor: KmConstructor, containingClass: CirContainingClass, typeResolver: CirTypeResolver
|
||||||
): CirTreeClassConstructor {
|
): CirClassConstructor {
|
||||||
return CirTreeClassConstructor(
|
return CirDeserializers.constructor(
|
||||||
approximationKey = ConstructorApproximationKey(constructor, typeResolver),
|
source = constructor,
|
||||||
constructor = CirDeserializers.constructor(
|
containingClass = containingClass,
|
||||||
source = constructor,
|
typeResolver = typeResolver
|
||||||
containingClass = containingClass,
|
|
||||||
typeResolver = typeResolver
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-12
@@ -8,16 +8,16 @@ package org.jetbrains.kotlin.commonizer.tree.deserializer
|
|||||||
import kotlinx.metadata.KmFunction
|
import kotlinx.metadata.KmFunction
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirClass
|
import org.jetbrains.kotlin.commonizer.cir.CirClass
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirContainingClass
|
import org.jetbrains.kotlin.commonizer.cir.CirContainingClass
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.FunctionApproximationKey
|
import org.jetbrains.kotlin.commonizer.cir.CirFunction
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirName
|
||||||
import org.jetbrains.kotlin.commonizer.metadata.CirDeserializers
|
import org.jetbrains.kotlin.commonizer.metadata.CirDeserializers
|
||||||
import org.jetbrains.kotlin.commonizer.metadata.CirTypeResolver
|
import org.jetbrains.kotlin.commonizer.metadata.CirTypeResolver
|
||||||
import org.jetbrains.kotlin.commonizer.tree.CirTreeFunction
|
|
||||||
import org.jetbrains.kotlin.commonizer.utils.isFakeOverride
|
import org.jetbrains.kotlin.commonizer.utils.isFakeOverride
|
||||||
import org.jetbrains.kotlin.commonizer.utils.isKniBridgeFunction
|
import org.jetbrains.kotlin.commonizer.utils.isKniBridgeFunction
|
||||||
import org.jetbrains.kotlin.commonizer.utils.isTopLevelDeprecatedFunction
|
import org.jetbrains.kotlin.commonizer.utils.isTopLevelDeprecatedFunction
|
||||||
|
|
||||||
object CirTreeFunctionDeserializer {
|
object CirTreeFunctionDeserializer {
|
||||||
operator fun invoke(function: KmFunction, containingClass: CirContainingClass?, typeResolver: CirTypeResolver): CirTreeFunction? {
|
operator fun invoke(function: KmFunction, containingClass: CirContainingClass?, typeResolver: CirTypeResolver): CirFunction? {
|
||||||
val functionTypeResolver = typeResolver.create(function.typeParameters)
|
val functionTypeResolver = typeResolver.create(function.typeParameters)
|
||||||
if (function.isFakeOverride()
|
if (function.isFakeOverride()
|
||||||
|| function.isKniBridgeFunction()
|
|| function.isKniBridgeFunction()
|
||||||
@@ -26,15 +26,11 @@ object CirTreeFunctionDeserializer {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val approximationKey = FunctionApproximationKey(function, functionTypeResolver)
|
return CirDeserializers.function(
|
||||||
return CirTreeFunction(
|
name = CirName.create(function.name),
|
||||||
approximationKey = approximationKey,
|
source = function,
|
||||||
function = CirDeserializers.function(
|
containingClass = containingClass,
|
||||||
name = approximationKey.name,
|
typeResolver = functionTypeResolver
|
||||||
source = function,
|
|
||||||
containingClass = containingClass,
|
|
||||||
typeResolver = functionTypeResolver
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-12
@@ -7,25 +7,21 @@ package org.jetbrains.kotlin.commonizer.tree.deserializer
|
|||||||
|
|
||||||
import kotlinx.metadata.KmProperty
|
import kotlinx.metadata.KmProperty
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirContainingClass
|
import org.jetbrains.kotlin.commonizer.cir.CirContainingClass
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.PropertyApproximationKey
|
import org.jetbrains.kotlin.commonizer.cir.CirName
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirProperty
|
||||||
import org.jetbrains.kotlin.commonizer.metadata.CirDeserializers
|
import org.jetbrains.kotlin.commonizer.metadata.CirDeserializers
|
||||||
import org.jetbrains.kotlin.commonizer.metadata.CirTypeResolver
|
import org.jetbrains.kotlin.commonizer.metadata.CirTypeResolver
|
||||||
import org.jetbrains.kotlin.commonizer.tree.CirTreeProperty
|
|
||||||
import org.jetbrains.kotlin.commonizer.utils.isFakeOverride
|
import org.jetbrains.kotlin.commonizer.utils.isFakeOverride
|
||||||
|
|
||||||
object CirTreePropertyDeserializer {
|
object CirTreePropertyDeserializer {
|
||||||
operator fun invoke(property: KmProperty, containingClass: CirContainingClass?, typeResolver: CirTypeResolver): CirTreeProperty? {
|
operator fun invoke(property: KmProperty, containingClass: CirContainingClass?, typeResolver: CirTypeResolver): CirProperty? {
|
||||||
if (property.isFakeOverride()) return null
|
if (property.isFakeOverride()) return null
|
||||||
val propertyTypeResolver = typeResolver.create(property.typeParameters)
|
val propertyTypeResolver = typeResolver.create(property.typeParameters)
|
||||||
val approximationKey = PropertyApproximationKey(property, propertyTypeResolver)
|
return CirDeserializers.property(
|
||||||
return CirTreeProperty(
|
name = CirName.create(property.name),
|
||||||
approximationKey = PropertyApproximationKey(property, propertyTypeResolver),
|
source = property,
|
||||||
property = CirDeserializers.property(
|
containingClass = containingClass,
|
||||||
name = approximationKey.name,
|
typeResolver = propertyTypeResolver
|
||||||
source = property,
|
|
||||||
containingClass = containingClass,
|
|
||||||
typeResolver = propertyTypeResolver
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,16 @@
|
|||||||
package org.jetbrains.kotlin.commonizer.tree
|
package org.jetbrains.kotlin.commonizer.tree
|
||||||
|
|
||||||
import org.jetbrains.kotlin.commonizer.TargetDependent
|
import org.jetbrains.kotlin.commonizer.TargetDependent
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirRoot
|
import org.jetbrains.kotlin.commonizer.cir.*
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.*
|
import org.jetbrains.kotlin.commonizer.mergedtree.*
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
internal data class TargetBuildingContext(
|
internal data class TargetBuildingContext(
|
||||||
val storageManager: StorageManager, val classifiers: CirKnownClassifiers, val targets: Int, val targetIndex: Int
|
val storageManager: StorageManager, val classifiers: CirKnownClassifiers, val memberContext: CirMemberContext = CirMemberContext.empty,
|
||||||
)
|
val targets: Int, val targetIndex: Int
|
||||||
|
) {
|
||||||
|
fun withMemberContextOf(clazz: CirClass) = copy(memberContext = memberContext.withContextOf(clazz))
|
||||||
|
}
|
||||||
|
|
||||||
internal fun mergeCirTree(
|
internal fun mergeCirTree(
|
||||||
storageManager: StorageManager, classifiers: CirKnownClassifiers, roots: TargetDependent<CirTreeRoot>
|
storageManager: StorageManager, classifiers: CirKnownClassifiers, roots: TargetDependent<CirTreeRoot>
|
||||||
@@ -20,7 +23,9 @@ internal fun mergeCirTree(
|
|||||||
val node = buildRootNode(storageManager, roots.size)
|
val node = buildRootNode(storageManager, roots.size)
|
||||||
roots.targets.withIndex().forEach { (targetIndex, target) ->
|
roots.targets.withIndex().forEach { (targetIndex, target) ->
|
||||||
node.targetDeclarations[targetIndex] = CirRoot.create(target)
|
node.targetDeclarations[targetIndex] = CirRoot.create(target)
|
||||||
node.buildModules(TargetBuildingContext(storageManager, classifiers, roots.size, targetIndex), roots[target].modules)
|
node.buildModules(
|
||||||
|
TargetBuildingContext(storageManager, classifiers, CirMemberContext.empty, roots.size, targetIndex), roots[target].modules
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
@@ -55,37 +60,38 @@ internal fun CirNodeWithMembers<*, *>.buildClass(
|
|||||||
buildClassNode(context.storageManager, context.targets, context.classifiers, CirNodeRelationship.ParentNode(parent), treeClass.id)
|
buildClassNode(context.storageManager, context.targets, context.classifiers, CirNodeRelationship.ParentNode(parent), treeClass.id)
|
||||||
}
|
}
|
||||||
classNode.targetDeclarations[context.targetIndex] = treeClass.clazz
|
classNode.targetDeclarations[context.targetIndex] = treeClass.clazz
|
||||||
treeClass.functions.forEach { function -> classNode.buildFunction(context, function, classNode) }
|
val contextWithClass = context.withMemberContextOf(treeClass.clazz)
|
||||||
treeClass.properties.forEach { property -> classNode.buildProperty(context, property, classNode) }
|
treeClass.functions.forEach { function -> classNode.buildFunction(contextWithClass, function, classNode) }
|
||||||
treeClass.constructors.forEach { constructor -> classNode.buildConstructor(context, constructor, classNode) }
|
treeClass.properties.forEach { property -> classNode.buildProperty(contextWithClass, property, classNode) }
|
||||||
treeClass.classes.forEach { clazz -> classNode.buildClass(context, clazz, classNode) }
|
treeClass.constructors.forEach { constructor -> classNode.buildConstructor(contextWithClass, constructor, classNode) }
|
||||||
|
treeClass.classes.forEach { clazz -> classNode.buildClass(contextWithClass, clazz, classNode) }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun CirNodeWithMembers<*, *>.buildFunction(
|
internal fun CirNodeWithMembers<*, *>.buildFunction(
|
||||||
context: TargetBuildingContext, treeFunction: CirTreeFunction, parent: CirNode<*, *>? = null
|
context: TargetBuildingContext, function: CirFunction, parent: CirNode<*, *>? = null
|
||||||
) {
|
) {
|
||||||
val functionNode = functions.getOrPut(treeFunction.approximationKey) {
|
val functionNode = functions.getOrPut(FunctionApproximationKey.create(context.memberContext, function)) {
|
||||||
buildFunctionNode(context.storageManager, context.targets, context.classifiers, CirNodeRelationship.ParentNode(parent))
|
buildFunctionNode(context.storageManager, context.targets, context.classifiers, CirNodeRelationship.ParentNode(parent))
|
||||||
}
|
}
|
||||||
functionNode.targetDeclarations[context.targetIndex] = treeFunction.function
|
functionNode.targetDeclarations[context.targetIndex] = function
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun CirNodeWithMembers<*, *>.buildProperty(
|
internal fun CirNodeWithMembers<*, *>.buildProperty(
|
||||||
context: TargetBuildingContext, treeProperty: CirTreeProperty, parent: CirNode<*, *>? = null
|
context: TargetBuildingContext, property: CirProperty, parent: CirNode<*, *>? = null
|
||||||
) {
|
) {
|
||||||
val propertyNode = properties.getOrPut(treeProperty.approximationKey) {
|
val propertyNode = properties.getOrPut(PropertyApproximationKey.create(context.memberContext, property)) {
|
||||||
buildPropertyNode(context.storageManager, context.targets, context.classifiers, CirNodeRelationship.ParentNode(parent))
|
buildPropertyNode(context.storageManager, context.targets, context.classifiers, CirNodeRelationship.ParentNode(parent))
|
||||||
}
|
}
|
||||||
propertyNode.targetDeclarations[context.targetIndex] = treeProperty.property
|
propertyNode.targetDeclarations[context.targetIndex] = property
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun CirClassNode.buildConstructor(
|
internal fun CirClassNode.buildConstructor(
|
||||||
context: TargetBuildingContext, treeConstructor: CirTreeClassConstructor, parent: CirNode<*, *>
|
context: TargetBuildingContext, constructor: CirClassConstructor, parent: CirNode<*, *>
|
||||||
) {
|
) {
|
||||||
val constructorNode = constructors.getOrPut(treeConstructor.approximationKey) {
|
val constructorNode = constructors.getOrPut(ConstructorApproximationKey.create(context.memberContext, constructor)) {
|
||||||
buildClassConstructorNode(context.storageManager, context.targets, context.classifiers, CirNodeRelationship.ParentNode(parent))
|
buildClassConstructorNode(context.storageManager, context.targets, context.classifiers, CirNodeRelationship.ParentNode(parent))
|
||||||
}
|
}
|
||||||
constructorNode.targetDeclarations[context.targetIndex] = treeConstructor.constructor
|
constructorNode.targetDeclarations[context.targetIndex] = constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun CirPackageNode.buildTypeAlias(context: TargetBuildingContext, treeTypeAlias: CirTreeTypeAlias) {
|
internal fun CirPackageNode.buildTypeAlias(context: TargetBuildingContext, treeTypeAlias: CirTreeTypeAlias) {
|
||||||
|
|||||||
@@ -25,8 +25,13 @@ class CommonizedGroup<T : Any>(
|
|||||||
|
|
||||||
operator fun set(index: Int, value: T) {
|
operator fun set(index: Int, value: T) {
|
||||||
val oldValue = this[index]
|
val oldValue = this[index]
|
||||||
check(oldValue == null) { "$oldValue can not be overwritten with $value at index $index" }
|
check(oldValue == null) {
|
||||||
|
"$oldValue can not be overwritten with $value at index $index"
|
||||||
|
}
|
||||||
|
|
||||||
elements[index] = value
|
elements[index] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface I<T>
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.commonizer.utils
|
package org.jetbrains.kotlin.commonizer.utils
|
||||||
|
|
||||||
import kotlinx.metadata.ClassName
|
import kotlinx.metadata.ClassName
|
||||||
import kotlinx.metadata.KmAnnotation
|
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirEntityId
|
import org.jetbrains.kotlin.commonizer.cir.CirEntityId
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirName
|
import org.jetbrains.kotlin.commonizer.cir.CirName
|
||||||
@@ -52,9 +51,8 @@ private val OBJC_INTEROP_CALLABLE_ANNOTATIONS: List<CirName> = listOf(
|
|||||||
CirName.create("ObjCFactory")
|
CirName.create("ObjCFactory")
|
||||||
)
|
)
|
||||||
|
|
||||||
private val OBJC_INTEROP_CALLABLE_ANNOTATION_FULL_NAMES: List<ClassName> = OBJC_INTEROP_CALLABLE_ANNOTATIONS.map { name ->
|
internal val COMMONIZER_OBJC_INTEROP_CALLABLE_ANNOTATION_ID =
|
||||||
CirEntityId.create(CINTEROP_PACKAGE, name).toString()
|
CirEntityId.create(CirPackageName.create("kotlin.commonizer"), CirName.create("ObjCCallable"))
|
||||||
}
|
|
||||||
|
|
||||||
internal val DEFAULT_CONSTRUCTOR_NAME: CirName = CirName.create("<init>")
|
internal val DEFAULT_CONSTRUCTOR_NAME: CirName = CirName.create("<init>")
|
||||||
internal val DEFAULT_SETTER_VALUE_NAME: CirName = CirName.create("value")
|
internal val DEFAULT_SETTER_VALUE_NAME: CirName = CirName.create("value")
|
||||||
@@ -69,7 +67,7 @@ internal val CirPackageName.isUnderKotlinNativeSyntheticPackages: Boolean
|
|||||||
get() = KOTLIN_NATIVE_SYNTHETIC_PACKAGES.any(::startsWith)
|
get() = KOTLIN_NATIVE_SYNTHETIC_PACKAGES.any(::startsWith)
|
||||||
|
|
||||||
internal val CirEntityId.isObjCInteropCallableAnnotation: Boolean
|
internal val CirEntityId.isObjCInteropCallableAnnotation: Boolean
|
||||||
get() = packageName == CINTEROP_PACKAGE && relativeNameSegments.singleOrNull() in OBJC_INTEROP_CALLABLE_ANNOTATIONS
|
get() = this == COMMONIZER_OBJC_INTEROP_CALLABLE_ANNOTATION_ID ||
|
||||||
|
packageName == CINTEROP_PACKAGE && relativeNameSegments.singleOrNull() in OBJC_INTEROP_CALLABLE_ANNOTATIONS
|
||||||
|
|
||||||
|
|
||||||
internal val KmAnnotation.isObjCInteropCallableAnnotation: Boolean
|
|
||||||
get() = className in OBJC_INTEROP_CALLABLE_ANNOTATION_FULL_NAMES
|
|
||||||
|
|||||||
Vendored
+12
@@ -85,29 +85,41 @@ expect fun functionMismatchedParameterNames29(vararg variadicArguments: Int)
|
|||||||
expect fun functionMismatchedParameterNames30(arg0: Int, vararg variadicArguments: Int)
|
expect fun functionMismatchedParameterNames30(arg0: Int, vararg variadicArguments: Int)
|
||||||
|
|
||||||
expect fun functionMismatchedParameterNames31(i: Int, s: String)
|
expect fun functionMismatchedParameterNames31(i: Int, s: String)
|
||||||
|
|
||||||
|
@kotlin.commonizer.ObjCCallable
|
||||||
expect fun functionMismatchedParameterNames34(i: Int, s: String)
|
expect fun functionMismatchedParameterNames34(i: Int, s: String)
|
||||||
|
|
||||||
|
@kotlin.commonizer.ObjCCallable
|
||||||
expect fun functionMismatchedParameterNames37(arg0: Int, arg1: String)
|
expect fun functionMismatchedParameterNames37(arg0: Int, arg1: String)
|
||||||
|
|
||||||
// hasStableParameterNames=false
|
// hasStableParameterNames=false
|
||||||
|
@kotlin.commonizer.ObjCCallable
|
||||||
expect fun functionMismatchedParameterNames38(i: Int, s: String)
|
expect fun functionMismatchedParameterNames38(i: Int, s: String)
|
||||||
|
|
||||||
// hasStableParameterNames=false
|
// hasStableParameterNames=false
|
||||||
|
@kotlin.commonizer.ObjCCallable
|
||||||
expect fun functionMismatchedParameterNames39(i: Int, s: String)
|
expect fun functionMismatchedParameterNames39(i: Int, s: String)
|
||||||
|
|
||||||
// hasStableParameterNames=false
|
// hasStableParameterNames=false
|
||||||
|
@kotlin.commonizer.ObjCCallable
|
||||||
expect fun functionMismatchedParameterNames40(i: Int, s: String)
|
expect fun functionMismatchedParameterNames40(i: Int, s: String)
|
||||||
|
|
||||||
// hasStableParameterNames=false
|
// hasStableParameterNames=false
|
||||||
|
@kotlin.commonizer.ObjCCallable
|
||||||
expect fun functionMismatchedParameterNames41(arg0: Int, arg1: String)
|
expect fun functionMismatchedParameterNames41(arg0: Int, arg1: String)
|
||||||
|
|
||||||
// hasStableParameterNames=false
|
// hasStableParameterNames=false
|
||||||
|
@kotlin.commonizer.ObjCCallable
|
||||||
expect fun functionMismatchedParameterNames42(arg0: Int, arg1: String)
|
expect fun functionMismatchedParameterNames42(arg0: Int, arg1: String)
|
||||||
|
|
||||||
// hasStableParameterNames=false
|
// hasStableParameterNames=false
|
||||||
|
@kotlin.commonizer.ObjCCallable
|
||||||
expect fun functionMismatchedParameterNames43(arg0: Int, arg1: String)
|
expect fun functionMismatchedParameterNames43(arg0: Int, arg1: String)
|
||||||
|
|
||||||
|
@kotlin.commonizer.ObjCCallable
|
||||||
expect fun overloadedFunctionByParameterNames(i: Int, s: String)
|
expect fun overloadedFunctionByParameterNames(i: Int, s: String)
|
||||||
|
|
||||||
|
@kotlin.commonizer.ObjCCallable
|
||||||
expect fun overloadedFunctionByParameterNames(xi: Int, xs: String)
|
expect fun overloadedFunctionByParameterNames(xi: Int, xs: String)
|
||||||
|
|
||||||
expect inline fun inlineFunction1(lazyMessage: () -> String)
|
expect inline fun inlineFunction1(lazyMessage: () -> String)
|
||||||
|
|||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package kotlin.commonizer
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
|
||||||
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
annotation class ObjCCallable()
|
||||||
+1
@@ -4,3 +4,4 @@ package kotlinx.cinterop
|
|||||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
|
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
|
||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
annotation class ObjCMethod() // fake annotation class without properties
|
annotation class ObjCMethod() // fake annotation class without properties
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.commonizer.tree.deserializer
|
package org.jetbrains.kotlin.commonizer.tree.deserializer
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirFunction
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirProperty
|
||||||
import org.jetbrains.kotlin.commonizer.tree.*
|
import org.jetbrains.kotlin.commonizer.tree.*
|
||||||
import org.jetbrains.kotlin.commonizer.utils.KtInlineSourceCommonizerTestCase
|
import org.jetbrains.kotlin.commonizer.utils.KtInlineSourceCommonizerTestCase
|
||||||
|
|
||||||
@@ -14,14 +16,14 @@ abstract class AbstractCirTreeDeserializerTest : KtInlineSourceCommonizerTestCas
|
|||||||
?: kotlin.test.fail("Expected single package. Found ${packages.map { it.pkg.packageName }}")
|
?: kotlin.test.fail("Expected single package. Found ${packages.map { it.pkg.packageName }}")
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun CirTreeModule.assertSingleProperty(): CirTreeProperty {
|
protected fun CirTreeModule.assertSingleProperty(): CirProperty {
|
||||||
return assertSinglePackage().properties.singleOrNull()
|
return assertSinglePackage().properties.singleOrNull()
|
||||||
?: kotlin.test.fail("Expected single property. Found ${assertSinglePackage().properties.map { it.property.name }}")
|
?: kotlin.test.fail("Expected single property. Found ${assertSinglePackage().properties.map { it.name }}")
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun CirTreeModule.assertSingleFunction(): CirTreeFunction {
|
protected fun CirTreeModule.assertSingleFunction(): CirFunction {
|
||||||
return assertSinglePackage().functions.singleOrNull()
|
return assertSinglePackage().functions.singleOrNull()
|
||||||
?: kotlin.test.fail("Expected single property. Found ${assertSinglePackage().functions.map { it.function.name }}")
|
?: kotlin.test.fail("Expected single property. Found ${assertSinglePackage().functions.map { it.name }}")
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun CirTreeModule.assertSingleClass(): CirTreeClass {
|
protected fun CirTreeModule.assertSingleClass(): CirTreeClass {
|
||||||
|
|||||||
+2
-2
@@ -150,12 +150,12 @@ class CirTreeClassDeserializerTest : AbstractCirTreeDeserializerTest() {
|
|||||||
val clazz = module.assertSingleClass()
|
val clazz = module.assertSingleClass()
|
||||||
|
|
||||||
fun assertContainsProperty(name: String) {
|
fun assertContainsProperty(name: String) {
|
||||||
clazz.properties.singleOrNull { it.property.name.toStrippedString() == name }
|
clazz.properties.singleOrNull { it.name.toStrippedString() == name }
|
||||||
?: kotlin.test.fail("Missing property '$name'")
|
?: kotlin.test.fail("Missing property '$name'")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun assertContainsFunction(name: String) {
|
fun assertContainsFunction(name: String) {
|
||||||
clazz.functions.singleOrNull { it.function.name.toStrippedString() == name }
|
clazz.functions.singleOrNull { it.name.toStrippedString() == name }
|
||||||
?: kotlin.test.fail("Missing function '$name'")
|
?: kotlin.test.fail("Missing function '$name'")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -17,7 +17,7 @@ class CirTreeFunctionDeserializerTest : AbstractCirTreeDeserializerTest() {
|
|||||||
|
|
||||||
fun `test simple function`() {
|
fun `test simple function`() {
|
||||||
val module = createCirTreeFromSourceCode("fun x() = Unit")
|
val module = createCirTreeFromSourceCode("fun x() = Unit")
|
||||||
val (_, function) = module.assertSingleFunction()
|
val function = module.assertSingleFunction()
|
||||||
|
|
||||||
assertNull(function.containingClass, "Expected function to *not* have containing class")
|
assertNull(function.containingClass, "Expected function to *not* have containing class")
|
||||||
assertEquals(Visibilities.Public, function.visibility, "Expected function to be public")
|
assertEquals(Visibilities.Public, function.visibility, "Expected function to be public")
|
||||||
@@ -30,7 +30,7 @@ class CirTreeFunctionDeserializerTest : AbstractCirTreeDeserializerTest() {
|
|||||||
|
|
||||||
fun `test generic function`() {
|
fun `test generic function`() {
|
||||||
val module = createCirTreeFromSourceCode("""fun <T: Any> T.isHappy(): Boolean = true""")
|
val module = createCirTreeFromSourceCode("""fun <T: Any> T.isHappy(): Boolean = true""")
|
||||||
val (_, function) = module.assertSingleFunction()
|
val function = module.assertSingleFunction()
|
||||||
|
|
||||||
val extensionReceiver = assertNotNull(function.extensionReceiver, "Expected function being extension receiver")
|
val extensionReceiver = assertNotNull(function.extensionReceiver, "Expected function being extension receiver")
|
||||||
val extensionReceiverType = extensionReceiver.type as? CirTypeParameterType
|
val extensionReceiverType = extensionReceiver.type as? CirTypeParameterType
|
||||||
@@ -59,8 +59,8 @@ class CirTreeFunctionDeserializerTest : AbstractCirTreeDeserializerTest() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val parent = module.assertSingleClass()
|
val parent = module.assertSingleClass()
|
||||||
val function = parent.functions.singleOrNull()?.function
|
val function = parent.functions.singleOrNull()
|
||||||
?: kotlin.test.fail("Expected single function in parent. Found ${parent.functions.map { it.function.name }}")
|
?: kotlin.test.fail("Expected single function in parent. Found ${parent.functions.map { it.name }}")
|
||||||
|
|
||||||
val containingClass = assertIs<CirClass>(kotlin.test.assertNotNull(function.containingClass))
|
val containingClass = assertIs<CirClass>(kotlin.test.assertNotNull(function.containingClass))
|
||||||
assertEquals(ClassKind.OBJECT, containingClass.kind, "Expected containing class being object")
|
assertEquals(ClassKind.OBJECT, containingClass.kind, "Expected containing class being object")
|
||||||
|
|||||||
+6
-6
@@ -58,12 +58,12 @@ class CirTreePackageDeserializerTest : AbstractCirTreeDeserializerTest() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
kotlin.test.assertTrue(
|
kotlin.test.assertTrue(
|
||||||
properties.any { it.property.name.toStrippedString() == "rootProperty" },
|
properties.any { it.name.toStrippedString() == "rootProperty" },
|
||||||
"Expected 'rootProperty'"
|
"Expected 'rootProperty'"
|
||||||
)
|
)
|
||||||
|
|
||||||
kotlin.test.assertTrue(
|
kotlin.test.assertTrue(
|
||||||
functions.any { it.function.name.toStrippedString() == "rootFunction" },
|
functions.any { it.name.toStrippedString() == "rootFunction" },
|
||||||
"Expected 'rootFunction'"
|
"Expected 'rootFunction'"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -80,12 +80,12 @@ class CirTreePackageDeserializerTest : AbstractCirTreeDeserializerTest() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
kotlin.test.assertTrue(
|
kotlin.test.assertTrue(
|
||||||
properties.any { it.property.name.toStrippedString() == "pkg1Property" },
|
properties.any { it.name.toStrippedString() == "pkg1Property" },
|
||||||
"Expected 'pkg1Property'"
|
"Expected 'pkg1Property'"
|
||||||
)
|
)
|
||||||
|
|
||||||
kotlin.test.assertTrue(
|
kotlin.test.assertTrue(
|
||||||
functions.any { it.function.name.toStrippedString() == "pkg1Function" },
|
functions.any { it.name.toStrippedString() == "pkg1Function" },
|
||||||
"Expected 'pkg1Function'"
|
"Expected 'pkg1Function'"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -102,12 +102,12 @@ class CirTreePackageDeserializerTest : AbstractCirTreeDeserializerTest() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
kotlin.test.assertTrue(
|
kotlin.test.assertTrue(
|
||||||
properties.any { it.property.name.toStrippedString() == "pkg2Property" },
|
properties.any { it.name.toStrippedString() == "pkg2Property" },
|
||||||
"Expected 'pkg2Property'"
|
"Expected 'pkg2Property'"
|
||||||
)
|
)
|
||||||
|
|
||||||
kotlin.test.assertTrue(
|
kotlin.test.assertTrue(
|
||||||
functions.any { it.function.name.toStrippedString() == "pkg2Function" },
|
functions.any { it.name.toStrippedString() == "pkg2Function" },
|
||||||
"Expected 'pkg2Function'"
|
"Expected 'pkg2Function'"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+6
-7
@@ -18,8 +18,7 @@ class CirTreePropertyDeserializerTest : AbstractCirTreeDeserializerTest() {
|
|||||||
fun `test simple val property`() {
|
fun `test simple val property`() {
|
||||||
val module = createCirTreeFromSourceCode("val x: Int = 42")
|
val module = createCirTreeFromSourceCode("val x: Int = 42")
|
||||||
|
|
||||||
val (key, property) = module.assertSingleProperty()
|
val property = module.assertSingleProperty()
|
||||||
assertEquals(PropertyApproximationKey(CirName.Companion.create("x"), null), key)
|
|
||||||
|
|
||||||
assertEquals("x", property.name.toStrippedString())
|
assertEquals("x", property.name.toStrippedString())
|
||||||
assertFalse(property.isConst, "Expected property to is *no* const")
|
assertFalse(property.isConst, "Expected property to is *no* const")
|
||||||
@@ -33,7 +32,7 @@ class CirTreePropertyDeserializerTest : AbstractCirTreeDeserializerTest() {
|
|||||||
|
|
||||||
fun `test simple var property`() {
|
fun `test simple var property`() {
|
||||||
val module = createCirTreeFromSourceCode("var x: Int = 42")
|
val module = createCirTreeFromSourceCode("var x: Int = 42")
|
||||||
val (_, property) = module.assertSingleProperty()
|
val property = module.assertSingleProperty()
|
||||||
assertNotNull(property.getter, "Expected property has getter")
|
assertNotNull(property.getter, "Expected property has getter")
|
||||||
assertNotNull(property.setter, "Expected property has setter")
|
assertNotNull(property.setter, "Expected property has setter")
|
||||||
assertFalse(property.isLateInit, "Expected property to be not lateinit")
|
assertFalse(property.isLateInit, "Expected property to be not lateinit")
|
||||||
@@ -42,7 +41,7 @@ class CirTreePropertyDeserializerTest : AbstractCirTreeDeserializerTest() {
|
|||||||
|
|
||||||
fun `test lateinit var property`() {
|
fun `test lateinit var property`() {
|
||||||
val module = createCirTreeFromSourceCode("lateinit var x: Int")
|
val module = createCirTreeFromSourceCode("lateinit var x: Int")
|
||||||
val (_, property) = module.assertSingleProperty()
|
val property = module.assertSingleProperty()
|
||||||
|
|
||||||
assertNotNull(property.getter, "Expected property has getter")
|
assertNotNull(property.getter, "Expected property has getter")
|
||||||
assertNotNull(property.setter, "Expected property has setter")
|
assertNotNull(property.setter, "Expected property has setter")
|
||||||
@@ -52,7 +51,7 @@ class CirTreePropertyDeserializerTest : AbstractCirTreeDeserializerTest() {
|
|||||||
|
|
||||||
fun `test generic var property`() {
|
fun `test generic var property`() {
|
||||||
val module = createCirTreeFromSourceCode("var <T> T.x: T get() = this")
|
val module = createCirTreeFromSourceCode("var <T> T.x: T get() = this")
|
||||||
val (_, property) = module.assertSingleProperty()
|
val property = module.assertSingleProperty()
|
||||||
|
|
||||||
assertNotNull(property.extensionReceiver, "Expected property has extension receiver")
|
assertNotNull(property.extensionReceiver, "Expected property has extension receiver")
|
||||||
assertTrue(
|
assertTrue(
|
||||||
@@ -74,8 +73,8 @@ class CirTreePropertyDeserializerTest : AbstractCirTreeDeserializerTest() {
|
|||||||
val pkg = module.assertSinglePackage()
|
val pkg = module.assertSinglePackage()
|
||||||
assertEquals(4, pkg.properties.size, "Expected exactly 4 properties in package")
|
assertEquals(4, pkg.properties.size, "Expected exactly 4 properties in package")
|
||||||
|
|
||||||
val answerProperty = pkg.properties.single { it.property.name.toStrippedString() == "answer" }
|
val answerProperty = pkg.properties.single { it.name.toStrippedString() == "answer" }
|
||||||
val answerReturnType = answerProperty.property.returnType as? CirClassType
|
val answerReturnType = answerProperty.returnType as? CirClassType
|
||||||
?: kotlin.test.fail("Expected answer return type is class")
|
?: kotlin.test.fail("Expected answer return type is class")
|
||||||
assertEquals("kotlin/Int", answerReturnType.classifierId.toString())
|
assertEquals("kotlin/Int", answerReturnType.classifierId.toString())
|
||||||
assertTrue(answerReturnType.isMarkedNullable, "Expected answer return type being marked nullable")
|
assertTrue(answerReturnType.isMarkedNullable, "Expected answer return type being marked nullable")
|
||||||
|
|||||||
Reference in New Issue
Block a user