/[eiffelstudio]/branches/eth/eve/Src/Eiffel/API/evaluated_type/renaming_a.e
ViewVC logotype

Contents of /branches/eth/eve/Src/Eiffel/API/evaluated_type/renaming_a.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 93518 - (show annotations)
Fri Nov 22 10:13:29 2013 UTC (6 years ago) by jasonw
File size: 13490 byte(s)
<<Merged from trunk#93517.>>
1 note
2 description: "[
3 This class maps new feature names onto old feature names.
4 It does this not by using strings but by using the `name_id' of each
5 feature which obtained by using an instance of the NAMES_HEAP class.
6 ]"
7 author: ""
8 date: "$Date$"
9 revision: "$Revision$"
10
11 class
12 RENAMING_A
13
14 inherit
15
16 HASH_TABLE[INTEGER,INTEGER]
17 rename
18 put as ht_put,
19 make as ht_make
20 export
21 {RENAMING_A} force, ht_put
22 end
23
24 COMPILER_EXPORTER
25 undefine
26 copy, is_equal
27 end
28
29
30 SHARED_WORKBENCH
31 undefine
32 copy, is_equal
33 end
34
35 SHARED_ERROR_HANDLER
36 undefine
37 copy, is_equal
38 end
39
40 SHARED_NAMES_HEAP
41 undefine
42 copy, is_equal
43 end
44
45 INTERNAL_COMPILER_STRING_EXPORTER
46 undefine
47 copy, is_equal
48 end
49
50 create
51 make
52
53 create {RENAMING_A}
54 ht_make
55
56 feature {NONE} -- Initialization
57
58 make (a_renamings: EIFFEL_LIST [RENAME_AS]; a_constraint: CLASS_C)
59 -- Create current
60 require
61 a_renamings_not_void: a_renamings /= Void
62 a_constraint_not_void: a_constraint /= Void
63 local
64 l_rename: RENAME_AS
65 l_new_name: FEATURE_NAME
66 l_old_name_id: INTEGER
67 l_feature_table: FEATURE_TABLE
68 l_old_feature: FEATURE_I
69 do
70 -- Create table.
71 ht_make (a_renamings.count)
72
73 -- Initialize table.
74 from
75 l_feature_table := a_constraint.feature_table
76 a_renamings.start
77 until
78 a_renamings.after
79 loop
80 l_rename := a_renamings.item
81 l_old_name_id := l_rename.old_name.internal_name.name_id
82 l_old_feature := l_feature_table.item_id (l_old_name_id)
83 if l_old_feature = Void then
84 -- Old name does not even exist, don't bother checking the new name.
85 if error_report = Void then
86 error_report := new_error_report
87 end
88 error_report.non_existent.put(names_heap.item (l_old_name_id))
89 else
90 l_new_name := l_rename.new_name
91 -- Add new name to the list.
92 put (l_old_name_id, l_new_name.internal_name.name_id)
93
94 if attached {INFIX_PREFIX_AS} l_new_name as l_infix_prefix_name then
95 -- Check validity of infix/prefix for that particular routine.
96 process_alias (l_rename.new_name, l_old_feature)
97 -- No need to add it, because infix have the same internal name as their alias.
98 elseif attached {FEATURE_NAME_ALIAS_AS} l_new_name as l_alias_name then
99 -- Check validity of alias for that particular routine.
100 process_alias (l_rename.new_name, l_old_feature)
101 -- Because `l_old_name_id' is already there, we do not want to generate an error
102 -- and thus we call `internal_put'.
103 internal_put (l_old_name_id, l_new_name.internal_alias_name_id)
104 end
105
106 -- If previously it was an alias routine, we removed the alias from the original class.
107 if l_old_feature.alias_name_id /= 0 and not l_old_feature.is_infix and not l_old_feature.is_prefix then
108 if removed_alias = Void then
109 create removed_alias.make (10)
110 end
111 removed_alias.extend (l_old_feature.alias_name_id)
112 end
113 end
114 a_renamings.forth
115 end
116
117 -- Check that we do not end up with twice or more feature with the same name.
118 from
119 start
120 until
121 after
122 loop
123 if
124 l_feature_table.has_id (key_for_iteration) and then
125 not is_feature_renamed_by_name_id (key_for_iteration)
126 then
127 if error_report = Void then
128 error_report := new_error_report
129 end
130 error_report.renamed_to_same_name.put (names_heap.item (key_for_iteration))
131 end
132 forth
133 end
134 end
135
136 feature -- Element change
137
138 put (a_original_name: INTEGER; a_new_name: INTEGER)
139 -- Add pair to renaming and check for errors.
140 --| `a_original_name' used to be the new item to add to the hashtable.
141 --| `a_newm_name' is the key for the hashtable.
142 do
143 if has_item (a_original_name) then
144 if not has_error then
145 error_report := new_error_report
146 end
147 error_report.renamed_multiple_times.put (names_heap.item (a_original_name))
148 end
149 internal_put (a_original_name, a_new_name)
150 end
151
152 feature {NONE} -- Element change
153
154 internal_put (a_original_name: INTEGER_32; a_new_name: INTEGER_32)
155 -- Add pair to renaming and check for errors.
156 do
157 ht_put (a_original_name, a_new_name)
158 if conflict then
159 if not has_error then
160 error_report := new_error_report
161 end
162 error_report.renamed_to_same_name.put (names_heap.item (a_new_name))
163 end
164 end
165
166 feature -- Access
167
168 error_report: TUPLE [renamed_multiple_times: SEARCH_TABLE[STRING];
169 renamed_to_same_name: SEARCH_TABLE[STRING];
170 non_existent: SEARCH_TABLE[STRING]]
171 -- Error report for renaming clause. Contains all problematic cases.
172 --| Is Void if no error occurred.
173
174 renamed (a_name_id: INTEGER): INTEGER
175 -- Renames `a_name_id' into it's old name or leaves it unchanged if it is not renamed.
176 -- Return -1 if `a_name_id' has been renamed into another name.
177 do
178 -- We're looking for f (a_name_id)
179 search (a_name_id)
180 if found then
181 -- Someone renamed x into f
182 -- Result is now x
183 Result := found_item
184 else
185 if removed_alias /= Void and removed_alias.has (a_name_id) then
186 Result := -1
187 elseif not has_item (a_name_id) then
188 -- Nobody touched our feature:
189 -- Result is therefore f (unchanged)
190 Result := a_name_id
191 else
192 -- f got actually renamed into y
193 -- Therefore we return -1
194 Result := -1
195 end
196 end
197 ensure
198 renamed_result_valid: Result > 0 or Result = -1
199 end
200
201 new_name (a_feature_name_id: INTEGER): INTEGER
202 -- Renames `a_feature_name_id' into it's new name or leaves it unchanged.
203 do
204 from
205 start
206 until
207 after or Result /= 0
208 loop
209 if item_for_iteration = a_feature_name_id then
210 Result := key_for_iteration
211 end
212 forth
213 end
214 if Result = 0 then
215 -- No new name found for this feature
216 -- Just keep the old one
217 Result := a_feature_name_id
218 end
219 end
220
221 feature -- Status
222
223 is_feature_renamed_by_name_id (a_feature_name_id: INTEGER): BOOLEAN
224 -- Is `a_feature' renamed under renaming of `Current'?
225 do
226 Result := has_item (a_feature_name_id)
227 end
228
229 is_feature_renamed (a_feature: ID_AS): BOOLEAN
230 -- Is `a_feature' renamed under renaming of `Current'?
231 do
232 Result := is_feature_renamed_by_name_id (a_feature.name_id)
233 end
234
235 has_error: BOOLEAN
236 -- Is the renaming clause in-valid?
237 --| Are there any features which are renamed multiple times?
238 --| Are there any features which are renamed to the same name?
239 --| Are there any non-existent features? (This is only the case
240 --| if `check_against_feature_table' has been called.)
241 --| In either case perform proper error reporting.
242 do
243 Result := error_report /= Void
244 end
245
246 feature -- Output
247
248 append_to_with_pebbles (a_text_formatter: TEXT_FORMATTER; a_class_c: CLASS_C)
249 -- Append `Current' renaming.
250 --
251 -- `a_text_formatter' is the object where the current renaming is appended to.
252 -- `a_type_set' is a list of types to which the renaming is actually applied. It is used
253 -- to link features.
254 require
255 a_text_formatter_not_void: a_text_formatter /= Void
256 a_class_c_not_void: a_class_c /= Void
257 do
258 append_to_impl (a_text_formatter, a_class_c)
259 end
260
261 append_to (a_text_formatter: TEXT_FORMATTER)
262 -- Append `Current' renaming.
263 --
264 -- `a_text_formatter' is the object where the current renaming is appended to.
265 do
266 append_to_impl (a_text_formatter, Void)
267 end
268
269 dump: STRING
270 -- Dump
271 local
272 l_as_keyword, l_comma_space: STRING
273 do
274 l_as_keyword := " as "
275 if not is_empty then
276 Result := "rename "
277 from
278 start
279 until
280 after
281 loop
282 if l_comma_space = Void then
283 l_comma_space := ", "
284 else
285 Result.append (l_comma_space)
286 end
287 Result.append (names_heap.item (item_for_iteration))
288 Result.append (l_as_keyword)
289 Result.append (names_heap.item (key_for_iteration))
290 forth
291 end
292 Result.append (" end")
293 end
294 end
295
296 feature {NONE} -- Implementation
297
298 removed_alias: ARRAYED_LIST [INTEGER]
299 -- List of removed aliases from the original class.
300
301 process_alias (a_name: FEATURE_NAME; a_old_feature: FEATURE_I)
302 -- Check if `a_rename' is a valid infix/prefix/alias.
303 require
304 a_name_not_void: a_name /= Void
305 a_old_feature_not_void: a_old_feature /= Void
306 local
307 l_infix_prefix: INFIX_PREFIX_AS
308 l_argument_count: INTEGER
309 l_operator: STRING
310 l_vfav: VFAV_SYNTAX
311 do
312 -- TODO: This code should be refactored as it occurs almost the same way in
313 -- `{AST_COMPILER_FACTORY}.new_feature_as'
314 l_operator := a_name.alias_name.value
315 l_argument_count := a_old_feature.argument_count
316
317 if a_name.is_bracket then
318 if not a_old_feature.has_return_value or else l_argument_count < 1 then
319 -- Invalid bracket alias
320 create {VFAV2_SYNTAX} l_vfav.make (a_name)
321 elseif a_name.has_convert_mark then
322 -- Invalid convert mark
323 create {VFAV3_SYNTAX} l_vfav.make (a_name)
324 end
325 elseif a_name.is_parentheses then
326 if l_argument_count < 1 then
327 -- Invalid parenthesis alias.
328 create {VFAV4_SYNTAX} l_vfav.make (a_name)
329 elseif a_name.has_convert_mark then
330 -- Invalid convert mark.
331 create {VFAV3_SYNTAX} l_vfav.make (a_name)
332 end
333 elseif
334 a_old_feature.has_return_value and then
335 ((l_argument_count = 0 and then a_name.is_valid_unary_operator (l_operator)) or else
336 (l_argument_count = 1 and then a_name.is_valid_binary_operator (l_operator)))
337 then
338 if l_argument_count = 1 then
339 l_infix_prefix ?= a_name
340 if l_infix_prefix /= Void then
341 if l_infix_prefix.is_prefix then
342 -- Ok, the feature renamed is not capable to be a prefix, throw an error.
343 -- Invalid operator alias
344 create {VFAV1_SYNTAX} l_vfav.make (a_name)
345 end
346 else
347 a_name.set_is_binary
348 end
349 elseif a_name.has_convert_mark then
350 -- Invalid convert mark
351 create {VFAV3_SYNTAX} l_vfav.make (a_name)
352 else
353 l_infix_prefix ?= a_name
354 if l_infix_prefix /= Void then
355 if l_infix_prefix.is_infix then
356 -- Ok, the feature renamed is not capable to be an infix, throw an error.
357 -- Invalid operator alias
358 create {VFAV1_SYNTAX} l_vfav.make (a_name)
359 end
360 else
361 a_name.set_is_unary
362 end
363
364 end
365 else
366 -- Invalid operator alias
367 create {VFAV1_SYNTAX} l_vfav.make (a_name)
368 end
369 if l_vfav /= Void then
370 error_handler.insert_error (l_vfav)
371 end
372 end
373
374 append_to_impl (a_text_formatter: TEXT_FORMATTER; a_class_c: CLASS_C)
375 -- Append `Current' renaming.
376 --
377 -- `a_text_formatter' is the object where the current renaming is appended to.
378 -- `a_type_set' is a list of types to which the renaming is actually applied. It is used to
379 -- link features.
380 require
381 a_text_formatter_attached: a_text_formatter /= Void
382 a_class_c_attached: a_class_c /= Void
383 local
384 l_as_keyword, l_comma_space: STRING
385 l_feature: E_FEATURE
386 do
387 l_as_keyword := " as "
388
389 if not is_empty then
390 a_text_formatter.process_keyword_text (" rename ", Void)
391 from
392 start
393 until
394 after
395 loop
396 if l_comma_space = Void then
397 l_comma_space := ", "
398 else
399 a_text_formatter.add (l_comma_space)
400 end
401 if a_class_c /= Void and then a_class_c.has_feature_table then
402 l_feature := a_class_c.feature_with_name_id (item_for_iteration)
403 end
404 if l_feature /= Void then
405 a_text_formatter.process_feature_text (names_heap.item_32 (item_for_iteration), l_feature, False)
406 else
407 a_text_formatter.add (names_heap.item_32 (item_for_iteration))
408 end
409 a_text_formatter.process_keyword_text (l_as_keyword, Void)
410 a_text_formatter.add (names_heap.item_32 (key_for_iteration))
411 forth
412 end
413 a_text_formatter.process_keyword_text (" end", Void)
414 end
415 end
416
417 new_error_report: TUPLE [SEARCH_TABLE[STRING], SEARCH_TABLE[STRING], SEARCH_TABLE[STRING]]
418 -- Create a new instance of an error report.
419 require
420 no_error_report_exists: error_report = Void
421 do
422 Result := [ create {SEARCH_TABLE[STRING]}.make(3),
423 create {SEARCH_TABLE[STRING]}.make (3),
424 create {SEARCH_TABLE[STRING]}.make (3)]
425 ensure
426 result_not_void: Result /= Void
427 end
428 note
429 copyright: "Copyright (c) 1984-2013, Eiffel Software"
430 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
431 licensing_options: "http://www.eiffel.com/licensing"
432 copying: "[
433 This file is part of Eiffel Software's Eiffel Development Environment.
434
435 Eiffel Software's Eiffel Development Environment is free
436 software; you can redistribute it and/or modify it under
437 the terms of the GNU General Public License as published
438 by the Free Software Foundation, version 2 of the License
439 (available at the URL listed under "license" above).
440
441 Eiffel Software's Eiffel Development Environment is
442 distributed in the hope that it will be useful, but
443 WITHOUT ANY WARRANTY; without even the implied warranty
444 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
445 See the GNU General Public License for more details.
446
447 You should have received a copy of the GNU General Public
448 License along with Eiffel Software's Eiffel Development
449 Environment; if not, write to the Free Software Foundation,
450 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
451 ]"
452 source: "[
453 Eiffel Software
454 5949 Hollister Ave., Goleta, CA 93117 USA
455 Telephone 805-685-1006, Fax 805-685-6869
456 Website http://www.eiffel.com
457 Customer support http://support.eiffel.com
458 ]"
459 end

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.23