X-Git-Url: http://nitlanguage.org diff --git a/src/metamodel/inheritance.nit b/src/metamodel/inheritance.nit index 31d7ce8..aaca1da 100644 --- a/src/metamodel/inheritance.nit +++ b/src/metamodel/inheritance.nit @@ -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,10 +44,10 @@ 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 self[g] != null then continue + if _local_class_by_global.has_key(g) then continue var impl = new MMImplicitLocalClass(self, g) end end @@ -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 + 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 @@ -88,7 +88,7 @@ redef class MMLocalClass 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 + 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 @@ -130,40 +129,47 @@ redef class MMLocalClass continue end - var gname = glob.intro.name - var conf_set: Array[MMGlobalProperty] - if names.has_key(gname) then - conf_set = names[gname] - else - conf_set = new Array[MMGlobalProperty] - names[gname] = conf_set - end - conf_set.add(glob) + make_visible_an_inherited_global_property(glob) end end end + # Make the name of a global property meaningful in the class + fun make_visible_an_inherited_global_property(glob: MMGlobalProperty) + do + var names = _properties_by_name + var gname = glob.intro.name + var conf_set: Array[MMGlobalProperty] + if names.has_key(gname) then + conf_set = names[gname] + else + conf_set = new Array[MMGlobalProperty] + names[gname] = conf_set + end + conf_set.add(glob) + 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 @@ -184,17 +190,19 @@ redef class MMLocalClass return ra end - redef meth [](glob) + redef fun [](glob) do - var prop = super(glob) - if prop == null and _global_properties.has(glob) then - prop = inherit_local_property(glob) + if _local_property_by_global.has_key(glob) then + return _local_property_by_global[glob] + else if has_global_property(glob) then + return inherit_local_property(glob) + else + abort end - return prop 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 @@ -205,21 +213,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 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) @@ -227,16 +233,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 @@ -254,7 +259,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]] @@ -276,7 +281,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] @@ -311,138 +316,77 @@ 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 impls = glob.get_compatible_concrete_properties_for(self) - if impls.length != 1 then - stderr.write("Fatal error: inherit_local_property error\n") - print("------- {module}::{self} {glob.intro.full_name}") - for i in impls do - print(" {i.full_name}") - end - print("------- {glob.concrete_property_hierarchy.first}") - print("------- {glob.concrete_property_hierarchy.to_dot}") - exit(1) - end - var impl = impls.first - var ac = ancestor_for(impl.local_class) - ac.local_class.inherit_global_properties - var a = ac.stype - - assert a.local_class != self - var sup = a.select_property(glob) # Select super prop - assert sup != null - var prop = sup.inherit_to(get_type) # special the new prop - return prop - end -end -redef class MMConcreteProperty - # FIXME: use this - meth is_deferred: Bool do return false -end + var impl: MMLocalProperty -redef class MMGlobalProperty - # Get the most specific local properties defined in superclasses of c - private meth get_compatible_concrete_properties_for(cla: MMLocalClass): Array[MMConcreteProperty] - do - var impl_hier = _concrete_property_hierarchy - if impl_hier.length == 1 then return [intro] - var impls = new ArraySet[MMConcreteProperty] - var clache = cla.che - if true then - #print "{cla.module}::{cla} get glob {intro.local_class}::{intro.name}" - for sc in cla.che.direct_greaters do - #print " try {sc.module}::{sc} {sc.che != null} {sc.crhe != null} {sc.che != null}" - var p = sc[self] - if p == null then continue - var impl = p.concrete_property - impls.add(impl) - end + var ghier = glob.property_hierarchy + var supers = che.direct_greaters + if ghier.length == 1 then + # Unredefined property + impl = glob.intro + else if supers.length == 1 then + # Single inheritance + impl = supers.first[glob] else - for impl in impl_hier do - var bc = impl.local_class - if clache < bc then - impls.add(impl) + # Hard multiple inheritance + # First compute the set of bottom properties + var impls = new ArraySet[MMLocalProperty] + for sc in supers do + if sc.has_global_property(glob) then impls.add(sc[glob]) end + # Second, extract most specific + var impls2 = ghier.select_smallests(impls) + # Conflict case (FIXME) + if impls2.length != 1 then + stderr.write("Fatal error: inherit_local_property error\n") + print("------- {module}::{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) + end + impl = impls2.first end - end - return impl_hier.select_smallests(impls) + + # FIXME: Why these 3 lines ? + #var ac = ancestor_for(impl.local_class) + #ac.local_class.inherit_global_properties + #var a = ac.stype + #assert a.local_class != self + + # Register the local property + _local_property_by_global[glob] = impl + + return impl end end redef class MMLocalProperty # Attach self to a global property - meth inherit_global(g: MMGlobalProperty) + fun inherit_global(g: MMGlobalProperty) do set_global(g) - # What the next line used for? - g.add_concrete_property(concrete_property, g.get_compatible_concrete_properties_for(local_class)) - end - - # Create an adaptation of self to a different receiver - meth inherit_to(t: MMType): MMLocalProperty is abstract - - # ? - protected meth inherit_from(s: MMLocalProperty, t: MMType) # for the super bugs - do - assert _super_prop == null - _super_prop = s - if _global == null then - set_global(s.global) + var impls = new Array[MMLocalProperty] + for sc in local_class.che.direct_greaters do + if not sc.has_global_property(g) then continue + impls.add(sc[g]) end + g.add_local_property(self, impls) end - -end - -redef class MMMethod - redef meth inherit_to(t) do - return new MMImplicitMethod(self, t) - end -end - -# A local property that is an adatation of an exiting one -class MMImplicitProperty -special MMLocalProperty - # Create a property from an existing property and a new receiver - init(prop: MMLocalProperty, bt: MMType) - do - super(prop.name, bt.local_class, prop.concrete_property) - inherit_from(prop, bt) - end -end - -class MMImplicitMethod -special MMMethod -special MMImplicitProperty - init(p, t) do super -end - -redef class MMAttribute - redef meth inherit_to(t) - do - return new MMImplicitAttribute(self,t) - end -end - -class MMImplicitAttribute -special MMAttribute -special MMImplicitProperty - init(p, t) do super 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 + 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) if a.local_class != inheriter.local_class then @@ -468,15 +412,14 @@ special 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 + redef readable var _local_class: MMLocalClass init(b: MMLocalClass, a: MMLocalClass) do @@ -489,7 +432,7 @@ end class MMSpecAncestor special MMAncestor - redef meth local_class do return stype.local_class + redef fun local_class do return stype.local_class init(inheriter: MMType, stype: MMType) do @@ -500,13 +443,10 @@ end class MMDefaultAncestor special MMAncestor - redef meth local_class do return stype.local_class + 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