parser: move things from parser_prod to parser_nodes
[nit.git] / src / metamodel / abstractmetamodel.nit
index 47c6a41..37f9472 100644 (file)
 package abstractmetamodel
 
 import partial_order
+import location
+import symbol
 
 # The main singleton which knows everything
-class MMContext
+abstract class MMContext
 
        init do end
 
@@ -39,11 +41,11 @@ class MMContext
        readable var _modules: Array[MMModule] = new Array[MMModule]
 
        # Register a new module with the modules it depends on
-       fun add_module(module: MMModule, supers: Array[MMModule])
+       fun add_module(mod: MMModule, supers: Array[MMModule])
        do
-               _module_hierarchy.add(module, _module_hierarchy.select_smallests(supers))
-               _modules.add(module)
-               module._mhe = _module_hierarchy[module]
+               _module_hierarchy.add(mod, _module_hierarchy.select_smallests(supers))
+               _modules.add(mod)
+               mod._mhe = _module_hierarchy[mod]
        end
 
        # Register a global class
@@ -53,7 +55,6 @@ class MMContext
        fun add_local_class(c: MMLocalClass, sup: Array[MMLocalClass])
        do
                var csup = new Array[MMLocalClass]
-               var csups = new Array[String]
                for s in sup do
                        if s isa MMConcreteClass then
                                csup.add(s)
@@ -88,10 +89,10 @@ class MMDirectory
        readable var _modules: Map[Symbol, MMModule] = new HashMap[Symbol, MMModule]
 
        # Register a new module
-       fun add_module(module: MMModule)
+       fun add_module(mod: MMModule)
        do
-               assert not _modules.has_key(module.name)
-               _modules[module.name] = module
+               assert not _modules.has_key(mod.name)
+               _modules[mod.name] = mod
        end
 
        init(name: Symbol, path: String, parent: nullable MMDirectory) do
@@ -106,8 +107,8 @@ class MMDirectory
        end
 end
 
-# A module is a NIT package
-class MMModule
+# A module is a Nit file
+abstract class MMModule
        # Global context
        readable var _context: MMContext 
 
@@ -120,17 +121,17 @@ class MMModule
        # The directory of the module
        readable var _directory: MMDirectory
 
-       # The filename of the module
-       readable var _filename: String
+       # Location of this module
+       readable var _location: Location
 
        # Module dependence hierarchy element
        readable var _mhe: nullable PartialOrderElement[MMModule]
 
        # All global classes of the module (defined and imported)
-       readable var _global_classes: Array[MMGlobalClass] = new Array[MMGlobalClass]
+       readable var _global_classes: Set[MMGlobalClass] = new HashSet[MMGlobalClass]
 
        # All local classes of the module (defined and imported)
-       readable var _local_classes: Array[MMLocalClass] = new Array[MMLocalClass]
+       readable var _local_classes: Set[MMLocalClass] = new HashSet[MMLocalClass]
 
        # Class specialization hierarchy of the module.
        readable var _class_specialization_hierarchy: PartialOrder[MMLocalClass] = new PartialOrder[MMLocalClass]
@@ -153,13 +154,21 @@ class MMModule
        # Dictionary of global classes
        var _global_class_by_name: Map[Symbol, MMGlobalClass] = new HashMap[Symbol, MMGlobalClass]
 
-       protected init(name: Symbol, dir: MMDirectory, context: MMContext, filename: String)
+       # Is a hybrid module partially implemented in extern code
+       # It is if it contains a new extern class or an
+       # extern class declaration
+       var is_extern_hybrid : Bool writable = false
+
+       # Uses foreign function interface
+       fun uses_ffi : Bool is abstract
+
+       protected init(name: Symbol, dir: MMDirectory, context: MMContext, loc: Location)
        do
                _name = name
                _directory = dir
                _context = context
                _full_name = dir.full_name_for(name)
-               _filename = filename
+               _location = loc
        end
 
        # Register that a module is imported with a visibility
@@ -271,9 +280,9 @@ class MMGlobalClass
        end
 
        # The module that introduces the global class
-       fun module: MMModule
+       fun mmmodule: MMModule
        do
-               return intro.module
+               return intro.mmmodule
        end
 
        redef fun to_s
@@ -286,7 +295,7 @@ class MMGlobalClass
        do
                var sup = new Array[MMLocalClass]
                for s in class_refinement_hierarchy do
-                       if c.module.mhe < s.module and s isa MMConcreteClass then
+                       if c.mmmodule.mhe < s.mmmodule and s isa MMConcreteClass then
                                sup.add(s)
                        end
                end
@@ -299,8 +308,11 @@ class MMGlobalClass
        # Is the global class an abstract class?
        readable writable var _is_abstract: Bool = false
 
-       # Is the global class a universal class?
-       readable writable var _is_universal: Bool = false
+       # Is the global class a enum class?
+       readable writable var _is_enum: Bool = false
+
+       # Is the global class an extern class?
+       readable writable var _is_extern: Bool = false
 
        # Visibility of the global class
        # 1 -> public
@@ -322,16 +334,16 @@ class MMGlobalClass
 end
 
 # Local classes are classes defined, refined or imported in a module
-class MMLocalClass
+abstract class MMLocalClass
        # The name of the local class
