K2: implement FirClassAnySynthesizedMemberScope #KT-54844 Fixed
This commit is contained in:
committed by
Space Team
parent
c898b264ba
commit
2a825f8df1
+1
-1
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.hasBody
|
import org.jetbrains.kotlin.fir.declarations.utils.hasBody
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
|
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
|
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
|
||||||
import org.jetbrains.kotlin.fir.resolve.isEquals
|
import org.jetbrains.kotlin.fir.symbols.impl.isEquals
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions.TO_STRING
|
import org.jetbrains.kotlin.util.OperatorNameConventions.TO_STRING
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -22,9 +22,9 @@ import org.jetbrains.kotlin.fir.declarations.utils.*
|
|||||||
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.isEquals
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
|
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.isEquals
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitAnyTypeRef
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitAnyTypeRef
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ fun FirSession.registerCommonComponents(languageVersionSettings: LanguageVersion
|
|||||||
|
|
||||||
register(FirSubstitutionOverrideStorage::class, FirSubstitutionOverrideStorage(this))
|
register(FirSubstitutionOverrideStorage::class, FirSubstitutionOverrideStorage(this))
|
||||||
register(FirIntersectionOverrideStorage::class, FirIntersectionOverrideStorage(this))
|
register(FirIntersectionOverrideStorage::class, FirIntersectionOverrideStorage(this))
|
||||||
|
register(FirSynthesizedStorage::class, FirSynthesizedStorage(this))
|
||||||
register(FirGeneratedMemberDeclarationsStorage::class, FirGeneratedMemberDeclarationsStorage(this))
|
register(FirGeneratedMemberDeclarationsStorage::class, FirGeneratedMemberDeclarationsStorage(this))
|
||||||
register(FirSamConstructorStorage::class, FirSamConstructorStorage(this))
|
register(FirSamConstructorStorage::class, FirSamConstructorStorage(this))
|
||||||
register(FirOverrideService::class, FirOverrideService(this))
|
register(FirOverrideService::class, FirOverrideService(this))
|
||||||
|
|||||||
+17
-4
@@ -12,8 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.FirClass
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.delegateFields
|
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeRawScopeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeRawScopeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
@@ -65,13 +64,23 @@ class FirKotlinScopeProvider(
|
|||||||
).mapNotNull { useSiteSuperType ->
|
).mapNotNull { useSiteSuperType ->
|
||||||
useSiteSuperType.scopeForSupertype(useSiteSession, scopeSession, klass, memberRequiredPhase = memberRequiredPhase)
|
useSiteSuperType.scopeForSupertype(useSiteSession, scopeSession, klass, memberRequiredPhase = memberRequiredPhase)
|
||||||
}
|
}
|
||||||
|
val useSiteMemberScope = FirClassUseSiteMemberScope(
|
||||||
FirClassUseSiteMemberScope(
|
|
||||||
klass,
|
klass,
|
||||||
useSiteSession,
|
useSiteSession,
|
||||||
scopes,
|
scopes,
|
||||||
decoratedDeclaredMemberScope,
|
decoratedDeclaredMemberScope,
|
||||||
)
|
)
|
||||||
|
if (klass is FirRegularClass && !klass.isExpect && (klass.isData || klass.isInline)) {
|
||||||
|
val lookupTag = klass.symbol.toLookupTag()
|
||||||
|
scopeSession.getOrBuild(lookupTag, AnySynthesizedScopeKey(lookupTag)) {
|
||||||
|
FirClassAnySynthesizedMemberScope(
|
||||||
|
useSiteSession, useSiteMemberScope, lookupTag,
|
||||||
|
klass.moduleData, klass.defaultType(), klass.source
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
useSiteMemberScope
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,6 +119,10 @@ data class ConeSubstitutionScopeKey(
|
|||||||
val derivedClassLookupTag: ConeClassLikeLookupTag?
|
val derivedClassLookupTag: ConeClassLikeLookupTag?
|
||||||
) : ScopeSessionKey<FirClass, FirClassSubstitutionScope>()
|
) : ScopeSessionKey<FirClass, FirClassSubstitutionScope>()
|
||||||
|
|
||||||
|
data class AnySynthesizedScopeKey(
|
||||||
|
val lookupTag: ConeClassLikeLookupTag
|
||||||
|
) : ScopeSessionKey<ConeClassLikeLookupTag, FirClassAnySynthesizedMemberScope>()
|
||||||
|
|
||||||
fun FirClass.unsubstitutedScope(
|
fun FirClass.unsubstitutedScope(
|
||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
|
|||||||
+199
@@ -0,0 +1,199 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.scopes.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
|
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.fakeElement
|
||||||
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
|
import org.jetbrains.kotlin.fir.caches.FirCache
|
||||||
|
import org.jetbrains.kotlin.fir.caches.FirCachesFactory
|
||||||
|
import org.jetbrains.kotlin.fir.caches.createCache
|
||||||
|
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBooleanTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitIntTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitNullableAnyTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitStringTypeRef
|
||||||
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
|
||||||
|
|
||||||
|
class FirClassAnySynthesizedMemberScope(
|
||||||
|
session: FirSession,
|
||||||
|
private val useSiteMemberScope: FirClassUseSiteMemberScope,
|
||||||
|
private val lookupTag: ConeClassLikeLookupTag,
|
||||||
|
private val baseModuleData: FirModuleData,
|
||||||
|
private val dispatchReceiverType: ConeClassLikeType,
|
||||||
|
classSource: KtSourceElement?,
|
||||||
|
) : FirTypeScope() {
|
||||||
|
private val synthesizedCache = session.synthesizedStorage.synthesizedCacheByScope.getValue(lookupTag, null)
|
||||||
|
|
||||||
|
private val synthesizedOverrides = mutableMapOf<FirNamedFunctionSymbol, FirNamedFunctionSymbol>()
|
||||||
|
|
||||||
|
private val synthesizedSource = classSource?.fakeElement(KtFakeSourceElementKind.DataClassGeneratedMembers)
|
||||||
|
|
||||||
|
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
||||||
|
useSiteMemberScope.processClassifiersByNameWithSubstitution(name, processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||||
|
useSiteMemberScope.processDeclaredConstructors(processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processDirectOverriddenPropertiesWithBaseScope(
|
||||||
|
propertySymbol: FirPropertySymbol,
|
||||||
|
processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction
|
||||||
|
): ProcessorAction {
|
||||||
|
return useSiteMemberScope.processDirectOverriddenPropertiesWithBaseScope(propertySymbol, processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processDirectOverriddenFunctionsWithBaseScope(
|
||||||
|
functionSymbol: FirNamedFunctionSymbol,
|
||||||
|
processor: (FirNamedFunctionSymbol, FirTypeScope) -> ProcessorAction,
|
||||||
|
): ProcessorAction {
|
||||||
|
val overridden = synthesizedOverrides[functionSymbol]
|
||||||
|
?: return useSiteMemberScope.processDirectOverriddenFunctionsWithBaseScope(functionSymbol, processor)
|
||||||
|
return processor(overridden, useSiteMemberScope)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getCallableNames(): Set<Name> {
|
||||||
|
return useSiteMemberScope.getCallableNames()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getClassifierNames(): Set<Name> {
|
||||||
|
return useSiteMemberScope.getClassifierNames()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||||
|
useSiteMemberScope.processPropertiesByName(name, processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
|
||||||
|
if (name !in ANY_MEMBER_NAMES) {
|
||||||
|
useSiteMemberScope.processFunctionsByName(name, processor)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
useSiteMemberScope.processFunctionsByName(name) { fromUseSiteScope ->
|
||||||
|
if (fromUseSiteScope.rawStatus.modality == Modality.FINAL) {
|
||||||
|
processor(fromUseSiteScope)
|
||||||
|
} else {
|
||||||
|
val matchedSomeAnyMember = when (name) {
|
||||||
|
OperatorNameConventions.HASH_CODE, OperatorNameConventions.TO_STRING -> {
|
||||||
|
fromUseSiteScope.valueParameterSymbols.isEmpty() && !fromUseSiteScope.isExtension &&
|
||||||
|
fromUseSiteScope.fir.contextReceivers.isEmpty()
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
fromUseSiteScope.lazyResolveToPhase(FirResolvePhase.TYPES)
|
||||||
|
fromUseSiteScope.fir.isEquals()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val hasSameReceiver =
|
||||||
|
dispatchReceiverType.lookupTag == (fromUseSiteScope.dispatchReceiverType as? ConeClassLikeType)?.lookupTag
|
||||||
|
if (!matchedSomeAnyMember || hasSameReceiver) {
|
||||||
|
processor(fromUseSiteScope)
|
||||||
|
} else {
|
||||||
|
val synthesized = synthesizedCache.synthesizedFunctionAndOverrides.getValue(name, this)
|
||||||
|
synthesizedOverrides[synthesized] = fromUseSiteScope
|
||||||
|
processor(synthesized)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun generateSyntheticFunctionByName(name: Name): FirNamedFunctionSymbol =
|
||||||
|
when (name) {
|
||||||
|
OperatorNameConventions.EQUALS -> generateEqualsFunction()
|
||||||
|
OperatorNameConventions.HASH_CODE -> generateHashCodeFunction()
|
||||||
|
OperatorNameConventions.TO_STRING -> generateToStringFunction()
|
||||||
|
else -> shouldNotBeCalled()
|
||||||
|
}.symbol
|
||||||
|
|
||||||
|
private fun generateEqualsFunction(): FirSimpleFunction =
|
||||||
|
buildSimpleFunction {
|
||||||
|
generateSyntheticFunction(OperatorNameConventions.EQUALS, isOperator = true)
|
||||||
|
returnTypeRef = FirImplicitBooleanTypeRef(source)
|
||||||
|
this.valueParameters.add(
|
||||||
|
buildValueParameter {
|
||||||
|
this.name = Name.identifier("other")
|
||||||
|
origin = FirDeclarationOrigin.Synthetic
|
||||||
|
moduleData = baseModuleData
|
||||||
|
this.returnTypeRef = FirImplicitNullableAnyTypeRef(null)
|
||||||
|
this.symbol = FirValueParameterSymbol(this.name)
|
||||||
|
containingFunctionSymbol = this@buildSimpleFunction.symbol
|
||||||
|
isCrossinline = false
|
||||||
|
isNoinline = false
|
||||||
|
isVararg = false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateHashCodeFunction(): FirSimpleFunction =
|
||||||
|
buildSimpleFunction {
|
||||||
|
generateSyntheticFunction(OperatorNameConventions.HASH_CODE)
|
||||||
|
returnTypeRef = FirImplicitIntTypeRef(source)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateToStringFunction(): FirSimpleFunction =
|
||||||
|
buildSimpleFunction {
|
||||||
|
generateSyntheticFunction(OperatorNameConventions.TO_STRING)
|
||||||
|
returnTypeRef = FirImplicitStringTypeRef(source)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirSimpleFunctionBuilder.generateSyntheticFunction(
|
||||||
|
name: Name,
|
||||||
|
isOperator: Boolean = false,
|
||||||
|
) {
|
||||||
|
this.source = synthesizedSource
|
||||||
|
moduleData = baseModuleData
|
||||||
|
origin = FirDeclarationOrigin.Synthetic
|
||||||
|
this.name = name
|
||||||
|
status = FirResolvedDeclarationStatusImpl(Visibilities.Public, Modality.OPEN, EffectiveVisibility.Public).apply {
|
||||||
|
this.isOperator = isOperator
|
||||||
|
}
|
||||||
|
symbol = FirNamedFunctionSymbol(CallableId(lookupTag.classId, name))
|
||||||
|
dispatchReceiverType = this@FirClassAnySynthesizedMemberScope.dispatchReceiverType
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val ANY_MEMBER_NAMES = hashSetOf(
|
||||||
|
OperatorNameConventions.HASH_CODE, OperatorNameConventions.EQUALS, OperatorNameConventions.TO_STRING
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FirSynthesizedStorage(val session: FirSession) : FirSessionComponent {
|
||||||
|
private val cachesFactory = session.firCachesFactory
|
||||||
|
|
||||||
|
val synthesizedCacheByScope: FirCache<ConeClassLikeLookupTag, SynthesizedCache, Nothing?> =
|
||||||
|
cachesFactory.createCache { _ -> SynthesizedCache(session.firCachesFactory) }
|
||||||
|
|
||||||
|
class SynthesizedCache(cachesFactory: FirCachesFactory) {
|
||||||
|
val synthesizedFunctionAndOverrides: FirCache<Name, FirNamedFunctionSymbol, FirClassAnySynthesizedMemberScope> =
|
||||||
|
cachesFactory.createCache { name, scope -> scope.generateSyntheticFunctionByName(name) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val FirSession.synthesizedStorage: FirSynthesizedStorage by FirSession.sessionComponentAccessor()
|
||||||
+1
-4
@@ -30,10 +30,7 @@ import org.jetbrains.kotlin.fir.scopes.getFunctions
|
|||||||
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
|
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
|
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||||
|
|||||||
@@ -87,12 +87,3 @@ var FirConstructor.originalConstructorIfTypeAlias: FirConstructor? by FirDeclara
|
|||||||
|
|
||||||
val FirConstructorSymbol.isTypeAliasedConstructor: Boolean
|
val FirConstructorSymbol.isTypeAliasedConstructor: Boolean
|
||||||
get() = fir.originalConstructorIfTypeAlias != null
|
get() = fir.originalConstructorIfTypeAlias != null
|
||||||
|
|
||||||
fun FirSimpleFunction.isEquals(): Boolean {
|
|
||||||
if (name != OperatorNameConventions.EQUALS) return false
|
|
||||||
if (valueParameters.size != 1) return false
|
|
||||||
if (contextReceivers.isNotEmpty()) return false
|
|
||||||
if (receiverParameter != null) return false
|
|
||||||
val parameter = valueParameters.first()
|
|
||||||
return parameter.returnTypeRef.isNullableAny
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.types.*
|
|||||||
import org.jetbrains.kotlin.mpp.CallableSymbolMarker
|
import org.jetbrains.kotlin.mpp.CallableSymbolMarker
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
abstract class FirCallableSymbol<D : FirCallableDeclaration> : FirBasedSymbol<D>(), CallableSymbolMarker {
|
abstract class FirCallableSymbol<D : FirCallableDeclaration> : FirBasedSymbol<D>(), CallableSymbolMarker {
|
||||||
abstract val callableId: CallableId
|
abstract val callableId: CallableId
|
||||||
@@ -95,3 +96,12 @@ val FirCallableSymbol<*>.isExtension: Boolean
|
|||||||
is FirProperty -> fir.receiverParameter != null
|
is FirProperty -> fir.receiverParameter != null
|
||||||
is FirVariable -> false
|
is FirVariable -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FirSimpleFunction.isEquals(): Boolean {
|
||||||
|
if (name != OperatorNameConventions.EQUALS) return false
|
||||||
|
if (valueParameters.size != 1) return false
|
||||||
|
if (contextReceivers.isNotEmpty()) return false
|
||||||
|
if (receiverParameter != null) return false
|
||||||
|
val parameter = valueParameters.first()
|
||||||
|
return parameter.returnTypeRef.isNullableAny
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE
|
|
||||||
// FIR status: [IR VALIDATION] Duplicate IR node: FUN GENERATED_DATA_CLASS_MEMBER name:toString
|
|
||||||
// CHECK_BYTECODE_LISTING
|
// CHECK_BYTECODE_LISTING
|
||||||
// FIR_IDENTICAL
|
// FIR_IDENTICAL
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE
|
|
||||||
// FIR status: [IR VALIDATION] Duplicate IR node: FUN GENERATED_DATA_CLASS_MEMBER name:equals
|
|
||||||
|
|
||||||
interface A {
|
interface A {
|
||||||
fun Any.equals(other: Any?): Boolean = false
|
fun Any.equals(other: Any?): Boolean = false
|
||||||
fun Any.hashCode(): Int = 0
|
fun Any.hashCode(): Int = 0
|
||||||
|
|||||||
Reference in New Issue
Block a user