rename 'package' to 'module'
[nit.git] / src / metamodel / inheritance.nit
index 170e038..ed5518f 100644 (file)
 # limitations under the License.
 
 # Compute importation of classes and inheritance of properties
-package inheritance
+module inheritance
 
 intrude import static_type
 
+redef class MMContext
+       # Method to redefine to handle the property conflicts
+       # FIXME: This is just a bad workaround because of a bad design
+       fun handle_property_conflict(lc: MMLocalClass, impls2: Array[MMLocalProperty])
+       do
+               var glob = impls2.first.global
+               stderr.write("Fatal error: inherit_local_property error\n")
+               print("------- {lc.mmmodule}::{lc} {glob.intro.full_name}")
+               for i in impls2 do
+                       print("   {i.full_name}")
+               end
+               print("------- {glob.property_hierarchy.first}")
+               print("------- {glob.property_hierarchy.to_dot}")
+               exit(1)
+       end
+end
+
 redef class MMModule
        # The root of the class hierarchy
        fun type_any: MMType
@@ -28,6 +45,13 @@ redef class MMModule
                return c_name.get_type
        end
 
+       # Root of then extern class hierarchy
+       fun type_any_extern : MMType
+       do
+               var c_name = class_by_name(once ("Pointer".to_symbol))
+               return c_name.get_type
+       end
+
        # Import global classes from supermodules
        fun import_global_classes
        do
@@ -96,7 +120,7 @@ redef class MMLocalClass
                var ancestors = group_ancestors(build_ancestors)
                _ancestors = new HashMap[MMLocalClass, MMAncestor]
 
-               for set in ancestors do
+               for set in ancestors.values do
                        if set.length == 1 then
                                add_ancestor(set.first)
                        else
@@ -129,6 +153,9 @@ redef class MMLocalClass
                                        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
@@ -184,6 +211,7 @@ redef class MMLocalClass
                                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
@@ -253,19 +281,46 @@ redef class MMLocalClass
                        return _local_property_by_global[glob]
                else if has_global_property(glob) then
                        return inherit_local_property(glob)
+               else if not computed_super_classes then
+                       compute_super_classes
+                       computed_ancestors
+                       inherit_global_properties
+                       assert has_global_property(glob)
+                       return inherit_local_property(glob)
                else
                        abort
                end
        end
 
        # Add default super class in direct parent and in super classes if this is not the Object class
+       # Default super class is Pointer for extern types
        private fun add_default_any_class(supers: Array[MMLocalClass])
        do
-               if supers.is_empty and name != once ("Object".to_symbol) then
-                       var t_any = mmmodule.type_any
-                       supers.add(t_any.local_class)
-                       var default = new MMDefaultAncestor(self, t_any)
-                       add_direct_parent(default)
+               if name != once ("Object".to_symbol) then
+                       var has_no_top = false
+                       if supers.is_empty then
+                               has_no_top = true
+                       else if global.is_extern then
+                               has_no_top = true
+                               for s in supers do
+                                       if s.global.is_extern then
+                                               has_no_top = false
+                                               break
+                                       end
+                               end
+                       end
+
+                       if has_no_top then
+                               var top_type
+                               if name != once ("Pointer".to_symbol) and global.is_extern then
+                                       top_type = mmmodule.type_any_extern
+                               else
+                                       top_type = mmmodule.type_any
+                               end
+                               supers.add(top_type.local_class)
+                               var default = new MMDefaultAncestor(self, top_type)
+                               add_direct_parent(default)
+                       end
                end
        end
        
@@ -398,14 +453,7 @@ redef class MMLocalClass
                        var impls2 = ghier.select_smallests(impls)
                        # Conflict case (FIXME)
                        if impls2.length != 1 then
-                               stderr.write("Fatal error: inherit_local_property error\n")
-                               print("------- {mmmodule}::{self} {glob.intro.full_name}")
-                               for i in impls2 do
-                                       print("   {i.full_name}")
-                               end
-                               print("------- {glob.property_hierarchy.first}")
-                               print("------- {glob.property_hierarchy.to_dot}")
-                               exit(1)
+                               self.mmmodule.context.handle_property_conflict(self, impls2)
                        end
                        impl = impls2.first
                end
@@ -443,7 +491,7 @@ redef class MMAncestor
        do
                tab.add(self)
                stype.local_class.compute_ancestors
-               for anc in stype.local_class.ancestors.as(not null) do
+               for anc in stype.local_class.ancestors.values 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
@@ -465,7 +513,7 @@ 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
@@ -475,7 +523,7 @@ special MMLocalClass
 end
 
 class MMRefineAncestor
-special MMAncestor
+       super MMAncestor
        redef readable var _local_class: MMLocalClass
 
        init(b: MMLocalClass, a: MMLocalClass)
@@ -488,7 +536,7 @@ end
 
 
 class MMSpecAncestor
-special MMAncestor
+       super MMAncestor
        redef fun local_class do return stype.local_class
 
        init(inheriter: MMType, stype: MMType)
@@ -499,7 +547,7 @@ special MMAncestor
 end
 
 class MMDefaultAncestor
-special MMAncestor
+       super MMAncestor
        redef fun local_class do return stype.local_class
 
        init(b: MMLocalClass, anc: MMType)