-        readable var _name: Symbol
+       readable var _name: Symbol
 
        # Arity of the local class (if generic)
        # FIXME: How to move this into the generic module in a sane way?
        readable var _arity : Int 
 
        # The module of the local class
-       readable var _module: MMModule
+       readable var _mmmodule: MMModule
 
        # The global class of the local class
        fun global: MMGlobalClass do return _global.as(not null)
@@ -355,13 +367,16 @@ class MMLocalClass
        # All known global properties
        readable var _global_properties: Set[MMGlobalProperty] = new HashSet[MMGlobalProperty]
 
+       # All locally defined local properties
+       readable var _local_local_properties: Set[MMLocalProperty] = new HashSet[MMLocalProperty]
+
        # Dictionnary of global properties
        var _properties_by_name: Map[Symbol, Array[MMGlobalProperty]] = new HashMap[Symbol, Array[MMGlobalProperty]]
 
        # Create a new class with a given name and arity
        protected init(mod: MMModule, name: Symbol, arity: Int)
        do
-               _module = mod
+               _mmmodule = mod
                _name = name
                _arity = arity
                mod._local_classes.add(self)
@@ -377,8 +392,8 @@ class MMLocalClass
        fun new_global
        do
                var g = new MMGlobalClass(self)
-               _module._global_classes.add(g)
-               _module._global_class_by_name[name] = g
+               _mmmodule._global_classes.add(g)
+               _mmmodule._global_class_by_name[name] = g
                set_global(g)
        end
 
@@ -389,7 +404,7 @@ class MMLocalClass
        do
                _global = g
                _global.register_local_class(self)
-               _module.register_global_class(self)
+               _mmmodule.register_global_class(self)
        end
 
        # Is there a global propery with a given name
@@ -464,6 +479,9 @@ class MMLocalClass
        fun register_local_property(p: MMLocalProperty)
        do
                _local_property_by_global[p.global] = p
+               if p.local_class == self then
+                       _local_local_properties.add(p)
+               end
        end
 
        # Register a global property and associate it with its name
@@ -486,19 +504,41 @@ class MMLocalClass
                return _global_properties.has(glob)
        end
 
-       # Get a local proprty by its global property
+       # Get a local property by its global property
        fun [](glob: MMGlobalProperty): MMLocalProperty
        do
                return _local_property_by_global[glob]
        end
 
        # The current MMContext
-       fun context: MMContext do return module.context
+       fun context: MMContext do return mmmodule.context
 
        redef fun to_s
        do
                return _name.to_s
        end
+
+       # Comparaison in a total order that superset the class refinement and the class specialisation relations
+       fun total_order_compare(b: MMLocalClass): Int
+       do
+               var a = self
+               if a == b then
+                       return 0
+               else if a.mmmodule.mhe < b.mmmodule then
+                       return 1
+               else if b.mmmodule.mhe < a.mmmodule then
+                       return -1
+               end
+               var ar = a.cshe.rank
+               var br = b.cshe.rank
+               if ar > br then
+                       return 1
+               else if br > ar then
+                       return -1
+               else
+                       return b.name.to_s <=> a.name.to_s
+               end
+       end
 end
 
 # A global property gather local properties that correspond to a same message
@@ -558,7 +598,7 @@ class MMGlobalProperty
 end
 
 # Local properties are properties defined (explicitely or not) in a local class
-class MMLocalProperty
+abstract class MMLocalProperty
        # The name of the property
        readable var _name: Symbol
 
@@ -577,17 +617,17 @@ class MMLocalProperty
        fun prhe: PartialOrderElement[MMLocalProperty] do return _prhe.as(not null)
 
        # The module of the local property
-       fun module: MMModule do return _local_class.module
+       fun mmmodule: MMModule do return _local_class.mmmodule
 
        # Full expanded name with all qualifications
        fun full_name: String
        do
                if _global == null then
-                       return "{local_class.module}::{local_class}::(?::{name})"
+                       return "{local_class.mmmodule}::{local_class}::(?::{name})"
                else if global.intro == self then
-                       return "{local_class.module}::{local_class}::{name}"
+                       return "{local_class.mmmodule}::{local_class}::{name}"
                else
-                       return "{local_class.module}::{local_class}::({global.intro.full_name})"
+                       return "{local_class.mmmodule}::{local_class}::({global.intro.full_name})"
                end
        end
 
@@ -620,17 +660,36 @@ class MMLocalProperty
 end
 
 # Attribute local properties
-class MMAttribute
-special MMLocalProperty
+abstract class MMAttribute
+       super MMLocalProperty
+end
+
+class MMExplicitImport
+       var local_class : MMLocalClass
+       var method : MMMethod
 end
 
 # Method local properties
-class MMMethod
-special MMLocalProperty
+abstract class MMMethod
+       super MMLocalProperty
+       # Is the method defined with intern
+       fun is_intern: Bool is abstract
+
+       # Is the method abstract
+       fun is_abstract: Bool is abstract
+
+       # Is the method extern
+       fun is_extern: Bool is abstract
+
+       # extern name when specified explicitly in nit code
+       fun extern_name: nullable String is abstract
+
+       # properties explicitly exported to native code
+       fun explicit_imports : Set[ MMExplicitImport ] is abstract
 end
 
 # Concrete local classes
-class MMConcreteClass
-special MMLocalClass
+abstract class MMConcreteClass
+       super MMLocalClass
 end