metamodel: lazily compute global properties
authorJean Privat <jean@pryen.org>
Fri, 22 Jan 2010 22:27:38 +0000 (17:27 -0500)
committerJean Privat <jean@pryen.org>
Fri, 22 Jan 2010 22:27:38 +0000 (17:27 -0500)
has_global_property and has_global_property_by_name perform a look-up
global_properties calls inherit_global_properties if needed
inherit_global_properties is made private

Signed-off-by: Jean Privat <jean@pryen.org>

src/metamodel/inheritance.nit
src/nitdoc.nit
src/program.nit
src/syntax/mmbuilder.nit
tests/sav/base_init_inherit2_alt3.sav

index aaca1da..196ef85 100644 (file)
@@ -109,7 +109,7 @@ redef class MMLocalClass
        var _are_global_properties_inherited: Bool = false
 
        # Inherit global properties for a class
-       fun inherit_global_properties
+       private fun inherit_global_properties
        do
                if _are_global_properties_inherited then return
                _are_global_properties_inherited = true
@@ -134,6 +134,63 @@ redef class MMLocalClass
                end
        end
 
+       redef fun global_properties
+       do
+               if _are_global_properties_inherited then return _global_properties
+               assert computed_super_classes
+               inherit_global_properties
+               return _global_properties
+       end
+
+       redef fun has_global_property(g)
+       do
+               # has_global_property can be called during the construction of the class
+               # hierarchy to check that a type "X" is not a formal type.
+               if not computed_super_classes then return false
+
+               var set = _global_properties
+               if set.has(g) then return true
+               for c in che.direct_greaters do
+                       if c.has_global_property(g) then
+                               set.add(g)
+                               return true
+                       end
+               end
+               return false
+       end
+
+       redef fun has_global_property_by_name(n)
+       do
+               # has_global_property can be called during the construction of the class
+               # hierarchy to check that a type "X" is not a formal type.
+               if not computed_super_classes then return false
+
+               # Ensure that super-classes are constructed
+               compute_super_classes
+
+               if _properties_by_name.has_key(n) then
+                       return _properties_by_name[n].length == 1
+               end
+               var set = _global_properties
+               var nset
+               if _properties_by_name.has_key(n) then
+                       nset = _properties_by_name[n]
+               else
+                       nset = new Array[MMGlobalProperty]
+                       _properties_by_name[n] = nset
+               end
+               for c in che.direct_greaters do
+                       if c.has_global_property_by_name(n) then
+                               var g = c.get_property_by_name(n)
+                               if not set.has(g) then set.add(g)
+                               if g.is_init and g.intro.local_class.global != global then continue
+                               if nset.has(g) then continue
+                               nset.add(g)
+                       end
+               end
+               return nset.length == 1
+       end
+
        # Make the name of a global property meaningful in the class
        fun make_visible_an_inherited_global_property(glob: MMGlobalProperty)
        do
index 4582f8e..a8e1b45 100644 (file)
@@ -813,7 +813,6 @@ special MMEntity
                                if not c2 isa MMConcreteClass then continue
                                c2.compute_super_classes
                                c2.compute_ancestors
-                               c2.inherit_global_properties
                        end
                        for c2 in c.cshe.direct_smallers do
                                if c2.global.intro == c2 then
index 63572e3..b08ee8c 100644 (file)
@@ -64,7 +64,6 @@ class Program
 
                for c in classes do
                        c.compute_ancestors
-                       c.inherit_global_properties
                end
        end
 
index 6d7c697..d296fbb 100644 (file)
@@ -93,9 +93,6 @@ redef class MMSrcModule
                # Property inhritance and introduction
                var mmbv2 = new PropertyBuilderVisitor(tc, self)
                for c in classes do
-                       # Inherit global properties
-                       c.inherit_global_properties
-
                        # Global property introduction and redefinition 
                        c.accept_class_visitor(mmbv2)
 
index e280b79..2f118ea 100644 (file)
@@ -1 +1 @@
-alt/base_init_inherit2_alt3.nit:75,1--81,7: Error: Explicit constructor required in N since multiple inheritance of constructor is forbiden. Conflicting classes are B, C. Costructors are base_init_inherit2_alt3::A::ca, base_init_inherit2_alt3::B::cb, base_init_inherit2_alt3::C::cc.
+alt/base_init_inherit2_alt3.nit:75,1--81,7: Error: Explicit constructor required in N since multiple inheritance of constructor is forbiden. Conflicting classes are B, C. Costructors are base_init_inherit2_alt3::B::cb, base_init_inherit2_alt3::A::ca, base_init_inherit2_alt3::C::cc.