[FIR] Support sealed class inheritors in multiple files
This commit is contained in:
+1
-1
@@ -29,7 +29,7 @@ sealed class P {
|
|||||||
class K : P()
|
class K : P()
|
||||||
|
|
||||||
<!REDECLARATION!>object B<!> {
|
<!REDECLARATION!>object B<!> {
|
||||||
class I : <!SEALED_SUPERTYPE!>P<!>()
|
class I : P()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
|
|||||||
+8
-35
@@ -20,26 +20,18 @@ object FirSealedSupertypeChecker : FirMemberDeclarationChecker() {
|
|||||||
override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
if (declaration is FirClass<*>) {
|
if (declaration is FirClass<*>) {
|
||||||
// only the file declaration is present
|
// only the file declaration is present
|
||||||
when {
|
if (declaration.classId.isLocal) {
|
||||||
context.containingDeclarations.size == 1 -> {
|
checkLocalDeclaration(declaration, context, reporter)
|
||||||
checkTopLevelDeclaration(declaration, context, reporter)
|
} else {
|
||||||
}
|
checkGlobalDeclaration(declaration, context, reporter)
|
||||||
declaration.classId.isLocal -> {
|
|
||||||
checkLocalDeclaration(declaration, context, reporter)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
checkInnerDeclaration(declaration, context, reporter)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (declaration is FirProperty) {
|
} else if (declaration is FirProperty) {
|
||||||
val initializer = declaration.initializer.safeAs<FirClass<*>>()
|
val initializer = declaration.initializer.safeAs<FirClass<*>>() ?: return
|
||||||
?: return
|
|
||||||
|
|
||||||
checkLocalDeclaration(initializer, context, reporter)
|
checkLocalDeclaration(initializer, context, reporter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkTopLevelDeclaration(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
private fun checkGlobalDeclaration(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
for (it in declaration.superTypeRefs) {
|
for (it in declaration.superTypeRefs) {
|
||||||
val classId = it.coneType.classId ?: continue
|
val classId = it.coneType.classId ?: continue
|
||||||
|
|
||||||
@@ -51,9 +43,9 @@ object FirSealedSupertypeChecker : FirMemberDeclarationChecker() {
|
|||||||
?.fir.safeAs<FirRegularClass>()
|
?.fir.safeAs<FirRegularClass>()
|
||||||
?: continue
|
?: continue
|
||||||
|
|
||||||
if (fir.status.modality == Modality.SEALED && classId.outerClassId != null) {
|
if (fir.status.modality == Modality.SEALED && declaration.classId.packageFqName != fir.classId.packageFqName) {
|
||||||
reporter.reportOn(it.source, FirErrors.SEALED_SUPERTYPE, context)
|
reporter.reportOn(it.source, FirErrors.SEALED_SUPERTYPE, context)
|
||||||
return
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,23 +68,4 @@ object FirSealedSupertypeChecker : FirMemberDeclarationChecker() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkInnerDeclaration(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
|
||||||
for (it in declaration.superTypeRefs) {
|
|
||||||
val classId = it.coneType.classId ?: continue
|
|
||||||
|
|
||||||
if (classId.isLocal) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
val fir = context.session.symbolProvider.getClassLikeSymbolByFqName(classId)
|
|
||||||
?.fir.safeAs<FirRegularClass>()
|
|
||||||
?: continue
|
|
||||||
|
|
||||||
if (fir.status.modality == Modality.SEALED && !context.containingDeclarations.contains(fir)) {
|
|
||||||
reporter.reportOn(it.source, FirErrors.SEALED_SUPERTYPE, context)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,17 +65,24 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
Visibilities.Private, Visibilities.PrivateToThis -> {
|
Visibilities.Private, Visibilities.PrivateToThis -> {
|
||||||
val ownerId = symbol.getOwnerId()
|
val ownerId = symbol.getOwnerId()
|
||||||
if (declaration.session == session) {
|
if (declaration.session == session) {
|
||||||
if (ownerId == null || declaration is FirConstructor && declaration.isFromSealedClass) {
|
when {
|
||||||
val candidateFile = when (symbol) {
|
ownerId == null -> {
|
||||||
is FirClassLikeSymbol<*> -> provider.getFirClassifierContainerFileIfAny(symbol)
|
val candidateFile = when (symbol) {
|
||||||
is FirCallableSymbol<*> -> provider.getFirCallableContainerFile(symbol)
|
is FirClassLikeSymbol<*> -> provider.getFirClassifierContainerFileIfAny(symbol)
|
||||||
else -> null
|
is FirCallableSymbol<*> -> provider.getFirCallableContainerFile(symbol)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
// Top-level: visible in file
|
||||||
|
candidateFile == useSiteFile
|
||||||
|
}
|
||||||
|
declaration is FirConstructor && declaration.isFromSealedClass -> {
|
||||||
|
// Sealed class constructor: visible in same package
|
||||||
|
declaration.symbol.callableId.packageName == useSiteFile.packageFqName
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// Member: visible inside parent class, including all its member classes
|
||||||
|
canSeePrivateMemberOf(containingDeclarations, ownerId, session)
|
||||||
}
|
}
|
||||||
// Top-level: visible in file
|
|
||||||
candidateFile == useSiteFile
|
|
||||||
} else {
|
|
||||||
// Member: visible inside parent class, including all its member classes
|
|
||||||
canSeePrivateMemberOf(containingDeclarations, ownerId, session)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
declaration is FirSimpleFunction && declaration.isAllowedToBeAccessedFromOutside()
|
declaration is FirSimpleFunction && declaration.isAllowedToBeAccessedFromOutside()
|
||||||
|
|||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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.fir.resolve.transformers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.compose
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This processor is needed only for IDE until there won't be proper IDE implementation
|
||||||
|
* for detecting sealed inheritors in multiple files
|
||||||
|
*/
|
||||||
|
class FirLegacySealedClassInheritorsProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(session, scopeSession) {
|
||||||
|
override val transformer = FirLegacySealedClassInheritorsTransformer()
|
||||||
|
}
|
||||||
|
|
||||||
|
class FirLegacySealedClassInheritorsTransformer : FirTransformer<Nothing?>() {
|
||||||
|
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||||
|
throw IllegalStateException("Should not be there")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
||||||
|
val sealedClassInheritorsMap = mutableMapOf<FirRegularClass, MutableList<ClassId>>()
|
||||||
|
file.accept(FirSealedClassInheritorsProcessor.InheritorsCollector, sealedClassInheritorsMap)
|
||||||
|
if (sealedClassInheritorsMap.isEmpty()) return file.compose()
|
||||||
|
return file.transform(FirSealedClassInheritorsProcessor.InheritorsTransformer(sealedClassInheritorsMap), null)
|
||||||
|
}
|
||||||
|
}
|
||||||
+52
-57
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2021 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.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -11,38 +11,69 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
|
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType
|
import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
import org.jetbrains.kotlin.fir.visitors.*
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
|
||||||
import org.jetbrains.kotlin.fir.visitors.compose
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
class FirSealedClassInheritorsProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(session, scopeSession) {
|
class FirSealedClassInheritorsProcessor(
|
||||||
override val transformer = FirSealedClassInheritorsTransformer()
|
session: FirSession,
|
||||||
}
|
scopeSession: ScopeSession
|
||||||
|
) : FirGlobalResolveProcessor(session, scopeSession) {
|
||||||
class FirSealedClassInheritorsTransformer : FirTransformer<Nothing?>() {
|
override fun process(files: Collection<FirFile>) {
|
||||||
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
|
||||||
throw IllegalStateException("Should not be there")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
|
||||||
val sealedClassInheritorsMap = mutableMapOf<FirRegularClass, MutableList<ClassId>>()
|
val sealedClassInheritorsMap = mutableMapOf<FirRegularClass, MutableList<ClassId>>()
|
||||||
file.accept(InheritorsCollector, sealedClassInheritorsMap)
|
files.forEach { it.accept(InheritorsCollector, sealedClassInheritorsMap) }
|
||||||
if (sealedClassInheritorsMap.isEmpty()) return file.compose()
|
files.forEach { it.transformSingle(InheritorsTransformer(sealedClassInheritorsMap), null) }
|
||||||
return file.transform(InheritorsTransformer(sealedClassInheritorsMap), null)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class InheritorsTransformer(private val inheritorsMap: MutableMap<FirRegularClass, MutableList<ClassId>>) : FirTransformer<Nothing?>() {
|
object InheritorsCollector : FirDefaultVisitor<Unit, MutableMap<FirRegularClass, MutableList<ClassId>>>() {
|
||||||
|
override fun visitElement(element: FirElement, data: MutableMap<FirRegularClass, MutableList<ClassId>>) {}
|
||||||
|
|
||||||
|
override fun visitFile(file: FirFile, data: MutableMap<FirRegularClass, MutableList<ClassId>>) {
|
||||||
|
file.declarations.forEach { it.accept(this, data) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitRegularClass(regularClass: FirRegularClass, data: MutableMap<FirRegularClass, MutableList<ClassId>>) {
|
||||||
|
regularClass.declarations.forEach { it.accept(this, data) }
|
||||||
|
|
||||||
|
if (regularClass.modality == Modality.SEALED) {
|
||||||
|
data.computeIfAbsent(regularClass) { mutableListOf() }
|
||||||
|
}
|
||||||
|
|
||||||
|
val symbolProvider = regularClass.session.symbolProvider
|
||||||
|
|
||||||
|
for (typeRef in regularClass.superTypeRefs) {
|
||||||
|
val parent = extractClassFromTypeRef(symbolProvider, typeRef).takeIf { it?.modality == Modality.SEALED } ?: continue
|
||||||
|
// Inheritors of sealed class are allowed only in same package
|
||||||
|
if (parent.classId.packageFqName != regularClass.classId.packageFqName) continue
|
||||||
|
val inheritors = data.computeIfAbsent(parent) { mutableListOf() }
|
||||||
|
inheritors += regularClass.symbol.classId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun extractClassFromTypeRef(symbolProvider: FirSymbolProvider, typeRef: FirTypeRef): FirRegularClass? {
|
||||||
|
val lookupTag = (typeRef.coneType as? ConeLookupTagBasedType)?.lookupTag ?: return null
|
||||||
|
val classLikeSymbol: FirClassifierSymbol<*> = symbolProvider.getSymbolByLookupTag(lookupTag) ?: return null
|
||||||
|
return when (classLikeSymbol) {
|
||||||
|
is FirRegularClassSymbol -> classLikeSymbol.fir
|
||||||
|
is FirTypeAliasSymbol -> {
|
||||||
|
classLikeSymbol.ensureResolved(FirResolvePhase.SUPER_TYPES, symbolProvider.session)
|
||||||
|
extractClassFromTypeRef(symbolProvider, classLikeSymbol.fir.expandedTypeRef)
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class InheritorsTransformer(private val inheritorsMap: MutableMap<FirRegularClass, MutableList<ClassId>>) : FirTransformer<Nothing?>() {
|
||||||
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||||
return element.compose()
|
return element.compose()
|
||||||
}
|
}
|
||||||
@@ -63,42 +94,6 @@ class FirSealedClassInheritorsTransformer : FirTransformer<Nothing?>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private object InheritorsCollector : FirDefaultVisitor<Unit, MutableMap<FirRegularClass, MutableList<ClassId>>>() {
|
|
||||||
override fun visitElement(element: FirElement, data: MutableMap<FirRegularClass, MutableList<ClassId>>) {}
|
|
||||||
|
|
||||||
override fun visitFile(file: FirFile, data: MutableMap<FirRegularClass, MutableList<ClassId>>) {
|
|
||||||
file.declarations.forEach { it.accept(this, data) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitRegularClass(regularClass: FirRegularClass, data: MutableMap<FirRegularClass, MutableList<ClassId>>) {
|
|
||||||
regularClass.declarations.forEach { it.accept(this, data) }
|
|
||||||
|
|
||||||
if (regularClass.modality == Modality.SEALED) {
|
|
||||||
data.computeIfAbsent(regularClass) { mutableListOf() }
|
|
||||||
}
|
|
||||||
|
|
||||||
val symbolProvider = regularClass.session.symbolProvider
|
|
||||||
|
|
||||||
for (typeRef in regularClass.superTypeRefs) {
|
|
||||||
val parent = extractClassFromTypeRef(symbolProvider, typeRef).takeIf { it?.modality == Modality.SEALED } ?: continue
|
|
||||||
val inheritors = data.computeIfAbsent(parent) { mutableListOf() }
|
|
||||||
inheritors += regularClass.symbol.classId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun extractClassFromTypeRef(symbolProvider: FirSymbolProvider, typeRef: FirTypeRef): FirRegularClass? {
|
|
||||||
val lookupTag = (typeRef.coneType as? ConeLookupTagBasedType)?.lookupTag ?: return null
|
|
||||||
val classLikeSymbol: FirClassifierSymbol<*> = symbolProvider.getSymbolByLookupTag(lookupTag) ?: return null
|
|
||||||
return when (classLikeSymbol) {
|
|
||||||
is FirRegularClassSymbol -> classLikeSymbol.fir
|
|
||||||
is FirTypeAliasSymbol -> {
|
|
||||||
classLikeSymbol.ensureResolved(FirResolvePhase.SUPER_TYPES, symbolProvider.session)
|
|
||||||
extractClassFromTypeRef(symbolProvider, classLikeSymbol.fir.expandedTypeRef)
|
|
||||||
}
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object SealedClassInheritorsKey : FirDeclarationDataKey()
|
object SealedClassInheritorsKey : FirDeclarationDataKey()
|
||||||
+2
-2
@@ -50,7 +50,7 @@ fun FirResolvePhase.createTransformerBasedProcessorByPhase(
|
|||||||
CLASS_GENERATION -> FirDummyTransformerBasedProcessor(session, scopeSession) // TODO: remove
|
CLASS_GENERATION -> FirDummyTransformerBasedProcessor(session, scopeSession) // TODO: remove
|
||||||
IMPORTS -> FirImportResolveProcessor(session, scopeSession)
|
IMPORTS -> FirImportResolveProcessor(session, scopeSession)
|
||||||
SUPER_TYPES -> FirSupertypeResolverProcessor(session, scopeSession)
|
SUPER_TYPES -> FirSupertypeResolverProcessor(session, scopeSession)
|
||||||
SEALED_CLASS_INHERITORS -> FirSealedClassInheritorsProcessor(session, scopeSession)
|
SEALED_CLASS_INHERITORS -> FirLegacySealedClassInheritorsProcessor(session, scopeSession)
|
||||||
TYPES -> FirTypeResolveProcessor(session, scopeSession)
|
TYPES -> FirTypeResolveProcessor(session, scopeSession)
|
||||||
ARGUMENTS_OF_PLUGIN_ANNOTATIONS -> FirAnnotationArgumentsResolveProcessor(session, scopeSession)
|
ARGUMENTS_OF_PLUGIN_ANNOTATIONS -> FirAnnotationArgumentsResolveProcessor(session, scopeSession)
|
||||||
EXTENSION_STATUS_UPDATE -> FirTransformerBasedExtensionStatusProcessor(session, scopeSession)
|
EXTENSION_STATUS_UPDATE -> FirTransformerBasedExtensionStatusProcessor(session, scopeSession)
|
||||||
@@ -74,4 +74,4 @@ private class FirDummyTransformerBasedProcessor(
|
|||||||
return element.compose()
|
return element.compose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// ISSUE: KT-13495
|
// ISSUE: KT-13495
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// !LANGUAGE: +AllowSealedInheritorsInDifferentFilesOfSamePackage
|
// !LANGUAGE: +AllowSealedInheritorsInDifferentFilesOfSamePackage
|
||||||
|
|
||||||
// FILE: Base.kt
|
// FILE: Base.kt
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
sealed class Base
|
sealed class Base
|
||||||
|
|
||||||
class Derived: Base() {
|
class Derived: Base() {
|
||||||
class Derived2: <!SEALED_SUPERTYPE!>Base<!>()
|
class Derived2: Base()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ sealed class Base {
|
|||||||
|
|
||||||
// FILE: B.kt
|
// FILE: B.kt
|
||||||
|
|
||||||
class B : <!HIDDEN!>Base<!>()
|
class B : Base()
|
||||||
|
|
||||||
// FILE: Container.kt
|
// FILE: Container.kt
|
||||||
|
|
||||||
class Containter {
|
class Containter {
|
||||||
class C : <!HIDDEN, SEALED_SUPERTYPE!>Base<!>()
|
class C : Base()
|
||||||
|
|
||||||
inner class D : <!HIDDEN, SEALED_SUPERTYPE!>Base<!>()
|
inner class D : Base()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
|
|||||||
@@ -13,21 +13,21 @@ sealed class Base {
|
|||||||
|
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
class B : <!HIDDEN!>Base<!>()
|
class B : Base()
|
||||||
|
|
||||||
// FILE: c.kt
|
// FILE: c.kt
|
||||||
|
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
class Container {
|
class Container {
|
||||||
class C : <!HIDDEN, SEALED_SUPERTYPE!>Base<!>()
|
class C : Base()
|
||||||
|
|
||||||
inner class D : <!HIDDEN, SEALED_SUPERTYPE!>Base<!>()
|
inner class D : Base()
|
||||||
|
|
||||||
val anon = object : <!HIDDEN, SEALED_SUPERTYPE_IN_LOCAL_CLASS!>Base<!>() {} // Should be an error
|
val anon = object : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>Base<!>() {} // Should be an error
|
||||||
|
|
||||||
fun someFun() {
|
fun someFun() {
|
||||||
class LocalClass : <!HIDDEN, SEALED_SUPERTYPE_IN_LOCAL_CLASS!>Base<!>() {} // Should be an error
|
class LocalClass : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>Base<!>() {} // Should be an error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,4 +37,4 @@ package bar
|
|||||||
|
|
||||||
import foo.Base
|
import foo.Base
|
||||||
|
|
||||||
class E : <!HIDDEN!>Base<!>()
|
class E : <!HIDDEN, SEALED_SUPERTYPE!>Base<!>()
|
||||||
|
|||||||
-39
@@ -1,39 +0,0 @@
|
|||||||
// ISSUE: KT-13495
|
|
||||||
// !LANGUAGE: +AllowSealedInheritorsInDifferentFilesOfSamePackage
|
|
||||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
|
||||||
|
|
||||||
// FILE: base.kt
|
|
||||||
|
|
||||||
package foo
|
|
||||||
|
|
||||||
class Container {
|
|
||||||
sealed class Base
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: a.kt
|
|
||||||
|
|
||||||
package foo
|
|
||||||
|
|
||||||
class A : <!HIDDEN, SEALED_SUPERTYPE!>Container.Base<!>()
|
|
||||||
|
|
||||||
// FILE: b.kt
|
|
||||||
|
|
||||||
package foo
|
|
||||||
|
|
||||||
class BContainer {
|
|
||||||
class B : <!HIDDEN, SEALED_SUPERTYPE!>Container.Base<!>()
|
|
||||||
|
|
||||||
inner class C : <!HIDDEN, SEALED_SUPERTYPE!>Container.Base<!>()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: test.kt
|
|
||||||
|
|
||||||
package foo
|
|
||||||
|
|
||||||
fun test(base: Container.Base) {
|
|
||||||
val x = when (base) {
|
|
||||||
is A -> 1
|
|
||||||
is BContainer.B -> 2
|
|
||||||
is BContainer.C -> 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// ISSUE: KT-13495
|
// ISSUE: KT-13495
|
||||||
// !LANGUAGE: +AllowSealedInheritorsInDifferentFilesOfSamePackage
|
// !LANGUAGE: +AllowSealedInheritorsInDifferentFilesOfSamePackage
|
||||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ class A {
|
|||||||
sealed class Base
|
sealed class Base
|
||||||
}
|
}
|
||||||
|
|
||||||
class Derived : <!SEALED_SUPERTYPE!>A.Base<!>()
|
class Derived : A.Base()
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
class DerivedLocal : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>A.Base<!>()
|
class DerivedLocal : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>A.Base<!>()
|
||||||
|
|||||||
Reference in New Issue
Block a user