X-Git-Url: http://nitlanguage.org diff --git a/src/metamodel/inheritance.nit b/src/metamodel/inheritance.nit index 870f266..46e6e88 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,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