modelize: introduce `AAttrPropdef::has_value`
authorJean Privat <jean@pryen.org>
Wed, 29 Oct 2014 16:43:01 +0000 (12:43 -0400)
committerJean Privat <jean@pryen.org>
Fri, 31 Oct 2014 11:10:05 +0000 (07:10 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

src/frontend/cached.nit
src/modelize/modelize_property.nit

index 830ff66..9737245 100644 (file)
@@ -22,6 +22,7 @@ import modelize
 private import parser_util
 import simple_misc_analysis
 private import annotation
+intrude import modelize::modelize_property
 
 redef class ToolContext
        var cached_phase: Phase = new CachedPhase(self, [modelize_property_phase])
@@ -143,6 +144,10 @@ private class CachedPhase
                # Sanity checks
                assert nclassdef.mclassdef == mclassdef
 
+               if n isa AAttrPropdef then
+                       n.has_value = n.n_expr != null or n.n_block != null
+               end
+
                # Required so that propdef are visited in visitors
                if not nclassdef.n_propdefs.has(n) then nclassdef.n_propdefs.add(n)
        end
index 0d2e3a6..69e1633 100644 (file)
@@ -147,12 +147,12 @@ redef class ModelBuilder
                                var at = npropdef.get_single_annotation("noinit", self)
                                if at != null then
                                        npropdef.noinit = true
-                                       if npropdef.n_expr != null then
+                                       if npropdef.has_value 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
+                               if npropdef.has_value then continue
                                var paramname = npropdef.mpropdef.mproperty.name.substring_from(1)
                                var ret_type = npropdef.mpropdef.static_mtype
                                if ret_type == null then return
@@ -746,6 +746,10 @@ redef class AAttrPropdef
        # Is the node tagged lazy?
        var is_lazy = false
 
+       # Has the node a default value?
+       # Could be through `n_expr` or `n_block`
+       var has_value = false
+
        # The guard associated to a lazy attribute.
        # Because some engines does not have a working `isset`,
        # this additional attribute is used to guard the lazy initialization.
@@ -798,9 +802,11 @@ redef class AAttrPropdef
                set_doc(mreadpropdef, modelbuilder)
                mpropdef.mdoc = mreadpropdef.mdoc
 
+               has_value = n_expr != null or n_block != null
+
                var atlazy = self.get_single_annotation("lazy", modelbuilder)
                if atlazy != null then
-                       if n_expr == null then
+                       if not has_value then
                                modelbuilder.error(atlazy, "Error: a lazy attribute needs a value")
                        end
                        is_lazy = true
@@ -811,7 +817,7 @@ redef class AAttrPropdef
 
                var atreadonly = self.get_single_annotation("readonly", modelbuilder)
                if atreadonly != null then
-                       if n_expr == null then
+                       if not has_value then
                                modelbuilder.error(atreadonly, "Error: a readonly attribute needs a value")
                        end
                        # No setter, so just leave