Rename REAMDE to README.md
[nit.git] / src / model / mmodule_data.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
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
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14
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.
18 module mmodule_data
19
20 import mmodule
21
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
28 var model: Model
29
30 # is a value locally defined in `mmodule`
31 fun has_mmodule(mmodule: MModule): Bool
32 do
33 return defs.has_key(mmodule)
34 end
35
36 # The value locally defined in `mmodule`.
37 # Return null if no value locally defined.
38 fun [](mmodule: MModule): nullable E
39 do
40 return defs.get_or_null(mmodule)
41 end
42
43 # Set the value locally defined in `mmodule`.
44 # Gining `null` just undefine the value
45 fun []=(mmodule: MModule, value: nullable E)
46 do
47 if value == null then
48 defs.keys.remove(mmodule)
49 else
50 defs[mmodule] = value
51 end
52 end
53
54 private var defs = new HashMap[MModule, E]
55
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]
59 do
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)
64 end
65 return res
66 end
67
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]
72 do
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]
77 return res
78 end
79
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]
85 do
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]
90 return res
91 end
92
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
96 do
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]
101 end
102 end
103
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]]
108
109 # Instead of `null` return an empty array usable
110 redef fun [](mmodule)
111 do
112 var res = super
113 if res == null then
114 res = new Array[E]
115 defs[mmodule] = res
116 end
117 return res
118 end
119
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]
122 do
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]
127 return res
128 end
129 end