FIR checker: add diagnostics for backing fields

This commit is contained in:
Jinseong Jeon
2021-02-02 13:25:59 -08:00
committed by Mikhail Glukhikh
parent a88b82d8ff
commit bd37badf29
27 changed files with 89 additions and 84 deletions
@@ -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 {
@@ -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() {}
@@ -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
} }
@@ -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>()
@@ -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)
} }
} }
} }
@@ -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")
@@ -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
View File
@@ -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<!>
+1 -1
View File
@@ -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
+5 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
@@ -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,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<!>
} }
@@ -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
@@ -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