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
23 # The main singleton which knows everything
28 # The module dependence hierarchy
29 readable attr _module_hierarchy
: PartialOrder[MMModule] = new PartialOrder[MMModule]
31 # The class refinement and specialization hierarchy
32 # It is not the real hierarchy since non concrete classes can only be leaves
33 readable attr _class_hierarchy
: PartialOrder[MMLocalClass] = new PartialOrder[MMLocalClass]
35 # All known global classes
36 attr _global_classes
: Array[MMGlobalClass] = new Array[MMGlobalClass]
39 readable attr _modules
: Array[MMModule] = new Array[MMModule]
41 # Register a new module with the modules it depends on
42 meth add_module
(module: MMModule, supers
: Array[MMModule])
45 _module_hierarchy
.add
(module, _module_hierarchy
.select_smallests
(supers
))
46 assert module.name
!= null
48 module._mhe
= _module_hierarchy
[module]
51 # Register a global class
52 private meth add_global_class
(c
: MMGlobalClass) do _global_classes
.add
(c
)
54 # Register a local class
55 meth add_local_class
(c
: MMLocalClass, sup
: Array[MMLocalClass])
58 var csup
= new Array[MMLocalClass]
59 var csups
= new Array[String]
61 if s
isa MMConcreteClass then
64 for ss
in s
.che
.direct_greaters
do
65 if csup
.has
(ss
) then continue
70 var che
= _class_hierarchy
.add
(c
, csup
)
75 # Directory of modules
77 # Full name of the directory
78 readable attr _name
: Symbol
81 readable attr _path
: String
85 readable attr _parent
: MMDirectory
87 # The module that introduces the directory if any
88 readable writable attr _owner
: MMModule
90 # Known modules in the directory
91 readable attr _modules
: Map[Symbol, MMModule] = new HashMap[Symbol, MMModule]
93 # Register a new module
94 meth add_module
(module: MMModule)
96 assert not _modules
.has_key
(module.name
)
97 _modules
[module.name
] = module
100 # Directory hierarchy element
101 readable attr _dhe
: PartialOrderElement[MMDirectory]
103 init(name
: Symbol, path
: String, parent
: MMDirectory) do
109 # The fullname of a a potentiel module in the directory
110 meth full_name_for
(module_name
: Symbol): Symbol do
111 return "{name}/{module_name}".to_symbol
115 # A module is a NIT package
118 readable attr _context
: MMContext
120 # Short name of the module
121 readable attr _name
: Symbol
123 # Full name of the module
124 readable attr _full_name
: Symbol
126 # The directory of the module
127 readable attr _directory
: MMDirectory
129 # Module dependence hierarchy element
130 readable attr _mhe
: PartialOrderElement[MMModule]
132 # All global classes of the module (defined and imported)
133 readable attr _global_classes
: Array[MMGlobalClass] = new Array[MMGlobalClass]
135 # All local classes of the module (defined and imported)
136 readable attr _local_classes
: Array[MMLocalClass] = new Array[MMLocalClass]
138 # Class specialization hierarchy of the module.
139 readable attr _class_specialization_hierarchy
: PartialOrder[MMLocalClass] = new PartialOrder[MMLocalClass]
141 # Modules intruded (directly or not)
142 attr _intrude_modules
: Set[MMModule] = new HashSet[MMModule]
144 # Module publicly imported (directly or not)
145 attr _public_modules
: Set[MMModule] = new HashSet[MMModule]
147 # Module privately imported (directly or not)
148 attr _private_modules
: Set[MMModule] = new HashSet[MMModule]
150 # Explicit imported modules
151 readable attr _explicit_imported_modules
: Set[MMModule] = new HashSet[MMModule]
153 # Association between local class and global classes
154 attr _local_class_by_global
: Map[MMGlobalClass, MMLocalClass] = new HashMap[MMGlobalClass, MMLocalClass]
156 # Dictionary of global classes
157 attr _global_class_by_name
: Map[Symbol, MMGlobalClass] = new HashMap[Symbol, MMGlobalClass]
159 protected init(name
: Symbol, dir
: MMDirectory, context
: MMContext)
168 _full_name
= dir
.full_name_for
(name
)
172 # Register that a module is imported with a visibility
176 meth add_super_module
(m
: MMModule, visibility_level
: Int)
178 _explicit_imported_modules
.add
(m
)
179 if visibility_level
== 0 then
180 _intrude_modules
.add
(m
)
181 _intrude_modules
.add_all
(m
._intrude_modules
)
182 _public_modules
.add_all
(m
._public_modules
)
183 _private_modules
.add_all
(m
._private_modules
)
184 else if visibility_level
== 1 then
185 _public_modules
.add
(m
)
186 _public_modules
.add_all
(m
._intrude_modules
)
187 _public_modules
.add_all
(m
._public_modules
)
189 _private_modules
.add
(m
)
190 _private_modules
.add_all
(m
._intrude_modules
)
191 _private_modules
.add_all
(m
._public_modules
)
196 # Return the visibiliy level of a super-module
197 # 3 -> self or intruded => see all
198 # 2 -> public => see public and protected
199 # 1 -> private => see public and protected
200 # 0 -> nothing => see nothing
201 meth visibility_for
(m
: MMModule): Int
203 if m
== self or _intrude_modules
.has
(m
) then
205 else if _public_modules
.has
(m
) then
207 else if _private_modules
.has
(m
) then
215 # Get the local class associated with a global class
216 meth
[](c
: MMGlobalClass): MMLocalClass
218 assert _local_class_by_global
!= null
220 if _local_class_by_global
.has_key
(c
) then
221 return _local_class_by_global
[c
]
227 # Register a local class to the module
228 meth add_local_class
(c
: MMLocalClass)
231 _local_classes
.add
(c
)
234 # Get a local class by its name
235 meth class_by_name
(n
: Symbol): MMLocalClass
237 return self[_global_class_by_name
[n
]]
240 # Is there a global class with this name
241 meth has_global_class_named
(n
: Symbol): Bool
243 return _global_class_by_name
.has_key
(n
)
246 # Get a global class by its name.
247 # Return null if not class match this name
248 meth global_class_named
(n
: Symbol): MMGlobalClass
250 if _global_class_by_name
.has_key
(n
) then
251 return _global_class_by_name
[n
]
257 redef meth to_s
do return name
.to_s
259 # Assign super_classes for a local class
260 meth set_supers_class
(c
: MMLocalClass, supers
: Array[MMLocalClass])
262 assert supers
!= null
263 var tab
= _class_specialization_hierarchy
.select_smallests
(supers
)
264 c
._cshe
= _class_specialization_hierarchy
.add
(c
,tab
)
265 var tab_all
= c
.crhe
.direct_greaters
.to_a
267 context
.add_local_class
(c
,tab_all
)
270 # Register a local class and its global class in the module
271 private meth register_global_class
(c
: MMLocalClass)
273 assert c
.global
!= null
274 _local_class_by_global
[c
.global
] = c
279 # The introducing local class
280 readable attr _intro
: MMLocalClass
282 # Class refinement hierarchy
283 # It is not the real hierarchy since non concrete classes can only be leaves
284 readable attr _class_refinement_hierarchy
: PartialOrder[MMLocalClass] = new PartialOrder[MMLocalClass]
286 # Create a new global class introduced with a given local class
287 init(c
: MMLocalClass)
290 c
.context
.add_global_class
(self)
293 # The name of the global class
299 # The module that introduces the global class
300 meth
module: MMModule
310 # register a new Local class to local class hierarchy (set the crhe value)
311 private meth register_local_class
(c
: MMLocalClass)
313 assert c
.module != null
314 assert c
.crhe
== null
315 var sup
= new Array[MMLocalClass]
316 for s
in class_refinement_hierarchy
do
317 if c
.module.mhe
< s
.module and s
isa MMConcreteClass then
321 c
._crhe
= _class_refinement_hierarchy
.add
(c
, sup
)
324 # Is the global class an interface?
325 readable writable attr _is_interface
: Bool
327 # Is the global class an abstract class?
328 readable writable attr _is_abstract
: Bool
330 # Is the global class a universal class?
331 readable writable attr _is_universal
: Bool
333 # Visibility of the global class
336 readable writable attr _visibility_level
: Int
339 # Local classes are classes defined, refined or imported in a module
341 # The name of the local class
342 readable attr _name
: Symbol
344 # Arity of the local class (if generic)
345 # FIXME: How to move this into the generic module in a sane way?
346 readable attr _arity
: Int
348 # The module of the local class
349 readable attr _module
: MMModule
351 # Is the class abstract
352 readable writable attr _abstract
: Bool
354 # The global class of the local class
355 readable attr _global
: MMGlobalClass
357 # The local class refinement hierarchy element
358 readable attr _crhe
: PartialOrderElement[MMLocalClass]
360 # The local class specialization hierarchy element
361 readable attr _cshe
: PartialOrderElement[MMLocalClass]
363 # The local class full hierarchy element
364 readable attr _che
: PartialOrderElement[MMLocalClass]
366 # Association between local properties and global properties
367 readable attr _local_property_by_global
: Map[MMGlobalProperty, MMLocalProperty]
369 # All known global properties
370 readable attr _global_properties
: Set[MMGlobalProperty]
372 # Dictionnary of global properties
373 readable attr _properties_by_name
: Map[Symbol, Array[MMGlobalProperty]]
375 # Create a new class with a given name and arity
376 protected init(name
: Symbol, arity
: Int)
382 # The corresponding local class in another module
383 meth for_module
(m
: MMModule): MMLocalClass
388 # Introduce a new global class to a new global one and register to hierarchy with no refine
391 var g
= new MMGlobalClass(self)
392 _module
._global_classes
.add
(g
)
393 _module
._global_class_by_name
[name
] = g
397 # Associate this local class to a global one and register to hierarchy
398 # the global class for this class
399 # refined classes for this class
400 meth set_global
(g
: MMGlobalClass)
404 _global
.register_local_class
(self)
405 _module
.register_global_class
(self)
408 # Is there a global propery with a given name
409 # TODO: Will disapear when qualified names will be available
410 meth has_global_property_by_name
(n
: Symbol): Bool
412 var props
= _properties_by_name
[n
]
416 # Get a global property by its name
417 # TODO: Will disapear when qualified names will be available
418 meth get_property_by_name
(n
: Symbol): MMGlobalProperty
420 var props
= _properties_by_name
[n
]
421 if props
== null or props
.length
> 1 then
427 # Get a attribute by its name
428 # TODO: Will disapear when qualified names will be available
429 meth attribute
(a
: Symbol): MMGlobalProperty
431 return get_property_by_name
(a
)
434 # Get a method by its name
435 # TODO: Will disapear when qualified names will be available
436 meth method
(na
: Symbol): MMGlobalProperty
438 assert _properties_by_name
!= null
439 var props
= _properties_by_name
[na
]
440 if props
!= null then
447 # Look in super-classes (by specialization) and return properties with name
448 # Beware, global property of results is not intended to be the same
449 meth super_methods_named
(n
: Symbol): Array[MMLocalProperty]
451 var classes
= new Array[MMLocalClass]
452 for c
in cshe
.greaters
do
454 if g
== null then continue
457 classes
= cshe
.order
.select_smallests
(classes
)
458 var res
= new Array[MMLocalProperty]
461 #print "found {c[g].full_name}"
467 # Register a local property and associate it with its global property
468 meth register_local_property
(p
: MMLocalProperty)
470 assert p
.global
!= null
472 if not _local_property_by_global
.has_key
(p
.global
) then
473 _local_property_by_global
[p
.global
] = p
477 # Register a global property and associate it with its name
478 meth register_global_property
(glob
: MMGlobalProperty)
480 var prop
= glob
.intro
482 var props
= _properties_by_name
[name
]
483 if props
== null then
484 _properties_by_name
[name
] = [glob
]
486 _properties_by_name
[name
].add
(glob
)
488 _global_properties
.add
(glob
)
489 register_local_property
(prop
)
492 # Get a local proprty by its global property
493 meth
[](glob
: MMGlobalProperty): MMLocalProperty
495 assert _local_property_by_global
!= null
497 if _local_property_by_global
.has_key
(glob
) then
498 return _local_property_by_global
[glob
]
503 # The current MMContext
504 meth context
: MMContext do return module.context
512 # A global property gather local properties that correspond to a same message
513 class MMGlobalProperty
514 # The local property for each class that has the global property
516 # The introducing local property
517 readable attr _intro
: MMConcreteProperty
519 # The local class that introduces the global property
520 meth local_class
: MMLocalClass
522 return intro
.local_class
525 # The concrete property redefinition hierarchy
526 readable attr _concrete_property_hierarchy
: PartialOrder[MMConcreteProperty] = new PartialOrder[MMConcreteProperty]
528 # Create a new global property introduced by a local one
529 protected init(p
: MMConcreteProperty)
532 assert p
.concrete_property
!= null
534 _concrete_property_hierarchy
= new PartialOrder[MMConcreteProperty]
537 add_concrete_property
(p
, new Array[MMConcreteProperty])
540 redef meth to_s
do return intro
.full_name
542 # Register a new concrete property
543 meth add_concrete_property
(i
: MMConcreteProperty, sup
: Array[MMConcreteProperty])
547 i
._cprhe
= _concrete_property_hierarchy
.add
(i
,sup
)
550 # Is the global property an attribute ?
551 meth is_attribute
: Bool do return intro
isa MMAttribute
553 # Is the global property a method (or a constructor)?
554 meth is_method
: Bool do return intro
isa MMMethod
556 # Is the global property a constructor (thus also a method)?
557 readable writable attr _is_init
: Bool
559 # Visibility of the property
563 readable writable attr _visibility_level
: Int
566 # Local properties are adaptation of concrete local properties
567 # They can be adapted for inheritance (or importation) or for type variarion (genericity, etc.)
568 class MMLocalProperty
569 # The name of the property
570 readable attr _name
: Symbol
572 # The local class who own the local property
573 readable attr _local_class
: MMLocalClass
575 # The global property where belong the local property
576 readable attr _global
: MMGlobalProperty
578 # The original property where self is derived
579 # May be null if self is an original one
580 readable attr _super_prop
: MMLocalProperty
582 # The concrete property
583 # May be self if self is a concrete property
584 readable attr _concrete_property
: MMConcreteProperty
586 # The module of the local property
587 meth
module: MMModule do return _local_class
.module
589 # Full expanded name with all qualifications
590 meth full_name
: String
592 if global
== null then
593 return "{local_class.module}::{local_class}::(?::{name})"
594 else if global
.intro
== self then
595 return "{local_class.module}::{local_class}::{name}"
597 return "{local_class.module}::{local_class}::({global.intro.full_name})"
601 # set the global property for this property
602 meth set_global
(g
: MMGlobalProperty)
606 _local_class
.register_local_property
(self)
609 redef meth to_s
do return name
.to_s
611 protected init(n
: Symbol, bc
: MMLocalClass, i
: MMConcreteProperty)
615 _concrete_property
= i
619 # Attribute local properties
621 special MMLocalProperty
624 # Method local properties
626 special MMLocalProperty
629 # Concrete local classes
630 class MMConcreteClass
634 # Concrete local properties
635 class MMConcreteProperty
636 special MMLocalProperty
637 # Redefinition hierarchy of the concrete property
638 readable attr _cprhe
: PartialOrderElement[MMConcreteProperty]
640 # Is the concrete property contain a `super' in the body?
641 readable writable attr _need_super
: Bool
643 # Introduce a new global property for this local one
646 assert _global
== null
647 _global
= new MMGlobalProperty(self)
648 _local_class
.register_global_property
(_global
)