package abstractmetamodel
import partial_order
+import location
# The main singleton which knows everything
class MMContext
init do end
# The module dependence hierarchy
- readable attr _module_hierarchy: PartialOrder[MMModule] = new PartialOrder[MMModule]
+ readable var _module_hierarchy: PartialOrder[MMModule] = new PartialOrder[MMModule]
# The class refinement and specialization hierarchy
# It is not the real hierarchy since non concrete classes can only be leaves
- readable attr _class_hierarchy: PartialOrder[MMLocalClass] = new PartialOrder[MMLocalClass]
+ readable var _class_hierarchy: PartialOrder[MMLocalClass] = new PartialOrder[MMLocalClass]
# All known global classes
- attr _global_classes: Array[MMGlobalClass] = new Array[MMGlobalClass]
+ var _global_classes: Array[MMGlobalClass] = new Array[MMGlobalClass]
# All known modules
- readable attr _modules: Array[MMModule] = new Array[MMModule]
+ readable var _modules: Array[MMModule] = new Array[MMModule]
- # Register a new module with the modules it depends on
- meth add_module(module: MMModule, supers: Array[MMModule])
+ # Register a new module with the modules it depends on
+ fun add_module(mod: MMModule, supers: Array[MMModule])
do
- assert supers != null
- _module_hierarchy.add(module, _module_hierarchy.select_smallests(supers))
- assert module.name != null
- _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
- private meth add_global_class(c: MMGlobalClass) do _global_classes.add(c)
+ private fun add_global_class(c: MMGlobalClass) do _global_classes.add(c)
# Register a local class
- meth add_local_class(c: MMLocalClass, sup: Array[MMLocalClass])
+ fun add_local_class(c: MMLocalClass, sup: Array[MMLocalClass])
do
- assert sup != null
var csup = new Array[MMLocalClass]
- var csups = new Array[String]
for s in sup do
if s isa MMConcreteClass then
csup.add(s)
# Directory of modules
class MMDirectory
# Full name of the directory
- readable attr _name: Symbol
+ readable var _name: Symbol
# Full path
- readable attr _path: String
+ readable var _path: String
# Parent directory
# null if none
- readable attr _parent: MMDirectory
+ readable var _parent: nullable MMDirectory
# The module that introduces the directory if any
- readable writable attr _owner: MMModule
+ readable writable var _owner: nullable MMModule = null
# Known modules in the directory
- readable attr _modules: Map[Symbol, MMModule] = new HashMap[Symbol, MMModule]
+ readable var _modules: Map[Symbol, MMModule] = new HashMap[Symbol, MMModule]
# Register a new module
- meth 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
- # Directory hierarchy element
- readable attr _dhe: PartialOrderElement[MMDirectory]
-
- init(name: Symbol, path: String, parent: MMDirectory) do
+ init(name: Symbol, path: String, parent: nullable MMDirectory) do
_name = name
_path = path
_parent = parent
end
# The fullname of a a potentiel module in the directory
- meth full_name_for(module_name: Symbol): Symbol do
+ fun full_name_for(module_name: Symbol): Symbol do
return "{name}/{module_name}".to_symbol
end
end
-# A module is a NIT package
+# A module is a Nit file
class MMModule
# Global context
- readable attr _context: MMContext
+ readable var _context: MMContext
# Short name of the module
- readable attr _name: Symbol
+ readable var _name: Symbol
# Full name of the module
- readable attr _full_name: Symbol
+ readable var _full_name: Symbol
# The directory of the module
- readable attr _directory: MMDirectory
+ readable var _directory: MMDirectory
- # The filename of the module
- readable attr _filename: String
+ # Location of this module
+ readable var _location: Location
# Module dependence hierarchy element
- readable attr _mhe: PartialOrderElement[MMModule]
+ readable var _mhe: nullable PartialOrderElement[MMModule]
# All global classes of the module (defined and imported)
- readable attr _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 attr _local_classes: Array[MMLocalClass] = new Array[MMLocalClass]
+ readable var _local_classes: Set[MMLocalClass] = new HashSet[MMLocalClass]
# Class specialization hierarchy of the module.
- readable attr _class_specialization_hierarchy: PartialOrder[MMLocalClass] = new PartialOrder[MMLocalClass]
+ readable var _class_specialization_hierarchy: PartialOrder[MMLocalClass] = new PartialOrder[MMLocalClass]
# Modules intruded (directly or not)
- attr _intrude_modules: Set[MMModule] = new HashSet[MMModule]
+ var _intrude_modules: Set[MMModule] = new HashSet[MMModule]
# Module publicly imported (directly or not)
- attr _public_modules: Set[MMModule] = new HashSet[MMModule]
+ var _public_modules: Set[MMModule] = new HashSet[MMModule]
# Module privately imported (directly or not)
- attr _private_modules: Set[MMModule] = new HashSet[MMModule]
+ var _private_modules: Set[MMModule] = new HashSet[MMModule]
# Explicit imported modules
- readable attr _explicit_imported_modules: Set[MMModule] = new HashSet[MMModule]
+ readable var _explicit_imported_modules: Set[MMModule] = new HashSet[MMModule]
# Association between local class and global classes
- attr _local_class_by_global: Map[MMGlobalClass, MMLocalClass] = new HashMap[MMGlobalClass, MMLocalClass]
+ var _local_class_by_global: Map[MMGlobalClass, MMLocalClass] = new HashMap[MMGlobalClass, MMLocalClass]
# Dictionary of global classes
- attr _global_class_by_name: Map[Symbol, MMGlobalClass] = new HashMap[Symbol, MMGlobalClass]
+ var _global_class_by_name: Map[Symbol, MMGlobalClass] = new HashMap[Symbol, MMGlobalClass]
- protected init(name: Symbol, dir: MMDirectory, context: MMContext, filename: String)
+ protected init(name: Symbol, dir: MMDirectory, context: MMContext, loc: Location)
do
_name = name
_directory = dir
_context = context
-
- if dir == null then
- _full_name = name
- else
- _full_name = dir.full_name_for(name)
- end
- _filename = filename
+ _full_name = dir.full_name_for(name)
+ _location = loc
end
# Register that a module is imported with a visibility
# 0 -> intrude
# 1 -> public
# 3 -> private
- meth add_super_module(m: MMModule, visibility_level: Int)
+ fun add_super_module(m: MMModule, visibility_level: Int)
do
_explicit_imported_modules.add(m)
if visibility_level == 0 then
# 2 -> public => see public and protected
# 1 -> private => see public and protected
# 0 -> nothing => see nothing
- meth visibility_for(m: MMModule): Int
+ fun visibility_for(m: MMModule): Int
do
if m == self or _intrude_modules.has(m) then
return 3
# Get the local class associated with a global class
- meth [](c: MMGlobalClass): MMLocalClass
+ fun [](c: MMGlobalClass): MMLocalClass
do
- assert _local_class_by_global != null
- assert c != null
return _local_class_by_global[c]
end
# Get a local class by its name
- meth class_by_name(n: Symbol): MMLocalClass
+ fun class_by_name(n: Symbol): MMLocalClass
do
return self[_global_class_by_name[n]]
end
# Is there a global class with this name
- meth has_global_class_named(n: Symbol): Bool
+ fun has_global_class_named(n: Symbol): Bool
do
return _global_class_by_name.has_key(n)
end
# Get a global class by its name.
# Return null if not class match this name
- meth global_class_named(n: Symbol): MMGlobalClass
+ fun global_class_named(n: Symbol): MMGlobalClass
do
return _global_class_by_name[n]
end
- redef meth to_s do return name.to_s
+ redef fun to_s do return name.to_s
# Assign super_classes for a local class
- meth set_supers_class(c: MMLocalClass, supers: Array[MMLocalClass])
+ fun set_supers_class(c: MMLocalClass, supers: Array[MMLocalClass])
do
- assert supers != null
var tab = _class_specialization_hierarchy.select_smallests(supers)
c._cshe = _class_specialization_hierarchy.add(c,tab)
var tab_all = c.crhe.direct_greaters.to_a
end
# Register a local class and its global class in the module
- private meth register_global_class(c: MMLocalClass)
+ private fun register_global_class(c: MMLocalClass)
do
- assert c.global != null
_local_class_by_global[c.global] = c
end
end
class MMGlobalClass
# The introducing local class
- readable attr _intro: MMLocalClass
+ readable var _intro: MMLocalClass
# Class refinement hierarchy
# It is not the real hierarchy since non concrete classes can only be leaves
- readable attr _class_refinement_hierarchy: PartialOrder[MMLocalClass] = new PartialOrder[MMLocalClass]
+ readable var _class_refinement_hierarchy: PartialOrder[MMLocalClass] = new PartialOrder[MMLocalClass]
# Create a new global class introduced with a given local class
init(c: MMLocalClass)
end
# The name of the global class
- meth name: Symbol
+ fun name: Symbol
do
return intro.name
end
# The module that introduces the global class
- meth module: MMModule
+ fun mmmodule: MMModule
do
- return intro.module
+ return intro.mmmodule
end
- redef meth to_s
+ redef fun to_s
do
return intro.to_s
end
# register a new Local class to local class hierarchy (set the crhe value)
- private meth register_local_class(c: MMLocalClass)
+ private fun register_local_class(c: MMLocalClass)
do
- assert c.module != null
- assert c.crhe == null
- var sup = new Array[MMLocalClass]
+ 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
end
# Is the global class an interface?
- readable writable attr _is_interface: Bool = false
+ readable writable var _is_interface: Bool = false
# Is the global class an abstract class?
- readable writable attr _is_abstract: Bool = false
+ readable writable var _is_abstract: Bool = false
- # Is the global class a universal class?
- readable writable attr _is_universal: Bool = false
+ # Is the global class a enum class?
+ readable writable var _is_enum: Bool = false
# Visibility of the global class
# 1 -> public
# 3 -> private
- readable writable attr _visibility_level: Int = 1 # FIXME: why this should be defined ?
+ readable writable var _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
+ fun 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
+ readable writable var _mixin_of: MMGlobalClass = self
end
# Local classes are classes defined, refined or imported in a module
class MMLocalClass
# The name of the local class
- readable attr _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 attr _arity : Int
+ readable var _arity : Int
# The module of the local class
- readable attr _module: MMModule
+ readable var _mmmodule: MMModule
# The global class of the local class
- readable attr _global: MMGlobalClass
+ fun global: MMGlobalClass do return _global.as(not null)
+ var _global: nullable MMGlobalClass
# The local class refinement hierarchy element
- readable attr _crhe: PartialOrderElement[MMLocalClass]
+ fun crhe: PartialOrderElement[MMLocalClass] do return _crhe.as(not null)
+ var _crhe: nullable PartialOrderElement[MMLocalClass]
# The local class specialization hierarchy element
- readable attr _cshe: PartialOrderElement[MMLocalClass]
+ fun cshe: PartialOrderElement[MMLocalClass] do return _cshe.as(not null)
+ var _cshe: nullable PartialOrderElement[MMLocalClass]
# The local class full hierarchy element
- readable attr _che: PartialOrderElement[MMLocalClass]
+ fun che: PartialOrderElement[MMLocalClass] do return _che.as(not null)
+ var _che: nullable PartialOrderElement[MMLocalClass]
# Association between local properties and global properties
- readable attr _local_property_by_global: Map[MMGlobalProperty, MMLocalProperty]
+ var _local_property_by_global: Map[MMGlobalProperty, MMLocalProperty] = new HashMap[MMGlobalProperty, MMLocalProperty]
# All known global properties
- readable attr _global_properties: Set[MMGlobalProperty]
+ 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
- readable attr _properties_by_name: Map[Symbol, Array[MMGlobalProperty]]
+ 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)
end
# The corresponding local class in another module
- meth for_module(m: MMModule): MMLocalClass
+ fun for_module(m: MMModule): MMLocalClass
do
return m[global]
end
# Introduce a new global class to a new global one and register to hierarchy with no refine
- meth new_global
+ 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
# Associate this local class to a global one and register to hierarchy
# the global class for this class
# refined classes for this class
- meth set_global(g: MMGlobalClass)
+ fun set_global(g: MMGlobalClass)
do
- assert g != null
_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
# TODO: Will disapear when qualified names will be available
- meth has_global_property_by_name(n: Symbol): Bool
+ fun has_global_property_by_name(n: Symbol): Bool
do
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
+ fun get_property_by_name(n: Symbol): MMGlobalProperty
do
if not has_global_property_by_name(n) then abort
var props = _properties_by_name[n]
# Get a attribute by its name
# TODO: Will disapear when qualified names will be available
- meth attribute(a: Symbol): MMGlobalProperty
+ fun attribute(a: Symbol): MMGlobalProperty
do
return get_property_by_name(a)
end
# Get a method by its name
# TODO: Will disapear when qualified names will be available
- meth method(na: Symbol): MMGlobalProperty
+ fun method(na: Symbol): MMGlobalProperty
do
- assert _properties_by_name != null
return _properties_by_name[na].first
end
# Select a method from its name
# TODO: Will disapear when qualified names will be available
- meth select_method(name: Symbol): MMMethod
+ fun select_method(name: Symbol): MMMethod
do
- assert name != null
var gp = method(name)
var res = self[gp]
assert res isa MMMethod
# Select an attribute from its name
# TODO: Will disapear when qualified names will be available
- meth select_attribute(name: Symbol): MMAttribute
+ fun select_attribute(name: Symbol): MMAttribute
do
- assert name != null
var gp = attribute(name)
var res = self[gp]
assert res isa MMAttribute
# Look in super-classes (by specialization) and return properties with name
# Beware, global property of results is not intended to be the same
- meth super_methods_named(n: Symbol): Array[MMLocalProperty]
+ fun super_methods_named(n: Symbol): Array[MMLocalProperty]
do
var classes = new Array[MMLocalClass]
for c in cshe.greaters do
end
# Register a local property and associate it with its global property
- meth register_local_property(p: MMLocalProperty)
+ fun register_local_property(p: MMLocalProperty)
do
- assert p.global != null
- # FIXME: Why a test?
- if not _local_property_by_global.has_key(p.global) then
- _local_property_by_global[p.global] = p
+ _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
- meth register_global_property(glob: MMGlobalProperty)
+ fun register_global_property(glob: MMGlobalProperty)
do
var prop = glob.intro
var name = prop.name
end
# Does the global property belong to the class?
- meth has_global_property(glob: MMGlobalProperty): Bool
+ fun 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
+ fun [](glob: MMGlobalProperty): MMLocalProperty
do
return _local_property_by_global[glob]
end
# The current MMContext
- meth context: MMContext do return module.context
+ fun context: MMContext do return mmmodule.context
- redef meth to_s
+ 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
# The local property for each class that has the global property
# The introducing local property
- readable attr _intro: MMLocalProperty
+ readable var _intro: MMLocalProperty
# The local class that introduces the global property
- meth local_class: MMLocalClass
- do
- return intro.local_class
- end
+ fun local_class: MMLocalClass
+ do
+ return intro.local_class
+ end
# The property redefinition hierarchy
- readable attr _property_hierarchy: PartialOrder[MMLocalProperty] = new PartialOrder[MMLocalProperty]
+ readable var _property_hierarchy: PartialOrder[MMLocalProperty] = new PartialOrder[MMLocalProperty]
# Create a new global property introduced by a local one
protected init(p: MMLocalProperty)
do
- assert p != null
-
- _property_hierarchy = new PartialOrder[MMLocalProperty]
-
_intro = p
add_local_property(p, new Array[MMLocalProperty])
end
- redef meth to_s do return intro.full_name
+ redef fun to_s do return intro.full_name
# Register a new local property
- meth add_local_property(i: MMLocalProperty, sup: Array[MMLocalProperty])
+ fun add_local_property(i: MMLocalProperty, sup: Array[MMLocalProperty])
do
- assert i != null
- assert sup != null
i._prhe = _property_hierarchy.add(i,sup)
end
# Is the global property an attribute ?
- meth is_attribute: Bool do return intro isa MMAttribute
+ fun is_attribute: Bool do return intro isa MMAttribute
# Is the global property a method (or a constructor)?
- meth is_method: Bool do return intro isa MMMethod
+ fun is_method: Bool do return intro isa MMMethod
# Is the global property a constructor (thus also a method)?
- readable writable attr _is_init: Bool
+ readable writable var _is_init: Bool = false
# Is the global property a constructor for a given class?
- meth is_init_for(c: MMLocalClass): Bool
+ fun is_init_for(c: MMLocalClass): Bool
do
if not is_init then return false
var sc = intro.local_class
# 1 -> public
# 2 -> protected
# 3 -> private
- readable writable attr _visibility_level: Int = 1 # FIXME: why this should be defined ?
+ readable writable var _visibility_level: Int = 1 # FIXME: why this should be defined ?
end
# Local properties are properties defined (explicitely or not) in a local class
class MMLocalProperty
# The name of the property
- readable attr _name: Symbol
+ readable var _name: Symbol
# The local class who own the local property
- readable attr _local_class: MMLocalClass
+ readable var _local_class: MMLocalClass
# The global property where belong the local property
- readable attr _global: MMGlobalProperty
+ var _global: nullable MMGlobalProperty
+
+ fun global: MMGlobalProperty do return _global.as(not null)
+ fun is_global_set: Bool do return _global != null
# Redefinition hierarchy of the local property
- readable attr _prhe: PartialOrderElement[MMLocalProperty]
+ var _prhe: nullable PartialOrderElement[MMLocalProperty]
+
+ fun prhe: PartialOrderElement[MMLocalProperty] do return _prhe.as(not null)
# The module of the local property
- meth module: MMModule do return _local_class.module
+ fun mmmodule: MMModule do return _local_class.mmmodule
# Full expanded name with all qualifications
- meth full_name: String
+ fun full_name: String
do
- if global == null then
- return "{local_class.module}::{local_class}::(?::{name})"
+ if _global == null then
+ 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
# set the global property for this property
- meth set_global(g: MMGlobalProperty)
+ fun set_global(g: MMGlobalProperty)
do
- assert g != null
_global = g
_local_class.register_local_property(self)
end
# Introduce a new global property for this local one
- meth new_global
+ fun new_global
do
assert _global == null
- _global = new MMGlobalProperty(self)
- _local_class.register_global_property(_global)
+ var global = new MMGlobalProperty(self)
+ _global = global
+ _local_class.register_global_property(global)
end
-
- redef meth to_s do return name.to_s
+
+ redef fun to_s do return name.to_s
# Is the concrete property contain a `super' in the body?
- readable writable attr _need_super: Bool = false
+ readable writable var _need_super: Bool = false
protected init(n: Symbol, bc: MMLocalClass)
do
# Attribute local properties
class MMAttribute
-special MMLocalProperty
+ super MMLocalProperty
end
# Method local properties
class MMMethod
-special MMLocalProperty
+ 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, if yes what is the extern_name
+ fun extern_name: nullable String is abstract
end
# Concrete local classes
class MMConcreteClass
-special MMLocalClass
+ super MMLocalClass
end