metamodel: rename 'universal' to 'enum'
[nit.git] / src / metamodel / inheritance.nit
index 870f266..46e6e88 100644 (file)
@@ -22,14 +22,14 @@ intrude import static_type
 
 redef class MMModule
        # The root of the class hierarchy
-       meth type_any: MMType
+       fun type_any: MMType
        do
                var c_name = class_by_name(once ("Object".to_symbol))
                return c_name.get_type
        end
 
        # Import global classes from supermodules
-       meth import_global_classes
+       fun import_global_classes
        do
                var globals = new HashMap[MMGlobalClass,HashSet[MMLocalClass]]
                assert mhe != null
@@ -44,7 +44,7 @@ redef class MMModule
        end 
        
        # Create implicit local classes for global classes that are not refined
-       meth import_local_classes
+       fun import_local_classes
        do
                for g in _global_classes do
                        if _local_class_by_global.has_key(g) then continue
@@ -55,14 +55,14 @@ end
 
 redef class MMLocalClass
        # List of all parents
-       attr _direct_parents: Array[MMAncestor] = new Array[MMAncestor]
+       var _direct_parents: Array[MMAncestor] = new Array[MMAncestor]
 
        # Is the class computing super.
        # Used to detect specialization loops.
-       attr _computing_super: Bool = false 
+       var _computing_super: Bool = false 
 
        # Compute super classes of a class
-       meth compute_super_classes
+       fun compute_super_classes
        do
                if computed_super_classes then
                        # do no recompute if allready done
@@ -81,14 +81,14 @@ 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
        end
 
        # Compute ancestors for a class
-       meth compute_ancestors
+       fun compute_ancestors
        do
                assert computed_super_classes
                if computed_ancestors then return
@@ -106,14 +106,13 @@ redef class MMLocalClass
                end
        end
 
+       var _are_global_properties_inherited: Bool = false
+
        # Inherit global properties for a class
-       meth inherit_global_properties
+       private fun inherit_global_properties
        do
-               if _global_properties != null then return
-
-               _global_properties = new HashSet[MMGlobalProperty]
-               _properties_by_name = new HashMap[Symbol, Array[MMGlobalProperty]]
-               _local_property_by_global = new HashMap[MMGlobalProperty, MMLocalProperty]
+               if _are_global_properties_inherited then return
+               _are_global_properties_inherited = true
 
                var names = _properties_by_name
                var set = _global_properties
@@ -124,19 +123,80 @@ 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
-       meth make_visible_an_inherited_global_property(glob: MMGlobalProperty)
+       fun make_visible_an_inherited_global_property(glob: MMGlobalProperty)
        do
                var names = _properties_by_name
                var gname = glob.intro.name
@@ -151,33 +211,33 @@ redef class MMLocalClass
        end
 
        # Add super stype of this current local class
-       meth add_direct_parent(p: MMAncestor)
+       fun add_direct_parent(p: MMAncestor)
        do
                _direct_parents.add(p)
        end
 
        # Are super-class already computed?
-       meth computed_super_classes: Bool
+       fun computed_super_classes: Bool
        do
                return _crhe != null and _cshe != null
        end
        
        # Are ancestors already computed
-       meth computed_ancestors: Bool
+       fun computed_ancestors: Bool
        do
                return _ancestors != null
        end
 
        # Get the ancestor for a given class
        # TODO: is this useful?
-       private meth ancestor_for(c: MMLocalClass): MMAncestor
+       private fun ancestor_for(c: MMLocalClass): MMAncestor
        do      
                assert ancestors != null
 
                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
@@ -191,7 +251,7 @@ redef class MMLocalClass
                return ra
        end
 
-       redef meth [](glob)
+       redef fun [](glob)
        do
                if _local_property_by_global.has_key(glob) then
                        return _local_property_by_global[glob]
@@ -203,10 +263,10 @@ redef class MMLocalClass
        end
 
        # Add default super class in direct parent and in super classes if this is not the Object class
