Revert "Temporarily remove isInitialized and tests, but keep the implementation"

This reverts commit 234148518e.
This commit is contained in:
Alexander Udalov
2017-09-15 20:15:28 +03:00
committed by Ilya Gorbunov
parent abdcbf1fb2
commit 00be512532
14 changed files with 436 additions and 0 deletions
@@ -0,0 +1,35 @@
// TARGET_BACKEND: JVM
// LANGUAGE_VERSION: 1.2
// WITH_RUNTIME
open class Foo {
lateinit var bar: String
private lateinit var baz: String
fun test(): String {
val isBarInitialized: () -> Boolean = { this::bar.isInitialized }
if (isBarInitialized()) return "Fail 1"
bar = "bar"
if (!isBarInitialized()) return "Fail 2"
baz = "baz"
return InnerSubclass().testInner()
}
inner class InnerSubclass : Foo() {
fun testInner(): String {
// This is access to InnerSubclass.bar which is inherited from Foo.bar
if (this::bar.isInitialized) return "Fail 3"
bar = "OK"
if (!this::bar.isInitialized) return "Fail 4"
// This is access to Foo.bar declared lexically above
if (!this@Foo::bar.isInitialized) return "Fail 5"
return "OK"
}
}
}
fun box(): String {
return Foo().test()
}
@@ -0,0 +1,21 @@
// TARGET_BACKEND: JVM
// LANGUAGE_VERSION: 1.2
// WITH_RUNTIME
class Foo {
lateinit var bar: String
fun test(): String {
var state = 0
if (run { state++; this }::bar.isInitialized) return "Fail 1"
bar = "A"
if (!run { state++; this }::bar.isInitialized) return "Fail 3"
return if (state == 2) "OK" else "Fail: state=$state"
}
}
fun box(): String {
return Foo().test()
}
@@ -0,0 +1,36 @@
// TARGET_BACKEND: JVM
// LANGUAGE_VERSION: 1.2
// WITH_RUNTIME
// FILE: J.java
public class J {
public static void deinitialize(Foo foo) {
foo.bar = null;
}
}
// FILE: main.kt
class Foo {
lateinit var bar: String
fun test(): String {
if (this::bar.isInitialized) return "Fail 1"
J.deinitialize(this)
if (this::bar.isInitialized) return "Fail 2"
bar = "A"
if (!this::bar.isInitialized) return "Fail 3"
J.deinitialize(this)
if (this::bar.isInitialized) return "Fail 4"
bar = "OK"
if (!this::bar.isInitialized) return "Fail 5"
return bar
}
}
fun box(): String {
return Foo().test()
}
@@ -0,0 +1,12 @@
// TARGET_BACKEND: JVM
// LANGUAGE_VERSION: 1.2
// WITH_RUNTIME
lateinit var bar: String
fun box(): String {
if (::bar.isInitialized) return "Fail 1"
bar = "OK"
if (!::bar.isInitialized) return "Fail 2"
return bar
}
@@ -0,0 +1,88 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -NOTHING_TO_INLINE
// !API_VERSION: 1.2
// FILE: test.kt
interface Base {
var x: String
}
open class Foo : Base {
override lateinit var x: String
private lateinit var y: String
var nonLateInit: Int = 1
fun ok() {
val b: Boolean = this::x.isInitialized
val otherInstance = Foo()
otherInstance::x.isInitialized
(this::x).isInitialized
(@Suppress("ALL") (this::x)).isInitialized
object {
fun local() {
class Local {
val xx = this@Foo::x.isInitialized
val yy = this@Foo::y.isInitialized
}
}
}
}
fun onLiteral() {
val p = this::x
p.<!LATEINIT_INTRINSIC_CALL_ON_NON_LITERAL!>isInitialized<!>
}
fun onNonLateinit() {
this::nonLateInit.<!LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT!>isInitialized<!>
}
inline fun inlineFun() {
this::x.<!LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION!>isInitialized<!>
object {
val z = this@Foo::x.isInitialized
}
}
inner class InnerSubclass : Foo() {
fun innerOk() {
// This is access to Foo.x declared lexically above
this@Foo::x.isInitialized
// This is access to InnerSubclass.x which is inherited from Foo.x
this::x.isInitialized
}
}
}
fun onNonAccessible() {
Foo()::x.<!LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY!>isInitialized<!>
}
fun onNonLateinit() {
Foo()::nonLateInit.<!LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT!>isInitialized<!>
}
object Unrelated {
fun onNonAccessible() {
Foo()::x.<!LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY!>isInitialized<!>
}
}
class FooImpl : Foo() {
fun onNonAccessible() {
this::x.<!LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY!>isInitialized<!>
}
}
// FILE: other.kt
class OtherFooImpl : Foo() {
fun onNonAccessible() {
this::x.<!LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY!>isInitialized<!>
}
}
@@ -0,0 +1,78 @@
package
public fun onNonAccessible(): kotlin.Unit
public fun onNonLateinit(): kotlin.Unit
public interface Base {
public abstract var x: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class Foo : Base {
public constructor Foo()
public final var nonLateInit: kotlin.Int
public open override /*1*/ lateinit var x: kotlin.String
private final lateinit var y: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final inline fun inlineFun(): kotlin.Unit
public final fun ok(): kotlin.Unit
public final fun onLiteral(): kotlin.Unit
public final fun onNonLateinit(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final inner class InnerSubclass : Foo {
public constructor InnerSubclass()
public final override /*1*/ /*fake_override*/ var nonLateInit: kotlin.Int
public open override /*1*/ lateinit /*fake_override*/ var x: kotlin.String
invisible_fake final override /*1*/ lateinit /*fake_override*/ var y: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final inline override /*1*/ /*fake_override*/ fun inlineFun(): kotlin.Unit
public final fun innerOk(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun ok(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onLiteral(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onNonLateinit(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public final class FooImpl : Foo {
public constructor FooImpl()
public final override /*1*/ /*fake_override*/ var nonLateInit: kotlin.Int
public open override /*1*/ lateinit /*fake_override*/ var x: kotlin.String
invisible_fake final override /*1*/ lateinit /*fake_override*/ var y: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final inline override /*1*/ /*fake_override*/ fun inlineFun(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun ok(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onLiteral(): kotlin.Unit
public final fun onNonAccessible(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onNonLateinit(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class OtherFooImpl : Foo {
public constructor OtherFooImpl()
public final override /*1*/ /*fake_override*/ var nonLateInit: kotlin.Int
public open override /*1*/ lateinit /*fake_override*/ var x: kotlin.String
invisible_fake final override /*1*/ lateinit /*fake_override*/ var y: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final inline override /*1*/ /*fake_override*/ fun inlineFun(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun ok(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onLiteral(): kotlin.Unit
public final fun onNonAccessible(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onNonLateinit(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public object Unrelated {
private constructor Unrelated()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun onNonAccessible(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -13861,6 +13861,39 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
doTest(fileName);
}
@TestMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class IsInitializedAndDeinitialize extends AbstractIrBlackBoxCodegenTest {
public void testAllFilesPresentInIsInitializedAndDeinitialize() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("innerSubclass.kt")
public void testInnerSubclass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt");
doTest(fileName);
}
@TestMetadata("sideEffects.kt")
public void testSideEffects() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/sideEffects.kt");
doTest(fileName);
}
@TestMetadata("simpleIsInitialized.kt")
public void testSimpleIsInitialized() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/simpleIsInitialized.kt");
doTest(fileName);
}
@TestMetadata("topLevelProperty.kt")
public void testTopLevelProperty() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/topLevelProperty.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/properties/lateinit/local")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -1371,6 +1371,21 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
}
}
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/lateinit")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Lateinit extends AbstractDiagnosticsTestWithStdLib {
public void testAllFilesPresentInLateinit() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/lateinit"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("isInitialized.kt")
public void testIsInitialized() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/lateinit/isInitialized.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/native")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -1371,6 +1371,21 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
}
}
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/lateinit")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Lateinit extends AbstractDiagnosticsTestWithStdLibUsingJavac {
public void testAllFilesPresentInLateinit() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/lateinit"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("isInitialized.kt")
public void testIsInitialized() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/lateinit/isInitialized.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/native")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -13861,6 +13861,39 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class IsInitializedAndDeinitialize extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInIsInitializedAndDeinitialize() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("innerSubclass.kt")
public void testInnerSubclass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt");
doTest(fileName);
}
@TestMetadata("sideEffects.kt")
public void testSideEffects() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/sideEffects.kt");
doTest(fileName);
}
@TestMetadata("simpleIsInitialized.kt")
public void testSimpleIsInitialized() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/simpleIsInitialized.kt");
doTest(fileName);
}
@TestMetadata("topLevelProperty.kt")
public void testTopLevelProperty() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/topLevelProperty.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/properties/lateinit/local")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -13861,6 +13861,39 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
doTest(fileName);
}
@TestMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class IsInitializedAndDeinitialize extends AbstractLightAnalysisModeTest {
public void testAllFilesPresentInIsInitializedAndDeinitialize() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("innerSubclass.kt")
public void testInnerSubclass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt");
doTest(fileName);
}
@TestMetadata("sideEffects.kt")
public void testSideEffects() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/sideEffects.kt");
doTest(fileName);
}
@TestMetadata("simpleIsInitialized.kt")
public void testSimpleIsInitialized() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/simpleIsInitialized.kt");
doTest(fileName);
}
@TestMetadata("topLevelProperty.kt")
public void testTopLevelProperty() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/topLevelProperty.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/properties/lateinit/local")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -15229,6 +15229,15 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
doTest(fileName);
}
@TestMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class IsInitializedAndDeinitialize extends AbstractJsCodegenBoxTest {
public void testAllFilesPresentInIsInitializedAndDeinitialize() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
}
}
@TestMetadata("compiler/testData/codegen/box/properties/lateinit/local")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -66,6 +66,15 @@ internal annotation class InlineOnly
@Retention(AnnotationRetention.BINARY)
internal annotation class DynamicExtension
/**
* The value of this parameter should be a property reference expression (`this::foo`), referencing a `lateinit` property,
* the backing field of which is accessible at the point where the corresponding argument is passed.
*/
@Target(AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.BINARY)
@SinceKotlin("1.2")
internal annotation class AccessibleLateinitPropertyLiteral
/**
* Specifies that this declaration is only completely supported since the specified version.
*
@@ -0,0 +1,19 @@
@file:kotlin.jvm.JvmName("LateinitKt")
@file:kotlin.jvm.JvmVersion
@file:Suppress("unused")
package kotlin
import kotlin.internal.InlineOnly
import kotlin.internal.AccessibleLateinitPropertyLiteral
import kotlin.reflect.KProperty0
/**
* Returns `true` if this lateinit property has been assigned a value, and `false` otherwise.
*
* Cannot be used in an inline function, to avoid binary compatibility issues.
*/
@SinceKotlin("1.2")
@InlineOnly
inline val @receiver:AccessibleLateinitPropertyLiteral KProperty0<*>.isInitialized: Boolean
get() = throw NotImplementedError("Implementation is intrinsic")