1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2004-2008 Jean Privat <jean@pryen.org>
4 # Copyright 2006-2008 Floréal Morandat <morandat@lirmm.fr>
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
18 # core NIT metamodel classes featuring the minimal and simpliest entities
19 package abstractmetamodel
24 # The main singleton which knows everything
29 # The module dependence hierarchy
30 readable var _module_hierarchy
: PartialOrder[MMModule] = new PartialOrder[MMModule]
32 # The class refinement and specialization hierarchy
33 # It is not the real hierarchy since non concrete classes can only be leaves
34 readable var _class_hierarchy
: PartialOrder[MMLocalClass] = new PartialOrder[MMLocalClass]
36 # All known global classes
37 var _global_classes
: Array[MMGlobalClass] = new Array[MMGlobalClass]
40 readable var _modules
: Array[MMModule] = new Array[MMModule]
42 # Register a new module with the modules it depends on
43 fun add_module
(module: MMModule, supers
: Array[MMModule])
45 _module_hierarchy
.add
(module, _module_hierarchy
.select_smallests
(supers
))
47 module._mhe
= _module_hierarchy
[module]
50 # Register a global class
51 private fun add_global_class
(c
: MMGlobalClass) do _global_classes
.add
(c
)
53 # Register a local class
54 fun add_local_class
(c
: MMLocalClass, sup
: Array[MMLocalClass])
56 var csup
= new Array[MMLocalClass]
58 if s
isa MMConcreteClass then
61 for ss
in s
.che
.direct_greaters
do
62 if csup
.has
(ss
) then continue
67 var che
= _class_hierarchy
.add
(c
, csup
)
72 # Directory of modules
74 # Full name of the directory
75 readable var _name
: Symbol
78 readable var _path
: String
82 readable var _parent
: nullable MMDirectory
84 # The module that introduces the directory if any
85 readable writable var _owner
: nullable MMModule = null
87 # Known modules in the directory
88 readable var _modules
: Map[Symbol, MMModule] = new HashMap[Symbol, MMModule]
90 # Register a new module
91 fun add_module
(module: MMModule)
93 assert not _modules
.has_key
(module.name
)
94 _modules
[module.name
] = module
97 init(name
: Symbol, path
: String, parent
: nullable MMDirectory) do
103 # The fullname of a a potentiel module in the directory
104 fun full_name_for
(module_name
: Symbol): Symbol do
105 return "{name}/{module_name}".to_symbol
109 # A module is a NIT package
112 readable var _context
: MMContext
114 # Short name of the module
115 readable var _name
: Symbol
117 # Full name of the module
118 readable var _full_name
: Symbol
120 # The directory of the module
121 readable var _directory
: MMDirectory
123 # Location of this module
124 readable var _location
: Location
126 # Module dependence hierarchy element
127 readable var _mhe
: nullable PartialOrderElement[MMModule]
129 # All global classes of the module (defined and imported)
130 readable var _global_classes
: Set[MMGlobalClass] = new HashSet[MMGlobalClass]
132 # All local classes of the module (defined and imported)
133 readable var _local_classes
: Set[MMLocalClass] = new HashSet[MMLocalClass]
135 # Class specialization hierarchy of the module.
136 readable var _class_specialization_hierarchy
: PartialOrder[MMLocalClass] = new PartialOrder[MMLocalClass]
138 # Modules intruded (directly or not)
139 var _intrude_modules
: Set[MMModule] = new HashSet[MMModule]
141 # Module publicly imported (directly or not)
142 var _public_modules
: Set[MMModule] = new HashSet[MMModule]
144 # Module privately imported (directly or not)
145 var _private_modules
: Set[MMModule] = new HashSet[MMModule]
147 # Explicit imported modules
148 readable var _explicit_imported_modules
: Set[MMModule] = new HashSet[MMModule]
150 # Association between local class and global classes
151 var _local_class_by_global
: Map[MMGlobalClass, MMLocalClass] = new HashMap[MMGlobalClass, MMLocalClass]
153 # Dictionary of global classes
154 var _global_class_by_name
: Map[Symbol, MMGlobalClass] = new HashMap[Symbol, MMGlobalClass]
156 protected init(name
: Symbol, dir
: MMDirectory, context
: MMContext, loc
: Location)
161 _full_name
= dir
.full_name_for
(name
)
165 # Register that a module is imported with a visibility
169 fun add_super_module
(m
: MMModule, visibility_level
: Int)
171 _explicit_imported_modules
.add
(m
)
172 if visibility_level
== 0 then
173 _intrude_modules
.add
(m
)
174 _intrude_modules
.add_all
(m
._intrude_modules
)
175 _public_modules
.add_all
(m
._public_modules
)
176 _private_modules
.add_all
(m
._private_modules
)
177 else if visibility_level
== 1 then
178 _public_modules
.add
(m
)
179 _public_modules
.add_all
(m
._intrude_modules
)
180 _public_modules
.add_all
(m
._public_modules
)
182 _private_modules
.add
(m
)
183 _private_modules
.add_all
(m
._intrude_modules
)
184 _private_modules
.add_all
(m
._public_modules
)
189 # Return the visibiliy level of a super-module
190 # 3 -> self or intruded => see all
191 # 2 -> public => see public and protected
192 # 1 -> private => see public and protected
193 # 0 -> nothing => see nothing
194 fun visibility_for
(m
: MMModule): Int
196 if m
== self or _intrude_modules
.has
(m
) then
198 else if _public_modules
.has
(m
) then
200 else if _private_modules
.has
(m
) then
208 # Get the local class associated with a global class
209 fun [](c
: MMGlobalClass): MMLocalClass
211 return _local_class_by_global
[c
]
214 # Get a local class by its name
215 fun class_by_name
(n
: Symbol): MMLocalClass
217 return self[_global_class_by_name
[n
]]
220 # Is there a global class with this name
221 fun has_global_class_named
(n
: Symbol): Bool
223 return _global_class_by_name
.has_key
(n
)
226 # Get a global class by its name.
227 # Return null if not class match this name
228 fun global_class_named
(n
: Symbol): MMGlobalClass
230 return _global_class_by_name
[n
]
233 redef fun to_s
do return name
.to_s
235 # Assign super_classes for a local class
236 fun set_supers_class
(c
: MMLocalClass, supers
: Array[MMLocalClass])
238 var tab
= _class_specialization_hierarchy
.select_smallests
(supers
)
239 c
._cshe
= _class_specialization_hierarchy
.add
(c
,tab
)
240 var tab_all
= c
.crhe
.direct_greaters
.to_a
242 context
.add_local_class
(c
,tab_all
)
245 # Register a local class and its global class in the module
246 private fun register_global_class
(c
: MMLocalClass)
248 _local_class_by_global
[c
.global
] = c
253 # The introducing local class
254 readable var _intro
: MMLocalClass
256 # Class refinement hierarchy
257 # It is not the real hierarchy since non concrete classes can only be leaves
258 readable var _class_refinement_hierarchy
: PartialOrder[MMLocalClass] = new PartialOrder[MMLocalClass]
260 # Create a new global class introduced with a given local class
261 init(c
: MMLocalClass)
264 c
.context
.add_global_class
(self)
267 # The name of the global class
273 # The module that introduces the global class
284 # register a new Local class to local class hierarchy (set the crhe value)
285 private fun register_local_class
(c
: MMLocalClass)
287 var sup
= new Array[MMLocalClass]
288 for s
in class_refinement_hierarchy
do
289 if c
.module.mhe
< s
.module and s
isa MMConcreteClass then
293 c
._crhe
= _class_refinement_hierarchy
.add
(c
, sup
)
296 # Is the global class an interface?
297 readable writable var _is_interface
: Bool = false
299 # Is the global class an abstract class?
300 readable writable var _is_abstract
: Bool = false
302 # Is the global class a universal class?
303 readable writable var _is_universal
: Bool = false
305 # Visibility of the global class
308 readable writable var _visibility_level
: Int = 1 # FIXME: why this should be defined ?
310 # Is the global class a mixin class?
311 # A mixin class inherits all constructors from a superclass
314 return _mixin_of
!= self
317 # Indicate the superclass the class is a mixin of.
318 # If mixin_of == self then the class is not a mixin
319 # Is two classes have the same mixin_of value, then they both belong to the same mixing group
320 readable writable var _mixin_of
: MMGlobalClass = self
324 # Local classes are classes defined, refined or imported in a module
326 # The name of the local class
327 readable var _name
: Symbol
329 # Arity of the local class (if generic)
330 # FIXME: How to move this into the generic module in a sane way?
331 readable var _arity
: Int
333 # The module of the local class
334 readable var _module
: MMModule
336 # The global class of the local class
337 fun global
: MMGlobalClass do return _global
.as(not null)
338 var _global
: nullable MMGlobalClass
340 # The local class refinement hierarchy element
341 fun crhe
: PartialOrderElement[MMLocalClass] do return _crhe
.as(not null)
342 var _crhe
: nullable PartialOrderElement[MMLocalClass]
344 # The local class specialization hierarchy element
345 fun cshe
: PartialOrderElement[MMLocalClass] do return _cshe
.as(not null)
346 var _cshe
: nullable PartialOrderElement[MMLocalClass]
348 # The local class full hierarchy element
349 fun che
: PartialOrderElement[MMLocalClass] do return _che
.as(not null)
350 var _che
: nullable PartialOrderElement[MMLocalClass]
352 # Association between local properties and global properties
353 var _local_property_by_global
: Map[MMGlobalProperty, MMLocalProperty] = new HashMap[MMGlobalProperty, MMLocalProperty]
355 # All known global properties
356 readable var _global_properties
: Set[MMGlobalProperty] = new HashSet[MMGlobalProperty]
358 # All locally defined local properties
359 readable var _local_local_properties
: Set[MMLocalProperty] = new HashSet[MMLocalProperty]
361 # Dictionnary of global properties
362 var _properties_by_name
: Map[Symbol, Array[MMGlobalProperty]] = new HashMap[Symbol, Array[MMGlobalProperty]]
364 # Create a new class with a given name and arity
365 protected init(mod
: MMModule, name
: Symbol, arity
: Int)
370 mod
._local_classes
.add
(self)
373 # The corresponding local class in another module
374 fun for_module
(m
: MMModule): MMLocalClass
379 # Introduce a new global class to a new global one and register to hierarchy with no refine
382 var g
= new MMGlobalClass(self)
383 _module
._global_classes
.add
(g
)
384 _module
._global_class_by_name
[name
] = g
388 # Associate this local class to a global one and register to hierarchy
389 # the global class for this class
390 # refined classes for this class
391 fun set_global
(g
: MMGlobalClass)
394 _global
.register_local_class
(self)
395 _module
.register_global_class
(self)
398 # Is there a global propery with a given name
399 # TODO: Will disapear when qualified names will be available
400 fun has_global_property_by_name
(n
: Symbol): Bool
402 return _properties_by_name
.has_key
(n
) and _properties_by_name
[n
].length
== 1
405 # Get a global property by its name
406 # TODO: Will disapear when qualified names will be available
407 fun get_property_by_name
(n
: Symbol): MMGlobalProperty
409 if not has_global_property_by_name
(n
) then abort
410 var props
= _properties_by_name
[n
]
414 # Get a attribute by its name
415 # TODO: Will disapear when qualified names will be available
416 fun attribute
(a
: Symbol): MMGlobalProperty
418 return get_property_by_name
(a
)
421 # Get a method by its name
422 # TODO: Will disapear when qualified names will be available
423 fun method
(na
: Symbol): MMGlobalProperty
425 return _properties_by_name
[na
].first
428 # Select a method from its name
429 # TODO: Will disapear when qualified names will be available
430 fun select_method
(name
: Symbol): MMMethod
432 var gp
= method
(name
)
434 assert res
isa MMMethod
438 # Select an attribute from its name
439 # TODO: Will disapear when qualified names will be available
440 fun select_attribute
(name
: Symbol): MMAttribute
442 var gp
= attribute
(name
)
444 assert res
isa MMAttribute
448 # Look in super-classes (by specialization) and return properties with name
449 # Beware, global property of results is not intended to be the same
450 fun super_methods_named
(n
: Symbol): Array[MMLocalProperty]
452 var classes
= new Array[MMLocalClass]
453 for c
in cshe
.greaters
do
454 if c
.has_global_property_by_name
(n
) then classes
.add
(c
)
456 classes
= cshe
.order
.select_smallests
(classes
)
457 var res
= new Array[MMLocalProperty]
460 #print "found {c[g].full_name}"
466 # Register a local property and associate it with its global property
467 fun register_local_property
(p
: MMLocalProperty)
469 _local_property_by_global
[p
.global
] = p
470 if p
.local_class
== self then
471 _local_local_properties
.add
(p
)
475 # Register a global property and associate it with its name
476 fun register_global_property
(glob
: MMGlobalProperty)
478 var prop
= glob
.intro
480 if _properties_by_name
.has_key
(name
) then
481 _properties_by_name
[name
].add
(glob
)
483 _properties_by_name
[name
] = [glob
]
485 _global_properties
.add
(glob
)
486 register_local_property
(prop
)
489 # Does the global property belong to the class?
490 fun has_global_property
(glob
: MMGlobalProperty): Bool
492 return _global_properties
.has
(glob
)
495 # Get a local proprty by its global property
496 fun [](glob
: MMGlobalProperty): MMLocalProperty
498 return _local_property_by_global
[glob
]
501 # The current MMContext
502 fun context
: MMContext do return module.context
509 # Comparaison in a total order that superset the class refinement and the class specialisation relations
510 fun total_order_compare
(b
: MMLocalClass): Int
515 else if a
.module.mhe
< b
.module then
517 else if b
.module.mhe
< a
.module then
527 return b
.name
.to_s
<=> a
.name
.to_s
532 # A global property gather local properties that correspond to a same message
533 class MMGlobalProperty
534 # The local property for each class that has the global property
536 # The introducing local property
537 readable var _intro
: MMLocalProperty
539 # The local class that introduces the global property
540 fun local_class
: MMLocalClass
542 return intro
.local_class
545 # The property redefinition hierarchy
546 readable var _property_hierarchy
: PartialOrder[MMLocalProperty] = new PartialOrder[MMLocalProperty]
548 # Create a new global property introduced by a local one
549 protected init(p
: MMLocalProperty)
552 add_local_property
(p
, new Array[MMLocalProperty])
555 redef fun to_s
do return intro
.full_name
557 # Register a new local property
558 fun add_local_property
(i
: MMLocalProperty, sup
: Array[MMLocalProperty])
560 i
._prhe
= _property_hierarchy
.add
(i
,sup
)
563 # Is the global property an attribute ?
564 fun is_attribute
: Bool do return intro
isa MMAttribute
566 # Is the global property a method (or a constructor)?
567 fun is_method
: Bool do return intro
isa MMMethod
569 # Is the global property a constructor (thus also a method)?
570 readable writable var _is_init
: Bool = false
572 # Is the global property a constructor for a given class?
573 fun is_init_for
(c
: MMLocalClass): Bool
575 if not is_init
then return false
576 var sc
= intro
.local_class
577 var res
= c
.che
<= sc
and c
.global
.mixin_of
== sc
.global
.mixin_of
581 # Visibility of the property
585 readable writable var _visibility_level
: Int = 1 # FIXME: why this should be defined ?
588 # Local properties are properties defined (explicitely or not) in a local class
589 class MMLocalProperty
590 # The name of the property
591 readable var _name
: Symbol
593 # The local class who own the local property
594 readable var _local_class
: MMLocalClass
596 # The global property where belong the local property
597 var _global
: nullable MMGlobalProperty
599 fun global
: MMGlobalProperty do return _global
.as(not null)
600 fun is_global_set
: Bool do return _global
!= null
602 # Redefinition hierarchy of the local property
603 var _prhe
: nullable PartialOrderElement[MMLocalProperty]
605 fun prhe
: PartialOrderElement[MMLocalProperty] do return _prhe
.as(not null)
607 # The module of the local property
608 fun module: MMModule do return _local_class
.module
610 # Full expanded name with all qualifications
611 fun full_name
: String
613 if _global
== null then
614 return "{local_class.module}::{local_class}::(?::{name})"
615 else if global
.intro
== self then
616 return "{local_class.module}::{local_class}::{name}"
618 return "{local_class.module}::{local_class}::({global.intro.full_name})"
622 # set the global property for this property
623 fun set_global
(g
: MMGlobalProperty)
626 _local_class
.register_local_property
(self)
629 # Introduce a new global property for this local one
632 assert _global
== null
633 var global
= new MMGlobalProperty(self)
635 _local_class
.register_global_property
(global
)
638 redef fun to_s
do return name
.to_s
640 # Is the concrete property contain a `super' in the body?
641 readable writable var _need_super
: Bool = false
643 protected init(n
: Symbol, bc
: MMLocalClass)
650 # Attribute local properties
652 special MMLocalProperty
655 # Method local properties
657 special MMLocalProperty
658 # Is the method defined with intern
659 fun is_intern
: Bool is abstract
661 # Is the method abstract
662 fun is_abstract
: Bool is abstract
664 # Is the method extern, if yes what is the extern_name
665 fun extern_name
: nullable String is abstract
668 # Concrete local classes
669 class MMConcreteClass