[FIR] Check visibility correctly for sealed class in file
This commit is contained in:
+4
@@ -645,6 +645,8 @@ class DeclarationsConverter(
|
|||||||
isExpect = modifiers.hasExpect()
|
isExpect = modifiers.hasExpect()
|
||||||
isActual = modifiers.hasActual()
|
isActual = modifiers.hasActual()
|
||||||
isInner = classWrapper.isInner()
|
isInner = classWrapper.isInner()
|
||||||
|
isFromSealedClass = classWrapper.isSealed()
|
||||||
|
isFromEnumClass = classWrapper.isEnum()
|
||||||
}
|
}
|
||||||
|
|
||||||
return PrimaryConstructor(
|
return PrimaryConstructor(
|
||||||
@@ -713,6 +715,8 @@ class DeclarationsConverter(
|
|||||||
isExpect = modifiers.hasExpect()
|
isExpect = modifiers.hasExpect()
|
||||||
isActual = modifiers.hasActual()
|
isActual = modifiers.hasActual()
|
||||||
isInner = classWrapper.isInner()
|
isInner = classWrapper.isInner()
|
||||||
|
isFromSealedClass = classWrapper.isSealed()
|
||||||
|
isFromEnumClass = classWrapper.isEnum()
|
||||||
}
|
}
|
||||||
|
|
||||||
val target = FirFunctionTarget(labelName = null, isLambda = false)
|
val target = FirFunctionTarget(labelName = null, isLambda = false)
|
||||||
|
|||||||
@@ -40,11 +40,11 @@ class ClassWrapper(
|
|||||||
return classKind == ClassKind.OBJECT
|
return classKind == ClassKind.OBJECT
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isSealed(): Boolean {
|
fun isSealed(): Boolean {
|
||||||
return modifiers.hasModality(Modality.SEALED)
|
return modifiers.hasModality(Modality.SEALED)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isEnum(): Boolean {
|
fun isEnum(): Boolean {
|
||||||
return modifiers.isEnum()
|
return modifiers.isEnum()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -472,6 +472,8 @@ class RawFirBuilder(session: FirSession, val baseScopeProvider: FirScopeProvider
|
|||||||
isExpect = this@toFirConstructor?.hasExpectModifier() ?: false
|
isExpect = this@toFirConstructor?.hasExpectModifier() ?: false
|
||||||
isActual = this@toFirConstructor?.hasActualModifier() ?: false
|
isActual = this@toFirConstructor?.hasActualModifier() ?: false
|
||||||
isInner = owner.hasModifier(INNER_KEYWORD)
|
isInner = owner.hasModifier(INNER_KEYWORD)
|
||||||
|
isFromSealedClass = owner.hasModifier(SEALED_KEYWORD)
|
||||||
|
isFromEnumClass = owner.hasModifier(ENUM_KEYWORD)
|
||||||
}
|
}
|
||||||
return buildPrimaryConstructor {
|
return buildPrimaryConstructor {
|
||||||
source = constructorSource
|
source = constructorSource
|
||||||
@@ -842,6 +844,8 @@ class RawFirBuilder(session: FirSession, val baseScopeProvider: FirScopeProvider
|
|||||||
isExpect = hasExpectModifier()
|
isExpect = hasExpectModifier()
|
||||||
isActual = hasActualModifier()
|
isActual = hasActualModifier()
|
||||||
isInner = owner.hasModifier(INNER_KEYWORD)
|
isInner = owner.hasModifier(INNER_KEYWORD)
|
||||||
|
isFromSealedClass = owner.hasModifier(SEALED_KEYWORD)
|
||||||
|
isFromEnumClass = owner.hasModifier(ENUM_KEYWORD)
|
||||||
}
|
}
|
||||||
symbol = FirConstructorSymbol(callableIdForClassConstructor())
|
symbol = FirConstructorSymbol(callableIdForClassConstructor())
|
||||||
delegatedConstructor = getDelegationCall().convert(delegatedSuperTypeRef, delegatedSelfTypeRef, hasPrimaryConstructor)
|
delegatedConstructor = getDelegationCall().convert(delegatedSuperTypeRef, delegatedSelfTypeRef, hasPrimaryConstructor)
|
||||||
|
|||||||
@@ -421,7 +421,7 @@ internal object CheckVisibility : CheckerStage() {
|
|||||||
}
|
}
|
||||||
Visibilities.PRIVATE, Visibilities.PRIVATE_TO_THIS -> {
|
Visibilities.PRIVATE, Visibilities.PRIVATE_TO_THIS -> {
|
||||||
if (declaration.session == callInfo.session) {
|
if (declaration.session == callInfo.session) {
|
||||||
if (ownerId == null) {
|
if (ownerId == null || declaration is FirConstructor && declaration.status.isFromSealedClass) {
|
||||||
// Top-level: visible in file
|
// Top-level: visible in file
|
||||||
candidateFile == useSiteFile
|
candidateFile == useSiteFile
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
sealed class Foo(val value: String)
|
||||||
|
|
||||||
|
class Bar : Foo("OK")
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
FILE: sealedClass.kt
|
||||||
|
public sealed class Foo : R|kotlin/Any| {
|
||||||
|
private constructor(value: R|kotlin/String|): R|Foo| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val value: R|kotlin/String| = R|<local>/value|
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class Bar : R|Foo| {
|
||||||
|
public constructor(): R|Bar| {
|
||||||
|
super<R|Foo|>(String(OK))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+5
@@ -263,6 +263,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/recursiveCallOnWhenWithSealedClass.kt");
|
runTest("compiler/fir/resolve/testData/resolve/recursiveCallOnWhenWithSealedClass.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("sealedClass.kt")
|
||||||
|
public void testSealedClass() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/sealedClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("simpleClass.kt")
|
@TestMetadata("simpleClass.kt")
|
||||||
public void testSimpleClass() throws Exception {
|
public void testSimpleClass() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/simpleClass.kt");
|
runTest("compiler/fir/resolve/testData/resolve/simpleClass.kt");
|
||||||
|
|||||||
Generated
+5
@@ -263,6 +263,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/recursiveCallOnWhenWithSealedClass.kt");
|
runTest("compiler/fir/resolve/testData/resolve/recursiveCallOnWhenWithSealedClass.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("sealedClass.kt")
|
||||||
|
public void testSealedClass() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/sealedClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("simpleClass.kt")
|
@TestMetadata("simpleClass.kt")
|
||||||
public void testSimpleClass() throws Exception {
|
public void testSimpleClass() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/simpleClass.kt");
|
runTest("compiler/fir/resolve/testData/resolve/simpleClass.kt");
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ interface FirDeclarationStatus : FirElement {
|
|||||||
val isData: Boolean
|
val isData: Boolean
|
||||||
val isSuspend: Boolean
|
val isSuspend: Boolean
|
||||||
val isStatic: Boolean
|
val isStatic: Boolean
|
||||||
|
val isFromSealedClass: Boolean
|
||||||
|
val isFromEnumClass: Boolean
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitDeclarationStatus(this, data)
|
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitDeclarationStatus(this, data)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -34,6 +34,8 @@ interface FirResolvedDeclarationStatus : FirDeclarationStatus {
|
|||||||
override val isData: Boolean
|
override val isData: Boolean
|
||||||
override val isSuspend: Boolean
|
override val isSuspend: Boolean
|
||||||
override val isStatic: Boolean
|
override val isStatic: Boolean
|
||||||
|
override val isFromSealedClass: Boolean
|
||||||
|
override val isFromEnumClass: Boolean
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitResolvedDeclarationStatus(this, data)
|
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitResolvedDeclarationStatus(this, data)
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-1
@@ -121,6 +121,18 @@ open class FirDeclarationStatusImpl(
|
|||||||
this[STATIC] = value
|
this[STATIC] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override var isFromSealedClass: Boolean
|
||||||
|
get() = this[FROM_SEALED]
|
||||||
|
set(value) {
|
||||||
|
this[FROM_SEALED] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override var isFromEnumClass: Boolean
|
||||||
|
get() = this[FROM_ENUM]
|
||||||
|
set(value) {
|
||||||
|
this[FROM_ENUM] = value
|
||||||
|
}
|
||||||
|
|
||||||
private enum class Modifier(val mask: Int) {
|
private enum class Modifier(val mask: Int) {
|
||||||
EXPECT(0x1),
|
EXPECT(0x1),
|
||||||
ACTUAL(0x2),
|
ACTUAL(0x2),
|
||||||
@@ -136,7 +148,9 @@ open class FirDeclarationStatusImpl(
|
|||||||
COMPANION(0x800),
|
COMPANION(0x800),
|
||||||
DATA(0x1000),
|
DATA(0x1000),
|
||||||
SUSPEND(0x2000),
|
SUSPEND(0x2000),
|
||||||
STATIC(0x4000)
|
STATIC(0x4000),
|
||||||
|
FROM_SEALED(0x8000),
|
||||||
|
FROM_ENUM(0x10000)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
|
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
|
||||||
|
|||||||
+2
-1
@@ -296,7 +296,8 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
|||||||
+modality
|
+modality
|
||||||
generateBooleanFields(
|
generateBooleanFields(
|
||||||
"expect", "actual", "override", "operator", "infix", "inline", "tailRec",
|
"expect", "actual", "override", "operator", "infix", "inline", "tailRec",
|
||||||
"external", "const", "lateInit", "inner", "companion", "data", "suspend", "static"
|
"external", "const", "lateInit", "inner", "companion", "data", "suspend", "static",
|
||||||
|
"fromSealedClass", "fromEnumClass"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -60,7 +60,7 @@ FILE fqName:<root> fileName:/expectedSealedClass.kt
|
|||||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Add
|
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Add
|
||||||
CONSTRUCTOR visibility:public <> () returnType:<root>.Add [primary]
|
CONSTRUCTOR visibility:public <> () returnType:<root>.Add [primary]
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
ERROR_CALL 'Cannot find delegated constructor call' type=<root>.Add
|
DELEGATING_CONSTRUCTOR_CALL 'private constructor <init> () [primary] declared in <root>.Ops'
|
||||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Add modality:FINAL visibility:public superTypes:[<root>.Ops]'
|
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Add modality:FINAL visibility:public superTypes:[<root>.Ops]'
|
||||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||||
overridden:
|
overridden:
|
||||||
|
|||||||
Reference in New Issue
Block a user