[IR] Factor out duplicated code in KotlinMangleComputer into base class
This commit is contained in:
committed by
Space Team
parent
de5b475f7a
commit
c447b91101
+101
-167
@@ -5,10 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.backend.jvm
|
package org.jetbrains.kotlin.fir.backend.jvm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.mangle.KotlinMangleComputer
|
import org.jetbrains.kotlin.backend.common.serialization.mangle.*
|
||||||
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.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
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.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.signaturer.irName
|
import org.jetbrains.kotlin.fir.signaturer.irName
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
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.FirClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
|
|
||||||
|
|
||||||
open class FirJvmMangleComputer(
|
class FirJvmMangleComputer(
|
||||||
private val builder: StringBuilder,
|
builder: StringBuilder,
|
||||||
private val mode: MangleMode
|
mode: MangleMode,
|
||||||
) : FirVisitor<Unit, Boolean>(), KotlinMangleComputer<FirDeclaration> {
|
) : BaseKotlinMangleComputer<
|
||||||
|
/*Declaration=*/FirDeclaration,
|
||||||
|
/*Type=*/ConeKotlinType,
|
||||||
|
/*TypeParameter=*/ConeTypeParameterLookupTag,
|
||||||
|
/*ValueParameter=*/FirValueParameter,
|
||||||
|
/*TypeParameterContainer=*/FirMemberDeclaration,
|
||||||
|
/*FunctionDeclaration=*/FirFunction,
|
||||||
|
/*Session=*/FirSession,
|
||||||
|
>(builder, mode) {
|
||||||
|
|
||||||
private val typeParameterContainer = ArrayList<FirMemberDeclaration>(4)
|
override fun getTypeSystemContext(session: FirSession) = object : ConeInferenceContext {
|
||||||
|
override val session: FirSession
|
||||||
|
get() = session
|
||||||
|
}
|
||||||
|
|
||||||
private var isRealExpect = false
|
override fun FirFunction.platformSpecificSuffix(): String? =
|
||||||
|
|
||||||
open fun FirFunction.platformSpecificFunctionName(): String? = null
|
|
||||||
|
|
||||||
open fun FirFunction.platformSpecificSuffix(): String? =
|
|
||||||
if (this is FirSimpleFunction && name.asString() == "main")
|
if (this is FirSimpleFunction && name.asString() == "main")
|
||||||
this.moduleData.session.firProvider.getFirCallableContainerFile(symbol)?.name
|
this.moduleData.session.firProvider.getFirCallableContainerFile(symbol)?.name
|
||||||
else null
|
else null
|
||||||
|
|
||||||
open fun FirFunction.specialValueParamPrefix(param: FirValueParameter): String = ""
|
override fun addReturnType(): Boolean = true
|
||||||
|
|
||||||
private fun addReturnType(): Boolean = true
|
|
||||||
|
|
||||||
override fun copy(newMode: MangleMode): FirJvmMangleComputer =
|
override fun copy(newMode: MangleMode): FirJvmMangleComputer =
|
||||||
FirJvmMangleComputer(builder, newMode)
|
FirJvmMangleComputer(builder, newMode)
|
||||||
|
|
||||||
private fun StringBuilder.appendName(s: String) {
|
override fun FirDeclaration.visitParent() {
|
||||||
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() {
|
|
||||||
val (parentPackageFqName, parentClassId) = when (this) {
|
val (parentPackageFqName, parentClassId) = when (this) {
|
||||||
is FirCallableDeclaration -> this.containingClassLookupTag()?.classId?.let { it.packageFqName to it } ?: return
|
is FirCallableDeclaration -> this.containingClassLookupTag()?.classId?.let { it.packageFqName to it } ?: return
|
||||||
is FirClassLikeDeclaration -> this.symbol.classId.let { it.packageFqName to it.outerClassId }
|
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
|
val parentClassLike = this.moduleData.session.symbolProvider.getClassLikeSymbolByClassId(parentClassId)?.fir
|
||||||
?: error("Attempt to find parent ($parentClassId) for probably-local declaration!")
|
?: error("Attempt to find parent ($parentClassId) for probably-local declaration!")
|
||||||
if (parentClassLike is FirRegularClass || parentClassLike is FirTypeAlias) {
|
if (parentClassLike is FirRegularClass || parentClassLike is FirTypeAlias) {
|
||||||
parentClassLike.accept(this@FirJvmMangleComputer, false)
|
parentClassLike.visit()
|
||||||
} else {
|
} else {
|
||||||
error("Strange class-like declaration: ${parentClassLike.render()}")
|
error("Strange class-like declaration: ${parentClassLike.render()}")
|
||||||
}
|
}
|
||||||
@@ -101,15 +72,8 @@ open class FirJvmMangleComputer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirDeclaration.mangleSimpleDeclaration(name: String) {
|
override fun FirDeclaration.visit() {
|
||||||
val l = builder.length
|
accept(Visitor(), null)
|
||||||
visitParent()
|
|
||||||
|
|
||||||
if (builder.length != l) {
|
|
||||||
builder.appendName(MangleConstant.FQN_SEPARATOR)
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.appendName(name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirFunction.mangleFunction(isCtor: Boolean, isStatic: Boolean, container: FirDeclaration) {
|
private fun FirFunction.mangleFunction(isCtor: Boolean, isStatic: Boolean, container: FirDeclaration) {
|
||||||
@@ -117,7 +81,7 @@ open class FirJvmMangleComputer(
|
|||||||
isRealExpect = isRealExpect || (this as? FirMemberDeclaration)?.isExpect == true
|
isRealExpect = isRealExpect || (this as? FirMemberDeclaration)?.isExpect == true
|
||||||
|
|
||||||
if (container is FirMemberDeclaration) {
|
if (container is FirMemberDeclaration) {
|
||||||
typeParameterContainer.add(container)
|
typeParameterContainers.add(container)
|
||||||
}
|
}
|
||||||
visitParent()
|
visitParent()
|
||||||
|
|
||||||
@@ -161,11 +125,11 @@ open class FirJvmMangleComputer(
|
|||||||
|
|
||||||
valueParameters.collectForMangler(builder, MangleConstant.VALUE_PARAMETERS) {
|
valueParameters.collectForMangler(builder, MangleConstant.VALUE_PARAMETERS) {
|
||||||
appendSignature(specialValueParamPrefix(it))
|
appendSignature(specialValueParamPrefix(it))
|
||||||
mangleValueParameter(this, it)
|
mangleValueParameter(this, it, moduleData.session)
|
||||||
}
|
}
|
||||||
(container as? FirTypeParametersOwner)?.typeParameters?.withIndex()?.toList().orEmpty()
|
(container as? FirTypeParametersOwner)?.typeParameters?.withIndex()?.toList().orEmpty()
|
||||||
.collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { (index, typeParameter) ->
|
.collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { (index, typeParameter) ->
|
||||||
mangleTypeParameter(this, typeParameter, index)
|
mangleTypeParameter(this, typeParameter.symbol.toLookupTag(), index, moduleData.session)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isCtor && !returnTypeRef.isUnit && addReturnType()) {
|
if (!isCtor && !returnTypeRef.isUnit && addReturnType()) {
|
||||||
@@ -173,8 +137,8 @@ open class FirJvmMangleComputer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirTypeParameter.effectiveParent(): FirMemberDeclaration {
|
override fun getEffectiveParent(typeParameter: ConeTypeParameterLookupTag): FirMemberDeclaration = typeParameter.symbol.fir.run {
|
||||||
for (parent in typeParameterContainer) {
|
for (parent in typeParameterContainers) {
|
||||||
if (this in parent.typeParameters) {
|
if (this in parent.typeParameters) {
|
||||||
return parent
|
return parent
|
||||||
}
|
}
|
||||||
@@ -188,33 +152,18 @@ open class FirJvmMangleComputer(
|
|||||||
throw IllegalStateException("Should not be here!")
|
throw IllegalStateException("Should not be here!")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mangleValueParameter(vpBuilder: StringBuilder, param: FirValueParameter) {
|
override fun renderDeclaration(declaration: FirDeclaration) = declaration.render()
|
||||||
mangleType(vpBuilder, param.returnTypeRef.coneType, param.moduleData.session)
|
|
||||||
|
|
||||||
if (param.isVararg) {
|
override fun getTypeParameterName(typeParameter: ConeTypeParameterLookupTag) = typeParameter.name.asString()
|
||||||
vpBuilder.appendSignature(MangleConstant.VAR_ARG_MARK)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun mangleTypeParameter(tpBuilder: StringBuilder, param: FirTypeParameter, index: Int) {
|
override fun isVararg(valueParameter: FirValueParameter) = valueParameter.isVararg
|
||||||
tpBuilder.appendSignature(index)
|
|
||||||
tpBuilder.appendSignature(MangleConstant.UPPER_BOUND_SEPARATOR)
|
|
||||||
|
|
||||||
param.bounds.map { it.coneType }.collectForMangler(tpBuilder, MangleConstant.UPPER_BOUNDS) {
|
override fun getValueParameterType(valueParameter: FirValueParameter) = valueParameter.returnTypeRef.coneType
|
||||||
mangleType(this, it, param.moduleData.session)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun StringBuilder.mangleTypeParameterReference(typeParameter: FirTypeParameter) {
|
override fun getIndexOfTypeParameter(typeParameter: ConeTypeParameterLookupTag, container: FirMemberDeclaration) =
|
||||||
val parent = typeParameter.effectiveParent()
|
container.typeParameters.indexOf(typeParameter.symbol.fir)
|
||||||
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))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun mangleType(tBuilder: StringBuilder, type: ConeKotlinType, declarationSiteSession: FirSession) {
|
override fun mangleType(tBuilder: StringBuilder, type: ConeKotlinType, declarationSiteSession: FirSession) {
|
||||||
when (type) {
|
when (type) {
|
||||||
is ConeLookupTagBasedType -> {
|
is ConeLookupTagBasedType -> {
|
||||||
when (val symbol = type.lookupTag.toSymbol(declarationSiteSession)) {
|
when (val symbol = type.lookupTag.toSymbol(declarationSiteSession)) {
|
||||||
@@ -223,29 +172,15 @@ open class FirJvmMangleComputer(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
is FirClassSymbol -> symbol.fir.accept(copy(MangleMode.FQNAME), false)
|
is FirClassSymbol -> with(copy(MangleMode.FQNAME)) { symbol.fir.visit() }
|
||||||
is FirTypeParameterSymbol -> tBuilder.mangleTypeParameterReference(symbol.fir)
|
is FirTypeParameterSymbol -> tBuilder.mangleTypeParameterReference(symbol.toLookupTag())
|
||||||
// This is performed for a case with invisible class-like symbol in fake override
|
// This is performed for a case with invisible class-like symbol in fake override
|
||||||
null -> (type.lookupTag as? ConeClassLikeLookupTag)?.let {
|
null -> (type.lookupTag as? ConeClassLikeLookupTag)?.let {
|
||||||
tBuilder.append(it.classId)
|
tBuilder.append(it.classId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type.typeArguments.asList().ifNotEmpty {
|
mangleTypeArguments(tBuilder, type, declarationSiteSession)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.isMarkedNullable) {
|
if (type.isMarkedNullable) {
|
||||||
tBuilder.appendSignature(MangleConstant.Q_MARK)
|
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) {
|
override fun visitElement(element: FirElement) = error("unexpected element ${element.render()}")
|
||||||
isRealExpect = isRealExpect or regularClass.isExpect
|
|
||||||
typeParameterContainer.add(regularClass)
|
|
||||||
regularClass.mangleSimpleDeclaration(regularClass.name.asString())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Boolean) {
|
override fun visitRegularClass(regularClass: FirRegularClass) {
|
||||||
anonymousObject.mangleSimpleDeclaration("<anonymous>")
|
isRealExpect = isRealExpect or regularClass.isExpect
|
||||||
}
|
typeParameterContainers.add(regularClass)
|
||||||
|
regularClass.mangleSimpleDeclaration(regularClass.name.asString())
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
variable.receiverParameter?.typeRef?.let {
|
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject) {
|
||||||
builder.appendSignature(MangleConstant.EXTENSION_RECEIVER_PREFIX)
|
anonymousObject.mangleSimpleDeclaration("<anonymous>")
|
||||||
mangleType(builder, it.coneType, variable.moduleData.session)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
variable.typeParameters.withIndex().toList().collectForMangler(builder, MangleConstant.TYPE_PARAMETERS) { (index, typeParameter) ->
|
override fun visitVariable(variable: FirVariable) {
|
||||||
mangleTypeParameter(this, typeParameter.symbol.fir, index)
|
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) {
|
||||||
}
|
visitVariable(property)
|
||||||
|
|
||||||
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 visitEnumEntry(enumEntry: FirEnumEntry, data: Boolean) {
|
override fun visitField(field: FirField) {
|
||||||
enumEntry.mangleSimpleDeclaration(enumEntry.name.asString())
|
if (field is FirJavaField) {
|
||||||
}
|
field.mangleSimpleDeclaration(field.name.asString())
|
||||||
|
} else {
|
||||||
override fun visitTypeAlias(typeAlias: FirTypeAlias, data: Boolean) =
|
visitVariable(field)
|
||||||
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 computeMangle(declaration: FirDeclaration): String {
|
override fun visitEnumEntry(enumEntry: FirEnumEntry) {
|
||||||
declaration.accept(this, true)
|
enumEntry.mangleSimpleDeclaration(enumEntry.name.asString())
|
||||||
return builder.toString()
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+181
@@ -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<Declaration, Type, TypeParameter, ValueParameter, TypeParameterContainer, FunctionDeclaration, Session>(
|
||||||
|
protected val builder: StringBuilder,
|
||||||
|
protected val mode: MangleMode
|
||||||
|
) : KotlinMangleComputer<Declaration>
|
||||||
|
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<TypeParameterContainer>(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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+133
-190
@@ -5,86 +5,44 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor
|
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.*
|
||||||
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.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptor
|
import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptor
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptor
|
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptor
|
||||||
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.types.*
|
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.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) :
|
abstract class DescriptorMangleComputer(builder: StringBuilder, mode: MangleMode) :
|
||||||
DeclarationDescriptorVisitor<Unit, Nothing?>, KotlinMangleComputer<DeclarationDescriptor> {
|
BaseKotlinMangleComputer<
|
||||||
|
/*Declaration=*/DeclarationDescriptor,
|
||||||
override fun computeMangle(declaration: DeclarationDescriptor): String {
|
/*Type=*/KotlinType,
|
||||||
declaration.accept(this, null)
|
/*TypeParameter=*/TypeParameterDescriptor,
|
||||||
return builder.toString()
|
/*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
|
abstract override fun copy(newMode: MangleMode): DescriptorMangleComputer
|
||||||
|
|
||||||
private fun StringBuilder.appendName(s: String) {
|
final override fun DeclarationDescriptor.visitParent() {
|
||||||
if (mode.fqn) {
|
containingDeclaration?.visit()
|
||||||
append(s)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun StringBuilder.appendName(c: Char) {
|
final override fun DeclarationDescriptor.visit() {
|
||||||
if (mode.fqn) {
|
accept(Visitor(), null)
|
||||||
append(c)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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<DeclarationDescriptor>(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) {
|
private fun reportUnexpectedDescriptor(descriptor: DeclarationDescriptor) {
|
||||||
error("unexpected descriptor $descriptor")
|
error("unexpected descriptor $descriptor")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun FunctionDescriptor.platformSpecificSuffix(): String? = null
|
|
||||||
open fun PropertyDescriptor.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
|
private val CallableDescriptor.isRealStatic: Boolean
|
||||||
get() = dispatchReceiverParameter == null && containingDeclaration !is PackageFragmentDescriptor
|
get() = dispatchReceiverParameter == null && containingDeclaration !is PackageFragmentDescriptor
|
||||||
|
|
||||||
@@ -92,8 +50,8 @@ abstract class DescriptorMangleComputer(protected val builder: StringBuilder, pr
|
|||||||
|
|
||||||
isRealExpect = isRealExpect or isExpect
|
isRealExpect = isRealExpect or isExpect
|
||||||
|
|
||||||
typeParameterContainer.add(container)
|
typeParameterContainers.add(container)
|
||||||
container.containingDeclaration.accept(this@DescriptorMangleComputer, null)
|
container.containingDeclaration.visit()
|
||||||
|
|
||||||
builder.appendName(MangleConstant.FUNCTION_NAME_PREFIX)
|
builder.appendName(MangleConstant.FUNCTION_NAME_PREFIX)
|
||||||
|
|
||||||
@@ -127,14 +85,14 @@ abstract class DescriptorMangleComputer(protected val builder: StringBuilder, pr
|
|||||||
|
|
||||||
valueParameters.collectForMangler(builder, MangleConstant.VALUE_PARAMETERS) {
|
valueParameters.collectForMangler(builder, MangleConstant.VALUE_PARAMETERS) {
|
||||||
appendSignature(specialValueParamPrefix(it))
|
appendSignature(specialValueParamPrefix(it))
|
||||||
mangleValueParameter(this, it)
|
mangleValueParameter(this, it, null)
|
||||||
}
|
}
|
||||||
realTypeParameterContainer.typeParameters.filter { it.containingDeclaration == realTypeParameterContainer }
|
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 {
|
returnType?.run {
|
||||||
if (!isCtor && !isUnit() && (addReturnType() || addReturnTypeSpecialCase(this@mangleSignature))) {
|
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) {
|
private fun mangleContextReceiverParameter(vpBuilder: StringBuilder, param: ReceiverParameterDescriptor) {
|
||||||
mangleType(vpBuilder, param.type)
|
mangleType(vpBuilder, param.type, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mangleExtensionReceiverParameter(vpBuilder: StringBuilder, param: ReceiverParameterDescriptor) {
|
private fun mangleExtensionReceiverParameter(vpBuilder: StringBuilder, param: ReceiverParameterDescriptor) {
|
||||||
mangleType(vpBuilder, param.type)
|
mangleType(vpBuilder, param.type, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mangleValueParameter(vpBuilder: StringBuilder, param: ValueParameterDescriptor) {
|
final override fun isVararg(valueParameter: ValueParameterDescriptor) = valueParameter.varargElementType != null
|
||||||
mangleType(vpBuilder, param.type)
|
|
||||||
|
|
||||||
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) {
|
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
|
||||||
tpBuilder.appendSignature(param.index)
|
final override fun mangleType(tBuilder: StringBuilder, wrappedType: KotlinType, declarationSiteSession: Nothing?) {
|
||||||
tpBuilder.appendSignature(MangleConstant.UPPER_BOUND_SEPARATOR)
|
when (val type = wrappedType.unwrap()) {
|
||||||
|
|
||||||
param.upperBounds.collectForMangler(tpBuilder, MangleConstant.UPPER_BOUNDS) { mangleType(this, it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun mangleType(tBuilder: StringBuilder, wtype: KotlinType) {
|
|
||||||
when (val type = wtype.unwrap()) {
|
|
||||||
is SimpleType -> {
|
is SimpleType -> {
|
||||||
|
|
||||||
if (type is SupposititiousSimpleType) {
|
if (type is SupposititiousSimpleType) {
|
||||||
@@ -180,26 +130,13 @@ abstract class DescriptorMangleComputer(protected val builder: StringBuilder, pr
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
when (val classifier = type.constructor.declarationDescriptor) {
|
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)
|
is TypeParameterDescriptor -> tBuilder.mangleTypeParameterReference(classifier)
|
||||||
else -> error("Unexpected classifier: $classifier")
|
else -> error("Unexpected classifier: $classifier")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type.arguments.ifNotEmpty {
|
mangleTypeArguments(tBuilder, type, null)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.isMarkedNullable) tBuilder.appendSignature(MangleConstant.Q_MARK)
|
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)
|
lower.replace(newArguments = upper.arguments)
|
||||||
} else lower
|
} else lower
|
||||||
val mixed = intermediate.makeNullableAsSpecified(upper.isMarkedNullable)
|
val mixed = intermediate.makeNullableAsSpecified(upper.isMarkedNullable)
|
||||||
mangleType(tBuilder, mixed)
|
mangleType(tBuilder, mixed, null)
|
||||||
} else mangleType(tBuilder, upper)
|
} 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) {
|
override fun renderDeclaration(declaration: DeclarationDescriptor) = DescriptorRenderer.SHORT_NAMES_IN_TYPES.render(declaration)
|
||||||
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 visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, data: Nothing?) {
|
override fun getTypeParameterName(typeParameter: TypeParameterDescriptor) = typeParameter.name.asString()
|
||||||
descriptor.fqName.let { if (!it.isRoot) builder.appendName(it.asString()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor, data: Nothing?) = reportUnexpectedDescriptor(descriptor)
|
final override fun getIndexOfTypeParameter(typeParameter: TypeParameterDescriptor, container: DeclarationDescriptor) =
|
||||||
|
typeParameter.index
|
||||||
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)
|
|
||||||
|
|
||||||
private fun manglePropertyAccessor(accessor: PropertyAccessorDescriptor) {
|
private fun manglePropertyAccessor(accessor: PropertyAccessorDescriptor) {
|
||||||
val property = accessor.correspondingProperty
|
val property = accessor.correspondingProperty
|
||||||
accessor.mangleFunction(false, property)
|
accessor.mangleFunction(false, property)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitPropertyGetterDescriptor(descriptor: PropertyGetterDescriptor, data: Nothing?) {
|
protected open fun visitModuleDeclaration(descriptor: ModuleDescriptor) = reportUnexpectedDescriptor(descriptor)
|
||||||
manglePropertyAccessor(descriptor)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitPropertySetterDescriptor(descriptor: PropertySetterDescriptor, data: Nothing?) {
|
private inner class Visitor : DeclarationDescriptorVisitor<Unit, Nothing?> {
|
||||||
manglePropertyAccessor(descriptor)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor, data: Nothing?) =
|
override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, data: Nothing?) {
|
||||||
reportUnexpectedDescriptor(descriptor)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+151
-206
@@ -5,10 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common.serialization.mangle.ir
|
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.*
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleConstant
|
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleMode
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.mangle.collectForMangler
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
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.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
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) :
|
abstract class IrMangleComputer(
|
||||||
IrElementVisitorVoid, KotlinMangleComputer<IrDeclaration> {
|
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<IrDeclaration>(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<String> = emptyList()
|
open fun IrFunction.platformSpecificFunctionMarks(): List<String> = 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
|
abstract override fun copy(newMode: MangleMode): IrMangleComputer
|
||||||
|
|
||||||
private fun StringBuilder.appendName(s: String) {
|
final override fun IrDeclaration.visitParent() {
|
||||||
if (mode.fqn) {
|
parent.acceptVoid(Visitor())
|
||||||
append(s)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun StringBuilder.appendName(c: Char) {
|
final override fun IrDeclaration.visit() {
|
||||||
if (mode.fqn) {
|
acceptVoid(Visitor())
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrFunction.mangleFunction(isCtor: Boolean, isStatic: Boolean, container: IrDeclaration) {
|
private fun IrFunction.mangleFunction(isCtor: Boolean, isStatic: Boolean, container: IrDeclaration) {
|
||||||
|
|
||||||
isRealExpect = isRealExpect or isExpect
|
isRealExpect = isRealExpect or isExpect
|
||||||
|
|
||||||
typeParameterContainer.add(container)
|
typeParameterContainers.add(container)
|
||||||
val containerParent = container.parent
|
val containerParent = container.parent
|
||||||
val realParent =
|
val realParent =
|
||||||
if (containerParent is IrField && containerParent.origin == IrDeclarationOrigin.DELEGATE) containerParent.parent else containerParent
|
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)
|
builder.appendName(MangleConstant.FUNCTION_NAME_PREFIX)
|
||||||
|
|
||||||
@@ -120,76 +85,53 @@ abstract class IrMangleComputer(protected val builder: StringBuilder, private va
|
|||||||
extensionReceiverParameter?.let {
|
extensionReceiverParameter?.let {
|
||||||
if (!it.isHidden) {
|
if (!it.isHidden) {
|
||||||
builder.appendSignature(MangleConstant.EXTENSION_RECEIVER_PREFIX)
|
builder.appendSignature(MangleConstant.EXTENSION_RECEIVER_PREFIX)
|
||||||
mangleValueParameter(builder, it)
|
mangleValueParameter(builder, it, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
valueParameters.collectForMangler(builder, MangleConstant.VALUE_PARAMETERS) {
|
valueParameters.collectForMangler(builder, MangleConstant.VALUE_PARAMETERS) {
|
||||||
if (!it.isHidden) {
|
if (!it.isHidden) {
|
||||||
appendSignature(specialValueParamPrefix(it))
|
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))) {
|
if (!isCtor && !returnType.isUnit() && (addReturnType() || addReturnTypeSpecialCase(this))) {
|
||||||
mangleType(builder, returnType)
|
mangleType(builder, returnType, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrTypeParameter.effectiveParent(): IrDeclaration = when (val irParent = parent) {
|
final override fun getEffectiveParent(typeParameter: IrTypeParameterSymbol): IrDeclaration = typeParameter.owner.run {
|
||||||
is IrSimpleFunction -> irParent.correspondingPropertySymbol?.owner ?: irParent
|
when (val irParent = parent) {
|
||||||
is IrTypeParametersContainer -> irParent
|
is IrSimpleFunction -> irParent.correspondingPropertySymbol?.owner ?: irParent
|
||||||
else -> error("Unexpected type parameter container ${irParent.render()} for TP ${render()}")
|
is IrTypeParametersContainer -> irParent
|
||||||
|
else -> error("Unexpected type parameter container ${irParent.render()} for TP ${render()}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mangleValueParameter(vpBuilder: StringBuilder, param: IrValueParameter) {
|
override fun renderDeclaration(declaration: IrDeclaration) = declaration.render()
|
||||||
mangleType(vpBuilder, param.type)
|
|
||||||
|
|
||||||
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) {
|
final override fun isVararg(valueParameter: IrValueParameter) = valueParameter.varargElementType != null
|
||||||
tpBuilder.appendSignature(param.index)
|
|
||||||
tpBuilder.appendSignature(MangleConstant.UPPER_BOUND_SEPARATOR)
|
|
||||||
|
|
||||||
param.superTypes.collectForMangler(tpBuilder, MangleConstant.UPPER_BOUNDS) { mangleType(this, it) }
|
final override fun getValueParameterType(valueParameter: IrValueParameter) = valueParameter.type
|
||||||
}
|
|
||||||
|
|
||||||
private fun StringBuilder.mangleTypeParameterReference(typeParameter: IrTypeParameter) {
|
final override fun getIndexOfTypeParameter(typeParameter: IrTypeParameterSymbol, container: IrDeclaration) = typeParameter.owner.index
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun mangleType(tBuilder: StringBuilder, type: IrType) {
|
final override fun mangleType(tBuilder: StringBuilder, type: IrType, declarationSiteSession: Nothing?) {
|
||||||
when (type) {
|
when (type) {
|
||||||
is IrSimpleType -> {
|
is IrSimpleType -> {
|
||||||
when (val classifier = type.classifier) {
|
when (val classifier = type.classifier) {
|
||||||
is IrClassSymbol -> classifier.owner.acceptVoid(copy(MangleMode.FQNAME))
|
is IrClassSymbol -> with(copy(MangleMode.FQNAME)) { classifier.owner.visit() }
|
||||||
is IrTypeParameterSymbol -> tBuilder.mangleTypeParameterReference(classifier.owner)
|
is IrTypeParameterSymbol -> tBuilder.mangleTypeParameterReference(classifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
type.arguments.ifNotEmpty {
|
mangleTypeArguments(tBuilder, type, null)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
if (type.isMarkedNullable()) tBuilder.appendSignature(MangleConstant.Q_MARK)
|
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) =
|
override fun visitElement(element: IrElement) =
|
||||||
error("unexpected element ${element.render()}")
|
error("unexpected element ${element.render()}")
|
||||||
|
|
||||||
override fun visitScript(declaration: IrScript) {
|
override fun visitScript(declaration: IrScript) {
|
||||||
declaration.parent.acceptVoid(this)
|
declaration.visitParent()
|
||||||
}
|
|
||||||
|
|
||||||
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()}"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isRealExpect = isRealExpect or declaration.isExpect
|
override fun visitErrorDeclaration(declaration: IrErrorDeclaration) {
|
||||||
typeParameterContainer.add(declaration)
|
declaration.mangleSimpleDeclaration(MangleConstant.ERROR_DECLARATION)
|
||||||
declaration.parent.acceptVoid(this)
|
}
|
||||||
|
|
||||||
val isStaticProperty = if (accessor != null)
|
override fun visitClass(declaration: IrClass) {
|
||||||
accessor.let {
|
isRealExpect = isRealExpect or declaration.isExpect
|
||||||
it.dispatchReceiverParameter == null && declaration.parent !is IrPackageFragment && !declaration.parent.isFacadeClass
|
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) {
|
private val IrProperty.isSyntheticForJavaField: Boolean
|
||||||
builder.appendSignature(MangleConstant.STATIC_MEMBER_MARK)
|
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 {
|
override fun visitEnumEntry(declaration: IrEnumEntry) {
|
||||||
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
|
|
||||||
declaration.mangleSimpleDeclaration(declaration.name.asString())
|
declaration.mangleSimpleDeclaration(declaration.name.asString())
|
||||||
} else {
|
|
||||||
visitProperty(prop.owner)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitEnumEntry(declaration: IrEnumEntry) {
|
override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) {
|
||||||
declaration.mangleSimpleDeclaration(declaration.name.asString())
|
val klass = declaration.parentAsClass
|
||||||
}
|
val anonInitializers = klass.declarations.filterIsInstance<IrAnonymousInitializer>()
|
||||||
|
|
||||||
override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) {
|
val anonName = buildString {
|
||||||
val klass = declaration.parentAsClass
|
append(MangleConstant.ANON_INIT_NAME_PREFIX)
|
||||||
val anonInitializers = klass.declarations.filterIsInstance<IrAnonymousInitializer>()
|
if (anonInitializers.size > 1) {
|
||||||
|
append(MangleConstant.LOCAL_DECLARATION_INDEX_PREFIX)
|
||||||
val anonName = buildString {
|
append(anonInitializers.indexOf(declaration))
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.backend.common.serialization.mangle
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
fun <T> Collection<T>.collectForMangler(builder: StringBuilder, params: MangleConstant, collect: StringBuilder.(T) -> Unit) {
|
fun <T> Iterable<T>.collectForMangler(builder: StringBuilder, params: MangleConstant, collect: StringBuilder.(T) -> Unit) {
|
||||||
var first = true
|
var first = true
|
||||||
|
|
||||||
builder.append(params.prefix)
|
builder.append(params.prefix)
|
||||||
|
|||||||
+5
-4
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.util.hasAnnotation
|
|||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
|
import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
|
||||||
import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability
|
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.UnwrappedType
|
||||||
import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext
|
import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ object JvmIrMangler : IrBasedKotlinManglerImpl() {
|
|||||||
override fun copy(newMode: MangleMode): IrMangleComputer =
|
override fun copy(newMode: MangleMode): IrMangleComputer =
|
||||||
JvmIrManglerComputer(builder, newMode, compatibleMode)
|
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) {
|
override fun mangleTypePlatformSpecific(type: IrType, tBuilder: StringBuilder) {
|
||||||
if (type.hasAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION)) {
|
if (type.hasAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION)) {
|
||||||
@@ -61,7 +62,7 @@ class JvmDescriptorMangler(private val mainDetector: MainFunctionDetector?) : De
|
|||||||
private val mainDetector: MainFunctionDetector?,
|
private val mainDetector: MainFunctionDetector?,
|
||||||
mode: MangleMode
|
mode: MangleMode
|
||||||
) : DescriptorMangleComputer(builder, mode) {
|
) : 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)
|
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
|
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)
|
// In general, having module descriptor as `containingDeclaration` for regular declaration is considered an error (in JS/Native)
|
||||||
// because there should be `PackageFragmentDescriptor` in between
|
// because there should be `PackageFragmentDescriptor` in between
|
||||||
// but on JVM there is `SyntheticJavaPropertyDescriptor` whose parent is a module. So let just skip it.
|
// 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
|
// Disambiguate between 'double' and '@NotNull java.lang.Double' types in mixed Java/Kotlin class hierarchies
|
||||||
if (SimpleClassicTypeSystemContext.hasEnhancedNullability(type)) {
|
if (SimpleClassicTypeSystemContext.hasEnhancedNullability(type)) {
|
||||||
tBuilder.appendSignature(MangleConstant.ENHANCED_NULLABILITY_MARK)
|
tBuilder.appendSignature(MangleConstant.ENHANCED_NULLABILITY_MARK)
|
||||||
|
|||||||
Reference in New Issue
Block a user