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
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
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
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
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
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
- 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)
+ # 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
+ 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
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
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
+ var t_any = mmmodule.type_any
supers.add(t_any.local_class)
var default = new MMDefaultAncestor(self, t_any)
add_direct_parent(default)
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)
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
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]]
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]
# 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("------- {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)
+ 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
- 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
# 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
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
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