Merge: Autoinit attributes
authorJean Privat <jean@pryen.org>
Fri, 31 Oct 2014 11:17:46 +0000 (07:17 -0400)
committerJean Privat <jean@pryen.org>
Fri, 31 Oct 2014 11:17:46 +0000 (07:17 -0400)
commitafceecbf6dd2d924ef63c33be2c27bf19ce92822
tree8f2070f6761487e5b326d301848665645c0c673c
parent0ada949e4d9cf60ee3e18d6284d257d0e6d7f4df
parent3b2c04a2c574e2919c8e28c3e8f2b2752099e226
Merge: Autoinit attributes

Allow `autoinit` on attributes.

This means that the initialization of the attribute is done during the initializer phase.
This will help when the initial value of an attribute depend on the value of another attribute set a the initializer phase.

So that

~~~
class A
   var x: String
   var y: String = x + " world!"
end
var a = new A("hello") # BOOM! uninitialized x while initializing y
print a.y
~~~

Can become:

~~~
class A
   var x: String
   var y: String = x + " world!" is autoinit
end
var a = new A("hello")
print a.y # => hello world!
~~~

The inconvenient is that the initialisation markers of attributes become more complex.
Now we have:

* no default value and no special annotation: the setter is collected as an initializer
* no default value and `noinit`: not automatically initialized
* default value and no special annotation: the value is set between the allocation and all initializers
* default value and annotation `lazy`: the value is set at the first access
* *new* default value and annotation `autoinit`: the value is set with all other initializers (other `autoinit`)

For an implementation explanation, the mechanism is a quick hack: `autoinit` means `lazy` + the getter is collector as an initializer. Therefore, when initializers are invoked, the getter will be invoked and the value lazily evaluated.

So the example is equivalent to

~~~
class A
   var x: String
   var y: String = x + " world!" is lazy
end
var a = ALLOCATE(A)
a.x = "hello" # collected setter for x
a.y # lazy getter for y
a.init
print a.y # => hello world!
~~~

Pull-Request: #857
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>