Merge: understand writable as an annotation
authorJean Privat <jean@pryen.org>
Tue, 22 Jul 2014 03:17:01 +0000 (23:17 -0400)
committerJean Privat <jean@pryen.org>
Tue, 22 Jul 2014 03:17:01 +0000 (23:17 -0400)
~~~.rb
class Toto
   var x: Int writable = 5 # before
   var y: Int = 5 is writable # after
~~~

This should become the new way, so while an active migration is not needed yet, once this PR is merger, new code should use the new notation.

Bonus: writable accepts an optional agrument that is the name of the writer.
This allows the reserve the name `foo=` for high-level setters.

Eg.
~~~.rb
class Toto
   var x: Int is private writable(set_x) # generates `set_x` instead of `x=`
   fun x=(v: Int) do # `x=` is feee, so I can use it for a distinct method
      assert x >= 0
      set_x(v) # I use the generated `set_x` as a private internal setter
   end
end
~~~

Pull-Request: #601
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>

1  2 
src/modelize_property.nit

@@@ -119,17 -119,8 +119,17 @@@ redef class ModelBuilde
                var mparameters = new Array[MParameter]
                var anode: nullable ANode = null
                for npropdef in nclassdef.n_propdefs do
 -                      if npropdef isa AAttrPropdef and npropdef.n_expr == null then
 +                      if npropdef isa AAttrPropdef then
                                if npropdef.mpropdef == null then return # Skip broken attribute
 +                              var at = npropdef.get_single_annotation("noinit", self)
 +                              if at != null then
 +                                      npropdef.noinit = true
 +                                      if npropdef.n_expr != null then
 +                                              self.error(at, "Error: `noinit` attributes cannot have an initial value")
 +                                      end
 +                                      continue # Skip noinit attributes
 +                              end
 +                              if npropdef.n_expr != null then continue
                                var paramname = npropdef.mpropdef.mproperty.name.substring_from(1)
                                var ret_type = npropdef.mpropdef.static_mtype
                                if ret_type == null then return
@@@ -642,9 -633,6 +642,9 @@@ en
  redef class AAttrPropdef
        redef type MPROPDEF: MAttributeDef
  
 +      # Is the node tagged `noinit`?
 +      var noinit = false
 +
        # The associated getter (read accessor) if any
        var mreadpropdef: nullable MMethodDef writable
        # The associated setter (write accessor) if any
  
                        var writename = name + "="
                        var nwritable = self.n_writable
+                       var atwritable = self.get_single_annotation("writable", modelbuilder)
+                       if atwritable != null then
+                               if not atwritable.n_args.is_empty then
+                                       writename = atwritable.arg_as_id(modelbuilder) or else writename
+                               end
+                       end
                        var mwriteprop = modelbuilder.try_get_mproperty_by_name(nid2, mclassdef, writename).as(nullable MMethod)
                        var nwkwredef: nullable Token = null
                        if nwritable != null then nwkwredef = nwritable.n_kwredef
+                       if atwritable != null then nwkwredef = atwritable.n_kwredef
                        if mwriteprop == null then
                                var mvisibility
                                if nwritable != null then
                                        mvisibility = new_property_visibility(modelbuilder, mclassdef, nwritable.n_visibility)
+                               else if atwritable != null then
+                                       mvisibility = new_property_visibility(modelbuilder, mclassdef, atwritable.n_visibility)
                                else
                                        mvisibility = private_visibility
                                end
                                if not self.check_redef_keyword(modelbuilder, mclassdef, nwkwredef or else n_kwredef, true, mwriteprop) then return
                                if nwritable != null then
                                        check_redef_property_visibility(modelbuilder, nwritable.n_visibility, mwriteprop)
+                               else if atwritable != null then
+                                       check_redef_property_visibility(modelbuilder, atwritable.n_visibility, mwriteprop)
                                end
                        end
                        mclassdef.mprop2npropdef[mwriteprop] = self