[FIR] Set actual modifier on implicitly actual primary constructors
... of annotations and inline classes. #KT-60139 Fixed
This commit is contained in:
committed by
Space Team
parent
fb04356829
commit
b0f1746012
+2
-4
@@ -10,10 +10,7 @@ import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.expectForActual
|
||||
import org.jetbrains.kotlin.fir.declarations.getSingleExpectForActualOrNull
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isActual
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
@@ -32,6 +29,7 @@ object FirActualCallableDeclarationChecker : FirCallableDeclarationChecker() {
|
||||
}
|
||||
|
||||
private fun checkActualFunctionWithDefaultArguments(function: FirFunction, reporter: DiagnosticReporter, context: CheckerContext) {
|
||||
if (function.symbol.isAnnotationConstructor(context.session)) return
|
||||
for (valueParameter in function.valueParameters) {
|
||||
if (valueParameter.defaultValue != null) {
|
||||
reporter.reportOn(valueParameter.source, FirErrors.ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS, context)
|
||||
|
||||
+10
-9
@@ -122,7 +122,6 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
) {
|
||||
val symbol = declaration.symbol
|
||||
val compatibilityToMembersMap = symbol.expectForActual ?: return
|
||||
val session = context.session
|
||||
|
||||
checkAmbiguousExpects(symbol, compatibilityToMembersMap, symbol, context, reporter)
|
||||
|
||||
@@ -131,7 +130,7 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
if (compatibilityToMembersMap.allStrongIncompatibilities()) return
|
||||
|
||||
if (Compatible in compatibilityToMembersMap) {
|
||||
if (checkActual && requireActualModifier(symbol, session)) {
|
||||
if (checkActual) {
|
||||
reporter.reportOn(source, FirErrors.ACTUAL_MISSING, context)
|
||||
}
|
||||
return
|
||||
@@ -168,13 +167,15 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
|
||||
Compatible !in compatibilityToMembersMap -> {
|
||||
reporter.reportOn(
|
||||
source,
|
||||
FirErrors.ACTUAL_WITHOUT_EXPECT,
|
||||
symbol,
|
||||
compatibilityToMembersMap,
|
||||
context
|
||||
)
|
||||
if (requireActualModifier(declaration.symbol, context.session)) {
|
||||
reporter.reportOn(
|
||||
source,
|
||||
FirErrors.ACTUAL_WITHOUT_EXPECT,
|
||||
symbol,
|
||||
compatibilityToMembersMap,
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
else -> {}
|
||||
|
||||
+5
-3
@@ -550,7 +550,8 @@ class LightTreeRawFirDeclarationBuilder(
|
||||
selfType.source,
|
||||
classWrapper,
|
||||
delegatedConstructorSource,
|
||||
containingClassIsExpectClass = status.isExpect
|
||||
containingClassIsExpectClass = status.isExpect,
|
||||
isImplicitlyActual = status.isActual && (status.isInline || classKind == ClassKind.ANNOTATION_CLASS)
|
||||
)
|
||||
val firPrimaryConstructor = primaryConstructorWrapper?.firConstructor
|
||||
firPrimaryConstructor?.let { declarations += it }
|
||||
@@ -884,7 +885,8 @@ class LightTreeRawFirDeclarationBuilder(
|
||||
classWrapper: ClassWrapper,
|
||||
delegatedConstructorSource: KtLightSourceElement?,
|
||||
isEnumEntry: Boolean = false,
|
||||
containingClassIsExpectClass: Boolean
|
||||
containingClassIsExpectClass: Boolean,
|
||||
isImplicitlyActual: Boolean = false,
|
||||
): PrimaryConstructor? {
|
||||
fun ClassKind.isEnumRelated(): Boolean = this == ClassKind.ENUM_CLASS || this == ClassKind.ENUM_ENTRY
|
||||
val shouldGenerateImplicitConstructor =
|
||||
@@ -955,7 +957,7 @@ class LightTreeRawFirDeclarationBuilder(
|
||||
}
|
||||
val status = FirDeclarationStatusImpl(explicitVisibility ?: defaultVisibility, Modality.FINAL).apply {
|
||||
isExpect = modifiers.hasExpect() || context.containerIsExpect
|
||||
isActual = modifiers.hasActual()
|
||||
isActual = modifiers.hasActual() || isImplicitlyActual
|
||||
isInner = classWrapper.isInner()
|
||||
isFromSealedClass = classWrapper.isSealed() && explicitVisibility !== Visibilities.Private
|
||||
isFromEnumClass = classWrapper.isEnum()
|
||||
|
||||
+3
-1
@@ -983,6 +983,7 @@ open class PsiRawFirBuilder(
|
||||
containingClassIsExpectClass,
|
||||
copyConstructedTypeRefWithImplicitSource = true,
|
||||
isErrorConstructor = !hasPrimaryConstructor,
|
||||
isImplicitlyActual = container.status.isActual && (container.status.isInline || classKind == ClassKind.ANNOTATION_CLASS)
|
||||
)
|
||||
container.declarations += firPrimaryConstructor
|
||||
}
|
||||
@@ -1003,6 +1004,7 @@ open class PsiRawFirBuilder(
|
||||
containingClassIsExpectClass: Boolean,
|
||||
copyConstructedTypeRefWithImplicitSource: Boolean,
|
||||
isErrorConstructor: Boolean = false,
|
||||
isImplicitlyActual: Boolean = false,
|
||||
): FirConstructor {
|
||||
val constructorSource = this?.toFirSourceElement()
|
||||
?: owner.toKtPsiSourceElement(KtFakeSourceElementKind.ImplicitConstructor)
|
||||
@@ -1050,7 +1052,7 @@ open class PsiRawFirBuilder(
|
||||
val explicitVisibility = this?.visibility?.takeUnless { it == Visibilities.Unknown }
|
||||
val status = FirDeclarationStatusImpl(explicitVisibility ?: defaultVisibility(), Modality.FINAL).apply {
|
||||
isExpect = this@toFirConstructor?.hasExpectModifier() == true || this@PsiRawFirBuilder.context.containerIsExpect
|
||||
isActual = this@toFirConstructor?.hasActualModifier() == true
|
||||
isActual = this@toFirConstructor?.hasActualModifier() == true || isImplicitlyActual
|
||||
isInner = owner.parent.parent !is KtScript && owner.hasModifier(INNER_KEYWORD) // a warning about inner script class is reported on the class itself
|
||||
isFromSealedClass = owner.hasModifier(SEALED_KEYWORD) && explicitVisibility !== Visibilities.Private
|
||||
isFromEnumClass = owner.hasModifier(ENUM_KEYWORD)
|
||||
|
||||
+1
-8
@@ -83,7 +83,7 @@ open class FirExpectActualMatcherTransformer(
|
||||
// ------------------------------------------------------
|
||||
|
||||
fun transformMemberDeclaration(memberDeclaration: FirMemberDeclaration) {
|
||||
if (!memberDeclaration.isActual && !memberDeclaration.isImplicitlyActual()) return
|
||||
if (!memberDeclaration.isActual) return
|
||||
val actualSymbol = memberDeclaration.symbol
|
||||
|
||||
// Regardless of whether any `expect` symbols are found for `memberDeclaration`, it must be assigned an `expectForActual` map.
|
||||
@@ -97,11 +97,4 @@ open class FirExpectActualMatcherTransformer(
|
||||
) ?: mapOf()
|
||||
memberDeclaration.expectForActual = expectForActualData
|
||||
}
|
||||
|
||||
// TODO KT-60139 Remove special handling when implicitly actual elements have the actual flag set.
|
||||
private fun FirMemberDeclaration.isImplicitlyActual(): Boolean {
|
||||
if (this !is FirPrimaryConstructor) return false
|
||||
val klass = getContainingClass(session) ?: return false
|
||||
return klass.isActual && (klass.isInline || klass.classKind == ClassKind.ANNOTATION_CLASS)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user