[FIR] Allow lateinit FirBackingField's
This commit is contained in:
committed by
TeamCityServer
parent
871aebd423
commit
6b532ccd0d
+3
@@ -875,6 +875,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val ACCESSOR_FOR_DELEGATED_PROPERTY by error<KtPropertyAccessor>()
|
||||
val PROPERTY_INITIALIZER_WITH_EXPLICIT_FIELD_DECLARATION by error<KtExpression>()
|
||||
val PROPERTY_FIELD_DECLARATION_MISSING_INITIALIZER by error<KtBackingField>()
|
||||
val LATEINIT_PROPERTY_FIELD_DECLARATION_WITH_INITIALIZER by error<KtBackingField>(PositioningStrategy.LATEINIT_MODIFIER)
|
||||
val LATEINIT_FIELD_IN_VAL_PROPERTY by error<KtBackingField>(PositioningStrategy.LATEINIT_MODIFIER)
|
||||
val LATEINIT_NULLABLE_BACKING_FIELD by error<KtBackingField>(PositioningStrategy.LATEINIT_MODIFIER)
|
||||
val PROPERTY_MUST_HAVE_GETTER by error<KtProperty>()
|
||||
val PROPERTY_MUST_HAVE_SETTER by error<KtProperty>()
|
||||
val EXPLICIT_BACKING_FIELD_IN_INTERFACE by error<KtBackingField>(PositioningStrategy.FIELD_KEYWORD)
|
||||
|
||||
@@ -482,6 +482,9 @@ object FirErrors {
|
||||
val ACCESSOR_FOR_DELEGATED_PROPERTY by error0<KtPropertyAccessor>()
|
||||
val PROPERTY_INITIALIZER_WITH_EXPLICIT_FIELD_DECLARATION by error0<KtExpression>()
|
||||
val PROPERTY_FIELD_DECLARATION_MISSING_INITIALIZER by error0<KtBackingField>()
|
||||
val LATEINIT_PROPERTY_FIELD_DECLARATION_WITH_INITIALIZER by error0<KtBackingField>(SourceElementPositioningStrategies.LATEINIT_MODIFIER)
|
||||
val LATEINIT_FIELD_IN_VAL_PROPERTY by error0<KtBackingField>(SourceElementPositioningStrategies.LATEINIT_MODIFIER)
|
||||
val LATEINIT_NULLABLE_BACKING_FIELD by error0<KtBackingField>(SourceElementPositioningStrategies.LATEINIT_MODIFIER)
|
||||
val PROPERTY_MUST_HAVE_GETTER by error0<KtProperty>()
|
||||
val PROPERTY_MUST_HAVE_SETTER by error0<KtProperty>()
|
||||
val EXPLICIT_BACKING_FIELD_IN_INTERFACE by error0<KtBackingField>(SourceElementPositioningStrategies.FIELD_KEYWORD)
|
||||
|
||||
+4
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.hasExplicitBackingField
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isLateInit
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
|
||||
@@ -44,6 +45,9 @@ object FirInapplicableLateinitChecker : FirPropertyChecker() {
|
||||
reporter.reportError(declaration.source, "is not allowed on properties of primitive types", context)
|
||||
}
|
||||
|
||||
declaration.hasExplicitBackingField ->
|
||||
reporter.reportError(declaration.source, "must be moved to the field declaration", context)
|
||||
|
||||
declaration.hasGetter() || declaration.hasSetter() ->
|
||||
reporter.reportError(declaration.source, "is not allowed on properties with a custom getter or setter", context)
|
||||
}
|
||||
|
||||
+21
-1
@@ -9,13 +9,17 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.FirBackingField
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.hasExplicitBackingField
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isLateInit
|
||||
import org.jetbrains.kotlin.fir.expressions.FirErrorExpression
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.ConeTypeParameterType
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.isNullable
|
||||
import org.jetbrains.kotlin.fir.types.isSubtypeOf
|
||||
|
||||
object FirPropertyFieldTypeChecker : FirPropertyChecker() {
|
||||
@@ -35,8 +39,18 @@ object FirPropertyFieldTypeChecker : FirPropertyChecker() {
|
||||
reporter.reportOn(declaration.initializer?.source, FirErrors.PROPERTY_INITIALIZER_WITH_EXPLICIT_FIELD_DECLARATION, context)
|
||||
}
|
||||
|
||||
if (backingField.initializer == null) {
|
||||
if (backingField.isLateInit && declaration.isVal) {
|
||||
reporter.reportOn(backingField.source, FirErrors.LATEINIT_FIELD_IN_VAL_PROPERTY, context)
|
||||
}
|
||||
|
||||
if (backingField.initializer == null && !backingField.isLateInit) {
|
||||
reporter.reportOn(backingField.source, FirErrors.PROPERTY_FIELD_DECLARATION_MISSING_INITIALIZER, context)
|
||||
} else if (backingField.initializer != null && backingField.isLateInit) {
|
||||
reporter.reportOn(backingField.source, FirErrors.LATEINIT_PROPERTY_FIELD_DECLARATION_WITH_INITIALIZER, context)
|
||||
}
|
||||
|
||||
if (backingField.isLateInit && backingField.isNullable) {
|
||||
reporter.reportOn(backingField.source, FirErrors.LATEINIT_NULLABLE_BACKING_FIELD, context)
|
||||
}
|
||||
|
||||
if (backingField.returnTypeRef.coneType == declaration.returnTypeRef.coneType) {
|
||||
@@ -53,6 +67,12 @@ object FirPropertyFieldTypeChecker : FirPropertyChecker() {
|
||||
}
|
||||
}
|
||||
|
||||
private val FirBackingField.isNullable
|
||||
get() = when (val type = returnTypeRef.coneType) {
|
||||
is ConeTypeParameterType -> type.isNullable || type.lookupTag.typeParameterSymbol.resolvedBounds.any { it.coneType.isNullable }
|
||||
else -> type.isNullable
|
||||
}
|
||||
|
||||
private val FirPropertyAccessor?.isNotExplicit
|
||||
get() = this == null || this is FirDefaultPropertyAccessor
|
||||
|
||||
|
||||
+15
@@ -257,6 +257,9 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVISIBLE_REFEREN
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.IS_ENUM_ENTRY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ITERATOR_AMBIGUITY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_FIELD_IN_VAL_PROPERTY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_NULLABLE_BACKING_FIELD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_PROPERTY_FIELD_DECLARATION_WITH_INITIALIZER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LEAKED_IN_PLACE_LAMBDA
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_ANNOTATION_CLASS_ERROR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_INTERFACE_NOT_ALLOWED
|
||||
@@ -1283,6 +1286,18 @@ class FirDefaultErrorMessages {
|
||||
PROPERTY_FIELD_DECLARATION_MISSING_INITIALIZER,
|
||||
"Property backing field declaration must have an initializer"
|
||||
)
|
||||
map.put(
|
||||
LATEINIT_PROPERTY_FIELD_DECLARATION_WITH_INITIALIZER,
|
||||
"Lateinit backing field cannot have an initializer"
|
||||
)
|
||||
map.put(
|
||||
LATEINIT_FIELD_IN_VAL_PROPERTY,
|
||||
"Only mutable properties can have a mutable backing field. Consider changing ''val'' to ''var''"
|
||||
)
|
||||
map.put(
|
||||
LATEINIT_NULLABLE_BACKING_FIELD,
|
||||
"Lateinit modifier is not allowed on backing fields of a type with nullable upper bound"
|
||||
)
|
||||
map.put(
|
||||
PROPERTY_MUST_HAVE_GETTER,
|
||||
"This property needs a custom getter, because it's type is not a supertype of the backing field's type"
|
||||
|
||||
+1
@@ -1403,6 +1403,7 @@ class DeclarationsConverter(
|
||||
return FirDeclarationStatusImpl(componentVisibility, modifiers.getModality(isClassOrObject = false)).apply {
|
||||
isInline = propertyModifiers.hasInline() || modifiers.hasInline()
|
||||
isExternal = propertyModifiers.hasExternal() || modifiers.hasExternal()
|
||||
isLateInit = modifiers.hasLateinit()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -463,6 +463,7 @@ open class RawFirBuilder(
|
||||
declaration?.hasModifier(INLINE_KEYWORD) == true
|
||||
isExternal = property.hasModifier(EXTERNAL_KEYWORD) ||
|
||||
declaration?.hasModifier(EXTERNAL_KEYWORD) == true
|
||||
isLateInit = declaration?.hasModifier(LATEINIT_KEYWORD) == true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -198,7 +198,12 @@ val possibleTargetMap = mapOf(
|
||||
REIFIED_KEYWORD to EnumSet.of(KotlinTarget.TYPE_PARAMETER),
|
||||
VARARG_KEYWORD to EnumSet.of(KotlinTarget.VALUE_PARAMETER, KotlinTarget.PROPERTY_PARAMETER),
|
||||
COMPANION_KEYWORD to EnumSet.of(KotlinTarget.OBJECT),
|
||||
LATEINIT_KEYWORD to EnumSet.of(KotlinTarget.MEMBER_PROPERTY, KotlinTarget.TOP_LEVEL_PROPERTY, KotlinTarget.LOCAL_VARIABLE),
|
||||
LATEINIT_KEYWORD to EnumSet.of(
|
||||
KotlinTarget.MEMBER_PROPERTY,
|
||||
KotlinTarget.TOP_LEVEL_PROPERTY,
|
||||
KotlinTarget.LOCAL_VARIABLE,
|
||||
KotlinTarget.BACKING_FIELD
|
||||
),
|
||||
DATA_KEYWORD to EnumSet.of(KotlinTarget.CLASS_ONLY, KotlinTarget.LOCAL_CLASS),
|
||||
INLINE_KEYWORD to EnumSet.of(
|
||||
KotlinTarget.FUNCTION,
|
||||
|
||||
+18
@@ -2418,6 +2418,24 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.LATEINIT_PROPERTY_FIELD_DECLARATION_WITH_INITIALIZER) { firDiagnostic ->
|
||||
LateinitPropertyFieldDeclarationWithInitializerImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.LATEINIT_FIELD_IN_VAL_PROPERTY) { firDiagnostic ->
|
||||
LateinitFieldInValPropertyImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.LATEINIT_NULLABLE_BACKING_FIELD) { firDiagnostic ->
|
||||
LateinitNullableBackingFieldImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.PROPERTY_MUST_HAVE_GETTER) { firDiagnostic ->
|
||||
PropertyMustHaveGetterImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
|
||||
+12
@@ -1711,6 +1711,18 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = PropertyFieldDeclarationMissingInitializer::class
|
||||
}
|
||||
|
||||
abstract class LateinitPropertyFieldDeclarationWithInitializer : KtFirDiagnostic<KtBackingField>() {
|
||||
override val diagnosticClass get() = LateinitPropertyFieldDeclarationWithInitializer::class
|
||||
}
|
||||
|
||||
abstract class LateinitFieldInValProperty : KtFirDiagnostic<KtBackingField>() {
|
||||
override val diagnosticClass get() = LateinitFieldInValProperty::class
|
||||
}
|
||||
|
||||
abstract class LateinitNullableBackingField : KtFirDiagnostic<KtBackingField>() {
|
||||
override val diagnosticClass get() = LateinitNullableBackingField::class
|
||||
}
|
||||
|
||||
abstract class PropertyMustHaveGetter : KtFirDiagnostic<KtProperty>() {
|
||||
override val diagnosticClass get() = PropertyMustHaveGetter::class
|
||||
}
|
||||
|
||||
+35
-37
@@ -2753,6 +2753,27 @@ internal class PropertyFieldDeclarationMissingInitializerImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class LateinitPropertyFieldDeclarationWithInitializerImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.LateinitPropertyFieldDeclarationWithInitializer(), KtAbstractFirDiagnostic<KtBackingField> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class LateinitFieldInValPropertyImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.LateinitFieldInValProperty(), KtAbstractFirDiagnostic<KtBackingField> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class LateinitNullableBackingFieldImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.LateinitNullableBackingField(), KtAbstractFirDiagnostic<KtBackingField> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class PropertyMustHaveGetterImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
@@ -2767,43 +2788,6 @@ internal class PropertyMustHaveSetterImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class AbstractPropertyInPrimaryConstructorParametersImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.AbstractPropertyInPrimaryConstructorParameters(), KtAbstractFirDiagnostic<KtModifierListOwner> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class LocalVariableWithTypeParametersWarningImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.LocalVariableWithTypeParametersWarning(), KtAbstractFirDiagnostic<KtProperty> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class LocalVariableWithTypeParametersImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.LocalVariableWithTypeParameters(), KtAbstractFirDiagnostic<KtProperty> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class InapplicableBackingFieldVisibilityImpl(
|
||||
override val modifier: KtModifierKeywordToken,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.InapplicableBackingFieldVisibility(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class InapplicableBackingFieldModifierImpl(
|
||||
override val modifier: KtModifierKeywordToken,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.InapplicableBackingFieldModifier(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class ExplicitBackingFieldInInterfaceImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
@@ -2839,6 +2823,20 @@ internal class AbstractPropertyInPrimaryConstructorParametersImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class LocalVariableWithTypeParametersWarningImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.LocalVariableWithTypeParametersWarning(), KtAbstractFirDiagnostic<KtProperty> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class LocalVariableWithTypeParametersImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.LocalVariableWithTypeParameters(), KtAbstractFirDiagnostic<KtProperty> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class ExpectedDeclarationWithBodyImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
|
||||
Reference in New Issue
Block a user