Commits

Joe Groff committed 26e55ce4655
Sema: Initial parsing and synthesis for properties with behaviors. Parse 'var [behavior] x: T', and when we see it, try to instantiate the property's implementation in terms of the given behavior. To start out, behaviors are modeled as protocols. If the protocol follows this pattern: ``` protocol behavior { associatedtype Value } extension behavior { var value: Value { ... } } ``` then the property is instantiated by forming a conformance to `behavior` where `Self` is bound to the enclosing type and `Value` is bound to the property's declared type, and invoking the accessors of the `value` implementation: ``` struct Foo { var [behavior] foo: Int } /* behaves like */ extension Foo: private behavior { @implements(behavior.Value) private typealias `[behavior].Value` = Int var foo: Int { get { return value } set { value = newValue } } } ``` If the protocol requires a `storage` member, and provides an `initStorage` method to provide an initial value to the storage: ``` protocol storageBehavior { associatedtype Value var storage: Something<Value> { ... } } extension storageBehavior { var value: Value { ... } static func initStorage() -> Something<Value> { ... } } ``` then a stored property of the appropriate type is instantiated to witness the requirement, using `initStorage` to initialize: ``` struct Foo { var [storageBehavior] foo: Int } /* behaves like */ extension Foo: private storageBehavior { @implements(storageBehavior.Value) private typealias `[storageBehavior].Value` = Int @implements(storageBehavior.storage) private var `[storageBehavior].storage`: Something<Int> = initStorage() var foo: Int { get { return value } set { value = newValue } } } ``` In either case, the `value` and `storage` properties should support any combination of get-only/settable and mutating/nonmutating modifiers. The instantiated property follows the settability and mutating-ness of the `value` implementation. The protocol can also impose requirements on the `Self` and `Value` types. Bells and whistles such as initializer expressions, accessors, out-of-line initialization, etc. are not implemented. Additionally, behaviors that instantiate storage are currently only supported on instance properties. This also hasn't been tested past sema yet; SIL and IRGen will likely expose additional issues.