[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 {
setFunctionContent(irFunction.descriptor, originalFunction, firOverriddenSymbol = baseSymbol)
}
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION) {
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION && originalFunction.visibility != Visibilities.PRIVATE) {
// Trivial fake override case
val fakeOverrideSymbol =
FirClassSubstitutionScope.createFakeOverrideFunction(session, originalFunction, functionSymbol)
@@ -234,7 +234,7 @@ class Fir2IrVisitor(
declarations += irProperty.setParentByParentStack().withProperty {
setPropertyContent(irProperty.descriptor, originalProperty, firOverriddenSymbol = baseSymbol)
}
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION) {
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION && originalProperty.visibility != Visibilities.PRIVATE) {
// Trivial fake override case
val fakeOverrideSymbol =
FirClassSubstitutionScope.createFakeOverrideProperty(session, originalProperty, propertySymbol)
@@ -33,7 +33,7 @@ fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession)
else -> emptyMap()
}
fir.scope(substitutorByMap(substitution), useSiteSession, scopeSession)
fir.scope(substitutorByMap(substitution), useSiteSession, scopeSession, skipPrivateMembers = false)
}
is ConeTypeParameterType -> {
// 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)
val javaTypeParameters = javaClass.typeParameters
val javaSubstitution = createSubstitution(javaTypeParameters, typeArguments, session)
FirClassSubstitutionScope(session, useSiteMemberScope, builder, originalSubstitution + javaSubstitution)
FirClassSubstitutionScope(
session, useSiteMemberScope, builder, originalSubstitution + javaSubstitution, skipPrivateMembers = true
)
} 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
val symbol = useSiteSuperType.lookupTag.toSymbol(useSiteSession)
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 {
null
}
@@ -80,10 +83,15 @@ class KotlinScopeProvider(
data class ConeSubstitutionScopeKey(val substitutor: ConeSubstitutor) : ScopeSessionKey<FirClass<*>, FirClassSubstitutionScope>()
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(
this, useSiteSession, scopeSession
)
@@ -92,6 +100,6 @@ fun FirClass<*>.scope(substitutor: ConeSubstitutor, useSiteSession: FirSession,
return scopeSession.getOrBuild(
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
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirField
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.*
import org.jetbrains.kotlin.fir.declarations.builder.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
@@ -33,7 +31,8 @@ class FirClassSubstitutionScope(
private val session: FirSession,
private val useSiteMemberScope: FirScope,
scopeSession: ScopeSession,
private val substitutor: ConeSubstitutor
private val substitutor: ConeSubstitutor,
private val skipPrivateMembers: Boolean
) : FirScope() {
private val fakeOverrideFunctions = mutableMapOf<FirFunctionSymbol<*>, FirFunctionSymbol<*>>()
@@ -43,8 +42,9 @@ class FirClassSubstitutionScope(
constructor(
session: FirSession, useSiteMemberScope: FirScope, scopeSession: ScopeSession,
substitution: Map<FirTypeParameterSymbol, ConeKotlinType>
) : this(session, useSiteMemberScope, scopeSession, substitutorByMap(substitution))
substitution: Map<FirTypeParameterSymbol, ConeKotlinType>,
skipPrivateMembers: Boolean
) : this(session, useSiteMemberScope, scopeSession, substitutorByMap(substitution), skipPrivateMembers)
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
useSiteMemberScope.processFunctionsByName(name) process@{ original ->
@@ -101,6 +101,7 @@ class FirClassSubstitutionScope(
is FirConstructorSymbol -> return original
else -> throw AssertionError("Should not be here")
}
if (skipPrivateMembers && member.visibility == Visibilities.PRIVATE) return original
val (newTypeParameters, newSubstitutor) = createNewTypeParametersAndSubstitutor(member)
@@ -170,6 +171,7 @@ class FirClassSubstitutionScope(
private fun createFakeOverrideProperty(original: FirPropertySymbol): FirPropertySymbol {
if (substitutor == ConeSubstitutor.Empty) return original
val member = original.fir
if (skipPrivateMembers && member.visibility == Visibilities.PRIVATE) return original
val receiverType = member.receiverTypeRef?.coneTypeUnsafe<ConeKotlinType>()
val newReceiverType = receiverType?.substitute()
@@ -187,6 +189,7 @@ class FirClassSubstitutionScope(
private fun createFakeOverrideField(original: FirFieldSymbol): FirFieldSymbol {
if (substitutor == ConeSubstitutor.Empty) return original
val member = original.fir
if (skipPrivateMembers && member.visibility == Visibilities.PRIVATE) return original
val returnType = typeCalculator.tryCalculateReturnType(member).type
val newReturnType = returnType.substitute() ?: return original
@@ -197,6 +200,7 @@ class FirClassSubstitutionScope(
private fun createFakeOverrideAccessor(original: FirAccessorSymbol): FirAccessorSymbol {
if (substitutor == ConeSubstitutor.Empty) return original
val member = original.fir as FirSyntheticProperty
if (skipPrivateMembers && member.visibility == Visibilities.PRIVATE) return original
val returnType = typeCalculator.tryCalculateReturnType(member).type
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
// TARGET_BACKEND: JVM
public class SomeClass() : java.lang.Object() {
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: enable
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
var result = "fail"
interface B {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
open class A(private val s: String = "") {
fun foo() = s
}
@@ -17,10 +17,6 @@ FILE fqName:<root> fileName:/fakeOverridesForJavaStaticMembers.kt
overridden:
public/*package*/ open fun packagePrivateStaticMethod (): kotlin.Unit declared in 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]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any