[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:
Mikhail Glukhikh
2020-02-20 12:47:52 +03:00
parent b4d026f5bf
commit 334cab7357
11 changed files with 30 additions and 25 deletions
@@ -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)
} }
} }
@@ -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
View File
@@ -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
View File
@@ -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