Files
swift-mirror/test/Interpreter/property_behavior.swift
Joe Groff a4fa786a6f Handle a parameter to property behaviors.
For prototyping purposes, we only support a single trailing closure parameter to begin with.
2016-03-01 11:51:25 -08:00

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()