[API Usage] Use type refinements in overrides-related facilities

This commit is contained in:
Denis Zharkov
2019-07-01 15:36:24 +03:00
committed by Dmitry Savvinov
parent 694f521bfd
commit b7e011a29b
22 changed files with 165 additions and 60 deletions
@@ -305,7 +305,7 @@ class CollectionStubMethodGenerator(
}.groupBy { it.name } }.groupBy { it.name }
for ((name, fromSupertypes) in membersFromSupertypesByName) { for ((name, fromSupertypes) in membersFromSupertypesByName) {
OverridingUtil.generateOverridesInFunctionGroup(name, fromSupertypes, emptyList(), classDescriptor, strategy) OverridingUtil.DEFAULT.generateOverridesInFunctionGroup(name, fromSupertypes, emptyList(), classDescriptor, strategy)
} }
} }
@@ -38,13 +38,16 @@ import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Res
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
import org.jetbrains.kotlin.types.refinement.TypeRefinement
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
import java.util.* import java.util.*
class OverrideResolver( class OverrideResolver(
private val trace: BindingTrace, private val trace: BindingTrace,
private val overridesBackwardCompatibilityHelper: OverridesBackwardCompatibilityHelper, private val overridesBackwardCompatibilityHelper: OverridesBackwardCompatibilityHelper,
private val languageVersionSettings: LanguageVersionSettings private val languageVersionSettings: LanguageVersionSettings,
private val kotlinTypeRefiner: KotlinTypeRefiner
) { ) {
fun check(c: TopDownAnalysisContext) { fun check(c: TopDownAnalysisContext) {
@@ -270,7 +273,8 @@ class OverrideResolver(
val overriddenDescriptors = declared.overriddenDescriptors val overriddenDescriptors = declared.overriddenDescriptors
if (hasOverrideNode) { if (hasOverrideNode) {
checkOverridesForMemberMarkedOverride(declared, object : CheckOverrideReportForDeclaredMemberStrategy { checkOverridesForMemberMarkedOverride(
declared, kotlinTypeRefiner, object : CheckOverrideReportForDeclaredMemberStrategy {
private var finalOverriddenError = false private var finalOverriddenError = false
private var typeMismatchError = false private var typeMismatchError = false
private var kindMismatchError = false private var kindMismatchError = false
@@ -753,6 +757,7 @@ class OverrideResolver(
private fun checkOverridesForMemberMarkedOverride( private fun checkOverridesForMemberMarkedOverride(
declared: CallableMemberDescriptor, declared: CallableMemberDescriptor,
kotlinTypeRefiner: KotlinTypeRefiner,
reportError: CheckOverrideReportForDeclaredMemberStrategy reportError: CheckOverrideReportForDeclaredMemberStrategy
) { ) {
val overriddenDescriptors = declared.overriddenDescriptors val overriddenDescriptors = declared.overriddenDescriptors
@@ -765,7 +770,10 @@ class OverrideResolver(
"Overrides may only be resolved in a class, but $declared comes from $containingDeclaration" "Overrides may only be resolved in a class, but $declared comes from $containingDeclaration"
} }
val invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass) val invisibleOverriddenDescriptor =
findInvisibleOverriddenDescriptor(
declared, declaringClass, kotlinTypeRefiner
)
if (invisibleOverriddenDescriptor != null) { if (invisibleOverriddenDescriptor != null) {
reportError.cannotOverrideInvisibleMember(declared, invisibleOverriddenDescriptor) reportError.cannotOverrideInvisibleMember(declared, invisibleOverriddenDescriptor)
} else { } else {
@@ -863,9 +871,11 @@ class OverrideResolver(
private fun findInvisibleOverriddenDescriptor( private fun findInvisibleOverriddenDescriptor(
declared: CallableMemberDescriptor, declared: CallableMemberDescriptor,
declaringClass: ClassDescriptor declaringClass: ClassDescriptor,
kotlinTypeRefiner: KotlinTypeRefiner
): CallableMemberDescriptor? { ): CallableMemberDescriptor? {
for (supertype in declaringClass.typeConstructor.supertypes) { @UseExperimental(TypeRefinement::class)
for (supertype in kotlinTypeRefiner.refineSupertypes(declaringClass)) {
val all = linkedSetOf<CallableMemberDescriptor>() val all = linkedSetOf<CallableMemberDescriptor>()
all.addAll(supertype.memberScope.getContributedFunctions(declared.name, NoLookupLocation.WHEN_CHECK_OVERRIDES)) all.addAll(supertype.memberScope.getContributedFunctions(declared.name, NoLookupLocation.WHEN_CHECK_OVERRIDES))
all.addAll(supertype.memberScope.getContributedVariables(declared.name, NoLookupLocation.WHEN_CHECK_OVERRIDES)) all.addAll(supertype.memberScope.getContributedVariables(declared.name, NoLookupLocation.WHEN_CHECK_OVERRIDES))
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.WrappedTypeFactory import org.jetbrains.kotlin.types.WrappedTypeFactory
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
interface LazyClassContext { interface LazyClassContext {
val declarationScopeProvider: DeclarationScopeProvider val declarationScopeProvider: DeclarationScopeProvider
@@ -43,4 +44,5 @@ interface LazyClassContext {
val syntheticResolveExtension: SyntheticResolveExtension val syntheticResolveExtension: SyntheticResolveExtension
val delegationFilter: DelegationFilter val delegationFilter: DelegationFilter
val wrappedTypeFactory: WrappedTypeFactory val wrappedTypeFactory: WrappedTypeFactory
val kotlinTypeChecker: NewKotlinTypeChecker
} }
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.resolve.scopes.MemberScope;
import org.jetbrains.kotlin.storage.*; import org.jetbrains.kotlin.storage.*;
import org.jetbrains.kotlin.types.WrappedTypeFactory; import org.jetbrains.kotlin.types.WrappedTypeFactory;
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker;
import org.jetbrains.kotlin.utils.SmartList; import org.jetbrains.kotlin.utils.SmartList;
import javax.inject.Inject; import javax.inject.Inject;
@@ -84,6 +85,8 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
private final SyntheticResolveExtension syntheticResolveExtension; private final SyntheticResolveExtension syntheticResolveExtension;
private final NewKotlinTypeChecker kotlinTypeChecker;
private Project project; private Project project;
@Inject @Inject
@@ -153,7 +156,8 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
@NotNull GlobalContext globalContext, @NotNull GlobalContext globalContext,
@NotNull ModuleDescriptor rootDescriptor, @NotNull ModuleDescriptor rootDescriptor,
@NotNull DeclarationProviderFactory declarationProviderFactory, @NotNull DeclarationProviderFactory declarationProviderFactory,
@NotNull BindingTrace delegationTrace @NotNull BindingTrace delegationTrace,
@NotNull NewKotlinTypeChecker kotlinTypeChecker
) { ) {
LockBasedLazyResolveStorageManager lockBasedLazyResolveStorageManager = LockBasedLazyResolveStorageManager lockBasedLazyResolveStorageManager =
new LockBasedLazyResolveStorageManager(globalContext.getStorageManager()); new LockBasedLazyResolveStorageManager(globalContext.getStorageManager());
@@ -194,6 +198,7 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
syntheticResolveExtension = SyntheticResolveExtension.Companion.getInstance(project); syntheticResolveExtension = SyntheticResolveExtension.Companion.getInstance(project);
this.project = project; this.project = project;
this.kotlinTypeChecker = kotlinTypeChecker;
} }
private LazyAnnotations createAnnotations(KtFile file, List<KtAnnotationEntry> annotationEntries) { private LazyAnnotations createAnnotations(KtFile file, List<KtAnnotationEntry> annotationEntries) {
@@ -464,4 +469,10 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
public void assertValid() { public void assertValid() {
module.assertValid(); module.assertValid();
} }
@NotNull
@Override
public NewKotlinTypeChecker getKotlinTypeChecker() {
return kotlinTypeChecker;
}
} }
@@ -151,7 +151,7 @@ open class LazyClassMemberScope(
result: MutableCollection<D>, result: MutableCollection<D>,
exactDescriptorClass: Class<out D> exactDescriptorClass: Class<out D>
) { ) {
OverridingUtil.generateOverridesInFunctionGroup( c.kotlinTypeChecker.overridingUtil.generateOverridesInFunctionGroup(
name, name,
fromSupertypes, fromSupertypes,
ArrayList(result), ArrayList(result),
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.types.expressions
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.container.get import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.context.GlobalContext import org.jetbrains.kotlin.context.GlobalContext
@@ -33,6 +32,7 @@ import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.debugText.getDebugText import org.jetbrains.kotlin.psi.debugText.getDebugText
@@ -51,6 +51,7 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.WrappedTypeFactory import org.jetbrains.kotlin.types.WrappedTypeFactory
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
class LocalClassifierAnalyzer( class LocalClassifierAnalyzer(
private val globalContext: GlobalContext, private val globalContext: GlobalContext,
@@ -65,7 +66,8 @@ class LocalClassifierAnalyzer(
private val supertypeLoopChecker: SupertypeLoopChecker, private val supertypeLoopChecker: SupertypeLoopChecker,
private val languageVersionSettings: LanguageVersionSettings, private val languageVersionSettings: LanguageVersionSettings,
private val delegationFilter: DelegationFilter, private val delegationFilter: DelegationFilter,
private val wrappedTypeFactory: WrappedTypeFactory private val wrappedTypeFactory: WrappedTypeFactory,
private val kotlinTypeChecker: NewKotlinTypeChecker
) { ) {
fun processClassOrObject( fun processClassOrObject(
scope: LexicalWritableScope?, scope: LexicalWritableScope?,
@@ -98,7 +100,8 @@ class LocalClassifierAnalyzer(
languageVersionSettings, languageVersionSettings,
SyntheticResolveExtension.getInstance(project), SyntheticResolveExtension.getInstance(project),
delegationFilter, delegationFilter,
wrappedTypeFactory wrappedTypeFactory,
kotlinTypeChecker
), ),
analyzerServices analyzerServices
) )
@@ -126,7 +129,8 @@ class LocalClassDescriptorHolder(
val languageVersionSettings: LanguageVersionSettings, val languageVersionSettings: LanguageVersionSettings,
val syntheticResolveExtension: SyntheticResolveExtension, val syntheticResolveExtension: SyntheticResolveExtension,
val delegationFilter: DelegationFilter, val delegationFilter: DelegationFilter,
val wrappedTypeFactory: WrappedTypeFactory val wrappedTypeFactory: WrappedTypeFactory,
val kotlinTypeChecker: NewKotlinTypeChecker
) { ) {
// We do not need to synchronize here, because this code is used strictly from one thread // We do not need to synchronize here, because this code is used strictly from one thread
private var classDescriptor: ClassDescriptor? = null private var classDescriptor: ClassDescriptor? = null
@@ -166,6 +170,7 @@ class LocalClassDescriptorHolder(
override val syntheticResolveExtension = this@LocalClassDescriptorHolder.syntheticResolveExtension override val syntheticResolveExtension = this@LocalClassDescriptorHolder.syntheticResolveExtension
override val delegationFilter: DelegationFilter = this@LocalClassDescriptorHolder.delegationFilter override val delegationFilter: DelegationFilter = this@LocalClassDescriptorHolder.delegationFilter
override val wrappedTypeFactory: WrappedTypeFactory = this@LocalClassDescriptorHolder.wrappedTypeFactory override val wrappedTypeFactory: WrappedTypeFactory = this@LocalClassDescriptorHolder.wrappedTypeFactory
override val kotlinTypeChecker: NewKotlinTypeChecker = this@LocalClassDescriptorHolder.kotlinTypeChecker
}, },
containingDeclaration, containingDeclaration,
classOrObject.nameAsSafeName, classOrObject.nameAsSafeName,
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.serialization.deserialization.*
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInsPackageFragmentImpl import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInsPackageFragmentImpl
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
class JvmBuiltInsPackageFragmentProvider( class JvmBuiltInsPackageFragmentProvider(
storageManager: StorageManager, storageManager: StorageManager,
@@ -25,7 +26,8 @@ class JvmBuiltInsPackageFragmentProvider(
notFoundClasses: NotFoundClasses, notFoundClasses: NotFoundClasses,
additionalClassPartsProvider: AdditionalClassPartsProvider, additionalClassPartsProvider: AdditionalClassPartsProvider,
platformDependentDeclarationFilter: PlatformDependentDeclarationFilter, platformDependentDeclarationFilter: PlatformDependentDeclarationFilter,
deserializationConfiguration: DeserializationConfiguration deserializationConfiguration: DeserializationConfiguration,
kotlinTypeChecker: NewKotlinTypeChecker
) : AbstractDeserializedPackageFragmentProvider(storageManager, finder, moduleDescriptor) { ) : AbstractDeserializedPackageFragmentProvider(storageManager, finder, moduleDescriptor) {
init { init {
components = DeserializationComponents( components = DeserializationComponents(
@@ -46,7 +48,8 @@ class JvmBuiltInsPackageFragmentProvider(
notFoundClasses, notFoundClasses,
ContractDeserializer.DEFAULT, ContractDeserializer.DEFAULT,
additionalClassPartsProvider, platformDependentDeclarationFilter, additionalClassPartsProvider, platformDependentDeclarationFilter,
BuiltInSerializerProtocol.extensionRegistry BuiltInSerializerProtocol.extensionRegistry,
kotlinTypeChecker
) )
} }
@@ -42,18 +42,20 @@ public final class DescriptorResolverUtils {
@NotNull @NotNull
public static <D extends CallableMemberDescriptor> Collection<D> resolveOverridesForNonStaticMembers( public static <D extends CallableMemberDescriptor> Collection<D> resolveOverridesForNonStaticMembers(
@NotNull Name name, @NotNull Collection<D> membersFromSupertypes, @NotNull Collection<D> membersFromCurrent, @NotNull Name name, @NotNull Collection<D> membersFromSupertypes, @NotNull Collection<D> membersFromCurrent,
@NotNull ClassDescriptor classDescriptor, @NotNull ErrorReporter errorReporter @NotNull ClassDescriptor classDescriptor, @NotNull ErrorReporter errorReporter,
) { @NotNull OverridingUtil overridingUtil
return resolveOverrides(name, membersFromSupertypes, membersFromCurrent, classDescriptor, errorReporter, false); ) {
return resolveOverrides(name, membersFromSupertypes, membersFromCurrent, classDescriptor, errorReporter, overridingUtil, false);
} }
@NotNull @NotNull
public static <D extends CallableMemberDescriptor> Collection<D> resolveOverridesForStaticMembers( public static <D extends CallableMemberDescriptor> Collection<D> resolveOverridesForStaticMembers(
@NotNull Name name, @NotNull Collection<D> membersFromSupertypes, @NotNull Collection<D> membersFromCurrent, @NotNull Name name, @NotNull Collection<D> membersFromSupertypes, @NotNull Collection<D> membersFromCurrent,
@NotNull ClassDescriptor classDescriptor, @NotNull ErrorReporter errorReporter @NotNull ClassDescriptor classDescriptor, @NotNull ErrorReporter errorReporter,
) { @NotNull OverridingUtil overridingUtil
return resolveOverrides(name, membersFromSupertypes, membersFromCurrent, classDescriptor, errorReporter, true); ) {
return resolveOverrides(name, membersFromSupertypes, membersFromCurrent, classDescriptor, errorReporter, overridingUtil, true);
} }
@NotNull @NotNull
@@ -63,11 +65,12 @@ public final class DescriptorResolverUtils {
@NotNull Collection<D> membersFromCurrent, @NotNull Collection<D> membersFromCurrent,
@NotNull ClassDescriptor classDescriptor, @NotNull ClassDescriptor classDescriptor,
@NotNull final ErrorReporter errorReporter, @NotNull final ErrorReporter errorReporter,
@NotNull OverridingUtil overridingUtil,
final boolean isStaticContext final boolean isStaticContext
) { ) {
final Set<D> result = new LinkedHashSet<D>(); final Set<D> result = new LinkedHashSet<D>();
OverridingUtil.generateOverridesInFunctionGroup( overridingUtil.generateOverridesInFunctionGroup(
name, membersFromSupertypes, membersFromCurrent, classDescriptor, name, membersFromSupertypes, membersFromCurrent, classDescriptor,
new NonReportingOverrideStrategy() { new NonReportingOverrideStrategy() {
@Override @Override
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
import java.util.* import java.util.*
class JavaResolverComponents( class JavaResolverComponents(
@@ -64,7 +65,8 @@ class JavaResolverComponents(
val annotationTypeQualifierResolver: AnnotationTypeQualifierResolver, val annotationTypeQualifierResolver: AnnotationTypeQualifierResolver,
val signatureEnhancement: SignatureEnhancement, val signatureEnhancement: SignatureEnhancement,
val javaClassesTracker: JavaClassesTracker, val javaClassesTracker: JavaClassesTracker,
val settings: JavaResolverSettings val settings: JavaResolverSettings,
val kotlinTypeChecker: NewKotlinTypeChecker
) { ) {
fun replace( fun replace(
javaResolverCache: JavaResolverCache = this.javaResolverCache javaResolverCache: JavaResolverCache = this.javaResolverCache
@@ -73,7 +75,8 @@ class JavaResolverComponents(
signaturePropagator, errorReporter, javaResolverCache, signaturePropagator, errorReporter, javaResolverCache,
javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory, javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory,
moduleClassResolver, packagePartProvider, supertypeLoopChecker, lookupTracker, module, reflectionTypes, moduleClassResolver, packagePartProvider, supertypeLoopChecker, lookupTracker, module, reflectionTypes,
annotationTypeQualifierResolver, signatureEnhancement, javaClassesTracker, settings annotationTypeQualifierResolver, signatureEnhancement, javaClassesTracker, settings,
kotlinTypeChecker
) )
} }
@@ -57,6 +57,7 @@ import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.refinement.TypeRefinement
import org.jetbrains.kotlin.utils.SmartSet import org.jetbrains.kotlin.utils.SmartSet
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
@@ -280,7 +281,8 @@ class LazyJavaClassMemberScope(
// Merge functions with same signatures // Merge functions with same signatures
val mergedFunctionFromSuperTypes = resolveOverridesForNonStaticMembers( val mergedFunctionFromSuperTypes = resolveOverridesForNonStaticMembers(
name, functionsFromSupertypes, emptyList(), ownerDescriptor, ErrorReporter.DO_NOTHING name, functionsFromSupertypes, emptyList(), ownerDescriptor, ErrorReporter.DO_NOTHING,
c.components.kotlinTypeChecker.overridingUtil
) )
// add declarations // add declarations
@@ -309,7 +311,8 @@ class LazyJavaClassMemberScope(
) { ) {
val additionalOverrides = resolveOverridesForNonStaticMembers( val additionalOverrides = resolveOverridesForNonStaticMembers(
name, functionsFromSupertypes, result, ownerDescriptor, c.components.errorReporter name, functionsFromSupertypes, result, ownerDescriptor, c.components.errorReporter,
c.components.kotlinTypeChecker.overridingUtil
) )
if (!isSpecialBuiltinName) { if (!isSpecialBuiltinName) {
@@ -451,7 +454,12 @@ class LazyJavaClassMemberScope(
result.addAll( result.addAll(
resolveOverridesForNonStaticMembers( resolveOverridesForNonStaticMembers(
name, propertiesFromSupertypes + propertiesOverridesFromSuperTypes, result, ownerDescriptor, c.components.errorReporter name,
propertiesFromSupertypes + propertiesOverridesFromSuperTypes,
result,
ownerDescriptor,
c.components.errorReporter,
c.components.kotlinTypeChecker.overridingUtil
) )
) )
} }
@@ -64,7 +64,14 @@ class LazyJavaStaticClassScope(
override fun computeNonDeclaredFunctions(result: MutableCollection<SimpleFunctionDescriptor>, name: Name) { override fun computeNonDeclaredFunctions(result: MutableCollection<SimpleFunctionDescriptor>, name: Name) {
val functionsFromSupertypes = getStaticFunctionsFromJavaSuperClasses(name, ownerDescriptor) val functionsFromSupertypes = getStaticFunctionsFromJavaSuperClasses(name, ownerDescriptor)
result.addAll(resolveOverridesForStaticMembers(name, functionsFromSupertypes, result, ownerDescriptor, c.components.errorReporter)) result.addAll(resolveOverridesForStaticMembers(
name,
functionsFromSupertypes,
result,
ownerDescriptor,
c.components.errorReporter,
c.components.kotlinTypeChecker.overridingUtil
))
if (jClass.isEnum) { if (jClass.isEnum) {
when (name) { when (name) {
@@ -81,13 +88,23 @@ class LazyJavaStaticClassScope(
if (result.isNotEmpty()) { if (result.isNotEmpty()) {
result.addAll( result.addAll(
resolveOverridesForStaticMembers(name, propertiesFromSupertypes, result, ownerDescriptor, c.components.errorReporter) resolveOverridesForStaticMembers(
name,
propertiesFromSupertypes,
result,
ownerDescriptor,
c.components.errorReporter,
c.components.kotlinTypeChecker.overridingUtil
)
) )
} else { } else {
result.addAll(propertiesFromSupertypes.groupBy { result.addAll(propertiesFromSupertypes.groupBy {
it.realOriginal it.realOriginal
}.flatMap { }.flatMap {
resolveOverridesForStaticMembers(name, it.value, result, ownerDescriptor, c.components.errorReporter) resolveOverridesForStaticMembers(
name, it.value, result, ownerDescriptor, c.components.errorReporter,
c.components.kotlinTypeChecker.overridingUtil
)
}) })
} }
} }
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.load.java.lazy.LazyJavaPackageFragmentProvider
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.serialization.deserialization.*
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
// This class is needed only for easier injection: exact types of needed components are specified in the constructor here. // This class is needed only for easier injection: exact types of needed components are specified in the constructor here.
// Otherwise injector generator is not smart enough to deduce, for example, which package fragment provider DeserializationComponents needs // Otherwise injector generator is not smart enough to deduce, for example, which package fragment provider DeserializationComponents needs
@@ -39,7 +40,8 @@ class DeserializationComponentsForJava(
notFoundClasses: NotFoundClasses, notFoundClasses: NotFoundClasses,
errorReporter: ErrorReporter, errorReporter: ErrorReporter,
lookupTracker: LookupTracker, lookupTracker: LookupTracker,
contractDeserializer: ContractDeserializer contractDeserializer: ContractDeserializer,
kotlinTypeChecker: NewKotlinTypeChecker
) { ) {
val components: DeserializationComponents val components: DeserializationComponents
@@ -52,7 +54,8 @@ class DeserializationComponentsForJava(
emptyList(), notFoundClasses, contractDeserializer, emptyList(), notFoundClasses, contractDeserializer,
additionalClassPartsProvider = jvmBuiltIns?.settings ?: AdditionalClassPartsProvider.None, additionalClassPartsProvider = jvmBuiltIns?.settings ?: AdditionalClassPartsProvider.None,
platformDependentDeclarationFilter = jvmBuiltIns?.settings ?: PlatformDependentDeclarationFilter.NoPlatformDependent, platformDependentDeclarationFilter = jvmBuiltIns?.settings ?: PlatformDependentDeclarationFilter.NoPlatformDependent,
extensionRegistryLite = JvmProtoBufUtil.EXTENSION_REGISTRY extensionRegistryLite = JvmProtoBufUtil.EXTENSION_REGISTRY,
kotlinTypeChecker = kotlinTypeChecker
) )
} }
} }
@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.serialization.deserialization.ContractDeserializer
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
import org.jetbrains.kotlin.utils.Jsr305State import org.jetbrains.kotlin.utils.Jsr305State
class RuntimeModuleData private constructor( class RuntimeModuleData private constructor(
@@ -70,7 +71,7 @@ class RuntimeModuleData private constructor(
singleModuleClassResolver, PackagePartProvider.Empty, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING, module, singleModuleClassResolver, PackagePartProvider.Empty, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING, module,
ReflectionTypes(module, notFoundClasses), annotationTypeQualifierResolver, ReflectionTypes(module, notFoundClasses), annotationTypeQualifierResolver,
SignatureEnhancement(annotationTypeQualifierResolver, Jsr305State.DISABLED), SignatureEnhancement(annotationTypeQualifierResolver, Jsr305State.DISABLED),
JavaClassesTracker.Default, JavaResolverSettings.Default JavaClassesTracker.Default, JavaResolverSettings.Default, NewKotlinTypeChecker.Default
) )
val lazyJavaPackageFragmentProvider = LazyJavaPackageFragmentProvider(javaResolverComponents) val lazyJavaPackageFragmentProvider = LazyJavaPackageFragmentProvider(javaResolverComponents)
@@ -85,14 +86,14 @@ class RuntimeModuleData private constructor(
val deserializationComponentsForJava = DeserializationComponentsForJava( val deserializationComponentsForJava = DeserializationComponentsForJava(
storageManager, module, DeserializationConfiguration.Default, javaClassDataFinder, storageManager, module, DeserializationConfiguration.Default, javaClassDataFinder,
binaryClassAnnotationAndConstantLoader, lazyJavaPackageFragmentProvider, notFoundClasses, binaryClassAnnotationAndConstantLoader, lazyJavaPackageFragmentProvider, notFoundClasses,
RuntimeErrorReporter, LookupTracker.DO_NOTHING, ContractDeserializer.DEFAULT RuntimeErrorReporter, LookupTracker.DO_NOTHING, ContractDeserializer.DEFAULT, NewKotlinTypeChecker.Default
) )
// .kotlin_builtins files should be found by the same class loader that loaded stdlib classes // .kotlin_builtins files should be found by the same class loader that loaded stdlib classes
val stdlibClassLoader = Unit::class.java.classLoader val stdlibClassLoader = Unit::class.java.classLoader
val builtinsProvider = JvmBuiltInsPackageFragmentProvider( val builtinsProvider = JvmBuiltInsPackageFragmentProvider(
storageManager, ReflectKotlinClassFinder(stdlibClassLoader), module, notFoundClasses, builtIns.settings, builtIns.settings, storageManager, ReflectKotlinClassFinder(stdlibClassLoader), module, notFoundClasses, builtIns.settings, builtIns.settings,
DeserializationConfiguration.Default DeserializationConfiguration.Default, NewKotlinTypeChecker.Default
) )
singleModuleClassResolver.resolver = javaDescriptorResolver singleModuleClassResolver.resolver = javaDescriptorResolver
@@ -245,7 +245,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
) { ) {
final Set<D> result = new LinkedHashSet<D>(); final Set<D> result = new LinkedHashSet<D>();
OverridingUtil.generateOverridesInFunctionGroup( OverridingUtil.DEFAULT.generateOverridesInFunctionGroup(
name, fromSupertypes, Collections.<D>emptySet(), EnumEntrySyntheticClassDescriptor.this, name, fromSupertypes, Collections.<D>emptySet(), EnumEntrySyntheticClassDescriptor.this,
new NonReportingOverrideStrategy() { new NonReportingOverrideStrategy() {
@Override @Override
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.types.KotlinTypeKt;
import org.jetbrains.kotlin.types.TypeConstructor; import org.jetbrains.kotlin.types.TypeConstructor;
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
import org.jetbrains.kotlin.types.checker.KotlinTypeCheckerImpl; import org.jetbrains.kotlin.types.checker.KotlinTypeCheckerImpl;
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner;
import org.jetbrains.kotlin.utils.SmartSet; import org.jetbrains.kotlin.utils.SmartSet;
import java.util.*; import java.util.*;
@@ -49,22 +50,40 @@ public class OverridingUtil {
ExternalOverridabilityCondition.class.getClassLoader() ExternalOverridabilityCondition.class.getClassLoader()
)); ));
public static final OverridingUtil DEFAULT = new OverridingUtil(new KotlinTypeChecker.TypeConstructorEquality() { public static final OverridingUtil DEFAULT;
@Override
public boolean equals(@NotNull TypeConstructor a, @NotNull TypeConstructor b) { private static final KotlinTypeChecker.TypeConstructorEquality DEFAULT_TYPE_CONSTRUCTOR_EQUALITY =
return a.equals(b); new KotlinTypeChecker.TypeConstructorEquality() {
} @Override
}); public boolean equals(@NotNull TypeConstructor a, @NotNull TypeConstructor b) {
return a.equals(b);
}
};
static {
DEFAULT = new OverridingUtil(DEFAULT_TYPE_CONSTRUCTOR_EQUALITY, KotlinTypeRefiner.Default.INSTANCE);
}
@NotNull @NotNull
public static OverridingUtil createWithEqualityAxioms(@NotNull KotlinTypeChecker.TypeConstructorEquality equalityAxioms) { public static OverridingUtil createWithEqualityAxioms(@NotNull KotlinTypeChecker.TypeConstructorEquality equalityAxioms) {
return new OverridingUtil(equalityAxioms); return new OverridingUtil(equalityAxioms, KotlinTypeRefiner.Default.INSTANCE);
} }
@NotNull
public static OverridingUtil createWithTypeRefiner(@NotNull KotlinTypeRefiner kotlinTypeRefiner) {
return new OverridingUtil(DEFAULT_TYPE_CONSTRUCTOR_EQUALITY, kotlinTypeRefiner);
}
private final KotlinTypeRefiner kotlinTypeRefiner;
private final KotlinTypeChecker.TypeConstructorEquality equalityAxioms; private final KotlinTypeChecker.TypeConstructorEquality equalityAxioms;
private OverridingUtil(KotlinTypeChecker.TypeConstructorEquality axioms) { private OverridingUtil(
@NotNull KotlinTypeChecker.TypeConstructorEquality axioms,
@NotNull KotlinTypeRefiner kotlinTypeRefiner
) {
equalityAxioms = axioms; equalityAxioms = axioms;
this.kotlinTypeRefiner = kotlinTypeRefiner;
} }
/** /**
@@ -279,7 +298,12 @@ public class OverridingUtil {
if (superReturnType != null && subReturnType != null) { if (superReturnType != null && subReturnType != null) {
boolean bothErrors = KotlinTypeKt.isError(subReturnType) && KotlinTypeKt.isError(superReturnType); boolean bothErrors = KotlinTypeKt.isError(subReturnType) && KotlinTypeKt.isError(superReturnType);
if (!bothErrors && !typeChecker.isSubtypeOf(subReturnType, superReturnType)) { if (!bothErrors &&
!typeChecker.isSubtypeOf(
kotlinTypeRefiner.refineType(subReturnType),
kotlinTypeRefiner.refineType(superReturnType)
)
) {
return OverrideCompatibilityInfo.conflict("Return type mismatch"); return OverrideCompatibilityInfo.conflict("Return type mismatch");
} }
} }
@@ -356,18 +380,19 @@ public class OverridingUtil {
return null; return null;
} }
private static boolean areTypesEquivalent( private boolean areTypesEquivalent(
@NotNull KotlinType typeInSuper, @NotNull KotlinType typeInSuper,
@NotNull KotlinType typeInSub, @NotNull KotlinType typeInSub,
@NotNull KotlinTypeChecker typeChecker @NotNull KotlinTypeChecker typeChecker
) { ) {
boolean bothErrors = KotlinTypeKt.isError(typeInSuper) && KotlinTypeKt.isError(typeInSub); boolean bothErrors = KotlinTypeKt.isError(typeInSuper) && KotlinTypeKt.isError(typeInSub);
return bothErrors || typeChecker.equalTypes(typeInSuper, typeInSub); if (bothErrors) return true;
return typeChecker.equalTypes(kotlinTypeRefiner.refineType(typeInSuper), kotlinTypeRefiner.refineType(typeInSub));
} }
// See JLS 8, 8.4.4 Generic Methods // See JLS 8, 8.4.4 Generic Methods
// TODO: use TypeSubstitutor instead // TODO: use TypeSubstitutor instead
private static boolean areTypeParametersEquivalent( private boolean areTypeParametersEquivalent(
@NotNull TypeParameterDescriptor superTypeParameter, @NotNull TypeParameterDescriptor superTypeParameter,
@NotNull TypeParameterDescriptor subTypeParameter, @NotNull TypeParameterDescriptor subTypeParameter,
@NotNull KotlinTypeChecker typeChecker @NotNull KotlinTypeChecker typeChecker
@@ -404,7 +429,7 @@ public class OverridingUtil {
return parameters; return parameters;
} }
public static void generateOverridesInFunctionGroup( public void generateOverridesInFunctionGroup(
@SuppressWarnings("UnusedParameters") @SuppressWarnings("UnusedParameters")
@NotNull Name name, //DO NOT DELETE THIS PARAMETER: needed to make sure all descriptors have the same name @NotNull Name name, //DO NOT DELETE THIS PARAMETER: needed to make sure all descriptors have the same name
@NotNull Collection<? extends CallableMemberDescriptor> membersFromSupertypes, @NotNull Collection<? extends CallableMemberDescriptor> membersFromSupertypes,
@@ -428,7 +453,7 @@ public class OverridingUtil {
Visibilities.isVisibleIgnoringReceiver(fromSuper, overriding); Visibilities.isVisibleIgnoringReceiver(fromSuper, overriding);
} }
private static Collection<CallableMemberDescriptor> extractAndBindOverridesForMember( private Collection<CallableMemberDescriptor> extractAndBindOverridesForMember(
@NotNull CallableMemberDescriptor fromCurrent, @NotNull CallableMemberDescriptor fromCurrent,
@NotNull Collection<? extends CallableMemberDescriptor> descriptorsFromSuper, @NotNull Collection<? extends CallableMemberDescriptor> descriptorsFromSuper,
@NotNull ClassDescriptor current, @NotNull ClassDescriptor current,
@@ -437,7 +462,7 @@ public class OverridingUtil {
Collection<CallableMemberDescriptor> bound = new ArrayList<CallableMemberDescriptor>(descriptorsFromSuper.size()); Collection<CallableMemberDescriptor> bound = new ArrayList<CallableMemberDescriptor>(descriptorsFromSuper.size());
Collection<CallableMemberDescriptor> overridden = SmartSet.create(); Collection<CallableMemberDescriptor> overridden = SmartSet.create();
for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) { for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) {
OverrideCompatibilityInfo.Result result = DEFAULT.isOverridableBy(fromSupertype, fromCurrent, current).getResult(); OverrideCompatibilityInfo.Result result = isOverridableBy(fromSupertype, fromCurrent, current).getResult();
boolean isVisibleForOverride = isVisibleForOverride(fromCurrent, fromSupertype); boolean isVisibleForOverride = isVisibleForOverride(fromCurrent, fromSupertype);
@@ -61,7 +61,7 @@ abstract class GivenFunctionsMemberScope(
.filterIsInstance<CallableMemberDescriptor>() .filterIsInstance<CallableMemberDescriptor>()
for ((name, group) in allSuperDescriptors.groupBy { it.name }) { for ((name, group) in allSuperDescriptors.groupBy { it.name }) {
for ((isFunction, descriptors) in group.groupBy { it is FunctionDescriptor }) { for ((isFunction, descriptors) in group.groupBy { it is FunctionDescriptor }) {
OverridingUtil.generateOverridesInFunctionGroup( OverridingUtil.DEFAULT.generateOverridesInFunctionGroup(
name, name,
/* membersFromSupertypes = */ descriptors, /* membersFromSupertypes = */ descriptors,
/* membersFromCurrent = */ if (isFunction) functionsFromCurrent.filter { it.name == name } else listOf(), /* membersFromCurrent = */ if (isFunction) functionsFromCurrent.filter { it.name == name } else listOf(),
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.types.checker
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructorImpl import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructorImpl
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
@@ -57,6 +58,7 @@ object ErrorTypesAreEqualToAnything : KotlinTypeChecker {
interface NewKotlinTypeChecker : KotlinTypeChecker { interface NewKotlinTypeChecker : KotlinTypeChecker {
val kotlinTypeRefiner: KotlinTypeRefiner val kotlinTypeRefiner: KotlinTypeRefiner
val overridingUtil: OverridingUtil
fun transformToNewType(type: UnwrappedType): UnwrappedType fun transformToNewType(type: UnwrappedType): UnwrappedType
@@ -67,6 +69,7 @@ interface NewKotlinTypeChecker : KotlinTypeChecker {
class NewKotlinTypeCheckerImpl(override val kotlinTypeRefiner: KotlinTypeRefiner) : NewKotlinTypeChecker { class NewKotlinTypeCheckerImpl(override val kotlinTypeRefiner: KotlinTypeRefiner) : NewKotlinTypeChecker {
override val overridingUtil: OverridingUtil = OverridingUtil.createWithTypeRefiner(kotlinTypeRefiner)
override fun isSubtypeOf(subtype: KotlinType, supertype: KotlinType): Boolean = override fun isSubtypeOf(subtype: KotlinType, supertype: KotlinType): Boolean =
ClassicTypeCheckerContext(true, kotlinTypeRefiner = kotlinTypeRefiner) ClassicTypeCheckerContext(true, kotlinTypeRefiner = kotlinTypeRefiner)
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
import java.io.InputStream import java.io.InputStream
class MetadataPackageFragmentProvider( class MetadataPackageFragmentProvider(
@@ -41,7 +42,8 @@ class MetadataPackageFragmentProvider(
moduleDescriptor: ModuleDescriptor, moduleDescriptor: ModuleDescriptor,
notFoundClasses: NotFoundClasses, notFoundClasses: NotFoundClasses,
private val metadataPartProvider: MetadataPartProvider, private val metadataPartProvider: MetadataPartProvider,
contractDeserializer: ContractDeserializer contractDeserializer: ContractDeserializer,
kotlinTypeChecker: NewKotlinTypeChecker
) : AbstractDeserializedPackageFragmentProvider(storageManager, finder, moduleDescriptor) { ) : AbstractDeserializedPackageFragmentProvider(storageManager, finder, moduleDescriptor) {
init { init {
components = DeserializationComponents( components = DeserializationComponents(
@@ -59,7 +61,8 @@ class MetadataPackageFragmentProvider(
notFoundClasses, notFoundClasses,
contractDeserializer, contractDeserializer,
AdditionalClassPartsProvider.None, PlatformDependentDeclarationFilter.All, AdditionalClassPartsProvider.None, PlatformDependentDeclarationFilter.All,
BuiltInSerializerProtocol.extensionRegistry BuiltInSerializerProtocol.extensionRegistry,
kotlinTypeChecker
) )
} }
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
class DeserializationComponents( class DeserializationComponents(
val storageManager: StorageManager, val storageManager: StorageManager,
@@ -46,7 +47,8 @@ class DeserializationComponents(
val contractDeserializer: ContractDeserializer, val contractDeserializer: ContractDeserializer,
val additionalClassPartsProvider: AdditionalClassPartsProvider = AdditionalClassPartsProvider.None, val additionalClassPartsProvider: AdditionalClassPartsProvider = AdditionalClassPartsProvider.None,
val platformDependentDeclarationFilter: PlatformDependentDeclarationFilter = PlatformDependentDeclarationFilter.All, val platformDependentDeclarationFilter: PlatformDependentDeclarationFilter = PlatformDependentDeclarationFilter.All,
val extensionRegistryLite: ExtensionRegistryLite val extensionRegistryLite: ExtensionRegistryLite,
val kotlinTypeChecker: NewKotlinTypeChecker = NewKotlinTypeChecker.Default
) { ) {
val classDeserializer: ClassDeserializer = ClassDeserializer(this) val classDeserializer: ClassDeserializer = ClassDeserializer(this)
@@ -264,7 +264,7 @@ class DeserializedClassDescriptor(
result: MutableCollection<D> result: MutableCollection<D>
) { ) {
val fromCurrent = ArrayList<CallableMemberDescriptor>(result) val fromCurrent = ArrayList<CallableMemberDescriptor>(result)
OverridingUtil.generateOverridesInFunctionGroup( c.components.kotlinTypeChecker.overridingUtil.generateOverridesInFunctionGroup(
name, name,
fromSupertypes, fromSupertypes,
fromCurrent, fromCurrent,
@@ -7,4 +7,8 @@ expect interface BaseI {
fun f(p: Upper) fun f(p: Upper)
} }
interface I : BaseI interface Base2 {
fun foo(p: Upper)
}
interface I : BaseI
@@ -7,7 +7,9 @@ actual interface BaseI {
actual fun f(p: Upper) actual fun f(p: Upper)
} }
internal class Impl : I { internal class Impl : I, Base2 {
override fun f(p: Upper) { override fun f(p: Upper) {
} }
}
override fun foo(p: Upper) {}
}