metamodel: MMLocalClass::init takes the MMModule
[nit.git] / src / metamodel / abstractmetamodel.nit
index 2874b49..65b98c0 100644 (file)
@@ -217,18 +217,7 @@ class MMModule
        do
                assert _local_class_by_global != null
                assert c != null
-               if _local_class_by_global.has_key(c) then
-                       return _local_class_by_global[c]
-               else
-                       return null
-               end
-       end
-
-       # Register a local class to the module
-       meth add_local_class(c: MMLocalClass)
-       do
-               c._module = self
-               _local_classes.add(c)
+               return _local_class_by_global[c]
        end
 
        # Get a local class by its name
@@ -247,11 +236,7 @@ class MMModule
        # Return null if not class match this name
        meth global_class_named(n: Symbol): MMGlobalClass
        do
-               if _global_class_by_name.has_key(n) then
-                       return _global_class_by_name[n]
-               else
-                       return null
-               end
+               return _global_class_by_name[n]
        end
 
        redef meth to_s do return name.to_s
@@ -322,18 +307,31 @@ class MMGlobalClass
        end
 
        # Is the global class an interface?
-       readable writable attr _is_interface: Bool
+       readable writable attr _is_interface: Bool = false
 
        # Is the global class an abstract class?
-       readable writable attr _is_abstract: Bool
+       readable writable attr _is_abstract: Bool = false
 
        # Is the global class a universal class?
-       readable writable attr _is_universal: Bool
+       readable writable attr _is_universal: Bool = false
 
        # Visibility of the global class
        # 1 -> public
        # 3 -> private
-       readable writable attr _visibility_level: Int
+       readable writable attr _visibility_level: Int = 1 # FIXME: why this should be defined ?
+
+       # Is the global class a mixin class?
+       # A mixin class inherits all constructors from a superclass
+       meth is_mixin: Bool
+       do
+               return _mixin_of != self
+       end
+
+       # Indicate the superclass the class is a mixin of.
+       # If mixin_of == self then the class is not a mixin
+       # Is two classes have the same mixin_of value, then they both belong to the same mixing group
+       readable writable attr _mixin_of: MMGlobalClass = self
+
 end
 
 # Local classes are classes defined, refined or imported in a module
@@ -348,9 +346,6 @@ class MMLocalClass
        # The module of the local class
        readable attr _module: MMModule
 
-       # Is the class abstract
-       readable writable attr _abstract: Bool
-
        # The global class of the local class
        readable attr _global: MMGlobalClass 
 
@@ -373,10 +368,12 @@ class MMLocalClass
        readable attr _properties_by_name: Map[Symbol, Array[MMGlobalProperty]]
 
        # Create a new class with a given name and arity
-       protected init(name: Symbol, arity: Int)
+       protected init(mod: MMModule, name: Symbol, arity: Int)
        do
+               _module = mod
                _name = name
                _arity = arity
+               mod._local_classes.add(self)
        end
 
        # The corresponding local class in another module
@@ -409,18 +406,15 @@ class MMLocalClass
        # TODO: Will disapear when qualified names will be available
        meth has_global_property_by_name(n: Symbol): Bool
        do
-               var props = _properties_by_name[n]
-               return props != null
+               return _properties_by_name.has_key(n) and _properties_by_name[n].length == 1
        end
 
        # Get a global property by its name
        # TODO: Will disapear when qualified names will be available
        meth get_property_by_name(n: Symbol): MMGlobalProperty
        do
+               if not has_global_property_by_name(n) then abort
                var props = _properties_by_name[n]
-               if props == null or props.length > 1 then
-                       return null
-               end
                return props.first
        end
 
@@ -436,12 +430,29 @@ class MMLocalClass
        meth method(na: Symbol): MMGlobalProperty
        do
                assert _properties_by_name != null
-               var props = _properties_by_name[na]
-               if props != null then
-                       return props.first
-               end
+               return _properties_by_name[na].first
+       end
 
-               return null
+       # Select a method from its name
+       # TODO: Will disapear when qualified names will be available
+       meth select_method(name: Symbol): MMMethod
+       do
+               assert name != null
+               var gp = method(name)
+               var res = self[gp]
+               assert res isa MMMethod
+               return res
+       end
+       
+       # Select an attribute from its name
+       # TODO: Will disapear when qualified names will be available
+       meth select_attribute(name: Symbol): MMAttribute
+       do
+               assert name != null
+               var gp = attribute(name)
+               var res = self[gp]
+               assert res isa MMAttribute
+               return res
        end
        
        # Look in super-classes (by specialization) and return properties with name
@@ -450,9 +461,7 @@ class MMLocalClass
        do
                var classes = new Array[MMLocalClass]
                for c in cshe.greaters do
-                       var g = c.method(n)
-                       if g == null then continue
-                       classes.add(c)
+                       if c.has_global_property_by_name(n) then classes.add(c)
                end
                classes = cshe.order.select_smallests(classes)
                var res = new Array[MMLocalProperty]
@@ -479,25 +488,25 @@ class MMLocalClass
        do
                var prop = glob.intro
                var name = prop.name
-               var  props = _properties_by_name[name]
-               if props == null then
-                       _properties_by_name[name] = [glob]
-               else
+               if _properties_by_name.has_key(name) then
                        _properties_by_name[name].add(glob)
+               else
+                       _properties_by_name[name] = [glob]
                end
                _global_properties.add(glob)
                register_local_property(prop)
        end
 
+       # Does the global property belong to the class?
+       meth has_global_property(glob: MMGlobalProperty): Bool
+       do
+               return _global_properties.has(glob)
+       end
+
        # Get a local proprty by its global property
        meth [](glob: MMGlobalProperty): MMLocalProperty
        do
-               assert _local_property_by_global != null
-               assert glob != null
-               if _local_property_by_global.has_key(glob) then
-                       return _local_property_by_global[glob]
-               end
-               return null
+               return _local_property_by_global[glob]
        end
 
        # The current MMContext
@@ -555,11 +564,20 @@ class MMGlobalProperty
        # Is the global property a constructor (thus also a method)?
        readable writable attr _is_init: Bool
 
+       # Is the global property a constructor for a given class?
+       meth is_init_for(c: MMLocalClass): Bool
+       do
+               if not is_init then return false
+               var sc = intro.local_class
+               var res = c.che <= sc and c.global.mixin_of == sc.global.mixin_of
+               return res
+       end
+
        # Visibility of the property
        # 1 -> public
        # 2 -> protected
        # 3 -> private
-       readable writable attr _visibility_level: Int
+       readable writable attr _visibility_level: Int = 1 # FIXME: why this should be defined ?
 end
 
 # Local properties are properties defined (explicitely or not) in a local class
@@ -610,7 +628,7 @@ class MMLocalProperty
        redef meth to_s do return name.to_s
 
        # Is the concrete property contain a `super' in the body?
-       readable writable attr _need_super: Bool
+       readable writable attr _need_super: Bool = false
 
        protected init(n: Symbol, bc: MMLocalClass)
        do