FirClassAnySynthesizedMemberScope.kt: make it a declared member scope
Related to KT-54844, KT-58926
This commit is contained in:
committed by
Space Team
parent
0ea0346ec1
commit
668157eb41
+6
@@ -4195,6 +4195,12 @@ public class DiagnosticCompilerTestFirTestdataTestGenerated extends AbstractDiag
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("delegatedDataClass.kt")
|
||||||
|
public void testDelegatedDataClass() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/scopes/delegatedDataClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("explicitOverrideOfTwoMembers.kt")
|
@TestMetadata("explicitOverrideOfTwoMembers.kt")
|
||||||
public void testExplicitOverrideOfTwoMembers() throws Exception {
|
public void testExplicitOverrideOfTwoMembers() throws Exception {
|
||||||
|
|||||||
+6
@@ -4195,6 +4195,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("delegatedDataClass.kt")
|
||||||
|
public void testDelegatedDataClass() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/scopes/delegatedDataClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("explicitOverrideOfTwoMembers.kt")
|
@TestMetadata("explicitOverrideOfTwoMembers.kt")
|
||||||
public void testExplicitOverrideOfTwoMembers() throws Exception {
|
public void testExplicitOverrideOfTwoMembers() throws Exception {
|
||||||
|
|||||||
+5
@@ -3699,6 +3699,11 @@ public class LazyBodyIsNotTouchedTestGenerated extends AbstractLazyBodyIsNotTouc
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("delegatedDataClass.kt")
|
||||||
|
public void testDelegatedDataClass() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/scopes/delegatedDataClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("explicitOverrideOfTwoMembers.kt")
|
@TestMetadata("explicitOverrideOfTwoMembers.kt")
|
||||||
public void testExplicitOverrideOfTwoMembers() throws Exception {
|
public void testExplicitOverrideOfTwoMembers() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.kt");
|
||||||
|
|||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
FILE: delegatedDataClass.kt
|
||||||
|
public abstract interface AnyNeighbor : R|kotlin/Any| {
|
||||||
|
public abstract override operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean|
|
||||||
|
|
||||||
|
public abstract override fun hashCode(): R|kotlin/Int|
|
||||||
|
|
||||||
|
public abstract override fun toString(): R|kotlin/String|
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class Impl : R|AnyNeighbor| {
|
||||||
|
public constructor(): R|Impl| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public open override operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean| {
|
||||||
|
^equals Boolean(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
public open override fun hashCode(): R|kotlin/Int| {
|
||||||
|
^hashCode Int(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
public open override fun toString(): R|kotlin/String| {
|
||||||
|
^toString String()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final data class Data : R|AnyNeighbor| {
|
||||||
|
public constructor(i: R|Impl|): R|Data| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
private final field $$delegate_0: R|AnyNeighbor| = R|<local>/i|
|
||||||
|
|
||||||
|
public final val i: R|Impl| = R|<local>/i|
|
||||||
|
public get(): R|Impl|
|
||||||
|
|
||||||
|
public final operator fun component1(): R|Impl|
|
||||||
|
|
||||||
|
public final fun copy(i: R|Impl| = this@R|/Data|.R|/Data.i|): R|Data|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// SCOPE_DUMP: Data:equals, Data:hashCode, Data:toString
|
||||||
|
|
||||||
|
interface AnyNeighbor {
|
||||||
|
override fun equals(other: Any?): Boolean
|
||||||
|
|
||||||
|
override fun hashCode(): Int
|
||||||
|
|
||||||
|
override fun toString(): String
|
||||||
|
}
|
||||||
|
|
||||||
|
class Impl : AnyNeighbor {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Data(val i: Impl) : AnyNeighbor by i
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
Data:
|
||||||
|
[Delegated]: public open override operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean| from Use site scope of /Data [id: 0]
|
||||||
|
[Source]: public abstract override operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean| from Use site scope of /AnyNeighbor [id: 1]
|
||||||
|
[Library]: public open operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean| from Use site scope of kotlin/Any [id: 2]
|
||||||
|
|
||||||
|
Data:
|
||||||
|
[Delegated]: public open override fun hashCode(): R|kotlin/Int| from Use site scope of /Data [id: 0]
|
||||||
|
[Source]: public abstract override fun hashCode(): R|kotlin/Int| from Use site scope of /AnyNeighbor [id: 1]
|
||||||
|
[Library]: public open fun hashCode(): R|kotlin/Int| from Use site scope of kotlin/Any [id: 2]
|
||||||
|
|
||||||
|
Data:
|
||||||
|
[Delegated]: public open override fun toString(): R|kotlin/String| from Use site scope of /Data [id: 0]
|
||||||
|
[Source]: public abstract override fun toString(): R|kotlin/String| from Use site scope of /AnyNeighbor [id: 1]
|
||||||
|
[Library]: public open fun toString(): R|kotlin/String| from Use site scope of kotlin/Any [id: 2]
|
||||||
+6
@@ -4195,6 +4195,12 @@ public class FirLightTreeDiagnosticsTestGenerated extends AbstractFirLightTreeDi
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("delegatedDataClass.kt")
|
||||||
|
public void testDelegatedDataClass() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/scopes/delegatedDataClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("explicitOverrideOfTwoMembers.kt")
|
@TestMetadata("explicitOverrideOfTwoMembers.kt")
|
||||||
public void testExplicitOverrideOfTwoMembers() throws Exception {
|
public void testExplicitOverrideOfTwoMembers() throws Exception {
|
||||||
|
|||||||
+6
@@ -4195,6 +4195,12 @@ public class FirPsiDiagnosticTestGenerated extends AbstractFirPsiDiagnosticTest
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("delegatedDataClass.kt")
|
||||||
|
public void testDelegatedDataClass() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/scopes/delegatedDataClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("explicitOverrideOfTwoMembers.kt")
|
@TestMetadata("explicitOverrideOfTwoMembers.kt")
|
||||||
public void testExplicitOverrideOfTwoMembers() throws Exception {
|
public void testExplicitOverrideOfTwoMembers() throws Exception {
|
||||||
|
|||||||
+6
@@ -18411,6 +18411,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
|||||||
runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt");
|
runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("delegatedAndDataTogether.kt")
|
||||||
|
public void testDelegatedAndDataTogether() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/fir/delegatedAndDataTogether.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("differentSinceKotlin.kt")
|
@TestMetadata("differentSinceKotlin.kt")
|
||||||
public void testDifferentSinceKotlin() throws Exception {
|
public void testDifferentSinceKotlin() throws Exception {
|
||||||
|
|||||||
+6
@@ -18411,6 +18411,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
|||||||
runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt");
|
runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("delegatedAndDataTogether.kt")
|
||||||
|
public void testDelegatedAndDataTogether() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/fir/delegatedAndDataTogether.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("differentSinceKotlin.kt")
|
@TestMetadata("differentSinceKotlin.kt")
|
||||||
public void testDifferentSinceKotlin() throws Exception {
|
public void testDifferentSinceKotlin() throws Exception {
|
||||||
|
|||||||
+10
-14
@@ -45,7 +45,7 @@ class FirKotlinScopeProvider(
|
|||||||
|
|
||||||
return scopeSession.getOrBuild(klass.symbol, USE_SITE) {
|
return scopeSession.getOrBuild(klass.symbol, USE_SITE) {
|
||||||
val declaredScope = useSiteSession.declaredMemberScope(klass, memberRequiredPhase)
|
val declaredScope = useSiteSession.declaredMemberScope(klass, memberRequiredPhase)
|
||||||
val decoratedDeclaredMemberScope = declaredMemberScopeDecorator(
|
val possiblyDelegatedDeclaredMemberScope = declaredMemberScopeDecorator(
|
||||||
klass,
|
klass,
|
||||||
declaredScope,
|
declaredScope,
|
||||||
useSiteSession,
|
useSiteSession,
|
||||||
@@ -58,29 +58,25 @@ class FirKotlinScopeProvider(
|
|||||||
else
|
else
|
||||||
FirDelegatedMemberScope(useSiteSession, scopeSession, klass, it, delegateFields)
|
FirDelegatedMemberScope(useSiteSession, scopeSession, klass, it, delegateFields)
|
||||||
}
|
}
|
||||||
|
val declaredMemberScopeWithPossiblySynthesizedMembers =
|
||||||
|
if (klass is FirRegularClass && !klass.isExpect && (klass.isData || klass.isInline)) {
|
||||||
|
// See also KT-58926 (we apply delegation first, and data/value classes after it)
|
||||||
|
FirClassAnySynthesizedMemberScope(useSiteSession, possiblyDelegatedDeclaredMemberScope, klass, scopeSession)
|
||||||
|
} else {
|
||||||
|
possiblyDelegatedDeclaredMemberScope
|
||||||
|
}
|
||||||
|
|
||||||
val scopes = lookupSuperTypes(
|
val scopes = lookupSuperTypes(
|
||||||
klass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession, substituteTypes = true
|
klass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession, substituteTypes = true
|
||||||
).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,
|
declaredMemberScopeWithPossiblySynthesizedMembers,
|
||||||
)
|
)
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+58
-58
@@ -6,12 +6,10 @@
|
|||||||
package org.jetbrains.kotlin.fir.scopes.impl
|
package org.jetbrains.kotlin.fir.scopes.impl
|
||||||
|
|
||||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.KtSourceElement
|
|
||||||
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fakeElement
|
import org.jetbrains.kotlin.fakeElement
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
import org.jetbrains.kotlin.fir.caches.FirCache
|
import org.jetbrains.kotlin.fir.caches.FirCache
|
||||||
@@ -19,19 +17,22 @@ import org.jetbrains.kotlin.fir.caches.FirCachesFactory
|
|||||||
import org.jetbrains.kotlin.fir.caches.createCache
|
import org.jetbrains.kotlin.fir.caches.createCache
|
||||||
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
||||||
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.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
|
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.scopeForSupertype
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
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.FirImplicitBooleanTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitIntTypeRef
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitIntTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitNullableAnyTypeRef
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitNullableAnyTypeRef
|
||||||
@@ -41,86 +42,85 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
|
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This declared scope wrapper is created for data/value classes and provides Any method stubs, if necessary
|
||||||
|
*/
|
||||||
class FirClassAnySynthesizedMemberScope(
|
class FirClassAnySynthesizedMemberScope(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
private val useSiteMemberScope: FirClassUseSiteMemberScope,
|
private val declaredMemberScope: FirContainingNamesAwareScope,
|
||||||
private val lookupTag: ConeClassLikeLookupTag,
|
klass: FirRegularClass,
|
||||||
private val baseModuleData: FirModuleData,
|
scopeSession: ScopeSession,
|
||||||
private val dispatchReceiverType: ConeClassLikeType,
|
) : FirContainingNamesAwareScope() {
|
||||||
classSource: KtSourceElement?,
|
private val lookupTag = klass.symbol.toLookupTag()
|
||||||
) : FirTypeScope() {
|
|
||||||
|
private val baseModuleData = klass.moduleData
|
||||||
|
|
||||||
|
private val dispatchReceiverType = klass.defaultType()
|
||||||
|
|
||||||
private val synthesizedCache = session.synthesizedStorage.synthesizedCacheByScope.getValue(lookupTag, null)
|
private val synthesizedCache = session.synthesizedStorage.synthesizedCacheByScope.getValue(lookupTag, null)
|
||||||
|
|
||||||
private val synthesizedOverrides = mutableMapOf<FirNamedFunctionSymbol, FirNamedFunctionSymbol>()
|
private val synthesizedSource = klass.source?.fakeElement(KtFakeSourceElementKind.DataClassGeneratedMembers)
|
||||||
|
|
||||||
private val synthesizedSource = classSource?.fakeElement(KtFakeSourceElementKind.DataClassGeneratedMembers)
|
private val superKlassScope = lookupSuperTypes(
|
||||||
|
klass, lookupInterfaces = false, deep = false, useSiteSession = session, substituteTypes = true
|
||||||
|
).firstOrNull()?.scopeForSupertype(session, scopeSession, klass, memberRequiredPhase = FirResolvePhase.TYPES)
|
||||||
|
|
||||||
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
||||||
useSiteMemberScope.processClassifiersByNameWithSubstitution(name, processor)
|
declaredMemberScope.processClassifiersByNameWithSubstitution(name, processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||||
useSiteMemberScope.processDeclaredConstructors(processor)
|
declaredMemberScope.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> {
|
override fun getCallableNames(): Set<Name> {
|
||||||
return useSiteMemberScope.getCallableNames()
|
return declaredMemberScope.getCallableNames()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getClassifierNames(): Set<Name> {
|
override fun getClassifierNames(): Set<Name> {
|
||||||
return useSiteMemberScope.getClassifierNames()
|
return declaredMemberScope.getClassifierNames()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||||
useSiteMemberScope.processPropertiesByName(name, processor)
|
declaredMemberScope.processPropertiesByName(name, processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
|
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
|
||||||
if (name !in ANY_MEMBER_NAMES) {
|
if (name !in ANY_MEMBER_NAMES) {
|
||||||
useSiteMemberScope.processFunctionsByName(name, processor)
|
declaredMemberScope.processFunctionsByName(name, processor)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
useSiteMemberScope.processFunctionsByName(name) { fromUseSiteScope ->
|
var synthesizedFunctionIsNeeded = true
|
||||||
if (fromUseSiteScope.rawStatus.modality == Modality.FINAL) {
|
declaredMemberScope.processFunctionsByName(name) process@{ fromDeclaredScope ->
|
||||||
processor(fromUseSiteScope)
|
if (fromDeclaredScope.matchesSomeAnyMember(name)) {
|
||||||
} else {
|
// TODO: should we handle fromDeclaredScope.origin == FirDeclarationOrigin.Delegated somehow?
|
||||||
val matchedSomeAnyMember = when (name) {
|
// See also KT-58926
|
||||||
OperatorNameConventions.HASH_CODE, OperatorNameConventions.TO_STRING -> {
|
synthesizedFunctionIsNeeded = false
|
||||||
fromUseSiteScope.valueParameterSymbols.isEmpty() && !fromUseSiteScope.isExtension &&
|
}
|
||||||
fromUseSiteScope.fir.contextReceivers.isEmpty()
|
processor(fromDeclaredScope)
|
||||||
}
|
}
|
||||||
else -> {
|
if (!synthesizedFunctionIsNeeded) return
|
||||||
fromUseSiteScope.lazyResolveToPhase(FirResolvePhase.TYPES)
|
superKlassScope?.processFunctionsByName(name) { fromSuperType ->
|
||||||
fromUseSiteScope.fir.isEquals()
|
if (synthesizedFunctionIsNeeded) {
|
||||||
}
|
if (fromSuperType.rawStatus.modality == Modality.FINAL && fromSuperType.matchesSomeAnyMember(name)) {
|
||||||
}
|
synthesizedFunctionIsNeeded = false
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!synthesizedFunctionIsNeeded) return
|
||||||
|
processor(synthesizedCache.synthesizedFunction.getValue(name, this))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirNamedFunctionSymbol.matchesSomeAnyMember(name: Name): Boolean {
|
||||||
|
return when (name) {
|
||||||
|
OperatorNameConventions.HASH_CODE, OperatorNameConventions.TO_STRING -> {
|
||||||
|
valueParameterSymbols.isEmpty() && !isExtension && fir.contextReceivers.isEmpty()
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
lazyResolveToPhase(FirResolvePhase.TYPES)
|
||||||
|
fir.isEquals()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun generateSyntheticFunctionByName(name: Name): FirNamedFunctionSymbol =
|
internal fun generateSyntheticFunctionByName(name: Name): FirNamedFunctionSymbol =
|
||||||
@@ -191,7 +191,7 @@ class FirSynthesizedStorage(val session: FirSession) : FirSessionComponent {
|
|||||||
cachesFactory.createCache { _ -> SynthesizedCache(session.firCachesFactory) }
|
cachesFactory.createCache { _ -> SynthesizedCache(session.firCachesFactory) }
|
||||||
|
|
||||||
class SynthesizedCache(cachesFactory: FirCachesFactory) {
|
class SynthesizedCache(cachesFactory: FirCachesFactory) {
|
||||||
val synthesizedFunctionAndOverrides: FirCache<Name, FirNamedFunctionSymbol, FirClassAnySynthesizedMemberScope> =
|
val synthesizedFunction: FirCache<Name, FirNamedFunctionSymbol, FirClassAnySynthesizedMemberScope> =
|
||||||
cachesFactory.createCache { name, scope -> scope.generateSyntheticFunctionByName(name) }
|
cachesFactory.createCache { name, scope -> scope.generateSyntheticFunctionByName(name) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
// ISSUE: KT-58926
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val i1 = Impl()
|
||||||
|
val i2 = Impl()
|
||||||
|
val d1 = Data(i1, 1)
|
||||||
|
val d2 = Data(i2, 2)
|
||||||
|
return if (d1 != d2) "FAIL: should be equal" else "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AnyNeighbor {
|
||||||
|
override fun equals(other: Any?): Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
class Impl : AnyNeighbor {
|
||||||
|
override fun equals(other: Any?): Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Data(val i: Impl, val j: Int) : AnyNeighbor by i
|
||||||
+6
@@ -18411,6 +18411,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt");
|
runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("delegatedAndDataTogether.kt")
|
||||||
|
public void testDelegatedAndDataTogether() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/fir/delegatedAndDataTogether.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("differentSinceKotlin.kt")
|
@TestMetadata("differentSinceKotlin.kt")
|
||||||
public void testDifferentSinceKotlin() throws Exception {
|
public void testDifferentSinceKotlin() throws Exception {
|
||||||
|
|||||||
+6
@@ -18411,6 +18411,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
|||||||
runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt");
|
runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("delegatedAndDataTogether.kt")
|
||||||
|
public void testDelegatedAndDataTogether() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/fir/delegatedAndDataTogether.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("differentSinceKotlin.kt")
|
@TestMetadata("differentSinceKotlin.kt")
|
||||||
public void testDifferentSinceKotlin() throws Exception {
|
public void testDifferentSinceKotlin() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user