[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
|
||||
|
||||
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<Unit, Boolean>(), KotlinMangleComputer<FirDeclaration> {
|
||||
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<FirMemberDeclaration>(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("<anonymous>")
|
||||
}
|
||||
|
||||
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("<anonymous>")
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user