FIR checker: add diagnostics for backing fields
This commit is contained in:
committed by
Mikhail Glukhikh
parent
a88b82d8ff
commit
bd37badf29
+2
-2
@@ -11,7 +11,7 @@ var x2: Int = 1
|
|||||||
field = 1
|
field = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
val x3 = run {
|
val x3 = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>run {
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val c = 1 + 1
|
val c = 1 + 1
|
||||||
throw Exception()
|
throw Exception()
|
||||||
@@ -25,7 +25,7 @@ val x3 = run {
|
|||||||
}
|
}
|
||||||
|
|
||||||
throw Exception()
|
throw Exception()
|
||||||
}
|
}<!>
|
||||||
get() {
|
get() {
|
||||||
class GetterLocalClass {
|
class GetterLocalClass {
|
||||||
init {
|
init {
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ public interface ResolvedCall<D extends Descriptor> {
|
|||||||
|
|
||||||
// FILE: test.kt
|
// FILE: test.kt
|
||||||
|
|
||||||
val Descriptor.name = "123"
|
val Descriptor.name = <!EXTENSION_PROPERTY_WITH_BACKING_FIELD!>"123"<!>
|
||||||
fun Descriptor.correct(): Boolean = true
|
fun Descriptor.correct(): Boolean = true
|
||||||
fun Descriptor.foo() {}
|
fun Descriptor.foo() {}
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -80,7 +80,7 @@ open class J {
|
|||||||
field = value
|
field = value
|
||||||
}
|
}
|
||||||
|
|
||||||
var bar = 0
|
var bar = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>
|
||||||
get() = 3.1415926535
|
get() = 3.1415926535
|
||||||
set(value) {}
|
set(value) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ interface Some {
|
|||||||
|
|
||||||
<!REDUNDANT_OPEN_IN_INTERFACE!>open<!> var xx: Int
|
<!REDUNDANT_OPEN_IN_INTERFACE!>open<!> var xx: Int
|
||||||
open var yy = <!PROPERTY_INITIALIZER_IN_INTERFACE!>1<!>
|
open var yy = <!PROPERTY_INITIALIZER_IN_INTERFACE!>1<!>
|
||||||
open var zz: Int
|
<!BACKING_FIELD_IN_INTERFACE!>open var zz: Int<!>
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.fir.expressions.WhenMissingCase
|
|||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -303,6 +302,10 @@ val DIAGNOSTICS_LIST = DiagnosticListBuilder.buildDiagnosticList {
|
|||||||
val PROPERTY_INITIALIZER_IN_INTERFACE by error<FirSourceElement, KtExpression>()
|
val PROPERTY_INITIALIZER_IN_INTERFACE by error<FirSourceElement, KtExpression>()
|
||||||
val PROPERTY_WITH_NO_TYPE_NO_INITIALIZER by error<FirSourceElement, KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
|
val PROPERTY_WITH_NO_TYPE_NO_INITIALIZER by error<FirSourceElement, KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
|
||||||
|
|
||||||
|
val BACKING_FIELD_IN_INTERFACE by error<FirSourceElement, KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
|
||||||
|
val EXTENSION_PROPERTY_WITH_BACKING_FIELD by error<FirSourceElement, KtExpression>()
|
||||||
|
val PROPERTY_INITIALIZER_NO_BACKING_FIELD by error<FirSourceElement, KtExpression>()
|
||||||
|
|
||||||
val ABSTRACT_DELEGATED_PROPERTY by error<FirSourceElement, KtPropertyDelegate>()
|
val ABSTRACT_DELEGATED_PROPERTY by error<FirSourceElement, KtPropertyDelegate>()
|
||||||
val DELEGATED_PROPERTY_IN_INTERFACE by error<FirSourceElement, KtPropertyDelegate>()
|
val DELEGATED_PROPERTY_IN_INTERFACE by error<FirSourceElement, KtPropertyDelegate>()
|
||||||
// TODO: val ACCESSOR_FOR_DELEGATED_PROPERTY by error1<FirSourceElement, PsiElement, FirPropertyAccessorSymbol>()
|
// TODO: val ACCESSOR_FOR_DELEGATED_PROPERTY by error1<FirSourceElement, PsiElement, FirPropertyAccessorSymbol>()
|
||||||
|
|||||||
@@ -200,6 +200,9 @@ object FirErrors {
|
|||||||
val ABSTRACT_PROPERTY_WITH_INITIALIZER by error0<FirSourceElement, KtExpression>()
|
val ABSTRACT_PROPERTY_WITH_INITIALIZER by error0<FirSourceElement, KtExpression>()
|
||||||
val PROPERTY_INITIALIZER_IN_INTERFACE by error0<FirSourceElement, KtExpression>()
|
val PROPERTY_INITIALIZER_IN_INTERFACE by error0<FirSourceElement, KtExpression>()
|
||||||
val PROPERTY_WITH_NO_TYPE_NO_INITIALIZER by error0<FirSourceElement, KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
val PROPERTY_WITH_NO_TYPE_NO_INITIALIZER by error0<FirSourceElement, KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||||
|
val BACKING_FIELD_IN_INTERFACE by error0<FirSourceElement, KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||||
|
val EXTENSION_PROPERTY_WITH_BACKING_FIELD by error0<FirSourceElement, KtExpression>()
|
||||||
|
val PROPERTY_INITIALIZER_NO_BACKING_FIELD by error0<FirSourceElement, KtExpression>()
|
||||||
val ABSTRACT_DELEGATED_PROPERTY by error0<FirSourceElement, KtPropertyDelegate>()
|
val ABSTRACT_DELEGATED_PROPERTY by error0<FirSourceElement, KtPropertyDelegate>()
|
||||||
val DELEGATED_PROPERTY_IN_INTERFACE by error0<FirSourceElement, KtPropertyDelegate>()
|
val DELEGATED_PROPERTY_IN_INTERFACE by error0<FirSourceElement, KtPropertyDelegate>()
|
||||||
val ABSTRACT_PROPERTY_WITH_GETTER by error0<FirSourceElement, KtPropertyAccessor>()
|
val ABSTRACT_PROPERTY_WITH_GETTER by error0<FirSourceElement, KtPropertyAccessor>()
|
||||||
|
|||||||
+3
-4
@@ -59,11 +59,10 @@ internal fun checkPropertyInitializer(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: not exactly...
|
|
||||||
val backingFieldRequired = property.hasBackingField
|
val backingFieldRequired = property.hasBackingField
|
||||||
if (inInterface && backingFieldRequired && property.hasAccessorImplementation) {
|
if (inInterface && backingFieldRequired && property.hasAccessorImplementation) {
|
||||||
property.source?.let {
|
property.source?.let {
|
||||||
// reporter.reportOn(it, FirErrors.BACKING_FIELD_IN_INTERFACE, context)
|
reporter.reportOn(it, FirErrors.BACKING_FIELD_IN_INTERFACE, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,10 +79,10 @@ internal fun checkPropertyInitializer(
|
|||||||
reporter.reportOn(it, FirErrors.EXPECTED_PROPERTY_INITIALIZER, context)
|
reporter.reportOn(it, FirErrors.EXPECTED_PROPERTY_INITIALIZER, context)
|
||||||
}
|
}
|
||||||
!backingFieldRequired -> {
|
!backingFieldRequired -> {
|
||||||
// reporter.reportOn(it, FirErrors.PROPERTY_INITIALIZER_NO_BACKING_FIELD, context)
|
reporter.reportOn(it, FirErrors.PROPERTY_INITIALIZER_NO_BACKING_FIELD, context)
|
||||||
}
|
}
|
||||||
property.receiverTypeRef != null -> {
|
property.receiverTypeRef != null -> {
|
||||||
// reporter.reportOn(it, FirErrors.EXTENSION_PROPERTY_WITH_BACKING_FIELD, context)
|
reporter.reportOn(it, FirErrors.EXTENSION_PROPERTY_WITH_BACKING_FIELD, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANY_METHOD_IMPLEM
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGNED_VALUE_IS_NEVER_READ
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGNED_VALUE_IS_NEVER_READ
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGN_OPERATOR_AMBIGUITY
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGN_OPERATOR_AMBIGUITY
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BACKING_FIELD_IN_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE
|
||||||
@@ -71,6 +72,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_CLA
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_INTERFACE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPE_PARAMETER_BOUND
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPE_PARAMETER_BOUND
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXTENSION_PROPERTY_WITH_BACKING_FIELD
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUNCTION_DECLARATION_WITH_NO_NAME
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUNCTION_DECLARATION_WITH_NO_NAME
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.GENERIC_THROWABLE_SUBCLASS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.GENERIC_THROWABLE_SUBCLASS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HIDDEN
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HIDDEN
|
||||||
@@ -116,6 +118,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRIVATE_SETTER_FO
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRIVATE_SETTER_FOR_OPEN_PROPERTY
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRIVATE_SETTER_FOR_OPEN_PROPERTY
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_INITIALIZER_IN_INTERFACE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_INITIALIZER_IN_INTERFACE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_INITIALIZER_NO_BACKING_FIELD
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_TYPE_MISMATCH_ON_OVERRIDE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_TYPE_MISMATCH_ON_OVERRIDE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_WITH_NO_TYPE_NO_INITIALIZER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_WITH_NO_TYPE_NO_INITIALIZER
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE
|
||||||
@@ -440,11 +443,16 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
|||||||
map.put(PRIVATE_PROPERTY_IN_INTERFACE, "Abstract property in an interface cannot be private")
|
map.put(PRIVATE_PROPERTY_IN_INTERFACE, "Abstract property in an interface cannot be private")
|
||||||
|
|
||||||
map.put(ABSTRACT_PROPERTY_WITH_INITIALIZER, "Property with initializer cannot be abstract")
|
map.put(ABSTRACT_PROPERTY_WITH_INITIALIZER, "Property with initializer cannot be abstract")
|
||||||
|
|
||||||
|
map.put(EXTENSION_PROPERTY_WITH_BACKING_FIELD, "Extension property cannot be initialized because it has no backing field")
|
||||||
|
map.put(PROPERTY_INITIALIZER_NO_BACKING_FIELD, "Initializer is not allowed here because this property has no backing field")
|
||||||
|
|
||||||
map.put(PROPERTY_INITIALIZER_IN_INTERFACE, "Property initializers are not allowed in interfaces")
|
map.put(PROPERTY_INITIALIZER_IN_INTERFACE, "Property initializers are not allowed in interfaces")
|
||||||
map.put(
|
map.put(
|
||||||
PROPERTY_WITH_NO_TYPE_NO_INITIALIZER,
|
PROPERTY_WITH_NO_TYPE_NO_INITIALIZER,
|
||||||
"This property must either have a type annotation, be initialized or be delegated"
|
"This property must either have a type annotation, be initialized or be delegated"
|
||||||
)
|
)
|
||||||
|
map.put(BACKING_FIELD_IN_INTERFACE, "Property in an interface cannot have a backing field")
|
||||||
|
|
||||||
map.put(ABSTRACT_DELEGATED_PROPERTY, "Delegated property cannot be abstract")
|
map.put(ABSTRACT_DELEGATED_PROPERTY, "Delegated property cannot be abstract")
|
||||||
map.put(DELEGATED_PROPERTY_IN_INTERFACE, "Delegated properties are not allowed in interfaces")
|
map.put(DELEGATED_PROPERTY_IN_INTERFACE, "Delegated properties are not allowed in interfaces")
|
||||||
|
|||||||
+20
-23
@@ -752,32 +752,29 @@ class Fir2IrDeclarationStorage(
|
|||||||
val delegate = property.delegate
|
val delegate = property.delegate
|
||||||
val getter = property.getter
|
val getter = property.getter
|
||||||
val setter = property.setter
|
val setter = property.setter
|
||||||
if (property.isConst || (property.modality != Modality.ABSTRACT && (irParent !is IrClass || !irParent.isInterface))) {
|
if (delegate != null || property.hasBackingField) {
|
||||||
if (property.hasBackingField) {
|
backingField = if (delegate != null) {
|
||||||
backingField = if (delegate != null) {
|
createBackingField(
|
||||||
createBackingField(
|
property, IrDeclarationOrigin.PROPERTY_DELEGATE, descriptor,
|
||||||
property, IrDeclarationOrigin.PROPERTY_DELEGATE, descriptor,
|
components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility),
|
||||||
components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility),
|
Name.identifier("${property.name}\$delegate"), true, delegate
|
||||||
Name.identifier("${property.name}\$delegate"), true, delegate
|
)
|
||||||
)
|
} else {
|
||||||
} else {
|
createBackingField(
|
||||||
createBackingField(
|
property, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, descriptor,
|
||||||
property, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, descriptor,
|
components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility),
|
||||||
components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility),
|
property.name, property.isVal, initializer, type
|
||||||
property.name, property.isVal, initializer, type
|
).also { field ->
|
||||||
).also { field ->
|
if (initializer is FirConstExpression<*>) {
|
||||||
if (initializer is FirConstExpression<*>) {
|
// TODO: Normally we shouldn't have error type here
|
||||||
// TODO: Normally we shouldn't have error type here
|
val constType = initializer.typeRef.toIrType().takeIf { it !is IrErrorType } ?: type
|
||||||
val constType = initializer.typeRef.toIrType().takeIf { it !is IrErrorType } ?: type
|
field.initializer = factory.createExpressionBody(initializer.toIrConst(constType))
|
||||||
field.initializer = factory.createExpressionBody(initializer.toIrConst(constType))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (irParent != null) {
|
}
|
||||||
backingField?.parent = irParent
|
if (irParent != null) {
|
||||||
}
|
backingField?.parent = irParent
|
||||||
|
|
||||||
}
|
}
|
||||||
this.getter = createIrPropertyAccessor(
|
this.getter = createIrPropertyAccessor(
|
||||||
getter, property, this, type, irParent, thisReceiverOwner, false,
|
getter, property, this, type, irParent, thisReceiverOwner, false,
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ import org.jetbrains.kotlin.descriptors.SourceElement
|
|||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.FirRegularClassBuilder
|
import org.jetbrains.kotlin.fir.declarations.builder.FirRegularClassBuilder
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.FirTypeParameterBuilder
|
import org.jetbrains.kotlin.fir.declarations.builder.FirTypeParameterBuilder
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirFileImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirFileImpl
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirRegularClassImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirRegularClassImpl
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol
|
||||||
@@ -141,6 +139,7 @@ fun FirRegularClass.addDeclaration(declaration: FirDeclaration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private object SourceElementKey : FirDeclarationDataKey()
|
private object SourceElementKey : FirDeclarationDataKey()
|
||||||
|
|
||||||
var FirRegularClass.sourceElement: SourceElement? by FirDeclarationDataRegistry.data(SourceElementKey)
|
var FirRegularClass.sourceElement: SourceElement? by FirDeclarationDataRegistry.data(SourceElementKey)
|
||||||
|
|
||||||
val FirMemberDeclaration.containerSource: SourceElement?
|
val FirMemberDeclaration.containerSource: SourceElement?
|
||||||
@@ -151,16 +150,31 @@ val FirMemberDeclaration.containerSource: SourceElement?
|
|||||||
}
|
}
|
||||||
|
|
||||||
private object IsFromVarargKey : FirDeclarationDataKey()
|
private object IsFromVarargKey : FirDeclarationDataKey()
|
||||||
var FirProperty.isFromVararg: Boolean? by FirDeclarationDataRegistry.data(IsFromVarargKey)
|
|
||||||
private object IsReferredViaField : FirDeclarationDataKey()
|
private object IsReferredViaField : FirDeclarationDataKey()
|
||||||
|
|
||||||
|
var FirProperty.isFromVararg: Boolean? by FirDeclarationDataRegistry.data(IsFromVarargKey)
|
||||||
var FirProperty.isReferredViaField: Boolean? by FirDeclarationDataRegistry.data(IsReferredViaField)
|
var FirProperty.isReferredViaField: Boolean? by FirDeclarationDataRegistry.data(IsReferredViaField)
|
||||||
|
|
||||||
|
// See [BindingContext.BACKING_FIELD_REQUIRED]
|
||||||
val FirProperty.hasBackingField: Boolean
|
val FirProperty.hasBackingField: Boolean
|
||||||
get() = initializer != null ||
|
get() {
|
||||||
getter is FirDefaultPropertyGetter ||
|
if (isAbstract) return false
|
||||||
isVar && setter is FirDefaultPropertySetter ||
|
if (delegate != null) return false
|
||||||
delegate != null ||
|
when (origin) {
|
||||||
isReferredViaField == true
|
FirDeclarationOrigin.SubstitutionOverride -> return false
|
||||||
|
FirDeclarationOrigin.IntersectionOverride -> return false
|
||||||
|
FirDeclarationOrigin.Delegated -> return false
|
||||||
|
else -> {
|
||||||
|
val getter = getter ?: return true
|
||||||
|
if (isVar && setter == null) return true
|
||||||
|
if (setter?.hasBody == false) return true
|
||||||
|
if (!getter.hasBody) return true
|
||||||
|
|
||||||
|
return isReferredViaField == true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline val FirDeclaration.isFromLibrary: Boolean
|
inline val FirDeclaration.isFromLibrary: Boolean
|
||||||
get() = origin == FirDeclarationOrigin.Library
|
get() = origin == FirDeclarationOrigin.Library
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ package MyPackage
|
|||||||
abstract var c3: Int = 0; set(v: Int) { field = v }
|
abstract var c3: Int = 0; set(v: Int) { field = v }
|
||||||
|
|
||||||
val e: Int get() = a
|
val e: Int get() = a
|
||||||
val e1: Int = 0; get() = a
|
val e1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; get() = a
|
||||||
abstract val e2: Int get() = a
|
abstract val e2: Int get() = a
|
||||||
abstract val e3: Int = 0; get() = a
|
abstract val e3: Int = 0; get() = a
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ abstract class MyAbstractClass() {
|
|||||||
abstract var c3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_SETTER!>set(v: Int) { field = v }<!>
|
abstract var c3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_SETTER!>set(v: Int) { field = v }<!>
|
||||||
|
|
||||||
val e: Int get() = a
|
val e: Int get() = a
|
||||||
val e1: Int = 0; get() = a
|
val e1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; get() = a
|
||||||
abstract val e2: Int <!ABSTRACT_PROPERTY_WITH_GETTER!>get() = a<!>
|
abstract val e2: Int <!ABSTRACT_PROPERTY_WITH_GETTER!>get() = a<!>
|
||||||
abstract val e3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_GETTER!>get() = a<!>
|
abstract val e3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_GETTER!>get() = a<!>
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class MyClass() {
|
|||||||
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> var c3: Int = 0; set(v: Int) { field = v }
|
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> var c3: Int = 0; set(v: Int) { field = v }
|
||||||
|
|
||||||
val e: Int get() = a
|
val e: Int get() = a
|
||||||
val e1: Int = 0; get() = a
|
val e1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; get() = a
|
||||||
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> val e2: Int get() = a
|
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> val e2: Int get() = a
|
||||||
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> val e3: Int = 0; get() = a
|
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> val e3: Int = 0; get() = a
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ interface MyTrait {
|
|||||||
abstract var b2: Int private set
|
abstract var b2: Int private set
|
||||||
abstract var b3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; private set
|
abstract var b3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; private set
|
||||||
|
|
||||||
var c: Int set(v: Int) { field = v }
|
<!BACKING_FIELD_IN_INTERFACE!>var c: Int<!> set(v: Int) { field = v }
|
||||||
var c1: Int = <!PROPERTY_INITIALIZER_IN_INTERFACE!>0<!>; set(v: Int) { field = v }
|
<!BACKING_FIELD_IN_INTERFACE!>var c1: Int<!> = <!PROPERTY_INITIALIZER_IN_INTERFACE!>0<!>; set(v: Int) { field = v }
|
||||||
abstract var c2: Int <!ABSTRACT_PROPERTY_WITH_SETTER!>set(v: Int) { field = v }<!>
|
abstract var c2: Int <!ABSTRACT_PROPERTY_WITH_SETTER!>set(v: Int) { field = v }<!>
|
||||||
abstract var c3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_SETTER!>set(v: Int) { field = v }<!>
|
abstract var c3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_SETTER!>set(v: Int) { field = v }<!>
|
||||||
|
|
||||||
@@ -32,8 +32,8 @@ interface MyTrait {
|
|||||||
var i: Int abstract get abstract set
|
var i: Int abstract get abstract set
|
||||||
var i1: Int = <!PROPERTY_INITIALIZER_IN_INTERFACE!>0<!>; abstract get abstract set
|
var i1: Int = <!PROPERTY_INITIALIZER_IN_INTERFACE!>0<!>; abstract get abstract set
|
||||||
|
|
||||||
var j: Int get() = i; abstract set
|
<!BACKING_FIELD_IN_INTERFACE!>var j: Int<!> get() = i; abstract set
|
||||||
var j1: Int = <!PROPERTY_INITIALIZER_IN_INTERFACE!>0<!>; get() = i; abstract set
|
<!BACKING_FIELD_IN_INTERFACE!>var j1: Int<!> = <!PROPERTY_INITIALIZER_IN_INTERFACE!>0<!>; get() = i; abstract set
|
||||||
|
|
||||||
var k: Int abstract set
|
var k: Int abstract set
|
||||||
var k1: Int = <!PROPERTY_INITIALIZER_IN_INTERFACE!>0<!>; abstract set
|
var k1: Int = <!PROPERTY_INITIALIZER_IN_INTERFACE!>0<!>; abstract set
|
||||||
@@ -41,5 +41,5 @@ interface MyTrait {
|
|||||||
var l: Int abstract get abstract set
|
var l: Int abstract get abstract set
|
||||||
var l1: Int = <!PROPERTY_INITIALIZER_IN_INTERFACE!>0<!>; abstract get abstract set
|
var l1: Int = <!PROPERTY_INITIALIZER_IN_INTERFACE!>0<!>; abstract get abstract set
|
||||||
|
|
||||||
var n: Int abstract get abstract set(v: Int) {}
|
<!BACKING_FIELD_IN_INTERFACE!>var n: Int<!> abstract get abstract set(v: Int) {}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -29,7 +29,7 @@ class WithCPI(x : Int) {
|
|||||||
|
|
||||||
class NoCPI {
|
class NoCPI {
|
||||||
val a = 1
|
val a = 1
|
||||||
var ab = 1
|
var ab = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>1<!>
|
||||||
get() = 1
|
get() = 1
|
||||||
set(v) {}
|
set(v) {}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -5,11 +5,11 @@ var x : Int = 1 + x
|
|||||||
field = 1.toLong()
|
field = 1.toLong()
|
||||||
}
|
}
|
||||||
|
|
||||||
val xx : Int = 1 + x
|
val xx : Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>1 + x<!>
|
||||||
get() : Int = 1
|
get() : Int = 1
|
||||||
set(value : Long) {}
|
set(value : Long) {}
|
||||||
|
|
||||||
val p : Int = 1
|
val p : Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>1<!>
|
||||||
get() = 1
|
get() = 1
|
||||||
|
|
||||||
class Test() {
|
class Test() {
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
// See KT-9303: synthetic field variable does not exist for extension properties
|
|
||||||
val String.foo: Int
|
|
||||||
get() {
|
|
||||||
// No shadowing here
|
|
||||||
val field = 42
|
|
||||||
return field
|
|
||||||
}
|
|
||||||
|
|
||||||
val String.bar: Int = 13
|
|
||||||
// Error
|
|
||||||
get() = <!UNRESOLVED_REFERENCE!>field<!>
|
|
||||||
|
|
||||||
class My {
|
|
||||||
val String.x: Int = 7
|
|
||||||
// Error
|
|
||||||
get() = <!UNRESOLVED_REFERENCE!>field<!>
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// See KT-9303: synthetic field variable does not exist for extension properties
|
// See KT-9303: synthetic field variable does not exist for extension properties
|
||||||
val String.foo: Int
|
val String.foo: Int
|
||||||
get() {
|
get() {
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
interface My {
|
|
||||||
val x: Int = <!PROPERTY_INITIALIZER_IN_INTERFACE!>0<!>
|
|
||||||
get() = field
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
interface My {
|
interface My {
|
||||||
<!BACKING_FIELD_IN_INTERFACE!>val x: Int<!> = <!PROPERTY_INITIALIZER_IN_INTERFACE!>0<!>
|
<!BACKING_FIELD_IN_INTERFACE!>val x: Int<!> = <!PROPERTY_INITIALIZER_IN_INTERFACE!>0<!>
|
||||||
get() = field
|
get() = field
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ enum class MyEnum() {
|
|||||||
abstract var c3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_SETTER!>set(v: Int) { field = v }<!>
|
abstract var c3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_SETTER!>set(v: Int) { field = v }<!>
|
||||||
|
|
||||||
val e: Int get() = a
|
val e: Int get() = a
|
||||||
val e1: Int = 0; get() = a
|
val e1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; get() = a
|
||||||
abstract val e2: Int <!ABSTRACT_PROPERTY_WITH_GETTER!>get() = a<!>
|
abstract val e2: Int <!ABSTRACT_PROPERTY_WITH_GETTER!>get() = a<!>
|
||||||
abstract val e3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_GETTER!>get() = a<!>
|
abstract val e3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_GETTER!>get() = a<!>
|
||||||
|
|
||||||
|
|||||||
@@ -13,5 +13,5 @@ const val intArrayConst: IntArray = intArrayOf()
|
|||||||
|
|
||||||
const val unresolvedConst1 = <!UNRESOLVED_REFERENCE!>Unresolved<!>
|
const val unresolvedConst1 = <!UNRESOLVED_REFERENCE!>Unresolved<!>
|
||||||
const var unresolvedConst2 = <!UNRESOLVED_REFERENCE!>Unresolved<!>
|
const var unresolvedConst2 = <!UNRESOLVED_REFERENCE!>Unresolved<!>
|
||||||
const val unresolvedConst3 = <!UNRESOLVED_REFERENCE!>Unresolved<!>
|
const val unresolvedConst3 = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD, UNRESOLVED_REFERENCE!>Unresolved<!>
|
||||||
get() = 10
|
get() = 10
|
||||||
|
|||||||
+5
-5
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
package i
|
package i
|
||||||
|
|
||||||
val <T> List<T>.length = <!UNRESOLVED_REFERENCE!>size<!>
|
val <T> List<T>.length = <!EXTENSION_PROPERTY_WITH_BACKING_FIELD, UNRESOLVED_REFERENCE!>size<!>
|
||||||
|
|
||||||
val <T> List<T>.length1 : Int get() = size
|
val <T> List<T>.length1 : Int get() = size
|
||||||
|
|
||||||
val String.bd = <!NO_THIS!>this<!> + "!"
|
val String.bd = <!EXTENSION_PROPERTY_WITH_BACKING_FIELD!><!NO_THIS!>this<!> + "!"<!>
|
||||||
|
|
||||||
val String.bd1 : String get() = this + "!"
|
val String.bd1 : String get() = this + "!"
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ class A {
|
|||||||
val ii : Int = 1
|
val ii : Int = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
val A.foo = <!UNRESOLVED_REFERENCE!>ii<!>
|
val A.foo = <!EXTENSION_PROPERTY_WITH_BACKING_FIELD, UNRESOLVED_REFERENCE!>ii<!>
|
||||||
|
|
||||||
val A.foo1 : Int get() = ii
|
val A.foo1 : Int get() = ii
|
||||||
|
|
||||||
@@ -24,8 +24,8 @@ class C {
|
|||||||
inner class D {}
|
inner class D {}
|
||||||
}
|
}
|
||||||
|
|
||||||
val C.foo : C.D = <!UNRESOLVED_REFERENCE!>D<!>()
|
val C.foo : C.D = <!EXTENSION_PROPERTY_WITH_BACKING_FIELD!><!UNRESOLVED_REFERENCE!>D<!>()<!>
|
||||||
|
|
||||||
val C.bar : C.D = C().D()
|
val C.bar : C.D = C().<!EXTENSION_PROPERTY_WITH_BACKING_FIELD!>D()<!>
|
||||||
|
|
||||||
val C.foo1 : C.D get() = D()
|
val C.foo1 : C.D get() = D()
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
interface Base {
|
interface Base {
|
||||||
fun foo()
|
fun foo()
|
||||||
}
|
}
|
||||||
val String.test: Base = object: Base {
|
val String.test: Base = <!EXTENSION_PROPERTY_WITH_BACKING_FIELD!>object: Base<!> {
|
||||||
override fun foo() {
|
override fun foo() {
|
||||||
<!UNRESOLVED_LABEL!>this@test<!>
|
<!UNRESOLVED_LABEL!>this@test<!>
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -56,7 +56,7 @@ val topLevelAnonymousFunction = fun (x: Boolean) {
|
|||||||
contract { returns() implies (x) }
|
contract { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
var topLevelPropertyAccessors: Int? = 42
|
var topLevelPropertyAccessors: Int? = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>42<!>
|
||||||
get() {
|
get() {
|
||||||
contract { returns() implies (<!UNRESOLVED_REFERENCE!>field<!> != null) }
|
contract { returns() implies (<!UNRESOLVED_REFERENCE!>field<!> != null) }
|
||||||
return 42
|
return 42
|
||||||
|
|||||||
Vendored
+1
-1
@@ -71,7 +71,7 @@ val topLevelAnonymousFunction = fun (x: Boolean) {
|
|||||||
contract { returns() implies (x) }
|
contract { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
var topLevelPropertyAccessors: Int? = 42
|
var topLevelPropertyAccessors: Int? = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>42<!>
|
||||||
get() {
|
get() {
|
||||||
contract { returns() implies (<!UNRESOLVED_REFERENCE!>field<!> != null) }
|
contract { returns() implies (<!UNRESOLVED_REFERENCE!>field<!> != null) }
|
||||||
return 42
|
return 42
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ KtFirKotlinPropertySymbol:
|
|||||||
callableIdIfNonLocal: kotlin.CharSequence.length
|
callableIdIfNonLocal: kotlin.CharSequence.length
|
||||||
dispatchType: kotlin/CharSequence
|
dispatchType: kotlin/CharSequence
|
||||||
getter: KtFirPropertyGetterSymbol(<getter>)
|
getter: KtFirPropertyGetterSymbol(<getter>)
|
||||||
hasBackingField: true
|
hasBackingField: false
|
||||||
hasGetter: true
|
hasGetter: true
|
||||||
hasSetter: false
|
hasSetter: false
|
||||||
initializer: null
|
initializer: null
|
||||||
|
|||||||
Reference in New Issue
Block a user