IR: use IdSignature to compare classes in FqNameEqualityChecker
This is both simpler and a lot more performant.
This commit is contained in:
+5
-70
@@ -5,82 +5,17 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.symbols
|
package org.jetbrains.kotlin.ir.symbols
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
|
|
||||||
import org.jetbrains.kotlin.ir.util.isLocalClass
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
|
||||||
|
|
||||||
interface IrClassifierEqualityChecker {
|
interface IrClassifierEqualityChecker {
|
||||||
fun areEqual(left: IrClassifierSymbol, right: IrClassifierSymbol): Boolean
|
fun areEqual(left: IrClassifierSymbol, right: IrClassifierSymbol): Boolean
|
||||||
|
|
||||||
fun getHashCode(symbol: IrClassifierSymbol): Int
|
fun getHashCode(symbol: IrClassifierSymbol): Int
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
|
||||||
object FqNameEqualityChecker : IrClassifierEqualityChecker {
|
object FqNameEqualityChecker : IrClassifierEqualityChecker {
|
||||||
override fun areEqual(left: IrClassifierSymbol, right: IrClassifierSymbol): Boolean {
|
override fun areEqual(left: IrClassifierSymbol, right: IrClassifierSymbol): Boolean =
|
||||||
if (left === right) return true
|
left === right ||
|
||||||
if (!left.isBound || !right.isBound) {
|
left.isPublicApi && right.isPublicApi && left.signature == right.signature
|
||||||
return checkViaDescriptors(left.descriptor, right.descriptor)
|
|
||||||
}
|
|
||||||
return checkViaDeclarations(left.owner, right.owner)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getHashCode(symbol: IrClassifierSymbol): Int {
|
override fun getHashCode(symbol: IrClassifierSymbol): Int =
|
||||||
if (symbol.isBound) {
|
if (symbol.isPublicApi) symbol.signature.hashCode() else symbol.hashCode()
|
||||||
val owner = symbol.owner
|
|
||||||
if (owner is IrClass && !owner.isLocalClass()) {
|
|
||||||
return owner.fqName.hashCode()
|
|
||||||
}
|
|
||||||
return owner.hashCode()
|
|
||||||
}
|
|
||||||
|
|
||||||
val descriptor = symbol.descriptor
|
|
||||||
if (descriptor is ClassDescriptor && !DescriptorUtils.isLocal(descriptor)) {
|
|
||||||
return descriptor.fqNameSafe.hashCode()
|
|
||||||
}
|
|
||||||
return descriptor.hashCode()
|
|
||||||
}
|
|
||||||
|
|
||||||
private val IrDeclarationWithName.fqName: FqName?
|
|
||||||
get() {
|
|
||||||
val parentFqName = when (val parent = parent) {
|
|
||||||
is IrPackageFragment -> parent.fqName
|
|
||||||
is IrDeclarationWithName -> parent.fqName
|
|
||||||
else -> return null
|
|
||||||
}
|
|
||||||
return parentFqName?.child(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun areFqNamesEqual(c1: IrDeclarationWithName, c2: IrDeclarationWithName): Boolean {
|
|
||||||
if (c1.name != c2.name) return false
|
|
||||||
|
|
||||||
val parent1 = c1.parent
|
|
||||||
val parent2 = c2.parent
|
|
||||||
return when (parent1) {
|
|
||||||
is IrPackageFragment -> parent2 is IrPackageFragment && parent1.fqName == parent2.fqName
|
|
||||||
is IrDeclarationWithName -> parent2 is IrDeclarationWithName && areFqNamesEqual(parent1, parent2)
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkViaDeclarations(c1: IrSymbolOwner, c2: IrSymbolOwner): Boolean {
|
|
||||||
if (c1 is IrClass && c2 is IrClass) {
|
|
||||||
if (c1.isLocalClass() || c2.isLocalClass())
|
|
||||||
return c1 === c2 // Local declarations should be identical
|
|
||||||
|
|
||||||
return areFqNamesEqual(c1, c2)
|
|
||||||
}
|
|
||||||
|
|
||||||
return c1 == c2
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkViaDescriptors(c1: ClassifierDescriptor, c2: ClassifierDescriptor) = c1.typeConstructor == c2.typeConstructor
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user