Prohibit 'expect' lateinit member properties

#KT-20319 Fixed
This commit is contained in:
Alexander Udalov
2017-09-19 11:23:23 +03:00
parent 1f992ed845
commit 8ae7343557
7 changed files with 15 additions and 8 deletions
@@ -563,6 +563,7 @@ public interface Errors {
DiagnosticFactory0<KtEnumEntry> EXPECTED_ENUM_ENTRY_WITH_BODY = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtExpression> EXPECTED_PROPERTY_INITIALIZER = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtPropertyDelegate> EXPECTED_DELEGATED_PROPERTY = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> EXPECTED_LATEINIT_PROPERTY = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtTypeAlias> ACTUAL_TYPE_ALIAS_NOT_TO_CLASS = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory0<KtTypeAlias>
@@ -271,6 +271,7 @@ public class DefaultErrorMessages {
MAP.put(EXPECTED_ENUM_ENTRY_WITH_BODY, "Expected enum entry cannot have a body");
MAP.put(EXPECTED_PROPERTY_INITIALIZER, "Expected property cannot have an initializer");
MAP.put(EXPECTED_DELEGATED_PROPERTY, "Expected property cannot be delegated");
MAP.put(EXPECTED_LATEINIT_PROPERTY, "Expected property cannot be lateinit");
MAP.put(ACTUAL_TYPE_ALIAS_NOT_TO_CLASS, "Right-hand side of actual type alias should be a class, not another type alias");
MAP.put(ACTUAL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE, "Aliased class should not have type parameters with declaration-site variance");
@@ -670,9 +670,14 @@ class DeclarationsChecker(
else if (noExplicitTypeOrGetterType(property)) {
trace.report(PROPERTY_WITH_NO_TYPE_NO_INITIALIZER.on(property))
}
if (backingFieldRequired && !inInterface && propertyDescriptor.isLateInit && !isUninitialized &&
trace[MUST_BE_LATEINIT, propertyDescriptor] != true) {
trace.report(UNNECESSARY_LATEINIT.on(property))
if (propertyDescriptor.isLateInit) {
if (propertyDescriptor.isExpect) {
trace.report(EXPECTED_LATEINIT_PROPERTY.on(property.modifierList?.getModifier(KtTokens.LATEINIT_KEYWORD) ?: property))
}
if (backingFieldRequired && !inInterface && !isUninitialized && trace[MUST_BE_LATEINIT, propertyDescriptor] != true) {
trace.report(UNNECESSARY_LATEINIT.on(property))
}
}
}
}
@@ -191,9 +191,6 @@ object ModifierCheckerCore {
// (see the KEEP https://github.com/Kotlin/KEEP/blob/master/proposals/sealed-class-inheritance.md)
result += incompatibilityRegister(SEALED_KEYWORD, INNER_KEYWORD)
// lateinit is incompatible with header / expect
result += incompatibilityRegister(LATEINIT_KEYWORD, HEADER_KEYWORD, EXPECT_KEYWORD)
// header / expect / impl / actual are all incompatible
result += incompatibilityRegister(HEADER_KEYWORD, EXPECT_KEYWORD, IMPL_KEYWORD, ACTUAL_KEYWORD)
@@ -23,6 +23,8 @@ expect class Foo {
<!EXPECTED_DECLARATION_WITH_BODY!>get()<!> = "no"
<!EXPECTED_DECLARATION_WITH_BODY!>set(value)<!> {}
<!EXPECTED_LATEINIT_PROPERTY!>lateinit<!> var lateinitVar: String
val delegated: String <!EXPECTED_DELEGATED_PROPERTY!>by Delegate<!>
}
@@ -17,6 +17,7 @@ public final expect class Foo {
public expect final val delegated: kotlin.String
public expect final val justVal: kotlin.String
public expect final var justVar: kotlin.String
public expect final lateinit var lateinitVar: kotlin.String
public expect final val valWithGet: kotlin.String
public expect final var varWithGetSet: kotlin.String
public expect final val kotlin.String.extensionVal: kotlin.Unit
@@ -1,4 +1,4 @@
// !LANGUAGE: +MultiPlatformProjects
// !LANGUAGE: +MultiPlatformProjects +LateinitTopLevelProperties
// MODULE: m1-common
// FILE: common.kt
@@ -28,7 +28,7 @@ expect var customAccessorVar: String
expect <!CONST_VAL_WITHOUT_INITIALIZER!>const<!> val constVal: Int
<!INCOMPATIBLE_MODIFIERS!>expect<!> <!INCOMPATIBLE_MODIFIERS!>lateinit<!> var lateinitVar: String
expect <!EXPECTED_LATEINIT_PROPERTY!>lateinit<!> var lateinitVar: String
expect val delegated: String <!EXPECTED_DELEGATED_PROPERTY!>by Delegate<!>
object Delegate { operator fun getValue(x: Any?, y: Any?): String = "" }