[FIR] Handle explicitly private sealed class constructors properly

#KT-36850 Fixed
This commit is contained in:
Mikhail Glukhikh
2020-02-19 19:32:46 +03:00
parent 17b473fcb6
commit 5d7999a808
4 changed files with 44 additions and 12 deletions
@@ -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()
}
@@ -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())
+7
View File
@@ -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 : <!INAPPLICABLE_CANDIDATE!>WithPrivateConstructor<!>() // error
object Second : <!INAPPLICABLE_CANDIDATE!>WithPrivateConstructor<!>(0) // error
+25
View File
@@ -14,3 +14,28 @@ FILE: sealedClass.kt
}
}
public sealed class WithPrivateConstructor : R|kotlin/Any| {
private constructor(x: R|kotlin/Int|): R|WithPrivateConstructor| {
super<R|kotlin/Any|>()
}
public final val x: R|kotlin/Int| = R|<local>/x|
public get(): R|kotlin/Int|
private constructor(): R|WithPrivateConstructor| {
this<R|WithPrivateConstructor|>(Int(42))
}
}
public final object First : R|WithPrivateConstructor| {
private constructor(): R|First| {
super<R|WithPrivateConstructor|>()
}
}
public final object Second : R|WithPrivateConstructor| {
private constructor(): R|Second| {
super<R|WithPrivateConstructor|>(IntegerLiteral(0))
}
}