From 7503f134c23b57dc9d2e3b9a0b2b627bde7d0741 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 3 Aug 2020 22:48:00 +0200 Subject: [PATCH] IR: use IdSignature to compare classes in FqNameEqualityChecker This is both simpler and a lot more performant. --- .../ir/symbols/IrClassifierEqualityChecker.kt | 75 ++----------------- 1 file changed, 5 insertions(+), 70 deletions(-) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/IrClassifierEqualityChecker.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/IrClassifierEqualityChecker.kt index 9b8e16bdda0..11ad61fa45f 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/IrClassifierEqualityChecker.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/IrClassifierEqualityChecker.kt @@ -5,82 +5,17 @@ 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 { fun areEqual(left: IrClassifierSymbol, right: IrClassifierSymbol): Boolean fun getHashCode(symbol: IrClassifierSymbol): Int } -@OptIn(ObsoleteDescriptorBasedAPI::class) object FqNameEqualityChecker : IrClassifierEqualityChecker { - override fun areEqual(left: IrClassifierSymbol, right: IrClassifierSymbol): Boolean { - if (left === right) return true - if (!left.isBound || !right.isBound) { - return checkViaDescriptors(left.descriptor, right.descriptor) - } - return checkViaDeclarations(left.owner, right.owner) - } + override fun areEqual(left: IrClassifierSymbol, right: IrClassifierSymbol): Boolean = + left === right || + left.isPublicApi && right.isPublicApi && left.signature == right.signature - override fun getHashCode(symbol: IrClassifierSymbol): Int { - if (symbol.isBound) { - 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 + override fun getHashCode(symbol: IrClassifierSymbol): Int = + if (symbol.isPublicApi) symbol.signature.hashCode() else symbol.hashCode() }