diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index d6f5982adc5..0ad52a483be 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.fir.lightTree.converter import com.intellij.lang.LighterASTNode -import com.intellij.lang.LighterASTTokenNode import com.intellij.psi.TokenType import com.intellij.util.diff.FlyweightCapableTreeStructure import org.jetbrains.kotlin.KtNodeTypes.* @@ -638,14 +637,12 @@ class DeclarationsConverter( extractArgumentsFrom(classWrapper.superTypeCallEntry, stubMode) } - val status = FirDeclarationStatusImpl( - if (primaryConstructor != null) modifiers.getVisibility() else defaultVisibility, - Modality.FINAL - ).apply { + val explicitVisibility = if (primaryConstructor != null) modifiers.getVisibility() else null + val status = FirDeclarationStatusImpl(explicitVisibility ?: defaultVisibility, Modality.FINAL).apply { isExpect = modifiers.hasExpect() isActual = modifiers.hasActual() isInner = classWrapper.isInner() - isFromSealedClass = classWrapper.isSealed() + isFromSealedClass = classWrapper.isSealed() && explicitVisibility !== Visibilities.PRIVATE isFromEnumClass = classWrapper.isEnum() } @@ -711,11 +708,12 @@ class DeclarationsConverter( } else classWrapper.delegatedSelfTypeRef - val status = FirDeclarationStatusImpl(modifiers.getVisibility(), Modality.FINAL).apply { + val explicitVisibility = modifiers.getVisibility() + val status = FirDeclarationStatusImpl(explicitVisibility, Modality.FINAL).apply { isExpect = modifiers.hasExpect() isActual = modifiers.hasActual() isInner = classWrapper.isInner() - isFromSealedClass = classWrapper.isSealed() + isFromSealedClass = classWrapper.isSealed() && explicitVisibility !== Visibilities.PRIVATE isFromEnumClass = classWrapper.isEnum() } diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 4c4c00f60cd..d64fb9ea3cf 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -472,11 +472,12 @@ class RawFirBuilder( else -> Visibilities.UNKNOWN } - val status = FirDeclarationStatusImpl(this?.visibility ?: defaultVisibility(), Modality.FINAL).apply { + val explicitVisibility = this?.visibility + val status = FirDeclarationStatusImpl(explicitVisibility ?: defaultVisibility(), Modality.FINAL).apply { isExpect = this@toFirConstructor?.hasExpectModifier() ?: false isActual = this@toFirConstructor?.hasActualModifier() ?: false isInner = owner.hasModifier(INNER_KEYWORD) - isFromSealedClass = owner.hasModifier(SEALED_KEYWORD) + isFromSealedClass = owner.hasModifier(SEALED_KEYWORD) && explicitVisibility !== Visibilities.PRIVATE isFromEnumClass = owner.hasModifier(ENUM_KEYWORD) } return buildPrimaryConstructor { @@ -846,11 +847,12 @@ class RawFirBuilder( source = this@toFirConstructor.toFirSourceElement() session = baseSession returnTypeRef = delegatedSelfTypeRef - status = FirDeclarationStatusImpl(visibility, Modality.FINAL).apply { + val explicitVisibility = visibility + status = FirDeclarationStatusImpl(explicitVisibility, Modality.FINAL).apply { isExpect = hasExpectModifier() isActual = hasActualModifier() isInner = owner.hasModifier(INNER_KEYWORD) - isFromSealedClass = owner.hasModifier(SEALED_KEYWORD) + isFromSealedClass = owner.hasModifier(SEALED_KEYWORD) && explicitVisibility !== Visibilities.PRIVATE isFromEnumClass = owner.hasModifier(ENUM_KEYWORD) } symbol = FirConstructorSymbol(callableIdForClassConstructor()) diff --git a/compiler/fir/resolve/testData/resolve/sealedClass.kt b/compiler/fir/resolve/testData/resolve/sealedClass.kt index 7599e562784..ae5a69ea932 100644 --- a/compiler/fir/resolve/testData/resolve/sealedClass.kt +++ b/compiler/fir/resolve/testData/resolve/sealedClass.kt @@ -1,3 +1,10 @@ sealed class Foo(val value: String) class Bar : Foo("OK") + +sealed class WithPrivateConstructor private constructor(val x: Int) { + private constructor() : this(42) +} + +object First : WithPrivateConstructor() // error +object Second : WithPrivateConstructor(0) // error \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/sealedClass.txt b/compiler/fir/resolve/testData/resolve/sealedClass.txt index 82782c3a2ff..746394bc5ee 100644 --- a/compiler/fir/resolve/testData/resolve/sealedClass.txt +++ b/compiler/fir/resolve/testData/resolve/sealedClass.txt @@ -14,3 +14,28 @@ FILE: sealedClass.kt } } + public sealed class WithPrivateConstructor : R|kotlin/Any| { + private constructor(x: R|kotlin/Int|): R|WithPrivateConstructor| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + private constructor(): R|WithPrivateConstructor| { + this(Int(42)) + } + + } + public final object First : R|WithPrivateConstructor| { + private constructor(): R|First| { + super() + } + + } + public final object Second : R|WithPrivateConstructor| { + private constructor(): R|Second| { + super(IntegerLiteral(0)) + } + + }