IR: check visibility when building fake overrides
This fixes the difference at least in the IR text test testFakeOverridesForJavaNonStaticMembers. There's no fake override created anymore for `packagePrivateMethod` in Test2. #KT-61366 Fixed
This commit is contained in:
committed by
Space Team
parent
a23f2894b2
commit
bb381e7aef
@@ -216,12 +216,6 @@ class IrOverridingUtil(
|
||||
return trueFakeOverrides.ifEmpty { customizedFakeOverrides }
|
||||
}
|
||||
|
||||
private fun filterVisibleFakeOverrides(toFilter: Collection<IrOverridableMember>): Collection<IrOverridableMember> {
|
||||
return toFilter.filter { member: IrOverridableMember ->
|
||||
!DescriptorVisibilities.isPrivate(member.visibility) && member.visibility != DescriptorVisibilities.INVISIBLE_FAKE
|
||||
}
|
||||
}
|
||||
|
||||
private fun determineModalityForFakeOverride(
|
||||
members: Collection<IrOverridableMember>,
|
||||
current: IrClass
|
||||
@@ -328,7 +322,7 @@ class IrOverridingUtil(
|
||||
addedFakeOverrides: MutableList<IrOverridableMember>,
|
||||
compatibilityMode: Boolean
|
||||
) {
|
||||
val effectiveOverridden = filterVisibleFakeOverrides(overridables)
|
||||
val effectiveOverridden = overridables.filter { it.isVisibleInClass(currentClass) }
|
||||
|
||||
// The descriptor based algorithm goes further building invisible fakes here,
|
||||
// but we don't use invisible fakes in IR
|
||||
|
||||
@@ -5,22 +5,17 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.overrides
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithVisibility
|
||||
import org.jetbrains.kotlin.ir.declarations.IrOverridableDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrOverridableMember
|
||||
import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.types.getClass
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
|
||||
// The contents of this file is from VisibilityUtil.kt adapted to IR.
|
||||
// TODO: The code would better be commonized for descriptors, ir and fir.
|
||||
|
||||
fun isVisibleForOverride(
|
||||
@Suppress("UNUSED_PARAMETER") overriding: IrOverridableMember,
|
||||
fromSuper: IrOverridableMember
|
||||
): Boolean {
|
||||
return !DescriptorVisibilities.isPrivate((fromSuper as IrDeclarationWithVisibility).visibility)
|
||||
fun isVisibleForOverride(overriding: IrOverridableMember, fromSuper: IrOverridableMember): Boolean {
|
||||
return fromSuper.isVisibleInClass(overriding.parentAsClass)
|
||||
}
|
||||
|
||||
// Based on findMemberWithMaxVisibility from VisibilityUtil.kt.
|
||||
fun findMemberWithMaxVisibility(members: Collection<IrOverridableMember>): IrOverridableMember {
|
||||
assert(members.isNotEmpty())
|
||||
|
||||
@@ -60,3 +55,25 @@ fun IrDeclarationWithVisibility.isEffectivelyPrivate(): Boolean {
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
internal fun IrOverridableMember.isVisibleInClass(klass: IrClass): Boolean {
|
||||
if (DescriptorVisibilities.isPrivate(visibility) || visibility == DescriptorVisibilities.INVISIBLE_FAKE) return false
|
||||
|
||||
// OverridingUtil.isVisibleForOverride just calls DescriptorVisibilities.isVisible here. However, we can't use descriptors. Moreover,
|
||||
// the current member's parent has already been reassigned to the current class (in OverridingUtil, it is still the original class where
|
||||
// the member was declared at this point). So we load the original class from the dispatch receiver.
|
||||
val dispatchReceiver = when (this) {
|
||||
is IrSimpleFunction -> dispatchReceiverParameter
|
||||
is IrProperty -> getter?.dispatchReceiverParameter
|
||||
else -> error("Unsupported member: ${render()}")
|
||||
} ?: error("Members without dispatch receiver are not possible here: ${render()} (klass=${klass.fqNameWhenAvailable}")
|
||||
|
||||
// Package-private Java members are only overridable within the same package.
|
||||
val originalClass = dispatchReceiver.type.getClass()!!
|
||||
if (!visibility.visibleFromPackage(klass.getPackageFragment().packageFqName, originalClass.getPackageFragment().packageFqName))
|
||||
return false
|
||||
|
||||
// TODO (KT-61384): also check internal.
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
+6
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.java.JavaVisibilities;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
|
||||
@@ -41,6 +42,11 @@ public class JavaDescriptorVisibilities {
|
||||
) {
|
||||
return areInSamePackage(what, from);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visibleFromPackage(@NotNull FqName fromPackage, @NotNull FqName myPackage) {
|
||||
return fromPackage.equals(myPackage);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
|
||||
abstract class DescriptorVisibility protected constructor() {
|
||||
@@ -78,6 +79,8 @@ abstract class DescriptorVisibility protected constructor() {
|
||||
|
||||
// Should be overloaded in Java visibilities
|
||||
fun customEffectiveVisibility(): EffectiveVisibility? = delegate.customEffectiveVisibility()
|
||||
|
||||
open fun visibleFromPackage(fromPackage: FqName, myPackage: FqName): Boolean = true
|
||||
}
|
||||
|
||||
abstract class DelegatedDescriptorVisibility(override val delegate: Visibility) : DescriptorVisibility() {
|
||||
|
||||
Reference in New Issue
Block a user