-       private meth add_default_any_class(supers: Array[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)
@@ -214,21 +274,19 @@ redef class MMLocalClass
        end
        
        # Adding inherited class from previous refinement of self
-       private meth add_super_classes(supers: Array[MMLocalClass])
+       private fun add_super_classes(supers: Array[MMLocalClass])
        do
                assert _crhe != null
                for ref in _crhe.direct_greaters do
-                       assert ref.cshe != null
                        for sup in ref.cshe.direct_greaters do
-                               var cla = sup.for_module(_module)
-                               assert cla != null
+                               var cla = sup.for_module(_mmmodule)
                                supers.add(cla)
                        end
                end
        end
        
        # Add self parents of this local class
-       private meth add_explicit_classes(supers: Array[MMLocalClass])
+       private fun add_explicit_classes(supers: Array[MMLocalClass])
        do
                for p in _direct_parents do
                        supers.add(p.local_class)
@@ -236,16 +294,15 @@ redef class MMLocalClass
        end
 
        # Ensure all super parents are computed
-       private meth compute_super_parents(supers: Array[MMLocalClass])
+       private fun compute_super_parents(supers: Array[MMLocalClass])
        do
                for p in supers do
-                       assert p != null
                        p.compute_super_classes
                end
        end
 
        # compute all ancestors for a class (multiple)
-       private meth build_ancestors: Array[MMAncestor]
+       private fun build_ancestors: Array[MMAncestor]
        do
                var all_ancestors = new Array[MMAncestor]
                # Refined classes are ancestors
@@ -263,7 +320,7 @@ redef class MMLocalClass
        end
 
        # Build an ancestor map indexed by LocalClass
-       private meth group_ancestors(all: Array[MMAncestor]): Map[MMLocalClass, Set[MMAncestor]]
+       private fun group_ancestors(all: Array[MMAncestor]): Map[MMLocalClass, Set[MMAncestor]]
        do
                #print "process {self}"
                var map = new HashMap[MMLocalClass, Set[MMAncestor]]
@@ -285,7 +342,7 @@ redef class MMLocalClass
        end
 
        # Remove duplicate ancestors and merge if compatible, in the other case do an error
-       private meth merge_ancestors(set: Set[MMAncestor]): MMAncestor
+       private fun merge_ancestors(set: Set[MMAncestor]): MMAncestor
        do
                var marks = new HashSet[MMAncestor]
                var res = new Array[MMAncestor]
@@ -320,10 +377,9 @@ redef class MMLocalClass
        # Inherit a local property
        # Is lazily called
        # FIXME: dont crash lazily
-       private meth inherit_local_property(glob: MMGlobalProperty): MMLocalProperty
+       private fun inherit_local_property(glob: MMGlobalProperty): MMLocalProperty
        do
                assert not _local_property_by_global.has_key(glob)
-               assert glob != null
 
                var impl: MMLocalProperty
 
@@ -347,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
@@ -373,7 +429,7 @@ end
 
 redef class MMLocalProperty
        # Attach self to a global property
-       meth inherit_global(g: MMGlobalProperty)
+       fun inherit_global(g: MMGlobalProperty)
        do
                set_global(g)
                var impls = new Array[MMLocalProperty]
@@ -387,15 +443,13 @@ end
 
 redef class MMAncestor
        # Add this ancestor and it's super one in tab
-       private meth add_in(tab: Array[MMAncestor])
+       private fun add_in(tab: Array[MMAncestor])
        do
-               assert ancestor: stype != null
-               assert local_class: stype.local_class != null
                tab.add(self)
                stype.local_class.compute_ancestors
-               for anc in stype.local_class.ancestors do
-                       var aaa = anc.stype.for_module(stype.module)
-                       var a = aaa.adapt_to(stype).for_module(inheriter.module)
+               for anc in stype.local_class.ancestors.as(not null) do
+                       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
@@ -415,19 +469,18 @@ end
 
 # A local class that is a pure importation of an other local class
 class MMImplicitLocalClass
-special MMLocalClass
+       super MMLocalClass
        init(mod: MMModule, g: MMGlobalClass)
        do
                var cla = g.intro
-               super(cla.name, cla.arity)
-               mod.add_local_class(self)
+               super(mod, cla.name, cla.arity)
                set_global(g)
        end
 end
 
 class MMRefineAncestor
-special MMAncestor
-       redef readable attr _local_class: MMLocalClass
+       super MMAncestor
+       redef readable var _local_class: MMLocalClass
 
        init(b: MMLocalClass, a: MMLocalClass)
        do
@@ -439,8 +492,8 @@ end
 
 
 class MMSpecAncestor
-special MMAncestor
-       redef meth local_class do return stype.local_class
+       super MMAncestor
+       redef fun local_class do return stype.local_class
 
        init(inheriter: MMType, stype: MMType)
        do
@@ -450,14 +503,11 @@ special MMAncestor
 end
 
 class MMDefaultAncestor
-special MMAncestor
-       redef meth local_class do return stype.local_class
+       super MMAncestor
+       redef fun local_class do return stype.local_class
 
        init(b: MMLocalClass, anc: MMType)
        do
-               assert b != null
-               assert b.module != null
-               assert anc != null
                inheriter = b.get_type
                stype = anc
        end