[FIR] Don't build redundant fake overrides for private members
The only case we may need fake override for private members is a situation when class refers itself with different type arguments. So in this commit we forbid such fake overrides when we can prove that class does not refers itself here.
This commit is contained in:
@@ -206,7 +206,7 @@ class Fir2IrVisitor(
|
|||||||
declarations += irFunction.setParentByParentStack().withFunction {
|
declarations += irFunction.setParentByParentStack().withFunction {
|
||||||
setFunctionContent(irFunction.descriptor, originalFunction, firOverriddenSymbol = baseSymbol)
|
setFunctionContent(irFunction.descriptor, originalFunction, firOverriddenSymbol = baseSymbol)
|
||||||
}
|
}
|
||||||
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION) {
|
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION && originalFunction.visibility != Visibilities.PRIVATE) {
|
||||||
// Trivial fake override case
|
// Trivial fake override case
|
||||||
val fakeOverrideSymbol =
|
val fakeOverrideSymbol =
|
||||||
FirClassSubstitutionScope.createFakeOverrideFunction(session, originalFunction, functionSymbol)
|
FirClassSubstitutionScope.createFakeOverrideFunction(session, originalFunction, functionSymbol)
|
||||||
@@ -234,7 +234,7 @@ class Fir2IrVisitor(
|
|||||||
declarations += irProperty.setParentByParentStack().withProperty {
|
declarations += irProperty.setParentByParentStack().withProperty {
|
||||||
setPropertyContent(irProperty.descriptor, originalProperty, firOverriddenSymbol = baseSymbol)
|
setPropertyContent(irProperty.descriptor, originalProperty, firOverriddenSymbol = baseSymbol)
|
||||||
}
|
}
|
||||||
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION) {
|
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION && originalProperty.visibility != Visibilities.PRIVATE) {
|
||||||
// Trivial fake override case
|
// Trivial fake override case
|
||||||
val fakeOverrideSymbol =
|
val fakeOverrideSymbol =
|
||||||
FirClassSubstitutionScope.createFakeOverrideProperty(session, originalProperty, propertySymbol)
|
FirClassSubstitutionScope.createFakeOverrideProperty(session, originalProperty, propertySymbol)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession)
|
|||||||
else -> emptyMap()
|
else -> emptyMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fir.scope(substitutorByMap(substitution), useSiteSession, scopeSession)
|
fir.scope(substitutorByMap(substitution), useSiteSession, scopeSession, skipPrivateMembers = false)
|
||||||
}
|
}
|
||||||
is ConeTypeParameterType -> {
|
is ConeTypeParameterType -> {
|
||||||
// TODO: support LibraryTypeParameterSymbol or get rid of it
|
// TODO: support LibraryTypeParameterSymbol or get rid of it
|
||||||
|
|||||||
@@ -94,9 +94,11 @@ fun ConeClassLikeType.wrapSubstitutionScopeIfNeed(
|
|||||||
// to determine parameter types properly (e.g. String, String instead of K, V)
|
// to determine parameter types properly (e.g. String, String instead of K, V)
|
||||||
val javaTypeParameters = javaClass.typeParameters
|
val javaTypeParameters = javaClass.typeParameters
|
||||||
val javaSubstitution = createSubstitution(javaTypeParameters, typeArguments, session)
|
val javaSubstitution = createSubstitution(javaTypeParameters, typeArguments, session)
|
||||||
FirClassSubstitutionScope(session, useSiteMemberScope, builder, originalSubstitution + javaSubstitution)
|
FirClassSubstitutionScope(
|
||||||
|
session, useSiteMemberScope, builder, originalSubstitution + javaSubstitution, skipPrivateMembers = true
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
FirClassSubstitutionScope(session, useSiteMemberScope, builder, originalSubstitution)
|
FirClassSubstitutionScope(session, useSiteMemberScope, builder, originalSubstitution, skipPrivateMembers = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,10 @@ class KotlinScopeProvider(
|
|||||||
if (useSiteSuperType is ConeClassErrorType) return@mapNotNull null
|
if (useSiteSuperType is ConeClassErrorType) return@mapNotNull null
|
||||||
val symbol = useSiteSuperType.lookupTag.toSymbol(useSiteSession)
|
val symbol = useSiteSuperType.lookupTag.toSymbol(useSiteSession)
|
||||||
if (symbol is FirRegularClassSymbol) {
|
if (symbol is FirRegularClassSymbol) {
|
||||||
symbol.fir.scope(substitutor(symbol, useSiteSuperType, useSiteSession), useSiteSession, scopeSession)
|
symbol.fir.scope(
|
||||||
|
substitutor(symbol, useSiteSuperType, useSiteSession),
|
||||||
|
useSiteSession, scopeSession, skipPrivateMembers = true
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@@ -80,10 +83,15 @@ class KotlinScopeProvider(
|
|||||||
data class ConeSubstitutionScopeKey(val substitutor: ConeSubstitutor) : ScopeSessionKey<FirClass<*>, FirClassSubstitutionScope>()
|
data class ConeSubstitutionScopeKey(val substitutor: ConeSubstitutor) : ScopeSessionKey<FirClass<*>, FirClassSubstitutionScope>()
|
||||||
|
|
||||||
fun FirClass<*>.unsubstitutedScope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope {
|
fun FirClass<*>.unsubstitutedScope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope {
|
||||||
return scope(ConeSubstitutor.Empty, useSiteSession, scopeSession)
|
return scopeProvider.getUseSiteMemberScope(this, useSiteSession, scopeSession)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirClass<*>.scope(substitutor: ConeSubstitutor, useSiteSession: FirSession, scopeSession: ScopeSession): FirScope {
|
internal fun FirClass<*>.scope(
|
||||||
|
substitutor: ConeSubstitutor,
|
||||||
|
useSiteSession: FirSession,
|
||||||
|
scopeSession: ScopeSession,
|
||||||
|
skipPrivateMembers: Boolean
|
||||||
|
): FirScope {
|
||||||
val basicScope = scopeProvider.getUseSiteMemberScope(
|
val basicScope = scopeProvider.getUseSiteMemberScope(
|
||||||
this, useSiteSession, scopeSession
|
this, useSiteSession, scopeSession
|
||||||
)
|
)
|
||||||
@@ -92,6 +100,6 @@ fun FirClass<*>.scope(substitutor: ConeSubstitutor, useSiteSession: FirSession,
|
|||||||
return scopeSession.getOrBuild(
|
return scopeSession.getOrBuild(
|
||||||
this, ConeSubstitutionScopeKey(substitutor)
|
this, ConeSubstitutionScopeKey(substitutor)
|
||||||
) {
|
) {
|
||||||
FirClassSubstitutionScope(useSiteSession, basicScope, scopeSession, substitutor)
|
FirClassSubstitutionScope(useSiteSession, basicScope, scopeSession, substitutor, skipPrivateMembers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-7
@@ -5,11 +5,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.scopes.impl
|
package org.jetbrains.kotlin.fir.scopes.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirField
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
||||||
@@ -33,7 +31,8 @@ class FirClassSubstitutionScope(
|
|||||||
private val session: FirSession,
|
private val session: FirSession,
|
||||||
private val useSiteMemberScope: FirScope,
|
private val useSiteMemberScope: FirScope,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
private val substitutor: ConeSubstitutor
|
private val substitutor: ConeSubstitutor,
|
||||||
|
private val skipPrivateMembers: Boolean
|
||||||
) : FirScope() {
|
) : FirScope() {
|
||||||
|
|
||||||
private val fakeOverrideFunctions = mutableMapOf<FirFunctionSymbol<*>, FirFunctionSymbol<*>>()
|
private val fakeOverrideFunctions = mutableMapOf<FirFunctionSymbol<*>, FirFunctionSymbol<*>>()
|
||||||
@@ -43,8 +42,9 @@ class FirClassSubstitutionScope(
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
session: FirSession, useSiteMemberScope: FirScope, scopeSession: ScopeSession,
|
session: FirSession, useSiteMemberScope: FirScope, scopeSession: ScopeSession,
|
||||||
substitution: Map<FirTypeParameterSymbol, ConeKotlinType>
|
substitution: Map<FirTypeParameterSymbol, ConeKotlinType>,
|
||||||
) : this(session, useSiteMemberScope, scopeSession, substitutorByMap(substitution))
|
skipPrivateMembers: Boolean
|
||||||
|
) : this(session, useSiteMemberScope, scopeSession, substitutorByMap(substitution), skipPrivateMembers)
|
||||||
|
|
||||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
|
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
|
||||||
useSiteMemberScope.processFunctionsByName(name) process@{ original ->
|
useSiteMemberScope.processFunctionsByName(name) process@{ original ->
|
||||||
@@ -101,6 +101,7 @@ class FirClassSubstitutionScope(
|
|||||||
is FirConstructorSymbol -> return original
|
is FirConstructorSymbol -> return original
|
||||||
else -> throw AssertionError("Should not be here")
|
else -> throw AssertionError("Should not be here")
|
||||||
}
|
}
|
||||||
|
if (skipPrivateMembers && member.visibility == Visibilities.PRIVATE) return original
|
||||||
|
|
||||||
val (newTypeParameters, newSubstitutor) = createNewTypeParametersAndSubstitutor(member)
|
val (newTypeParameters, newSubstitutor) = createNewTypeParametersAndSubstitutor(member)
|
||||||
|
|
||||||
@@ -170,6 +171,7 @@ class FirClassSubstitutionScope(
|
|||||||
private fun createFakeOverrideProperty(original: FirPropertySymbol): FirPropertySymbol {
|
private fun createFakeOverrideProperty(original: FirPropertySymbol): FirPropertySymbol {
|
||||||
if (substitutor == ConeSubstitutor.Empty) return original
|
if (substitutor == ConeSubstitutor.Empty) return original
|
||||||
val member = original.fir
|
val member = original.fir
|
||||||
|
if (skipPrivateMembers && member.visibility == Visibilities.PRIVATE) return original
|
||||||
|
|
||||||
val receiverType = member.receiverTypeRef?.coneTypeUnsafe<ConeKotlinType>()
|
val receiverType = member.receiverTypeRef?.coneTypeUnsafe<ConeKotlinType>()
|
||||||
val newReceiverType = receiverType?.substitute()
|
val newReceiverType = receiverType?.substitute()
|
||||||
@@ -187,6 +189,7 @@ class FirClassSubstitutionScope(
|
|||||||
private fun createFakeOverrideField(original: FirFieldSymbol): FirFieldSymbol {
|
private fun createFakeOverrideField(original: FirFieldSymbol): FirFieldSymbol {
|
||||||
if (substitutor == ConeSubstitutor.Empty) return original
|
if (substitutor == ConeSubstitutor.Empty) return original
|
||||||
val member = original.fir
|
val member = original.fir
|
||||||
|
if (skipPrivateMembers && member.visibility == Visibilities.PRIVATE) return original
|
||||||
|
|
||||||
val returnType = typeCalculator.tryCalculateReturnType(member).type
|
val returnType = typeCalculator.tryCalculateReturnType(member).type
|
||||||
val newReturnType = returnType.substitute() ?: return original
|
val newReturnType = returnType.substitute() ?: return original
|
||||||
@@ -197,6 +200,7 @@ class FirClassSubstitutionScope(
|
|||||||
private fun createFakeOverrideAccessor(original: FirAccessorSymbol): FirAccessorSymbol {
|
private fun createFakeOverrideAccessor(original: FirAccessorSymbol): FirAccessorSymbol {
|
||||||
if (substitutor == ConeSubstitutor.Empty) return original
|
if (substitutor == ConeSubstitutor.Empty) return original
|
||||||
val member = original.fir as FirSyntheticProperty
|
val member = original.fir as FirSyntheticProperty
|
||||||
|
if (skipPrivateMembers && member.visibility == Visibilities.PRIVATE) return original
|
||||||
|
|
||||||
val returnType = typeCalculator.tryCalculateReturnType(member).type
|
val returnType = typeCalculator.tryCalculateReturnType(member).type
|
||||||
val newReturnType = returnType.substitute()
|
val newReturnType = returnType.substitute()
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TODO: Enable when JS backend supports Java class library
|
// TODO: Enable when JS backend supports Java class library
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
public class SomeClass() : java.lang.Object() {
|
public class SomeClass() : java.lang.Object() {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// !JVM_DEFAULT_MODE: enable
|
// !JVM_DEFAULT_MODE: enable
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// JVM_TARGET: 1.8
|
// JVM_TARGET: 1.8
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||||
// IGNORE_BACKEND: JS, NATIVE
|
// IGNORE_BACKEND: JS, NATIVE
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
var result = "fail"
|
var result = "fail"
|
||||||
|
|
||||||
interface B {
|
interface B {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
open class A(private val s: String = "") {
|
open class A(private val s: String = "") {
|
||||||
fun foo() = s
|
fun foo() = s
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,6 @@ FILE fqName:<root> fileName:/fakeOverridesForJavaStaticMembers.kt
|
|||||||
overridden:
|
overridden:
|
||||||
public/*package*/ open fun packagePrivateStaticMethod (): kotlin.Unit declared in a.Base
|
public/*package*/ open fun packagePrivateStaticMethod (): kotlin.Unit declared in a.Base
|
||||||
$this: VALUE_PARAMETER name:<this> type:a.Base
|
$this: VALUE_PARAMETER name:<this> type:a.Base
|
||||||
FUN FAKE_OVERRIDE name:privateStaticMethod visibility:private modality:OPEN <> ($this:a.Base) returnType:kotlin.Unit [fake_override]
|
|
||||||
overridden:
|
|
||||||
private open fun privateStaticMethod (): kotlin.Unit declared in a.Base
|
|
||||||
$this: VALUE_PARAMETER name:<this> type:a.Base
|
|
||||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||||
overridden:
|
overridden:
|
||||||
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
|
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
|
||||||
|
|||||||
Reference in New Issue
Block a user