# 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
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
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
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
var _are_global_properties_inherited: Bool = false
# Inherit global properties for a class
- fun inherit_global_properties
+ private fun inherit_global_properties
do
if _are_global_properties_inherited then return
_are_global_properties_inherited = true
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
fun make_visible_an_inherited_global_property(glob: MMGlobalProperty)
do
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 _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 = module.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
assert _crhe != null
for ref in _crhe.direct_greaters do
for sup in ref.cshe.direct_greaters do
- var cla = sup.for_module(_module)
+ var cla = sup.for_module(_mmmodule)
supers.add(cla)
end
end
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)
+ self.mmmodule.context.handle_property_conflict(self, impls2)
end
impl = impls2.first
end
do
tab.add(self)
stype.local_class.compute_ancestors
- 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)
+ 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
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
end
class MMRefineAncestor
-special MMAncestor
+ super MMAncestor
redef readable var _local_class: MMLocalClass
init(b: MMLocalClass, a: MMLocalClass)
class MMSpecAncestor
-special MMAncestor
+ super MMAncestor
redef fun local_class do return stype.local_class
init(inheriter: MMType, stype: MMType)
end
class MMDefaultAncestor
-special MMAncestor
+ super MMAncestor
redef fun local_class do return stype.local_class
init(b: MMLocalClass, anc: MMType)