diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmMangleComputer.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmMangleComputer.kt index ae51c28d4f0..5c57f7a8f72 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmMangleComputer.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmMangleComputer.kt @@ -5,10 +5,7 @@ package org.jetbrains.kotlin.fir.backend.jvm -import org.jetbrains.kotlin.backend.common.serialization.mangle.KotlinMangleComputer -import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleConstant -import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleMode -import org.jetbrains.kotlin.backend.common.serialization.mangle.collectForMangler +import org.jetbrains.kotlin.backend.common.serialization.mangle.* import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor @@ -21,68 +18,42 @@ import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.signaturer.irName import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag +import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.fir.visitors.FirVisitor -import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly -import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty +import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid -open class FirJvmMangleComputer( - private val builder: StringBuilder, - private val mode: MangleMode -) : FirVisitor(), KotlinMangleComputer { +class FirJvmMangleComputer( + builder: StringBuilder, + mode: MangleMode, +) : BaseKotlinMangleComputer< + /*Declaration=*/FirDeclaration, + /*Type=*/ConeKotlinType, + /*TypeParameter=*/ConeTypeParameterLookupTag, + /*ValueParameter=*/FirValueParameter, + /*TypeParameterContainer=*/FirMemberDeclaration, + /*FunctionDeclaration=*/FirFunction, + /*Session=*/FirSession, + >(builder, mode) { - private val typeParameterContainer = ArrayList(4) + override fun getTypeSystemContext(session: FirSession) = object : ConeInferenceContext { + override val session: FirSession + get() = session + } - private var isRealExpect = false - - open fun FirFunction.platformSpecificFunctionName(): String? = null - - open fun FirFunction.platformSpecificSuffix(): String? = + override fun FirFunction.platformSpecificSuffix(): String? = if (this is FirSimpleFunction && name.asString() == "main") this.moduleData.session.firProvider.getFirCallableContainerFile(symbol)?.name else null - open fun FirFunction.specialValueParamPrefix(param: FirValueParameter): String = "" - - private fun addReturnType(): Boolean = true + override fun addReturnType(): Boolean = true override fun copy(newMode: MangleMode): FirJvmMangleComputer = FirJvmMangleComputer(builder, newMode) - private fun StringBuilder.appendName(s: String) { - if (mode.fqn) { - append(s) - } - } - - private fun StringBuilder.appendName(c: Char) { - if (mode.fqn) { - append(c) - } - } - - private fun StringBuilder.appendSignature(s: String) { - if (mode.signature) { - append(s) - } - } - - private fun StringBuilder.appendSignature(c: Char) { - if (mode.signature) { - append(c) - } - } - - private fun StringBuilder.appendSignature(i: Int) { - if (mode.signature) { - append(i) - } - } - - private fun FirDeclaration.visitParent() { + override fun FirDeclaration.visitParent() { val (parentPackageFqName, parentClassId) = when (this) { is FirCallableDeclaration -> this.containingClassLookupTag()?.classId?.let { it.packageFqName to it } ?: return is FirClassLikeDeclaration -> this.symbol.classId.let { it.packageFqName to it.outerClassId } @@ -92,7 +63,7 @@ open class FirJvmMangleComputer( val parentClassLike = this.moduleData.session.symbolProvider.getClassLikeSymbolByClassId(parentClassId)?.fir ?: error("Attempt to find parent ($parentClassId) for probably-local declaration!") if (parentClassLike is FirRegularClass || parentClassLike is FirTypeAlias) { - parentClassLike.accept(this@FirJvmMangleComputer, false) + parentClassLike.visit() } else { error("Strange class-like declaration: ${parentClassLike.render()}") } @@ -101,15 +72,8 @@ open class FirJvmMangleComputer( } } - private fun FirDeclaration.mangleSimpleDeclaration(name: String) { - val l = builder.length - visitParent() - - if (builder.length != l) { - builder.appendName(MangleConstant.FQN_SEPARATOR) - } - - builder.appendName(name) + override fun FirDeclaration.visit() { + accept(Visitor(), null) } private fun FirFunction.mangleFunction(isCtor: Boolean, isStatic: Boolean, container: FirDeclaration) { @@ -117,7 +81,7 @@ open class FirJvmMangleComputer( isRealExpect = isRealExpect || (this as? FirMemberDeclaration)?.isExpect == true if (container is FirMemberDeclaration) { - typeParameterContainer.add(container) + typeParameterContainers.add(container) } visitParent() @@ -161,11 +125,11 @@ open class FirJvmMangleComputer( valueParameters.collectForMangler(builder, MangleConstant.VALUE_PARAMETERS) { appendSignature(specialValueParamPrefix(it)) - mangleValueParameter(this, it) + mangleValueParameter(this, it, moduleData.session) } (container as? FirTypeParametersOwner)?.typeParameters?.withIndex()?.toList().orEmpty() .collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { (index, typeParameter) -> - mangleTypeParameter(this, typeParameter, index) + mangleTypeParameter(this, typeParameter.symbol.toLookupTag(), index, moduleData.session) } if (!isCtor && !returnTypeRef.isUnit && addReturnType()) { @@ -173,8 +137,8 @@ open class FirJvmMangleComputer( } } - private fun FirTypeParameter.effectiveParent(): FirMemberDeclaration { - for (parent in typeParameterContainer) { + override fun getEffectiveParent(typeParameter: ConeTypeParameterLookupTag): FirMemberDeclaration = typeParameter.symbol.fir.run { + for (parent in typeParameterContainers) { if (this in parent.typeParameters) { return parent } @@ -188,33 +152,18 @@ open class FirJvmMangleComputer( throw IllegalStateException("Should not be here!") } - private fun mangleValueParameter(vpBuilder: StringBuilder, param: FirValueParameter) { - mangleType(vpBuilder, param.returnTypeRef.coneType, param.moduleData.session) + override fun renderDeclaration(declaration: FirDeclaration) = declaration.render() - if (param.isVararg) { - vpBuilder.appendSignature(MangleConstant.VAR_ARG_MARK) - } - } + override fun getTypeParameterName(typeParameter: ConeTypeParameterLookupTag) = typeParameter.name.asString() - private fun mangleTypeParameter(tpBuilder: StringBuilder, param: FirTypeParameter, index: Int) { - tpBuilder.appendSignature(index) - tpBuilder.appendSignature(MangleConstant.UPPER_BOUND_SEPARATOR) + override fun isVararg(valueParameter: FirValueParameter) = valueParameter.isVararg - param.bounds.map { it.coneType }.collectForMangler(tpBuilder, MangleConstant.UPPER_BOUNDS) { - mangleType(this, it, param.moduleData.session) - } - } + override fun getValueParameterType(valueParameter: FirValueParameter) = valueParameter.returnTypeRef.coneType - private fun StringBuilder.mangleTypeParameterReference(typeParameter: FirTypeParameter) { - val parent = typeParameter.effectiveParent() - val ci = typeParameterContainer.indexOf(parent) - require(ci >= 0) { "No type container found for ${typeParameter.render()}" } - appendSignature(ci) - appendSignature(MangleConstant.INDEX_SEPARATOR) - appendSignature(parent.typeParameters.indexOf(typeParameter)) - } + override fun getIndexOfTypeParameter(typeParameter: ConeTypeParameterLookupTag, container: FirMemberDeclaration) = + container.typeParameters.indexOf(typeParameter.symbol.fir) - private fun mangleType(tBuilder: StringBuilder, type: ConeKotlinType, declarationSiteSession: FirSession) { + override fun mangleType(tBuilder: StringBuilder, type: ConeKotlinType, declarationSiteSession: FirSession) { when (type) { is ConeLookupTagBasedType -> { when (val symbol = type.lookupTag.toSymbol(declarationSiteSession)) { @@ -223,29 +172,15 @@ open class FirJvmMangleComputer( return } - is FirClassSymbol -> symbol.fir.accept(copy(MangleMode.FQNAME), false) - is FirTypeParameterSymbol -> tBuilder.mangleTypeParameterReference(symbol.fir) + is FirClassSymbol -> with(copy(MangleMode.FQNAME)) { symbol.fir.visit() } + is FirTypeParameterSymbol -> tBuilder.mangleTypeParameterReference(symbol.toLookupTag()) // This is performed for a case with invisible class-like symbol in fake override null -> (type.lookupTag as? ConeClassLikeLookupTag)?.let { tBuilder.append(it.classId) } } - type.typeArguments.asList().ifNotEmpty { - collectForMangler(tBuilder, MangleConstant.TYPE_ARGUMENTS) { arg -> - when (arg) { - is ConeStarProjection -> appendSignature(MangleConstant.STAR_MARK) - is ConeKotlinTypeProjection -> { - if (arg.kind != ProjectionKind.INVARIANT) { - appendSignature(arg.kind.name.toLowerCaseAsciiOnly()) - appendSignature(MangleConstant.VARIANCE_SEPARATOR) - } - - mangleType(this, arg.type, declarationSiteSession) - } - } - } - } + mangleTypeArguments(tBuilder, type, declarationSiteSession) if (type.isMarkedNullable) { tBuilder.appendSignature(MangleConstant.Q_MARK) @@ -294,79 +229,78 @@ open class FirJvmMangleComputer( } } - override fun visitElement(element: FirElement, data: Boolean) = error("unexpected element ${element.render()}") + private inner class Visitor : FirVisitorVoid() { - override fun visitRegularClass(regularClass: FirRegularClass, data: Boolean) { - isRealExpect = isRealExpect or regularClass.isExpect - typeParameterContainer.add(regularClass) - regularClass.mangleSimpleDeclaration(regularClass.name.asString()) - } + override fun visitElement(element: FirElement) = error("unexpected element ${element.render()}") - override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Boolean) { - anonymousObject.mangleSimpleDeclaration("") - } - - override fun visitVariable(variable: FirVariable, data: Boolean) { - isRealExpect = isRealExpect or variable.isExpect - typeParameterContainer.add(variable) - variable.visitParent() - - val isStaticProperty = variable.isStatic - if (isStaticProperty) { - builder.appendSignature(MangleConstant.STATIC_MEMBER_MARK) + override fun visitRegularClass(regularClass: FirRegularClass) { + isRealExpect = isRealExpect or regularClass.isExpect + typeParameterContainers.add(regularClass) + regularClass.mangleSimpleDeclaration(regularClass.name.asString()) } - variable.receiverParameter?.typeRef?.let { - builder.appendSignature(MangleConstant.EXTENSION_RECEIVER_PREFIX) - mangleType(builder, it.coneType, variable.moduleData.session) + override fun visitAnonymousObject(anonymousObject: FirAnonymousObject) { + anonymousObject.mangleSimpleDeclaration("") } - variable.typeParameters.withIndex().toList().collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { (index, typeParameter) -> - mangleTypeParameter(this, typeParameter.symbol.fir, index) + override fun visitVariable(variable: FirVariable) { + isRealExpect = isRealExpect or variable.isExpect + typeParameterContainers.add(variable) + variable.visitParent() + + val isStaticProperty = variable.isStatic + if (isStaticProperty) { + builder.appendSignature(MangleConstant.STATIC_MEMBER_MARK) + } + + variable.receiverParameter?.typeRef?.let { + builder.appendSignature(MangleConstant.EXTENSION_RECEIVER_PREFIX) + mangleType(builder, it.coneType, variable.moduleData.session) + } + + variable.typeParameters.withIndex().toList() + .collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { (index, typeParameter) -> + mangleTypeParameter(this, typeParameter.symbol.toLookupTag(), index, variable.moduleData.session) + } + + builder.append(variable.name.asString()) } - builder.append(variable.name.asString()) - } - - override fun visitProperty(property: FirProperty, data: Boolean) { - visitVariable(property, data) - } - - override fun visitField(field: FirField, data: Boolean) { - if (field is FirJavaField) { - field.mangleSimpleDeclaration(field.name.asString()) - } else { - visitVariable(field, data) + override fun visitProperty(property: FirProperty) { + visitVariable(property) } - } - override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Boolean) { - enumEntry.mangleSimpleDeclaration(enumEntry.name.asString()) - } - - override fun visitTypeAlias(typeAlias: FirTypeAlias, data: Boolean) = - typeAlias.mangleSimpleDeclaration(typeAlias.name.asString()) - - override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Boolean) { - isRealExpect = isRealExpect || simpleFunction.isExpect - val isStatic = simpleFunction.isStatic - simpleFunction.mangleFunction(false, isStatic, simpleFunction) - } - - override fun visitConstructor(constructor: FirConstructor, data: Boolean) = - constructor.mangleFunction(isCtor = true, isStatic = false, constructor) - - override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor, data: Boolean) { - if (propertyAccessor is FirSyntheticPropertyAccessor) { - // No need to distinguish between the accessor and its delegate. - visitSimpleFunction(propertyAccessor.delegate, data) - } else { - propertyAccessor.mangleFunction(isCtor = false, propertyAccessor.isStatic, propertyAccessor.propertySymbol.fir) + override fun visitField(field: FirField) { + if (field is FirJavaField) { + field.mangleSimpleDeclaration(field.name.asString()) + } else { + visitVariable(field) + } } - } - override fun computeMangle(declaration: FirDeclaration): String { - declaration.accept(this, true) - return builder.toString() + override fun visitEnumEntry(enumEntry: FirEnumEntry) { + enumEntry.mangleSimpleDeclaration(enumEntry.name.asString()) + } + + override fun visitTypeAlias(typeAlias: FirTypeAlias) = + typeAlias.mangleSimpleDeclaration(typeAlias.name.asString()) + + override fun visitSimpleFunction(simpleFunction: FirSimpleFunction) { + isRealExpect = isRealExpect || simpleFunction.isExpect + val isStatic = simpleFunction.isStatic + simpleFunction.mangleFunction(false, isStatic, simpleFunction) + } + + override fun visitConstructor(constructor: FirConstructor) = + constructor.mangleFunction(isCtor = true, isStatic = false, constructor) + + override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor) { + if (propertyAccessor is FirSyntheticPropertyAccessor) { + // No need to distinguish between the accessor and its delegate. + visitSimpleFunction(propertyAccessor.delegate) + } else { + propertyAccessor.mangleFunction(isCtor = false, propertyAccessor.isStatic, propertyAccessor.propertySymbol.fir) + } + } } } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/BaseKotlinMangleComputer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/BaseKotlinMangleComputer.kt new file mode 100644 index 00000000000..6ad7c7fc2bf --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/BaseKotlinMangleComputer.kt @@ -0,0 +1,181 @@ +/* + * Copyright 2010-2022 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.backend.common.serialization.mangle + +import org.jetbrains.kotlin.types.model.* + +/** + * A base implementation of the [KotlinMangleComputer] interface containing routines that are common for all frontends and backends. + * + * @param Declaration A class representing a Kotlin declaration. + * @param Type A class representing a Kotlin type. + * @param TypeParameter A class representing a type parameter of a Kotlin class or function. + * @param ValueParameter A class representing a value parameter declaration of a Kotlin function. + * @param TypeParameterContainer A class representing something that can have type parameters, like a Kotlin function or class declaration. + * @param FunctionDeclaration A class representing a Kotlin function declaration. + * @param Session An additional context used for type computations. + * @property builder A string builder to write the mangled name into. + * @property mode The mangle mode. + */ +abstract class BaseKotlinMangleComputer( + protected val builder: StringBuilder, + protected val mode: MangleMode +) : KotlinMangleComputer + where Declaration : Any, + Type : KotlinTypeMarker, + TypeParameter : TypeParameterMarker, + ValueParameter : Declaration, + TypeParameterContainer : Declaration, + FunctionDeclaration : Declaration { + + /** + * The type system to use to query properties of types, type parameters and type arguments. + */ + protected abstract fun getTypeSystemContext(session: Session): TypeSystemContext + + protected val typeParameterContainers = ArrayList(4) + + protected var isRealExpect = false + + protected open fun FunctionDeclaration.platformSpecificFunctionName(): String? = null + + protected open fun FunctionDeclaration.platformSpecificSuffix(): String? = null + + protected open fun FunctionDeclaration.specialValueParamPrefix(param: ValueParameter): String = "" + + protected open fun addReturnType(): Boolean = false + + protected open fun addReturnTypeSpecialCase(function: FunctionDeclaration): Boolean = false + + protected fun StringBuilder.appendName(s: String) { + if (mode.fqn) { + append(s) + } + } + + protected fun StringBuilder.appendName(c: Char) { + if (mode.fqn) { + append(c) + } + } + + protected fun StringBuilder.appendSignature(s: String) { + if (mode.signature) { + append(s) + } + } + + protected fun StringBuilder.appendSignature(c: Char) { + if (mode.signature) { + append(c) + } + } + + protected fun StringBuilder.appendSignature(i: Int) { + if (mode.signature) { + append(i) + } + } + + protected abstract fun Declaration.visitParent() + + protected abstract fun Declaration.visit() + + final override fun computeMangle(declaration: Declaration): String { + declaration.visit() + return builder.toString() + } + + protected fun Declaration.mangleSimpleDeclaration(name: String) { + val l = builder.length + visitParent() + + if (builder.length != l) { + builder.appendName(MangleConstant.FQN_SEPARATOR) + } + + builder.appendName(name) + } + + protected abstract fun mangleType(tBuilder: StringBuilder, type: Type, declarationSiteSession: Session) + + protected open fun mangleTypePlatformSpecific(type: Type, tBuilder: StringBuilder) {} + + protected abstract fun isVararg(valueParameter: ValueParameter): Boolean + + protected abstract fun getValueParameterType(valueParameter: ValueParameter): Type + + protected abstract fun getIndexOfTypeParameter(typeParameter: TypeParameter, container: TypeParameterContainer): Int + + /** + * Used to show a meaningful exception message. + */ + protected abstract fun renderDeclaration(declaration: Declaration): String + + protected abstract fun getTypeParameterName(typeParameter: TypeParameter): String + + protected fun StringBuilder.mangleTypeParameterReference(typeParameter: TypeParameter) { + val parent = getEffectiveParent(typeParameter) + val containerIndex = typeParameterContainers.indexOf(parent) + require(containerIndex >= 0) { + "No container found for type parameter '${getTypeParameterName(typeParameter)}' of '${renderDeclaration(parent)}'" + } + appendSignature(containerIndex) + appendSignature(MangleConstant.INDEX_SEPARATOR) + appendSignature(getIndexOfTypeParameter(typeParameter, parent)) + } + + + protected fun mangleTypeParameter( + tpBuilder: StringBuilder, + param: TypeParameter, + index: Int, + declarationSiteSession: Session + ) = with(getTypeSystemContext(declarationSiteSession)) { + tpBuilder.appendSignature(index) + tpBuilder.appendSignature(MangleConstant.UPPER_BOUND_SEPARATOR) + + param.getUpperBounds().collectForMangler(tpBuilder, MangleConstant.UPPER_BOUNDS) { + @Suppress("UNCHECKED_CAST") + mangleType(this, it as Type, declarationSiteSession) + } + } + + protected abstract fun getEffectiveParent(typeParameter: TypeParameter): TypeParameterContainer + + protected fun mangleValueParameter(vpBuilder: StringBuilder, param: ValueParameter, declarationSiteSession: Session) { + mangleType(vpBuilder, getValueParameterType(param), declarationSiteSession) + + if (isVararg(param)) { + vpBuilder.appendSignature(MangleConstant.VAR_ARG_MARK) + } + } + + protected fun mangleTypeArguments(tBuilder: StringBuilder, type: Type, declarationSiteSession: Session) = + with(getTypeSystemContext(declarationSiteSession)) { + val typeArguments = type.getArguments().zip(type.typeConstructor().getParameters()) + if (typeArguments.isEmpty()) return + @Suppress("UNUSED_DESTRUCTURED_PARAMETER_ENTRY") + typeArguments.collectForMangler(tBuilder, MangleConstant.TYPE_ARGUMENTS) { (typeArgument, typeParameter) -> + when { + typeArgument.isStarProjection() -> appendSignature(MangleConstant.STAR_MARK) + else -> { + // FIXME: Use effective variance here according to the klib spec: `org.jetbrains.kotlin.types.AbstractTypeChecker.effectiveVariance(typeParameter.getVariance(), typeArgument.getVariance())` + // NOTE: If we start using effective variance instead of declared variance, we must take into account + // binary compatibility implications. + val variance = typeArgument.getVariance() + if (variance != TypeVariance.INV) { + appendSignature(variance.presentation) + appendSignature(MangleConstant.VARIANCE_SEPARATOR) + } + + @Suppress("UNCHECKED_CAST") + mangleType(this, typeArgument.getType() as Type, declarationSiteSession) + } + } + } + } +} diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorMangleComputer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorMangleComputer.kt index 89fb6d581de..afb5a55a90c 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorMangleComputer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorMangleComputer.kt @@ -5,86 +5,44 @@ package org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor -import org.jetbrains.kotlin.backend.common.serialization.mangle.KotlinMangleComputer -import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleConstant -import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleMode -import org.jetbrains.kotlin.backend.common.serialization.mangle.collectForMangler +import org.jetbrains.kotlin.backend.common.serialization.mangle.* import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptor import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptor +import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext +import org.jetbrains.kotlin.types.model.TypeSystemContext import org.jetbrains.kotlin.types.typeUtil.isUnit -import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsByExistingArgumentsWith -import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty -abstract class DescriptorMangleComputer(protected val builder: StringBuilder, private val mode: MangleMode) : - DeclarationDescriptorVisitor, KotlinMangleComputer { - - override fun computeMangle(declaration: DeclarationDescriptor): String { - declaration.accept(this, null) - return builder.toString() - } +abstract class DescriptorMangleComputer(builder: StringBuilder, mode: MangleMode) : + BaseKotlinMangleComputer< + /*Declaration=*/DeclarationDescriptor, + /*Type=*/KotlinType, + /*TypeParameter=*/TypeParameterDescriptor, + /*ValueParameter=*/ValueParameterDescriptor, + /*TypeParameterContainer=*/DeclarationDescriptor, + /*FunctionDeclaration=*/FunctionDescriptor, + /*Session=*/Nothing?, + >(builder, mode) { + final override fun getTypeSystemContext(session: Nothing?): TypeSystemContext = SimpleClassicTypeSystemContext abstract override fun copy(newMode: MangleMode): DescriptorMangleComputer - private fun StringBuilder.appendName(s: String) { - if (mode.fqn) { - append(s) - } + final override fun DeclarationDescriptor.visitParent() { + containingDeclaration?.visit() } - private fun StringBuilder.appendName(c: Char) { - if (mode.fqn) { - append(c) - } + final override fun DeclarationDescriptor.visit() { + accept(Visitor(), null) } - protected fun StringBuilder.appendSignature(s: String) { - if (mode.signature) { - append(s) - } - } - - private fun StringBuilder.appendSignature(c: Char) { - if (mode.signature) { - append(c) - } - } - - private fun StringBuilder.appendSignature(i: Int) { - if (mode.signature) { - append(i) - } - } - - private val typeParameterContainer = ArrayList(4) - - private var isRealExpect = false - - private fun DeclarationDescriptor.mangleSimpleDeclaration(name: String) { - val l = builder.length - containingDeclaration?.accept(this@DescriptorMangleComputer, null) - - if (builder.length != l) builder.appendName(MangleConstant.FQN_SEPARATOR) - - builder.appendName(name) - } - - open fun FunctionDescriptor.platformSpecificFunctionName(): String? = null - private fun reportUnexpectedDescriptor(descriptor: DeclarationDescriptor) { error("unexpected descriptor $descriptor") } - open fun FunctionDescriptor.platformSpecificSuffix(): String? = null open fun PropertyDescriptor.platformSpecificSuffix(): String? = null - protected open fun addReturnType(): Boolean = false - - protected open fun addReturnTypeSpecialCase(functionDescriptor: FunctionDescriptor): Boolean = false - - open fun FunctionDescriptor.specialValueParamPrefix(param: ValueParameterDescriptor): String = "" - private val CallableDescriptor.isRealStatic: Boolean get() = dispatchReceiverParameter == null && containingDeclaration !is PackageFragmentDescriptor @@ -92,8 +50,8 @@ abstract class DescriptorMangleComputer(protected val builder: StringBuilder, pr isRealExpect = isRealExpect or isExpect - typeParameterContainer.add(container) - container.containingDeclaration.accept(this@DescriptorMangleComputer, null) + typeParameterContainers.add(container) + container.containingDeclaration.visit() builder.appendName(MangleConstant.FUNCTION_NAME_PREFIX) @@ -127,14 +85,14 @@ abstract class DescriptorMangleComputer(protected val builder: StringBuilder, pr valueParameters.collectForMangler(builder, MangleConstant.VALUE_PARAMETERS) { appendSignature(specialValueParamPrefix(it)) - mangleValueParameter(this, it) + mangleValueParameter(this, it, null) } realTypeParameterContainer.typeParameters.filter { it.containingDeclaration == realTypeParameterContainer } - .collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { mangleTypeParameter(this, it) } + .collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { mangleTypeParameter(this, it, it.index, null) } returnType?.run { if (!isCtor && !isUnit() && (addReturnType() || addReturnTypeSpecialCase(this@mangleSignature))) { - mangleType(builder, this) + mangleType(builder, this, null) } } @@ -145,28 +103,20 @@ abstract class DescriptorMangleComputer(protected val builder: StringBuilder, pr } private fun mangleContextReceiverParameter(vpBuilder: StringBuilder, param: ReceiverParameterDescriptor) { - mangleType(vpBuilder, param.type) + mangleType(vpBuilder, param.type, null) } private fun mangleExtensionReceiverParameter(vpBuilder: StringBuilder, param: ReceiverParameterDescriptor) { - mangleType(vpBuilder, param.type) + mangleType(vpBuilder, param.type, null) } - private fun mangleValueParameter(vpBuilder: StringBuilder, param: ValueParameterDescriptor) { - mangleType(vpBuilder, param.type) + final override fun isVararg(valueParameter: ValueParameterDescriptor) = valueParameter.varargElementType != null - if (param.varargElementType != null) vpBuilder.appendSignature(MangleConstant.VAR_ARG_MARK) - } + final override fun getValueParameterType(valueParameter: ValueParameterDescriptor) = valueParameter.type - private fun mangleTypeParameter(tpBuilder: StringBuilder, param: TypeParameterDescriptor) { - tpBuilder.appendSignature(param.index) - tpBuilder.appendSignature(MangleConstant.UPPER_BOUND_SEPARATOR) - - param.upperBounds.collectForMangler(tpBuilder, MangleConstant.UPPER_BOUNDS) { mangleType(this, it) } - } - - private fun mangleType(tBuilder: StringBuilder, wtype: KotlinType) { - when (val type = wtype.unwrap()) { + @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") + final override fun mangleType(tBuilder: StringBuilder, wrappedType: KotlinType, declarationSiteSession: Nothing?) { + when (val type = wrappedType.unwrap()) { is SimpleType -> { if (type is SupposititiousSimpleType) { @@ -180,26 +130,13 @@ abstract class DescriptorMangleComputer(protected val builder: StringBuilder, pr } } else { when (val classifier = type.constructor.declarationDescriptor) { - is ClassDescriptor -> classifier.accept(copy(MangleMode.FQNAME), null) + is ClassDescriptor -> with(copy(MangleMode.FQNAME)) { classifier.visit() } is TypeParameterDescriptor -> tBuilder.mangleTypeParameterReference(classifier) else -> error("Unexpected classifier: $classifier") } } - type.arguments.ifNotEmpty { - collectForMangler(tBuilder, MangleConstant.TYPE_ARGUMENTS) { arg -> - if (arg.isStarProjection) { - appendSignature(MangleConstant.STAR_MARK) - } else { - if (arg.projectionKind != Variance.INVARIANT) { - appendSignature(arg.projectionKind.label) - appendSignature(MangleConstant.VARIANCE_SEPARATOR) - } - - mangleType(this, arg.type) - } - } - } + mangleTypeArguments(tBuilder, type, null) if (type.isMarkedNullable) tBuilder.appendSignature(MangleConstant.Q_MARK) @@ -219,113 +156,119 @@ abstract class DescriptorMangleComputer(protected val builder: StringBuilder, pr lower.replace(newArguments = upper.arguments) } else lower val mixed = intermediate.makeNullableAsSpecified(upper.isMarkedNullable) - mangleType(tBuilder, mixed) - } else mangleType(tBuilder, upper) + mangleType(tBuilder, mixed, null) + } else mangleType(tBuilder, upper, null) } - else -> error("Unexpected type $wtype") + else -> error("Unexpected type $wrappedType") } } - protected open fun mangleTypePlatformSpecific(type: UnwrappedType, tBuilder: StringBuilder) {} + final override fun getEffectiveParent(typeParameter: TypeParameterDescriptor) = typeParameter.containingDeclaration - private fun StringBuilder.mangleTypeParameterReference(typeParameter: TypeParameterDescriptor) { - val parent = typeParameter.containingDeclaration - val ci = typeParameterContainer.indexOf(parent) - // TODO: what should we do in this case? -// require(ci >= 0) { "No type container found for ${typeParameter.render()}" } - appendSignature(ci) - appendSignature(MangleConstant.INDEX_SEPARATOR) - appendSignature(typeParameter.index) - } + override fun renderDeclaration(declaration: DeclarationDescriptor) = DescriptorRenderer.SHORT_NAMES_IN_TYPES.render(declaration) - override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, data: Nothing?) { - descriptor.fqName.let { if (!it.isRoot) builder.appendName(it.asString()) } - } + override fun getTypeParameterName(typeParameter: TypeParameterDescriptor) = typeParameter.name.asString() - override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor, data: Nothing?) = reportUnexpectedDescriptor(descriptor) - - override fun visitVariableDescriptor(descriptor: VariableDescriptor, data: Nothing?) = reportUnexpectedDescriptor(descriptor) - - override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Nothing?) { - descriptor.mangleFunction(false, descriptor) - } - - override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor, data: Nothing?) { - descriptor.containingDeclaration.accept(this, data) - - builder.appendSignature(MangleConstant.TYPE_PARAM_INDEX_PREFIX) - builder.appendSignature(descriptor.index) - } - - override fun visitClassDescriptor(descriptor: ClassDescriptor, data: Nothing?) { - isRealExpect = isRealExpect or descriptor.isExpect - typeParameterContainer.add(descriptor) - descriptor.mangleSimpleDeclaration(descriptor.name.asString()) - } - - override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, data: Nothing?) { - descriptor.mangleSimpleDeclaration(descriptor.name.asString()) - } - - override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: Nothing?) = reportUnexpectedDescriptor(descriptor) - - override fun visitConstructorDescriptor(constructorDescriptor: ConstructorDescriptor, data: Nothing?) { - constructorDescriptor.mangleFunction(isCtor = true, container = constructorDescriptor) - } - - override fun visitScriptDescriptor(scriptDescriptor: ScriptDescriptor, data: Nothing?) = - visitClassDescriptor(scriptDescriptor, data) - - override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Nothing?) { - - if (descriptor is IrImplementingDelegateDescriptor) { - descriptor.mangleSimpleDeclaration(descriptor.name.asString()) - } else { - - val actualDescriptor = (descriptor as? IrPropertyDelegateDescriptor)?.correspondingProperty ?: descriptor - - val extensionReceiver = actualDescriptor.extensionReceiverParameter - - isRealExpect = isRealExpect or actualDescriptor.isExpect - - typeParameterContainer.add(actualDescriptor) - actualDescriptor.containingDeclaration.accept(this, data) - - if (actualDescriptor.isRealStatic) { - builder.appendSignature(MangleConstant.STATIC_MEMBER_MARK) - } - - if (extensionReceiver != null) { - builder.appendSignature(MangleConstant.EXTENSION_RECEIVER_PREFIX) - mangleExtensionReceiverParameter(builder, extensionReceiver) - } - - actualDescriptor.typeParameters.collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { mangleTypeParameter(this, it) } - - builder.append(actualDescriptor.name.asString()) - - actualDescriptor.platformSpecificSuffix()?.let { - builder.appendSignature(it) - } - } - } - - override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor, data: Nothing?) = - reportUnexpectedDescriptor(descriptor) + final override fun getIndexOfTypeParameter(typeParameter: TypeParameterDescriptor, container: DeclarationDescriptor) = + typeParameter.index private fun manglePropertyAccessor(accessor: PropertyAccessorDescriptor) { val property = accessor.correspondingProperty accessor.mangleFunction(false, property) } - override fun visitPropertyGetterDescriptor(descriptor: PropertyGetterDescriptor, data: Nothing?) { - manglePropertyAccessor(descriptor) - } + protected open fun visitModuleDeclaration(descriptor: ModuleDescriptor) = reportUnexpectedDescriptor(descriptor) - override fun visitPropertySetterDescriptor(descriptor: PropertySetterDescriptor, data: Nothing?) { - manglePropertyAccessor(descriptor) - } + private inner class Visitor : DeclarationDescriptorVisitor { - override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor, data: Nothing?) = - reportUnexpectedDescriptor(descriptor) + override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, data: Nothing?) { + descriptor.fqName.let { if (!it.isRoot) builder.appendName(it.asString()) } + } + + override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor, data: Nothing?) = reportUnexpectedDescriptor(descriptor) + + override fun visitVariableDescriptor(descriptor: VariableDescriptor, data: Nothing?) = reportUnexpectedDescriptor(descriptor) + + override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Nothing?) { + descriptor.mangleFunction(false, descriptor) + } + + override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor, data: Nothing?) { + descriptor.containingDeclaration.visit() + + builder.appendSignature(MangleConstant.TYPE_PARAM_INDEX_PREFIX) + builder.appendSignature(descriptor.index) + } + + override fun visitClassDescriptor(descriptor: ClassDescriptor, data: Nothing?) { + isRealExpect = isRealExpect or descriptor.isExpect + typeParameterContainers.add(descriptor) + descriptor.mangleSimpleDeclaration(descriptor.name.asString()) + } + + override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, data: Nothing?) { + descriptor.mangleSimpleDeclaration(descriptor.name.asString()) + } + + override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: Nothing?) { + visitModuleDeclaration(descriptor) + } + + override fun visitConstructorDescriptor(constructorDescriptor: ConstructorDescriptor, data: Nothing?) { + constructorDescriptor.mangleFunction(isCtor = true, container = constructorDescriptor) + } + + override fun visitScriptDescriptor(scriptDescriptor: ScriptDescriptor, data: Nothing?) = + visitClassDescriptor(scriptDescriptor, data) + + override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Nothing?) { + + if (descriptor is IrImplementingDelegateDescriptor) { + descriptor.mangleSimpleDeclaration(descriptor.name.asString()) + } else { + + val actualDescriptor = (descriptor as? IrPropertyDelegateDescriptor)?.correspondingProperty ?: descriptor + + val extensionReceiver = actualDescriptor.extensionReceiverParameter + + isRealExpect = isRealExpect or actualDescriptor.isExpect + + typeParameterContainers.add(actualDescriptor) + actualDescriptor.containingDeclaration.visit() + + if (actualDescriptor.isRealStatic) { + builder.appendSignature(MangleConstant.STATIC_MEMBER_MARK) + } + + if (extensionReceiver != null) { + builder.appendSignature(MangleConstant.EXTENSION_RECEIVER_PREFIX) + mangleExtensionReceiverParameter(builder, extensionReceiver) + } + + actualDescriptor.typeParameters.collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { + mangleTypeParameter(this, it, it.index, null) + } + + builder.append(actualDescriptor.name.asString()) + + actualDescriptor.platformSpecificSuffix()?.let { + builder.appendSignature(it) + } + } + } + + override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor, data: Nothing?) = + reportUnexpectedDescriptor(descriptor) + + override fun visitPropertyGetterDescriptor(descriptor: PropertyGetterDescriptor, data: Nothing?) { + manglePropertyAccessor(descriptor) + } + + override fun visitPropertySetterDescriptor(descriptor: PropertySetterDescriptor, data: Nothing?) { + manglePropertyAccessor(descriptor) + } + + override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor, data: Nothing?) = + reportUnexpectedDescriptor(descriptor) + } } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrMangleComputer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrMangleComputer.kt index a283264a9bd..82bb68a6543 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrMangleComputer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrMangleComputer.kt @@ -5,10 +5,8 @@ package org.jetbrains.kotlin.backend.common.serialization.mangle.ir -import org.jetbrains.kotlin.backend.common.serialization.mangle.KotlinMangleComputer -import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleConstant -import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleMode -import org.jetbrains.kotlin.backend.common.serialization.mangle.collectForMangler +import org.jetbrains.kotlin.backend.common.serialization.mangle.* +import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.symbols.IrClassSymbol @@ -17,80 +15,47 @@ import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid -import org.jetbrains.kotlin.types.Variance -import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty -abstract class IrMangleComputer(protected val builder: StringBuilder, private val mode: MangleMode, protected val compatibleMode: Boolean) : - IrElementVisitorVoid, KotlinMangleComputer { +abstract class IrMangleComputer( + builder: StringBuilder, + mode: MangleMode, + protected val compatibleMode: Boolean +) : BaseKotlinMangleComputer< + /*Declaration=*/IrDeclaration, + /*Type=*/IrType, + /*TypeParameter=*/IrTypeParameterSymbol, + /*ValueParameter=*/IrValueParameter, + /*TypeParameterContainer=*/IrDeclaration, + /*FunctionDeclaration=*/IrFunction, + /*Session=*/Nothing?, + >(builder, mode) { - private val typeParameterContainer = ArrayList(4) + final override fun getTypeSystemContext(session: Nothing?) = object : IrTypeSystemContext { + override val irBuiltIns: IrBuiltIns + get() = throw UnsupportedOperationException("Builtins are unavailable") + } - private var isRealExpect = false - - open fun IrFunction.platformSpecificFunctionName(): String? = null open fun IrFunction.platformSpecificFunctionMarks(): List = emptyList() - open fun IrFunction.specialValueParamPrefix(param: IrValueParameter): String = "" - - open fun addReturnType(): Boolean = false - - protected open fun addReturnTypeSpecialCase(irFunction: IrFunction): Boolean = false - abstract override fun copy(newMode: MangleMode): IrMangleComputer - private fun StringBuilder.appendName(s: String) { - if (mode.fqn) { - append(s) - } + final override fun IrDeclaration.visitParent() { + parent.acceptVoid(Visitor()) } - private fun StringBuilder.appendName(c: Char) { - if (mode.fqn) { - append(c) - } - } - - private fun StringBuilder.appendSignature(s: String) { - if (mode.signature) { - append(s) - } - } - - private fun StringBuilder.appendSignature(c: Char) { - if (mode.signature) { - append(c) - } - } - - private fun StringBuilder.appendSignature(i: Int) { - if (mode.signature) { - append(i) - } - } - - override fun computeMangle(declaration: IrDeclaration): String { - declaration.acceptVoid(this) - return builder.toString() - } - - private fun IrDeclaration.mangleSimpleDeclaration(name: String) { - val l = builder.length - parent.acceptVoid(this@IrMangleComputer) - - if (builder.length != l) builder.appendName(MangleConstant.FQN_SEPARATOR) - - builder.appendName(name) + final override fun IrDeclaration.visit() { + acceptVoid(Visitor()) } private fun IrFunction.mangleFunction(isCtor: Boolean, isStatic: Boolean, container: IrDeclaration) { isRealExpect = isRealExpect or isExpect - typeParameterContainer.add(container) + typeParameterContainers.add(container) val containerParent = container.parent val realParent = if (containerParent is IrField && containerParent.origin == IrDeclarationOrigin.DELEGATE) containerParent.parent else containerParent - realParent.acceptVoid(this@IrMangleComputer) + realParent.acceptVoid(Visitor()) builder.appendName(MangleConstant.FUNCTION_NAME_PREFIX) @@ -120,76 +85,53 @@ abstract class IrMangleComputer(protected val builder: StringBuilder, private va extensionReceiverParameter?.let { if (!it.isHidden) { builder.appendSignature(MangleConstant.EXTENSION_RECEIVER_PREFIX) - mangleValueParameter(builder, it) + mangleValueParameter(builder, it, null) } } valueParameters.collectForMangler(builder, MangleConstant.VALUE_PARAMETERS) { if (!it.isHidden) { appendSignature(specialValueParamPrefix(it)) - mangleValueParameter(this, it) + mangleValueParameter(this, it, null) } } - typeParameters.collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { mangleTypeParameter(this, it) } + typeParameters.collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { + mangleTypeParameter(this, it.symbol, it.index, null) + } if (!isCtor && !returnType.isUnit() && (addReturnType() || addReturnTypeSpecialCase(this))) { - mangleType(builder, returnType) + mangleType(builder, returnType, null) } } - private fun IrTypeParameter.effectiveParent(): IrDeclaration = when (val irParent = parent) { - is IrSimpleFunction -> irParent.correspondingPropertySymbol?.owner ?: irParent - is IrTypeParametersContainer -> irParent - else -> error("Unexpected type parameter container ${irParent.render()} for TP ${render()}") + final override fun getEffectiveParent(typeParameter: IrTypeParameterSymbol): IrDeclaration = typeParameter.owner.run { + when (val irParent = parent) { + is IrSimpleFunction -> irParent.correspondingPropertySymbol?.owner ?: irParent + is IrTypeParametersContainer -> irParent + else -> error("Unexpected type parameter container ${irParent.render()} for TP ${render()}") + } } - private fun mangleValueParameter(vpBuilder: StringBuilder, param: IrValueParameter) { - mangleType(vpBuilder, param.type) + override fun renderDeclaration(declaration: IrDeclaration) = declaration.render() - if (param.isVararg) vpBuilder.appendSignature(MangleConstant.VAR_ARG_MARK) - } + override fun getTypeParameterName(typeParameter: IrTypeParameterSymbol) = typeParameter.owner.name.asString() - private fun mangleTypeParameter(tpBuilder: StringBuilder, param: IrTypeParameter) { - tpBuilder.appendSignature(param.index) - tpBuilder.appendSignature(MangleConstant.UPPER_BOUND_SEPARATOR) + final override fun isVararg(valueParameter: IrValueParameter) = valueParameter.varargElementType != null - param.superTypes.collectForMangler(tpBuilder, MangleConstant.UPPER_BOUNDS) { mangleType(this, it) } - } + final override fun getValueParameterType(valueParameter: IrValueParameter) = valueParameter.type - private fun StringBuilder.mangleTypeParameterReference(typeParameter: IrTypeParameter) { - val parent = typeParameter.effectiveParent() - val ci = typeParameterContainer.indexOf(parent) - // TODO: what should we do in this case? -// require(ci >= 0) { "No type container found for ${typeParameter.render()}" } - appendSignature(ci) - appendSignature(MangleConstant.INDEX_SEPARATOR) - appendSignature(typeParameter.index) - } + final override fun getIndexOfTypeParameter(typeParameter: IrTypeParameterSymbol, container: IrDeclaration) = typeParameter.owner.index - private fun mangleType(tBuilder: StringBuilder, type: IrType) { + final override fun mangleType(tBuilder: StringBuilder, type: IrType, declarationSiteSession: Nothing?) { when (type) { is IrSimpleType -> { when (val classifier = type.classifier) { - is IrClassSymbol -> classifier.owner.acceptVoid(copy(MangleMode.FQNAME)) - is IrTypeParameterSymbol -> tBuilder.mangleTypeParameterReference(classifier.owner) + is IrClassSymbol -> with(copy(MangleMode.FQNAME)) { classifier.owner.visit() } + is IrTypeParameterSymbol -> tBuilder.mangleTypeParameterReference(classifier) } - type.arguments.ifNotEmpty { - collectForMangler(tBuilder, MangleConstant.TYPE_ARGUMENTS) { arg -> - when (arg) { - is IrStarProjection -> appendSignature(MangleConstant.STAR_MARK) - is IrTypeProjection -> { - if (arg.variance != Variance.INVARIANT) { - appendSignature(arg.variance.label) - appendSignature(MangleConstant.VARIANCE_SEPARATOR) - } - - mangleType(this, arg.type) - } - } - } - } + mangleTypeArguments(tBuilder, type, null) //TODO if (type.isMarkedNullable()) tBuilder.appendSignature(MangleConstant.Q_MARK) @@ -202,124 +144,127 @@ abstract class IrMangleComputer(protected val builder: StringBuilder, private va } } - protected open fun mangleTypePlatformSpecific(type: IrType, tBuilder: StringBuilder) {} + private inner class Visitor : IrElementVisitorVoid { - override fun visitElement(element: IrElement) = - error("unexpected element ${element.render()}") + override fun visitElement(element: IrElement) = + error("unexpected element ${element.render()}") - override fun visitScript(declaration: IrScript) { - declaration.parent.acceptVoid(this) - } - - override fun visitErrorDeclaration(declaration: IrErrorDeclaration) { - declaration.mangleSimpleDeclaration(MangleConstant.ERROR_DECLARATION) - } - - override fun visitClass(declaration: IrClass) { - isRealExpect = isRealExpect or declaration.isExpect - typeParameterContainer.add(declaration) - - val className = declaration.name.asString() - declaration.mangleSimpleDeclaration(className) - } - - override fun visitPackageFragment(declaration: IrPackageFragment) { - declaration.fqName.let { if (!it.isRoot) builder.appendName(it.asString()) } - } - - override fun visitProperty(declaration: IrProperty) { - val accessor = declaration.run { getter ?: setter } - require(accessor != null || declaration.backingField != null) { - "Expected at least one accessor or backing field for property ${declaration.render()}" + override fun visitScript(declaration: IrScript) { + declaration.visitParent() } - isRealExpect = isRealExpect or declaration.isExpect - typeParameterContainer.add(declaration) - declaration.parent.acceptVoid(this) + override fun visitErrorDeclaration(declaration: IrErrorDeclaration) { + declaration.mangleSimpleDeclaration(MangleConstant.ERROR_DECLARATION) + } - val isStaticProperty = if (accessor != null) - accessor.let { - it.dispatchReceiverParameter == null && declaration.parent !is IrPackageFragment && !declaration.parent.isFacadeClass + override fun visitClass(declaration: IrClass) { + isRealExpect = isRealExpect or declaration.isExpect + typeParameterContainers.add(declaration) + + val className = declaration.name.asString() + declaration.mangleSimpleDeclaration(className) + } + + override fun visitPackageFragment(declaration: IrPackageFragment) { + declaration.fqName.let { if (!it.isRoot) builder.appendName(it.asString()) } + } + + override fun visitProperty(declaration: IrProperty) { + val accessor = declaration.run { getter ?: setter } + require(accessor != null || declaration.backingField != null) { + "Expected at least one accessor or backing field for property ${declaration.render()}" + } + + isRealExpect = isRealExpect or declaration.isExpect + typeParameterContainers.add(declaration) + declaration.visitParent() + + val isStaticProperty = if (accessor != null) + accessor.let { + it.dispatchReceiverParameter == null && declaration.parent !is IrPackageFragment && !declaration.parent.isFacadeClass + } + else { + // Fake override for a Java field + val backingField = declaration.resolveFakeOverride()?.backingField + ?: error("Expected at least one accessor or a backing field for property ${declaration.render()}") + backingField.isStatic + } + + if (isStaticProperty) { + builder.appendSignature(MangleConstant.STATIC_MEMBER_MARK) + } + + accessor?.extensionReceiverParameter?.let { + builder.appendSignature(MangleConstant.EXTENSION_RECEIVER_PREFIX) + mangleValueParameter(builder, it, null) + } + + val typeParameters = accessor?.typeParameters ?: emptyList() + + typeParameters.collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { + mangleTypeParameter(this, it.symbol, it.index, null) + } + + builder.append(declaration.name.asString()) + + if (declaration.isSyntheticForJavaField) { + builder.append(MangleConstant.JAVA_FIELD_SUFFIX) } - else { - // Fake override for a Java field - val backingField = declaration.resolveFakeOverride()?.backingField - ?: error("Expected at least one accessor or a backing field for property ${declaration.render()}") - backingField.isStatic } - if (isStaticProperty) { - builder.appendSignature(MangleConstant.STATIC_MEMBER_MARK) + private val IrProperty.isSyntheticForJavaField: Boolean + get() = origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && getter == null && setter == null + + override fun visitField(declaration: IrField) { + val prop = declaration.correspondingPropertySymbol + if (compatibleMode || prop == null) { // act as used to be (KT-48912) + // test compiler/testData/codegen/box/ir/serializationRegressions/anonFakeOverride.kt + declaration.mangleSimpleDeclaration(declaration.name.asString()) + } else { + visitProperty(prop.owner) + } } - accessor?.extensionReceiverParameter?.let { - builder.appendSignature(MangleConstant.EXTENSION_RECEIVER_PREFIX) - mangleValueParameter(builder, it) - } - - val typeParameters = accessor?.typeParameters ?: emptyList() - - typeParameters.collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { mangleTypeParameter(this, it) } - - builder.append(declaration.name.asString()) - - if (declaration.isSyntheticForJavaField) { - builder.append(MangleConstant.JAVA_FIELD_SUFFIX) - } - } - - private val IrProperty.isSyntheticForJavaField: Boolean - get() = origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && getter == null && setter == null - - override fun visitField(declaration: IrField) { - val prop = declaration.correspondingPropertySymbol - if (compatibleMode || prop == null) { // act as used to be (KT-48912) - // test compiler/testData/codegen/box/ir/serializationRegressions/anonFakeOverride.kt + override fun visitEnumEntry(declaration: IrEnumEntry) { declaration.mangleSimpleDeclaration(declaration.name.asString()) - } else { - visitProperty(prop.owner) } - } - override fun visitEnumEntry(declaration: IrEnumEntry) { - declaration.mangleSimpleDeclaration(declaration.name.asString()) - } + override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) { + val klass = declaration.parentAsClass + val anonInitializers = klass.declarations.filterIsInstance() - override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) { - val klass = declaration.parentAsClass - val anonInitializers = klass.declarations.filterIsInstance() - - val anonName = buildString { - append(MangleConstant.ANON_INIT_NAME_PREFIX) - if (anonInitializers.size > 1) { - append(MangleConstant.LOCAL_DECLARATION_INDEX_PREFIX) - append(anonInitializers.indexOf(declaration)) + val anonName = buildString { + append(MangleConstant.ANON_INIT_NAME_PREFIX) + if (anonInitializers.size > 1) { + append(MangleConstant.LOCAL_DECLARATION_INDEX_PREFIX) + append(anonInitializers.indexOf(declaration)) + } } + + declaration.mangleSimpleDeclaration(anonName) } - declaration.mangleSimpleDeclaration(anonName) + override fun visitTypeAlias(declaration: IrTypeAlias) = + declaration.mangleSimpleDeclaration(declaration.name.asString()) + + override fun visitTypeParameter(declaration: IrTypeParameter) { + getEffectiveParent(declaration.symbol).visit() + + builder.appendSignature(MangleConstant.TYPE_PARAM_INDEX_PREFIX) + builder.appendSignature(declaration.index) + } + + override fun visitSimpleFunction(declaration: IrSimpleFunction) { + isRealExpect = isRealExpect or declaration.isExpect + + val container = declaration.correspondingPropertySymbol?.owner ?: declaration + val isStatic = declaration.dispatchReceiverParameter == null && + (container.parent !is IrPackageFragment && !container.parent.isFacadeClass) + + declaration.mangleFunction(false, isStatic, container) + } + + override fun visitConstructor(declaration: IrConstructor) = + declaration.mangleFunction(isCtor = true, isStatic = false, declaration) } - - override fun visitTypeAlias(declaration: IrTypeAlias) = - declaration.mangleSimpleDeclaration(declaration.name.asString()) - - override fun visitTypeParameter(declaration: IrTypeParameter) { - declaration.effectiveParent().acceptVoid(this) - - builder.appendSignature(MangleConstant.TYPE_PARAM_INDEX_PREFIX) - builder.appendSignature(declaration.index) - } - - override fun visitSimpleFunction(declaration: IrSimpleFunction) { - isRealExpect = isRealExpect or declaration.isExpect - - val container = declaration.correspondingPropertySymbol?.owner ?: declaration - val isStatic = declaration.dispatchReceiverParameter == null && - (container.parent !is IrPackageFragment && !container.parent.isFacadeClass) - - declaration.mangleFunction(false, isStatic, container) - } - - override fun visitConstructor(declaration: IrConstructor) = - declaration.mangleFunction(isCtor = true, isStatic = false, declaration) } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/mangleUtils.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/mangleUtils.kt index 784eab43f55..703302bc782 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/mangleUtils.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/mangleUtils.kt @@ -7,7 +7,7 @@ package org.jetbrains.kotlin.backend.common.serialization.mangle import org.jetbrains.kotlin.name.FqName -fun Collection.collectForMangler(builder: StringBuilder, params: MangleConstant, collect: StringBuilder.(T) -> Unit) { +fun Iterable.collectForMangler(builder: StringBuilder, params: MangleConstant, collect: StringBuilder.(T) -> Unit) { var first = true builder.append(params.prefix) diff --git a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmMangler.kt b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmMangler.kt index a8b8235679f..1de522e0735 100644 --- a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmMangler.kt +++ b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmMangler.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.util.hasAnnotation import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability +import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext @@ -36,7 +37,7 @@ object JvmIrMangler : IrBasedKotlinManglerImpl() { override fun copy(newMode: MangleMode): IrMangleComputer = JvmIrManglerComputer(builder, newMode, compatibleMode) - override fun addReturnTypeSpecialCase(irFunction: IrFunction): Boolean = true + override fun addReturnTypeSpecialCase(function: IrFunction): Boolean = true override fun mangleTypePlatformSpecific(type: IrType, tBuilder: StringBuilder) { if (type.hasAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION)) { @@ -61,7 +62,7 @@ class JvmDescriptorMangler(private val mainDetector: MainFunctionDetector?) : De private val mainDetector: MainFunctionDetector?, mode: MangleMode ) : DescriptorMangleComputer(builder, mode) { - override fun addReturnTypeSpecialCase(functionDescriptor: FunctionDescriptor): Boolean = true + override fun addReturnTypeSpecialCase(function: FunctionDescriptor): Boolean = true override fun copy(newMode: MangleMode): DescriptorMangleComputer = JvmDescriptorManglerComputer(builder, mainDetector, newMode) @@ -78,13 +79,13 @@ class JvmDescriptorMangler(private val mainDetector: MainFunctionDetector?) : De return if (isJavaField) MangleConstant.JAVA_FIELD_SUFFIX else null } - override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: Nothing?) { + override fun visitModuleDeclaration(descriptor: ModuleDescriptor) { // In general, having module descriptor as `containingDeclaration` for regular declaration is considered an error (in JS/Native) // because there should be `PackageFragmentDescriptor` in between // but on JVM there is `SyntheticJavaPropertyDescriptor` whose parent is a module. So let just skip it. } - override fun mangleTypePlatformSpecific(type: UnwrappedType, tBuilder: StringBuilder) { + override fun mangleTypePlatformSpecific(type: KotlinType, tBuilder: StringBuilder) { // Disambiguate between 'double' and '@NotNull java.lang.Double' types in mixed Java/Kotlin class hierarchies if (SimpleClassicTypeSystemContext.hasEnhancedNullability(type)) { tBuilder.appendSignature(MangleConstant.ENHANCED_NULLABILITY_MARK)