Merge branch 'package2module' into wip
[nit.git] / src / metamodel / inheritance.nit
index aaca1da..4d21665 100644 (file)
@@ -81,7 +81,7 @@ redef class MMLocalClass
                var set = new HashSet[MMLocalClass]
                set.add_all(supers)
                var u = set.to_a
-               module.set_supers_class(self,u)
+               mmmodule.set_supers_class(self,u)
                assert _crhe != null
                assert _cshe != null
                _computing_super = false
@@ -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
@@ -123,17 +123,78 @@ redef class MMLocalClass
                                set.add(glob) # Add the global property
 
                                # Do not inherit constructors trough specialization
-                               #print "{c.module}::{c} -> {module}::{self} for {glob.local_property.local_class.module}::{glob.local_property.local_class}::{glob.local_property} : {glob.is_init}"
+                               #print "{c.mmmodule}::{c} -> {mmmodule}::{self} for {glob.local_property.local_class.mmmodule}::{glob.local_property.local_class}::{glob.local_property} : {glob.is_init}"
                                if glob.is_init and glob.intro.local_class.global != global then
                                        #print "pass"
                                        continue
                                end
 
+                               # Do not inherit new style attributes
+                               if glob.intro.name.to_s[0] == '@' then continue
+
                                make_visible_an_inherited_global_property(glob)
                        end
                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 g.intro.name.to_s.first == '@' then continue # inherited new style attibutes are invisible
+                               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
@@ -176,7 +237,7 @@ redef class MMLocalClass
                if _ancestors.has_key(c) then
                        return _ancestors[c]
                end
-               var a = c.for_module(module)
+               var a = c.for_module(mmmodule)
                assert cshe <= a
                var ra: MMAncestor
                if _ancestors.has_key(a) then
@@ -205,7 +266,7 @@ redef class MMLocalClass
        private fun add_default_any_class(supers: Array[MMLocalClass])
        do
                if supers.is_empty and name != once ("Object".to_symbol) then
-                       var t_any = module.type_any
+                       var t_any = mmmodule.type_any
                        supers.add(t_any.local_class)
                        var default = new MMDefaultAncestor(self, t_any)
                        add_direct_parent(default)
@@ -218,7 +279,7 @@ redef class MMLocalClass
                assert _crhe != null
                for ref in _crhe.direct_greaters do
                        for sup in ref.cshe.direct_greaters do
-                               var cla = sup.for_module(_module)
+                               var cla = sup.for_module(_mmmodule)
                                supers.add(cla)
                        end
                end
@@ -342,7 +403,7 @@ redef class MMLocalClass
                        # Conflict case (FIXME)
                        if impls2.length != 1 then
                                stderr.write("Fatal error: inherit_local_property error\n")
-                               print("------- {module}::{self} {glob.intro.full_name}")
+                               print("------- {mmmodule}::{self} {glob.intro.full_name}")
                                for i in impls2 do
                                        print("   {i.full_name}")
                                end
@@ -387,8 +448,8 @@ redef class MMAncestor
                tab.add(self)
                stype.local_class.compute_ancestors
                for anc in stype.local_class.ancestors.as(not null) do
-                       var aaa = anc.stype.for_module(stype.module)
-                       var a = aaa.adapt_to(stype).for_module(inheriter.module)
+                       var aaa = anc.stype.for_module(stype.mmmodule)
+                       var a = aaa.adapt_to(stype).for_module(inheriter.mmmodule)
                        if a.local_class != inheriter.local_class then
                                var it = tab.iterator
                                var b = true