diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers/KtTypeAndAnnotations.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers/KtTypeAndAnnotations.kt index 693e69f51ce..dca2a9feaf4 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers/KtTypeAndAnnotations.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers/KtTypeAndAnnotations.kt @@ -6,10 +6,28 @@ package org.jetbrains.kotlin.idea.frontend.api.symbols.markers import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner -import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.idea.frontend.api.types.KtType public abstract class KtTypeAndAnnotations : ValidityTokenOwner { public abstract val type: KtType public abstract val annotations: List + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as KtTypeAndAnnotations + + if (token != other.token) return false + if (type != other.type) return false + if (annotations != other.annotations) return false + + return true + } + + override fun hashCode(): Int { + var result = token.hashCode() + result = 31 * result + type.hashCode() + result = 31 * result + annotations.hashCode() + return result + } } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirAnonymousFunctionSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirAnonymousFunctionSymbol.kt index 31d76cca1f0..2e67e425ec0 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirAnonymousFunctionSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirAnonymousFunctionSymbol.kt @@ -53,4 +53,7 @@ internal class KtFirAnonymousFunctionSymbol( KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } error("Could not create a pointer for anonymous function from library") } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirAnonymousObjectSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirAnonymousObjectSymbol.kt index 405fce9fa8e..6159e3bc667 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirAnonymousObjectSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirAnonymousObjectSymbol.kt @@ -46,4 +46,7 @@ internal class KtFirAnonymousObjectSymbol( override fun createPointer(): KtSymbolPointer = KtPsiBasedSymbolPointer.createForSymbolFromSource(this) ?: throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException("Cannot create pointer for KtFirAnonymousObjectSymbol") + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirBackingFieldSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirBackingFieldSymbol.kt index e2a197527c2..f71fcbbe368 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirBackingFieldSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirBackingFieldSymbol.kt @@ -39,4 +39,18 @@ internal class KtFirBackingFieldSymbol( override fun createPointer(): KtSymbolPointer { return KtFirBackingFieldSymbolPointer(owningProperty.createPointer()) } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as KtFirBackingFieldSymbol + + if (this.token != other.token) return false + return this.propertyFirRef == other.propertyFirRef + } + + override fun hashCode(): Int { + return propertyFirRef.hashCode() * 31 + token.hashCode() + } } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorSymbol.kt index 65a25f599c8..d22cf80f387 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorSymbol.kt @@ -87,4 +87,7 @@ internal class KtFirConstructorSymbol( ?: error("ClassId should present for member declaration") return KtFirConstructorSymbolPointer(ownerClassId, isPrimary, firRef.withFir { it.createSignature() }) } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirEnumEntrySymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirEnumEntrySymbol.kt index b5fa37435c4..287f9056433 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirEnumEntrySymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirEnumEntrySymbol.kt @@ -55,4 +55,7 @@ internal class KtFirEnumEntrySymbol( ) } } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFileSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFileSymbol.kt index c211cc9bd34..d51a36b1ae8 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFileSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFileSymbol.kt @@ -38,4 +38,7 @@ internal class KtFirFileSymbol( override val annotations: List by cached { firRef.toAnnotationsList() } override fun containsAnnotation(classId: ClassId): Boolean = firRef.containsAnnotation(classId) override val annotationClassIds: Collection by cached { firRef.getAnnotationClassIds() } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionSymbol.kt index 9bfe9eb2988..fe7eae553c6 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionSymbol.kt @@ -120,4 +120,7 @@ internal class KtFirFunctionSymbol( ) } } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirJavaFieldSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirJavaFieldSymbol.kt index 58dfedfaac7..90d413e3c02 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirJavaFieldSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirJavaFieldSymbol.kt @@ -50,4 +50,7 @@ internal class KtFirJavaFieldSymbol( override fun createPointer(): KtSymbolPointer { TODO("Creating pointers for java fields is not supported yet") } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirKotlinPropertySymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirKotlinPropertySymbol.kt index 9b68fc70223..c9e2d769ccc 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirKotlinPropertySymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirKotlinPropertySymbol.kt @@ -129,4 +129,7 @@ internal class KtFirKotlinPropertySymbol( KtSymbolKind.LOCAL -> throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(name.asString()) } } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirLocalVariableSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirLocalVariableSymbol.kt index e3206e38415..b5f4b212705 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirLocalVariableSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirLocalVariableSymbol.kt @@ -49,4 +49,7 @@ internal class KtFirLocalVariableSymbol( KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(name.asString()) } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirNamedClassOrObjectSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirNamedClassOrObjectSymbol.kt index 5f6d00f28b8..029dad04663 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirNamedClassOrObjectSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirNamedClassOrObjectSymbol.kt @@ -114,4 +114,7 @@ internal class KtFirNamedClassOrObjectSymbol( } return KtFirClassOrObjectInLibrarySymbolPointer(classIdIfNonLocal!!) } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPackageSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPackageSymbol.kt index 82c550791b4..bc4c675bcc4 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPackageSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPackageSymbol.kt @@ -38,6 +38,24 @@ class KtFirPackageSymbol( check(session is KtFirAnalysisSession) session.firSymbolBuilder.createPackageSymbolIfOneExists(fqName) } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as KtFirPackageSymbol + + if (fqName != other.fqName) return false + if (token != other.token) return false + + return true + } + + override fun hashCode(): Int { + var result = fqName.hashCode() + result = 31 * result + token.hashCode() + return result + } } class KtPackage( diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertyGetterSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertyGetterSymbol.kt index 922743a2075..f1de0505354 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertyGetterSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertyGetterSymbol.kt @@ -67,4 +67,7 @@ internal class KtFirPropertyGetterSymbol( KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } TODO("Creating pointers for getters from library is not supported yet") } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySetterSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySetterSymbol.kt index 100b8d5233a..71b44301be4 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySetterSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySetterSymbol.kt @@ -74,4 +74,7 @@ internal class KtFirPropertySetterSymbol( KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } TODO("Creating pointers for setters from library is not supported yet") } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbol.kt index d86420cacc1..fb68c001790 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbol.kt @@ -24,6 +24,13 @@ internal interface KtFirSymbol : KtSymbol, ValidityToken override val origin: KtSymbolOrigin get() = firRef.withFir { it.ktSymbolOrigin() } } +internal fun KtFirSymbol<*>.symbolEquals(other: Any?): Boolean { + if (other !is KtFirSymbol<*>) return false + if (this.token != other.token) return false + return this.firRef == other.firRef +} + +internal fun KtFirSymbol<*>.symbolHashCode(): Int = firRef.hashCode() * 31 + token.hashCode() private tailrec fun FirDeclaration.ktSymbolOrigin(): KtSymbolOrigin = when (origin) { FirDeclarationOrigin.Source -> { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSyntheticJavaPropertySymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSyntheticJavaPropertySymbol.kt index 61f258d3c22..72c2544235a 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSyntheticJavaPropertySymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSyntheticJavaPropertySymbol.kt @@ -93,4 +93,7 @@ internal class KtFirSyntheticJavaPropertySymbol( override fun createPointer(): KtSymbolPointer { TODO("pointers to KtSyntheticJavaPropertySymbol is not supported yet") } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirTypeAliasSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirTypeAliasSymbol.kt index 5db50ccfa69..03901340501 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirTypeAliasSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirTypeAliasSymbol.kt @@ -42,4 +42,7 @@ internal class KtFirTypeAliasSymbol( KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } TODO("Creating symbols for library typealiases is not supported yet") } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirTypeParameterSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirTypeParameterSymbol.kt index 8c986c5a0e5..20693f659e7 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirTypeParameterSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirTypeParameterSymbol.kt @@ -44,4 +44,7 @@ internal class KtFirTypeParameterSymbol( KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } TODO("Creating symbols for library type parameters is not supported yet") } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirValueParameterSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirValueParameterSymbol.kt index bd381e5f0d7..c82f798833b 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirValueParameterSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirValueParameterSymbol.kt @@ -52,4 +52,7 @@ internal class KtFirValueParameterSymbol( KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } TODO("Creating pointers for functions parameters from library is not supported yet") } + + override fun equals(other: Any?): Boolean = symbolEquals(other) + override fun hashCode(): Int = symbolHashCode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/annotations/KtFirAnnotationCall.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/annotations/KtFirAnnotationCall.kt index 0738e51aa51..3b30e11cb4b 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/annotations/KtFirAnnotationCall.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/annotations/KtFirAnnotationCall.kt @@ -43,4 +43,14 @@ internal class KtFirAnnotationCall( KtNamedConstantValue(name, expression.convertConstantExpression()) } } + + override fun equals(other: Any?): Boolean { + if (other !is KtFirAnnotationCall) return false + if (this.token != other.token) return false + return annotationCallRef == other.annotationCallRef + } + + override fun hashCode(): Int { + return token.hashCode() * 31 + annotationCallRef.hashCode() + } } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/types/FirKtType.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/types/FirKtType.kt index c119b846977..d03e21f1004 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/types/FirKtType.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/types/FirKtType.kt @@ -9,7 +9,9 @@ import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType import org.jetbrains.kotlin.fir.resolve.inference.receiverType import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl -import org.jetbrains.kotlin.idea.frontend.api.* +import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgument +import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgumentWithVariance +import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef @@ -17,6 +19,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken import org.jetbrains.kotlin.idea.frontend.api.types.* +import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name @@ -24,6 +27,14 @@ internal interface KtFirType : ValidityTokenOwner { val coneType: ConeKotlinType } +private fun KtFirType.typeEquals(other: Any?): Boolean { + if (other !is KtFirType) return false + if (this.token != other.token) return false + return this.coneType == other.coneType +} + +private fun KtFirType.typeHashcode(): Int = token.hashCode() * 31 + coneType.hashCode() + internal class KtFirUsualClassType( _coneType: ConeClassLikeTypeImpl, override val token: ValidityToken, @@ -45,6 +56,8 @@ internal class KtFirUsualClassType( override val nullability: KtTypeNullability get() = withValidityAssertion { KtTypeNullability.create(coneType.canBeNull) } override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } + override fun equals(other: Any?) = typeEquals(other) + override fun hashCode() = typeHashcode() } internal class KtFirFunctionalType( @@ -96,6 +109,8 @@ internal class KtFirFunctionalType( get() = withValidityAssertion { (typeArguments.last() as KtTypeArgumentWithVariance).type } override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } + override fun equals(other: Any?) = typeEquals(other) + override fun hashCode() = typeHashcode() } internal class KtFirClassErrorType( @@ -106,6 +121,8 @@ internal class KtFirClassErrorType( override val error: String get() = withValidityAssertion { coneType.diagnostic.reason } override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } + override fun equals(other: Any?) = typeEquals(other) + override fun hashCode() = typeHashcode() } internal class KtFirCapturedType( @@ -114,6 +131,8 @@ internal class KtFirCapturedType( ) : KtCapturedType(), KtFirType { override val coneType by weakRef(_coneType) override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } + override fun equals(other: Any?) = typeEquals(other) + override fun hashCode() = typeHashcode() } internal class KtFirDefinitelyNotNullType( @@ -127,6 +146,8 @@ internal class KtFirDefinitelyNotNullType( override val original: KtType by cached { builder.typeBuilder.buildKtType(this.coneType.original) } override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } + override fun equals(other: Any?) = typeEquals(other) + override fun hashCode() = typeHashcode() } internal class KtFirTypeParameterType( @@ -145,6 +166,8 @@ internal class KtFirTypeParameterType( override val nullability: KtTypeNullability get() = withValidityAssertion { KtTypeNullability.create(coneType.canBeNull) } override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } + override fun equals(other: Any?) = typeEquals(other) + override fun hashCode() = typeHashcode() } internal class KtFirFlexibleType( @@ -158,6 +181,8 @@ internal class KtFirFlexibleType( override val lowerBound: KtType by cached { builder.typeBuilder.buildKtType(coneType.lowerBound) } override val upperBound: KtType by cached { builder.typeBuilder.buildKtType(coneType.upperBound) } override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } + override fun equals(other: Any?) = typeEquals(other) + override fun hashCode() = typeHashcode() } internal class KtFirIntersectionType( @@ -173,4 +198,6 @@ internal class KtFirIntersectionType( } override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } + override fun equals(other: Any?) = typeEquals(other) + override fun hashCode() = typeHashcode() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/FirRefWithValidityCheck.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/FirRefWithValidityCheck.kt index f713a0bfab6..2be8d3a017b 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/FirRefWithValidityCheck.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/FirRefWithValidityCheck.kt @@ -66,6 +66,19 @@ internal class FirRefWithValidityCheck(fir: D, resolveSt ValidityAwareCachedValue(token) { withFirByType(type) { fir -> createValue(fir) } } + + override fun equals(other: Any?): Boolean { + if (other !is FirRefWithValidityCheck<*>) return false + return getRefFir() == other.getRefFir() && this.token == other.token + } + + override fun hashCode(): Int { + return getRefFir().hashCode() * 31 + token.hashCode() + } + + private fun getRefFir(): FirDeclaration { + return firWeakRef.get() ?: throw EntityWasGarbageCollectedException("FirElement") + } } @Suppress("NOTHING_TO_INLINE")