mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
For prototyping purposes, we only support a single trailing closure parameter to begin with.
126 lines
2.4 KiB
Swift
126 lines
2.4 KiB
Swift
// RUN: rm -rf %t
|
|
// RUN: mkdir -p %t
|
|
// RUN: %target-build-swift -Xfrontend -enable-experimental-property-behaviors %s -o %t/a.out
|
|
// RUN: %target-run %t/a.out
|
|
// REQUIRES: executable_test
|
|
// REQUIRES: rdar24874073
|
|
|
|
import StdlibUnittest
|
|
|
|
protocol delayedImmutable {
|
|
associatedtype Value
|
|
var storage: Value? { get set }
|
|
}
|
|
extension delayedImmutable {
|
|
var value: Value {
|
|
// The property can only be read after it's been initialized.
|
|
get {
|
|
guard let theValue = storage else {
|
|
fatalError("delayedImmutable property read before initialization")
|
|
}
|
|
return theValue
|
|
}
|
|
|
|
// The property can only be written once to initialize it.
|
|
set {
|
|
guard storage == nil else {
|
|
fatalError("delayedImmutable property rewritten after initialization")
|
|
}
|
|
storage = newValue
|
|
}
|
|
}
|
|
|
|
static func initStorage() -> Value? {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
protocol lazy {
|
|
associatedtype Value
|
|
var storage: Value? { get set }
|
|
func parameter() -> Value
|
|
}
|
|
extension lazy {
|
|
var value: Value {
|
|
mutating get {
|
|
if let existing = storage {
|
|
return existing
|
|
}
|
|
let value = parameter()
|
|
storage = value
|
|
return value
|
|
}
|
|
|
|
set {
|
|
storage = newValue
|
|
}
|
|
}
|
|
|
|
static func initStorage() -> Value? {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
var lazyEvaluated = false
|
|
func evaluateLazy() -> Int {
|
|
lazyEvaluated = true
|
|
return 1738
|
|
}
|
|
|
|
class Foo {
|
|
var x: Int __behavior delayedImmutable
|
|
var y: Int __behavior lazy { evaluateLazy() }
|
|
}
|
|
|
|
var DelayedImmutable = TestSuite("DelayedImmutable")
|
|
|
|
DelayedImmutable.test("correct usage") {
|
|
let foo = Foo()
|
|
foo.x = 679
|
|
expectEqual(foo.x, 679)
|
|
}
|
|
|
|
DelayedImmutable.test("read before initialization") {
|
|
let foo = Foo()
|
|
expectCrashLater()
|
|
_ = foo.x
|
|
}
|
|
|
|
DelayedImmutable.test("write after initialization") {
|
|
let foo = Foo()
|
|
foo.x = 679
|
|
expectCrashLater()
|
|
foo.x = 680
|
|
}
|
|
|
|
var Lazy = TestSuite("Lazy")
|
|
|
|
Lazy.test("usage") {
|
|
let foo = Foo()
|
|
|
|
expectFalse(lazyEvaluated)
|
|
expectEqual(foo.y, 1738)
|
|
expectTrue(lazyEvaluated)
|
|
|
|
lazyEvaluated = false
|
|
expectEqual(foo.y, 1738)
|
|
expectFalse(lazyEvaluated)
|
|
|
|
foo.y = 36
|
|
expectEqual(foo.y, 36)
|
|
expectFalse(lazyEvaluated)
|
|
|
|
let foo2 = Foo()
|
|
expectFalse(lazyEvaluated)
|
|
foo2.y = 36
|
|
expectEqual(foo2.y, 36)
|
|
expectFalse(lazyEvaluated)
|
|
|
|
let foo3 = Foo()
|
|
expectFalse(lazyEvaluated)
|
|
expectEqual(foo3.y, 1738)
|
|
expectTrue(lazyEvaluated)
|
|
}
|
|
|
|
runAllTests()
|