1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Define and retrieve data in modules
16 # This module help analysis and tool to store piece of data in `MModule` then
17 # retrieve them through the importation relation.
22 # A map-like structure to associate `E` to` MModule`
23 # The advantage of this class is the various `lookup_*` method that
24 # allow to retrieve values trough the importation relation.
25 class MModuleData[E
: Object]
26 # The model associated with the data
27 # Used to execute correclty mmodule-related operation
30 # is a value locally defined in `mmodule`
31 fun has_mmodule
(mmodule
: MModule): Bool
33 return defs
.has_key
(mmodule
)
36 # The value locally defined in `mmodule`.
37 # Return null if no value locally defined.
38 fun [](mmodule
: MModule): nullable E
40 return defs
.get_or_null
(mmodule
)
43 # Set the value locally defined in `mmodule`.
44 # Gining `null` just undefine the value
45 fun []=(mmodule
: MModule, value
: nullable E
)
48 defs
.keys
.remove
(mmodule
)
54 private var defs
= new HashMap[MModule, E
]
56 # Return all the super modules that defines a value
57 # `min_visibility` is used to filter modules by their visibility in `mmodule`.
58 fun lookup_all_modules
(mmodule
: MModule, min_visibility
: MVisibility): Sequence[MModule]
60 var res
= new Array[MModule]
61 for m
in mmodule
.in_importation
.greaters
do
62 if mmodule
.visibility_for
(m
) < min_visibility
then continue
63 if self.defs
.has_key
(m
) then res
.add
(m
)
68 # Return all the values defined in `mmodule` and its imported modules.
69 # `min_visibility` is used to filter modules by their visibility in `mmodule`.
70 # This method could be usefull to check possible static conflicts.
71 fun lookup_all_values
(mmodule
: MModule, min_visibility
: MVisibility): Sequence[E
]
73 var mmodules
= lookup_all_modules
(mmodule
, min_visibility
)
74 mmodules
= model
.mmodule_importation_hierarchy
.linearize
(mmodules
)
75 var res
= new Array[E
]
76 for m
in mmodules
do res
.add defs
[m
]
80 # Return the most specific values defined in `mmodule` and its imported modules.
81 # `min_visibility_` is used to filter modules by their visibility in `mmodule`.
82 # Unlike `lookup_all_values`, redefined values are hidden,
83 # However, in case of conflit, all conflicting definitions are returned
84 fun lookup_values
(mmodule
: MModule, min_visibility
: MVisibility): Sequence[E
]
86 var mmodules
= lookup_all_modules
(mmodule
, min_visibility
)
87 mmodules
= model
.mmodule_importation_hierarchy
.select_smallest
(mmodules
)
88 var res
= new Array[E
]
89 for m
in mmodules
do res
.add defs
[m
]
93 # Return the most specific values defined in `mmodule` and its imported modules.
94 # Unlike `lookup_values`, only the most specific value, according to importation, is returned.
95 fun lookup_first_value
(mmodule
: MModule, min_visibility
: MVisibility): nullable E
97 var mmodules
= lookup_all_modules
(mmodule
, min_visibility
)
98 if mmodules
.is_empty
then return null
99 mmodules
= model
.mmodule_importation_hierarchy
.linearize
(mmodules
)
100 return defs
[mmodules
.last
]
104 # A `MModuleData` where multiples values could be set on a single module
105 # a-la `MultiHashMap`
106 class MModuleMultiData[E
]
107 super MModuleData[Array[E
]]
109 # Instead of `null` return an empty array usable
110 redef fun [](mmodule
)
120 # like `lookup_all_values` but return a big concatenated sequence (instead of a sequence of array)
121 fun lookup_joined_values
(mmodule
: MModule, min_visibility
: MVisibility): Sequence[E
]
123 var mmodules
= lookup_all_modules
(mmodule
, min_visibility
)
124 mmodules
= model
.mmodule_importation_hierarchy
.linearize
(mmodules
)
125 var res
= new Array[E
]
126 for m
in mmodules
do res
.add_all defs
[m
]