PageRenderTime 18ms CodeModel.GetById 13ms app.highlight 1ms RepoModel.GetById 1ms app.codeStats 0ms

/src/tools/semantics/types/utils/liberty_type_descriptor.e

http://github.com/tybor/Liberty
Specman e | 200 lines | 161 code | 24 blank | 15 comment | 4 complexity | 3d1edef073c6a20cb9f8f96106527e05 MD5 | raw file
  1-- This file is part of Liberty Eiffel.
  2--
  3-- Liberty Eiffel is free software: you can redistribute it and/or modify
  4-- it under the terms of the GNU General Public License as published by
  5-- the Free Software Foundation, version 3 of the License.
  6--
  7-- Liberty Eiffel is distributed in the hope that it will be useful,
  8-- but WITHOUT ANY WARRANTY; without even the implied warranty of
  9-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 10-- GNU General Public License for more details.
 11--
 12-- You should have received a copy of the GNU General Public License
 13-- along with Liberty Eiffel.  If not, see <http://www.gnu.org/licenses/>.
 14--
 15class LIBERTY_TYPE_DESCRIPTOR
 16
 17inherit
 18   LIBERTY_TYPE_LISTENER
 19      redefine
 20         copy, is_equal
 21      end
 22
 23insert
 24   HASHABLE
 25      redefine
 26         copy
 27      end
 28
 29create {ANY}
 30   make
 31
 32feature {ANY}
 33   file: FIXED_STRING
 34   parameters: TRAVERSABLE[LIBERTY_TYPE]
 35
 36   cluster: LIBERTY_CLUSTER is
 37      do
 38         Result := class_descriptor.cluster
 39      end
 40
 41   name: FIXED_STRING is
 42      do
 43         Result := class_descriptor.name
 44      end
 45
 46   position: LIBERTY_POSITION is
 47      do
 48         Result := class_descriptor.position
 49      end
 50
 51feature {ANY}
 52   hash_code: INTEGER
 53
 54   is_equal (other: like Current): BOOLEAN is
 55      do
 56         if hash_code = other.hash_code then
 57            Result := same_as(other)
 58         end
 59      end
 60
 61   same_as (other: like Current): BOOLEAN is
 62      local
 63         i, o: INTEGER
 64      do
 65         Result := class_descriptor.is_equal(other.class_descriptor) and then other.parameters.count = parameters.count
 66         from
 67            i := parameters.lower
 68         until
 69            not Result or else i > parameters.upper
 70         loop
 71            o := i - parameters.lower + other.parameters.lower
 72            Result := parameters.item(i) = other.parameters.item(o)
 73            i := i + 1
 74         end
 75      end
 76
 77   copy (other: like Current) is
 78      do
 79         class_descriptor := other.class_descriptor.twin
 80         parameters := other.parameters
 81      end
 82
 83feature {LIBERTY_TYPE_DESCRIPTOR_CHANGE_LISTENER}
 84   add_change_listener (a_listener: LIBERTY_TYPE_DESCRIPTOR_CHANGE_LISTENER) is
 85      require
 86         a_listener /= Void
 87         not has_change_listener(a_listener)
 88      do
 89         change_listeners.add_last(a_listener)
 90      ensure
 91         has_change_listener(a_listener)
 92      end
 93
 94   remove_change_listener (a_listener: LIBERTY_TYPE_DESCRIPTOR_CHANGE_LISTENER) is
 95      require
 96         a_listener /= Void
 97         has_change_listener(a_listener)
 98      do
 99         change_listeners.remove(change_listeners.fast_first_index_of(a_listener))
100      ensure
101         not has_change_listener(a_listener)
102      end
103
104   has_change_listener (a_listener: LIBERTY_TYPE_DESCRIPTOR_CHANGE_LISTENER): BOOLEAN is
105      require
106         a_listener /= Void
107      do
108         Result := change_listeners.fast_has(a_listener)
109      end
110
111feature {}
112   make (a_class_descriptor: like class_descriptor; a_parameters: like parameters) is
113      require
114         a_class_descriptor /= Void
115         a_parameters /= Void
116      do
117         class_descriptor := a_class_descriptor
118         parameters := a_parameters
119         file := a_class_descriptor.file
120         create {FAST_ARRAY[LIBERTY_TYPE_DESCRIPTOR_CHANGE_LISTENER]} change_listeners.with_capacity(2)
121         compute_hash_code
122         listen_to_parameters
123      ensure
124         class_descriptor = a_class_descriptor
125         parameters = a_parameters
126      end
127
128   change_listeners: COLLECTION[LIBERTY_TYPE_DESCRIPTOR_CHANGE_LISTENER]
129
130feature {}
131   compute_hash_code is
132      local
133         i, h: INTEGER
134      do
135         h := class_descriptor.hash_code
136         from
137            i := parameters.lower
138         until
139            i > parameters.upper
140         loop
141            h := h #*31 #+ parameters.item(i).hash_code
142            i := i + 1
143         end
144         if h > 0 then
145            hash_code := h
146         else
147            hash_code := ~h
148         end
149      end
150
151   listen_to_parameters is
152      local
153         i: INTEGER
154      do
155         from
156            i := parameters.lower
157         until
158            i > parameters.upper
159         loop
160            if not parameters.item(i).is_known then
161               parameters.item(i).add_listener(Current)
162            end
163            i := i + 1
164         end
165      end
166
167   fire_type_descriptor_changed is
168      local
169         i: INTEGER
170      do
171         from
172            i := change_listeners.lower
173         until
174            i > change_listeners.upper
175         loop
176            change_listeners.item(i).on_type_descriptor_changed(Current)
177            i := i + 1
178         end
179      end
180
181feature {LIBERTY_TYPE}
182   on_type_known (t: LIBERTY_TYPE) is
183      do
184         fire_type_descriptor_changed
185      end
186
187   on_type_built (t: LIBERTY_ACTUAL_TYPE) is
188      do
189         -- ignored
190      end
191
192feature {LIBERTY_TYPE_DESCRIPTOR}
193   class_descriptor: LIBERTY_CLASS_DESCRIPTOR
194
195invariant
196   file /= Void
197   parameters /= Void
198   change_listeners /= Void
199
200end