diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt index f17a0fdff53..4b814ca32f0 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt @@ -41,10 +41,8 @@ import org.jetbrains.kotlin.load.kotlin.DeserializationComponentsForJava import org.jetbrains.kotlin.load.kotlin.PackagePartProvider import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory import org.jetbrains.kotlin.platform.TargetPlatform -import org.jetbrains.kotlin.resolve.BindingTrace -import org.jetbrains.kotlin.resolve.TargetEnvironment +import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.calls.tower.ImplicitsExtensionsResolutionFilter -import org.jetbrains.kotlin.resolve.createContainer import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver import org.jetbrains.kotlin.resolve.jvm.JvmDiagnosticComponents import org.jetbrains.kotlin.resolve.jvm.multiplatform.OptionalAnnotationPackageFragmentProvider @@ -68,8 +66,12 @@ fun createContainerForLazyResolveWithJava( configureJavaClassFinder: (StorageComponentContainer.() -> Unit)? = null, javaClassTracker: JavaClassesTracker? = null, implicitsResolutionFilter: ImplicitsExtensionsResolutionFilter? = null, + sealedInheritorsProvider: SealedClassInheritorsProvider = CliSealedClassInheritorsProvider ): StorageComponentContainer = createContainer("LazyResolveWithJava", JvmPlatformAnalyzerServices) { - configureModule(moduleContext, jvmPlatform, JvmPlatformAnalyzerServices, bindingTrace, languageVersionSettings) + configureModule( + moduleContext, jvmPlatform, JvmPlatformAnalyzerServices, bindingTrace, languageVersionSettings, + sealedInheritorsProvider + ) configureIncrementalCompilation(lookupTracker, expectActualTracker) configureStandardResolveComponents() diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmResolverForModuleFactory.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmResolverForModuleFactory.kt index 1879fa01bf2..531b53b7e27 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmResolverForModuleFactory.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmResolverForModuleFactory.kt @@ -31,6 +31,7 @@ import org.jetbrains.kotlin.load.kotlin.PackagePartProvider import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer import org.jetbrains.kotlin.platform.TargetPlatform +import org.jetbrains.kotlin.resolve.SealedClassInheritorsProvider import org.jetbrains.kotlin.resolve.TargetEnvironment import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension import org.jetbrains.kotlin.resolve.lazy.ResolveSession @@ -54,7 +55,8 @@ class JvmResolverForModuleFactory( moduleContext: ModuleContext, moduleContent: ModuleContent, resolverForProject: ResolverForProject, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + sealedInheritorsProvider: SealedClassInheritorsProvider ): ResolverForModule { val (moduleInfo, syntheticFiles, moduleContentScope) = moduleContent val project = moduleContext.project @@ -108,6 +110,7 @@ class JvmResolverForModuleFactory( ExpectActualTracker.DoNothing, packagePartProvider, languageVersionSettings, + sealedInheritorsProvider = sealedInheritorsProvider, useBuiltInsProvider = false // TODO: load built-ins from module dependencies in IDE ) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt index 5dbdf8f0090..9c7f9e7ec19 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt @@ -32,6 +32,8 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.TargetPlatformVersion import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.resolve.SealedClassInheritorsProvider +import org.jetbrains.kotlin.resolve.CliSealedClassInheritorsProvider import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.getValue import java.util.* @@ -119,7 +121,8 @@ abstract class ResolverForModuleFactory { moduleContext: ModuleContext, moduleContent: ModuleContent, resolverForProject: ResolverForProject, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + sealedInheritorsProvider: SealedClassInheritorsProvider = CliSealedClassInheritorsProvider ): ResolverForModule } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonResolverForModuleFactory.kt b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonResolverForModuleFactory.kt index baf857079c6..c567395a529 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonResolverForModuleFactory.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonResolverForModuleFactory.kt @@ -85,7 +85,8 @@ class CommonResolverForModuleFactory( moduleContext: ModuleContext, moduleContent: ModuleContent, resolverForProject: ResolverForProject, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + sealedInheritorsProvider: SealedClassInheritorsProvider ): ResolverForModule { val (moduleInfo, syntheticFiles, moduleContentScope) = moduleContent val project = moduleContext.project diff --git a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt index 33f1f8e84ba..db014953858 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt @@ -51,8 +51,10 @@ fun StorageComponentContainer.configureModule( platform: TargetPlatform, analyzerServices: PlatformDependentAnalyzerServices, trace: BindingTrace, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + sealedProvider: SealedClassInheritorsProvider = CliSealedClassInheritorsProvider ) { + useInstance(sealedProvider) useInstance(moduleContext) useInstance(moduleContext.module) useInstance(moduleContext.project) @@ -103,7 +105,6 @@ private fun StorageComponentContainer.configurePlatformIndependentComponents() { useImpl() useImpl() useInstance(ProgressManagerBasedCancellationChecker) - useInstance(SealedClassInheritorsProviderImpl) } /** diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/SealedClassInheritorsProvider.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/SealedClassInheritorsProvider.kt index 0927584612e..253e165ebd5 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/SealedClassInheritorsProvider.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/SealedClassInheritorsProvider.kt @@ -18,17 +18,17 @@ abstract class SealedClassInheritorsProvider { */ abstract fun computeSealedSubclasses( sealedClass: ClassDescriptor, - freedomForSealedInterfacesSupported: Boolean + allowSealedInheritorsInDifferentFilesOfSamePackage: Boolean ): Collection } -object SealedClassInheritorsProviderImpl : SealedClassInheritorsProvider() { +object CliSealedClassInheritorsProvider : SealedClassInheritorsProvider() { // Note this is a generic and slow implementation which would work almost for any subclass of ClassDescriptor. // Please avoid using it in new code. // TODO: do something more clever instead at call sites of this function override fun computeSealedSubclasses( sealedClass: ClassDescriptor, - freedomForSealedInterfacesSupported: Boolean + allowSealedInheritorsInDifferentFilesOfSamePackage: Boolean ): Collection { if (sealedClass.modality != Modality.SEALED) return emptyList() @@ -48,7 +48,7 @@ object SealedClassInheritorsProviderImpl : SealedClassInheritorsProvider() { } } - val container = if (!freedomForSealedInterfacesSupported) { + val container = if (!allowSealedInheritorsInDifferentFilesOfSamePackage) { sealedClass.containingDeclaration } else { sealedClass.parents.firstOrNull { it is PackageFragmentDescriptor } @@ -56,7 +56,7 @@ object SealedClassInheritorsProviderImpl : SealedClassInheritorsProvider() { if (container is PackageFragmentDescriptor) { collectSubclasses( container.getMemberScope(), - collectNested = freedomForSealedInterfacesSupported + collectNested = allowSealedInheritorsInDifferentFilesOfSamePackage ) } collectSubclasses(sealedClass.unsubstitutedInnerClassesScope, collectNested = true) diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index bb29c10df39..1f9be75662b 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -18,7 +18,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorFactory import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy import org.jetbrains.kotlin.resolve.OverridingUtil -import org.jetbrains.kotlin.resolve.SealedClassInheritorsProviderImpl +import org.jetbrains.kotlin.resolve.CliSealedClassInheritorsProvider import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -165,7 +165,7 @@ class DeserializedClassDescriptor( } // This is needed because classes compiled with Kotlin 1.0 did not contain the sealed_subclass_fq_name field - return SealedClassInheritorsProviderImpl.computeSealedSubclasses(this, freedomForSealedInterfacesSupported = false) + return CliSealedClassInheritorsProvider.computeSealedSubclasses(this, allowSealedInheritorsInDifferentFilesOfSamePackage = false) } override fun getSealedSubclasses() = sealedSubclasses() diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/CompositeResolverForModuleFactory.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/CompositeResolverForModuleFactory.kt index 7b9f2e11be7..18104ec0db3 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/CompositeResolverForModuleFactory.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/CompositeResolverForModuleFactory.kt @@ -56,7 +56,8 @@ class CompositeResolverForModuleFactory( moduleContext: ModuleContext, moduleContent: ModuleContent, resolverForProject: ResolverForProject, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + sealedInheritorsProvider: SealedClassInheritorsProvider ): ResolverForModule { val (moduleInfo, syntheticFiles, moduleContentScope) = moduleContent val project = moduleContext.project @@ -178,7 +179,7 @@ class CompositeResolverForModuleFactory( } // Called by all normal containers set-ups - configureModule(moduleContext, targetPlatform, analyzerServices, trace, languageVersionSettings) + configureModule(moduleContext, targetPlatform, analyzerServices, trace, languageVersionSettings,) configureStandardResolveComponents() useInstance(moduleContentScope) useInstance(declarationProviderFactory) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/JsResolverForModuleFactory.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/JsResolverForModuleFactory.kt index 52de11d0adc..07ea2de2312 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/JsResolverForModuleFactory.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/JsResolverForModuleFactory.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices import org.jetbrains.kotlin.platform.idePlatformKind import org.jetbrains.kotlin.platform.js.JsPlatforms import org.jetbrains.kotlin.resolve.BindingTraceContext +import org.jetbrains.kotlin.resolve.SealedClassInheritorsProvider import org.jetbrains.kotlin.resolve.TargetEnvironment import org.jetbrains.kotlin.resolve.lazy.ResolveSession import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService @@ -38,7 +39,8 @@ class JsResolverForModuleFactory( moduleContext: ModuleContext, moduleContent: ModuleContent, resolverForProject: ResolverForProject, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + sealedInheritorsProvider: SealedClassInheritorsProvider ): ResolverForModule { val (moduleInfo, syntheticFiles, moduleContentScope) = moduleContent val project = moduleContext.project diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt index 6018b0533c4..a6d6c3ea69b 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo import org.jetbrains.kotlin.idea.caches.project.getNullableModuleInfo import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider import org.jetbrains.kotlin.idea.project.IdeaEnvironment +import org.jetbrains.kotlin.idea.compiler.IdeSealedClassInheritorsProvider import org.jetbrains.kotlin.idea.project.findAnalyzerServices import org.jetbrains.kotlin.idea.project.useCompositeAnalysis import org.jetbrains.kotlin.load.java.structure.JavaClass @@ -83,7 +84,8 @@ class IdeaResolverForProject( projectContext.withModule(descriptor), moduleContent, this, - languageVersionSettings + languageVersionSettings, + sealedInheritorsProvider = IdeSealedClassInheritorsProvider ) } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IdeSealedClassInheritorsProvider.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IdeSealedClassInheritorsProvider.kt new file mode 100644 index 00000000000..7f0268cd7c8 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IdeSealedClassInheritorsProvider.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.compiler + +import com.intellij.psi.* +import com.intellij.psi.search.* +import com.intellij.psi.search.searches.ClassInheritorsSearch +import com.intellij.psi.search.searches.ClassInheritorsSearch.SearchParameters +import org.jetbrains.kotlin.asJava.toLightClass +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.containingPackage +import org.jetbrains.kotlin.idea.caches.resolve.util.javaResolutionFacade +import org.jetbrains.kotlin.idea.caches.resolve.util.resolveToDescriptor +import org.jetbrains.kotlin.idea.util.module +import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi +import org.jetbrains.kotlin.psi.KtClass +import org.jetbrains.kotlin.resolve.SealedClassInheritorsProvider + +object IdeSealedClassInheritorsProvider : SealedClassInheritorsProvider() { + + override fun computeSealedSubclasses( + sealedClass: ClassDescriptor, + allowSealedInheritorsInDifferentFilesOfSamePackage: Boolean + ): Collection { + + val sealedKtClass = sealedClass.findPsi() as? KtClass ?: return emptyList() + val searchScope: SearchScope = if (allowSealedInheritorsInDifferentFilesOfSamePackage) { + val module = sealedKtClass.module ?: return emptyList() + val moduleSourceScope = GlobalSearchScope.moduleScope(module) + val containingPackage = sealedClass.containingPackage() ?: return emptyList() + val psiPackage = JavaDirectoryService.getInstance().getPackage(sealedKtClass.containingFile.containingDirectory) + ?: JavaPsiFacade.getInstance(sealedKtClass.project).findPackage(containingPackage.asString()) + ?: return emptyList() + val packageScope = PackageScope(psiPackage, false, false) + moduleSourceScope.intersectWith(packageScope) + } else { + GlobalSearchScope.fileScope(sealedKtClass.containingFile) // Kotlin version prior to 1.5 + } + + val lightClass = sealedKtClass.toLightClass() ?: return emptyList() + val searchParameters = SearchParameters(lightClass, searchScope, false, true, false) + + return ClassInheritorsSearch.search(searchParameters) + .map mapper@{ + val resolutionFacade = it.javaResolutionFacade() ?: return@mapper null + it.resolveToDescriptor(resolutionFacade) + }.filterNotNull() + .sortedBy(ClassDescriptor::getName) // order needs to be stable (at least for tests) + } +} \ No newline at end of file diff --git a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/analyzer/NativeResolverForModuleFactory.kt b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/analyzer/NativeResolverForModuleFactory.kt index 0d7200cceb8..65bdd545d39 100644 --- a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/analyzer/NativeResolverForModuleFactory.kt +++ b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/analyzer/NativeResolverForModuleFactory.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.idePlatformKind import org.jetbrains.kotlin.platform.konan.NativePlatforms import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer +import org.jetbrains.kotlin.resolve.SealedClassInheritorsProvider import org.jetbrains.kotlin.resolve.TargetEnvironment import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices import org.jetbrains.kotlin.resolve.lazy.ResolveSession @@ -32,7 +33,8 @@ class NativeResolverForModuleFactory( moduleContext: ModuleContext, moduleContent: ModuleContent, resolverForProject: ResolverForProject, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + sealedInheritorsProvider: SealedClassInheritorsProvider ): ResolverForModule { val declarationProviderFactory = createDeclarationProviderFactory( diff --git a/idea/testData/checker/sealed/SealedDeclaration.kt b/idea/testData/checker/sealed/SealedDeclaration.kt new file mode 100644 index 00000000000..f56775bc907 --- /dev/null +++ b/idea/testData/checker/sealed/SealedDeclaration.kt @@ -0,0 +1,14 @@ +// COMPILER_ARGUMENTS: -XXLanguage:+SealedInterfaces -XXLanguage:+FreedomForSealedClasses + +package sealed + +sealed class SealedDeclarationClass { + class AClass: SealedDeclarationClass() +} + +sealed interface SealedDeclarationInterface { + class A: SealedDeclarationInterface +} + +class B: SealedDeclarationInterface +class BClass: SealedDeclarationClass() \ No newline at end of file diff --git a/idea/testData/checker/sealed/SealedInheritors.kt b/idea/testData/checker/sealed/SealedInheritors.kt new file mode 100644 index 00000000000..3b399c28141 --- /dev/null +++ b/idea/testData/checker/sealed/SealedInheritors.kt @@ -0,0 +1,35 @@ +// COMPILER_ARGUMENTS: -XXLanguage:+SealedInterfaces -XXLanguage:+FreedomForSealedClasses +package sealed + +class C: SealedDeclarationInterface {} +class CClass: SealedDeclarationClass() {} + +class D: SealedDeclarationInterface { + class E: SealedDeclarationInterface { + class F: SealedDeclarationInterface + } +} + +class DClass: SealedDeclarationClass() { + class EClass: SealedDeclarationClass() { + class FClass: SealedDeclarationClass() + } +} + +fun checkWhenNone(value: SealedDeclarationInterface): Int = when (value) { +} + +fun checkWhenNone(value: SealedDeclarationClass): Int = when (value) { +} + +fun checkWhenOneMissing(value: SealedDeclarationInterface): Int = when (value) { + is SealedDeclarationInterface.A -> 1 + is B -> 2 + is C -> 3 +} + +fun checkWhenOneMissing(value: SealedDeclarationClass): Int = when (value) { + is SealedDeclarationClass.AClass -> 1 + is BClass -> 2 + is CClass -> 3 +} \ No newline at end of file diff --git a/idea/testData/checker/sealed/SealedOutsidePackageInheritors.kt b/idea/testData/checker/sealed/SealedOutsidePackageInheritors.kt new file mode 100644 index 00000000000..8a8913fd11f --- /dev/null +++ b/idea/testData/checker/sealed/SealedOutsidePackageInheritors.kt @@ -0,0 +1,7 @@ +// COMPILER_ARGUMENTS: -XXLanguage:+SealedInterfaces -XXLanguage:+FreedomForSealedClasses +package sealed.otherpackage +import sealed.SealedDeclarationInterface +import sealed.SealedDeclarationClass + +class D: SealedDeclarationInterface +class DClass: SealedDeclarationClass() \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/checkers/PsiCheckerSealedTest.kt b/idea/tests/org/jetbrains/kotlin/checkers/PsiCheckerSealedTest.kt new file mode 100644 index 00000000000..594fda3e8a1 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/checkers/PsiCheckerSealedTest.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.checkers + +import com.intellij.testFramework.LightProjectDescriptor +import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner +import org.jetbrains.kotlin.test.TestMetadata +import org.junit.runner.RunWith + +@TestMetadata("idea/testData/checker/sealed") +@RunWith(JUnit3WithIdeaConfigurationRunner::class) +class PsiCheckerSealedTest : AbstractPsiCheckerTest() { + + fun testOutsideOfPackageInheritors() { + doTest( + "SealedOutsidePackageInheritors.kt", // opened in the test editor + "SealedDeclaration.kt" + ) + } + + fun testWhenExhaustiveness() { + doTest( + "SealedInheritors.kt", // opened in the test editor + "SealedDeclaration.kt" + ) + } + + override fun getProjectDescriptor(): LightProjectDescriptor = getProjectDescriptorFromTestName() +} \ No newline at end of file diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedClassDescriptor.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedClassDescriptor.kt index 3404c4cd519..cc1fd67a432 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedClassDescriptor.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedClassDescriptor.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.builder -import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType @@ -15,7 +14,7 @@ import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorFactory.createPrimaryConstructorForObject -import org.jetbrains.kotlin.resolve.SealedClassInheritorsProviderImpl +import org.jetbrains.kotlin.resolve.CliSealedClassInheritorsProvider import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum @@ -55,7 +54,7 @@ class CommonizedClassDescriptor( private val sealedSubclasses = targetComponents.storageManager.createLazyValue { // TODO: pass proper language version settings if (modality == Modality.SEALED) { - SealedClassInheritorsProviderImpl.computeSealedSubclasses(this, freedomForSealedInterfacesSupported = false) + CliSealedClassInheritorsProvider.computeSealedSubclasses(this, allowSealedInheritorsInDifferentFilesOfSamePackage = false) } else { emptyList() }