Fir2Ir: deal with toplevel privates
This commit is contained in:
committed by
Alexander Udalov
parent
9ea14a6eab
commit
8771ce94ef
+4
@@ -322,6 +322,10 @@ open class FirJvmMangleComputer(
|
||||
override fun visitConstructor(constructor: FirConstructor, data: Boolean) =
|
||||
constructor.mangleFunction(isCtor = true, isStatic = false, constructor)
|
||||
|
||||
override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor, data: Boolean) {
|
||||
propertyAccessor.mangleFunction(isCtor = false, propertyAccessor.isStatic, propertyAccessor.propertySymbol!!.fir)
|
||||
}
|
||||
|
||||
override fun computeMangle(declaration: FirDeclaration): String {
|
||||
declaration.accept(this, true)
|
||||
return builder.toString()
|
||||
|
||||
@@ -113,8 +113,7 @@ class FirIrProvider(val fir2IrComponents: Fir2IrComponents) : IrProvider {
|
||||
}
|
||||
}
|
||||
|
||||
// The next line should have singleOrNull, but in some cases we get multiple references to the same FIR declaration.
|
||||
val firDeclaration = firCandidates.firstOrNull { fir2IrComponents.signatureComposer.composeSignature(it) == signature }
|
||||
val firDeclaration = findDeclarationByHash(firCandidates, signature.id)
|
||||
?: return null
|
||||
|
||||
return when (kind) {
|
||||
@@ -138,4 +137,15 @@ class FirIrProvider(val fir2IrComponents: Fir2IrComponents) : IrProvider {
|
||||
else -> error("Don't know how to deal with this symbol kind: $kind")
|
||||
}
|
||||
}
|
||||
|
||||
private fun findDeclarationByHash(candidates: Collection<FirDeclaration>, hash: Long?): FirDeclaration? =
|
||||
candidates.firstOrNull { candidate ->
|
||||
if (hash == null) {
|
||||
// We don't compute id for type aliases and classes.
|
||||
candidate is FirClass || candidate is FirTypeAlias
|
||||
} else {
|
||||
// The next line should have singleOrNull, but in some cases we get multiple references to the same FIR declaration.
|
||||
with(fir2IrComponents.signatureComposer.mangler) { candidate.signatureMangle(compatibleMode = false) == hash }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+55
-9
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.backend.Fir2IrSignatureComposer
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||
@@ -16,7 +18,7 @@ import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||
|
||||
@NoMutableState
|
||||
// @NoMutableState -- we'll restore this annotation once we get rid of withFileSignature().
|
||||
class FirBasedSignatureComposer(override val mangler: FirMangler) : Fir2IrSignatureComposer {
|
||||
var fileSignature: IdSignature.FileSignature? = null
|
||||
|
||||
@@ -80,7 +82,7 @@ class FirBasedSignatureComposer(override val mangler: FirMangler) : Fir2IrSignat
|
||||
} catch (t: Throwable) {
|
||||
throw IllegalStateException("Error while composing signature for ${declaration.render()}", t)
|
||||
}
|
||||
return when (declaration) {
|
||||
val publicSignature = when (declaration) {
|
||||
is FirRegularClass -> {
|
||||
// TODO: private classes are probably not acceptable here too
|
||||
val classId = declaration.classId
|
||||
@@ -96,7 +98,7 @@ class FirBasedSignatureComposer(override val mangler: FirMangler) : Fir2IrSignat
|
||||
)
|
||||
}
|
||||
is FirCallableDeclaration -> {
|
||||
if (declaration.visibility == Visibilities.Private) return null
|
||||
if (declaration.visibility == Visibilities.Private && !isTopLevelPrivate(declaration, containingClass)) return null
|
||||
val containingClassId = containingClass?.classId
|
||||
|
||||
val classId = containingClassId ?: declaration.containingClass()?.classId
|
||||
@@ -111,6 +113,11 @@ class FirBasedSignatureComposer(override val mangler: FirMangler) : Fir2IrSignat
|
||||
}
|
||||
else -> error("Unsupported FIR declaration in signature composer: ${declaration.render()}")
|
||||
}
|
||||
return if (isTopLevelPrivate(declaration, containingClass)) {
|
||||
val fileSig = fileSignature ?: return null
|
||||
IdSignature.CompositeSignature(fileSig, publicSignature)
|
||||
} else
|
||||
publicSignature
|
||||
}
|
||||
|
||||
override fun composeAccessorSignature(
|
||||
@@ -118,12 +125,51 @@ class FirBasedSignatureComposer(override val mangler: FirMangler) : Fir2IrSignat
|
||||
isSetter: Boolean,
|
||||
containingClass: ConeClassLikeLookupTag?
|
||||
): IdSignature? {
|
||||
val propertySignature = composeSignature(property, containingClass) as? IdSignature.CommonSignature ?: return null
|
||||
val accessorFqName = if (isSetter) {
|
||||
propertySignature.declarationFqName + ".<set-${property.name.asString()}>"
|
||||
} else {
|
||||
propertySignature.declarationFqName + ".<get-${property.name.asString()}>"
|
||||
val propSig: IdSignature.CommonSignature
|
||||
val fileSig: IdSignature.FileSignature?
|
||||
when (val propertySignature = composeSignature(property, containingClass)) {
|
||||
is IdSignature.CompositeSignature -> {
|
||||
propSig = propertySignature.inner as? IdSignature.CommonSignature ?: return null
|
||||
fileSig = propertySignature.container as? IdSignature.FileSignature ?: return null
|
||||
}
|
||||
is IdSignature.CommonSignature -> {
|
||||
propSig = propertySignature
|
||||
fileSig = null
|
||||
}
|
||||
else -> return null
|
||||
}
|
||||
return IdSignature.CommonSignature(propertySignature.packageFqName, accessorFqName, propertySignature.id, propertySignature.mask)
|
||||
val id = with(mangler) {
|
||||
if (isSetter) {
|
||||
property.setterOrDefault().signatureMangle(compatibleMode = false)
|
||||
} else {
|
||||
property.getterOrDefault().signatureMangle(compatibleMode = false)
|
||||
}
|
||||
}
|
||||
val accessorFqName = if (isSetter) {
|
||||
propSig.declarationFqName + ".<set-${property.name.asString()}>"
|
||||
} else {
|
||||
propSig.declarationFqName + ".<get-${property.name.asString()}>"
|
||||
}
|
||||
val commonSig = IdSignature.CommonSignature(propSig.packageFqName, accessorFqName, id, propSig.mask)
|
||||
val accessorSig = IdSignature.AccessorSignature(propSig, commonSig)
|
||||
return if (fileSig != null) {
|
||||
IdSignature.CompositeSignature(fileSig, accessorSig)
|
||||
} else accessorSig
|
||||
}
|
||||
|
||||
private fun isTopLevelPrivate(declaration: FirDeclaration, containingClass: ConeClassLikeLookupTag?): Boolean =
|
||||
containingClass == null && declaration is FirMemberDeclaration && declaration.visibility == Visibilities.Private
|
||||
|
||||
private fun FirProperty.getterOrDefault() =
|
||||
getter ?: FirDefaultPropertyGetter(
|
||||
source = null,
|
||||
moduleData, origin, returnTypeRef, visibility, symbol
|
||||
)
|
||||
|
||||
private fun FirProperty.setterOrDefault() =
|
||||
setter ?: FirDefaultPropertySetter(
|
||||
source = null,
|
||||
moduleData, origin, returnTypeRef, visibility, symbol
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@@ -14,5 +14,13 @@ val FirCallableDeclaration.irName: Name
|
||||
is FirConstructor -> SpecialNames.INIT
|
||||
is FirSimpleFunction -> this.name
|
||||
is FirVariable -> this.name
|
||||
is FirPropertyAccessor -> {
|
||||
val prefix = when {
|
||||
isGetter -> "<get-"
|
||||
isSetter -> "<set-"
|
||||
else -> error("unknown property accessor kind $this")
|
||||
}
|
||||
Name.special(prefix + propertySymbol!!.fir.name + ">")
|
||||
}
|
||||
else -> SpecialNames.ANONYMOUS
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user