/[eiffelstudio]/trunk/Src/Eiffel/API/evaluated_type/like_current.e
ViewVC logotype

Contents of /trunk/Src/Eiffel/API/evaluated_type/like_current.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 77825 - (show annotations)
Fri Mar 20 12:55:11 2009 UTC (10 years, 10 months ago) by alexk
File size: 16378 byte(s)
Removed attached status from types that are result of 'like Current' that comes from a non-void-safe class (this fixes test#attach032).
1 note
2 description:"Actual type like Current."
3 legal: "See notice at end of class."
4 status: "See notice at end of class."
5 date: "$Date$"
6 revision: "$Revision $"
7
8 class
9 LIKE_CURRENT
10
11 inherit
12 LIKE_TYPE_A
13 redefine
14 actual_type, deep_actual_type, context_free_type,
15 associated_class, associated_class_type, conform_to, conformance_type, convert_to,
16 generics, has_associated_class, has_associated_class_type, instantiated_in, duplicate,
17 is_basic, is_expanded, is_external, is_like_current, is_none, is_reference,
18 meta_type, set_actual_type, evaluated_type_in_descendant, is_tuple,
19 set_attached_mark, set_detachable_mark, set_is_implicitly_attached,
20 unset_is_implicitly_attached, description, c_type, is_explicit, formal_instantiation_in,
21 generated_id, generate_cid, generate_cid_array, generate_cid_init,
22 make_type_byte_code, generate_gen_type_il, internal_is_valid_for_class,
23 maximum_interval_value, minimum_interval_value, is_optimized_as_frozen,
24 is_generated_as_single_type, heaviest, instantiation_in, adapted_in,
25 hash_code, internal_generic_derivation, internal_same_generic_derivation_as,
26 is_class_valid, skeleton_adapted_in, good_generics, has_like_current, is_type_set
27 end
28
29 feature -- Visitor
30
31 process (v: TYPE_A_VISITOR)
32 -- Process current element.
33 do
34 v.process_like_current (Current)
35 end
36
37 feature -- Properties
38
39 actual_type: LIKE_CURRENT
40 -- Actual type of the anchored type in a given class
41
42 deep_actual_type: TYPE_A
43 -- <Precursor>
44 do
45 Result := conformance_type.deep_actual_type
46 end
47
48 context_free_type: like Current
49 -- <Precursor>
50 do
51 create Result
52 Result.set_actual_type (conformance_type.context_free_type)
53 end
54
55 conformance_type: TYPE_A
56 -- Type of the anchored type as specified in `set_actual_type'
57
58 has_associated_class: BOOLEAN
59 -- Does Current have an associated class?
60 do
61 Result := conformance_type /= Void and then conformance_type.has_associated_class
62 end
63
64 has_associated_class_type (a_context_type: TYPE_A): BOOLEAN
65 -- Does Current have an associated class?
66 do
67 Result := conformance_type /= Void and then conformance_type.has_associated_class_type (a_context_type)
68 end
69
70 is_class_valid: BOOLEAN
71 do
72 Result := conformance_type /= Void and then conformance_type.is_class_valid
73 end
74
75 has_like_current, is_like_current: BOOLEAN = True
76 -- Is the current type an anchored type on Current ?
77
78 is_explicit: BOOLEAN = False
79 -- Is type fixed at compile time without anchors or formals?
80 --| Ideally, it is explicit if at runtime there is no descendants and
81 --| that conformance_type is also explicit (to prevent case
82 --| where like Current represents A [G] for which we can have
83 --| many types) using the following code
84 --| Result := associated_class.direct_descendants.is_empty and then
85 --| conformance_type.is_explicit
86 --| Unfortunately it does not work because code generation is still
87 --| generating `dftype' instead which cannot be used in static array
88 --| type initialization.
89
90 is_expanded: BOOLEAN
91 -- Is type expanded?
92 do
93 if conformance_type /= Void then
94 Result := conformance_type.is_expanded
95 end
96 end
97
98 is_reference: BOOLEAN
99 -- Is type reference?
100 do
101 if conformance_type /= Void then
102 Result := conformance_type.is_reference
103 end
104 end
105
106 is_tuple: BOOLEAN
107 -- Is type reference?
108 do
109 if conformance_type /= Void then
110 Result := conformance_type.is_tuple
111 end
112 end
113
114 is_external: BOOLEAN = False
115 -- Is type external?
116
117 is_none: BOOLEAN = False
118 -- Is current actual type NONE?
119
120 is_type_set: BOOLEAN
121 -- <Precursor>
122 do
123 Result := conformance_type /= Void and then conformance_type.is_type_set
124 end
125
126 is_basic: BOOLEAN
127 -- Is the current actual type a basic one?
128 do
129 if conformance_type /= Void then
130 Result := conformance_type.is_basic
131 end
132 end
133
134 same_as (other: TYPE_A): BOOLEAN
135 -- Is the current type the same as `other' ?
136 local
137 l: LIKE_CURRENT
138 do
139 if other.is_like_current then
140 l ?= other
141 Result := has_same_attachment_marks (l)
142 end
143 end
144
145 good_generics: BOOLEAN = True
146 --| A current type always has the right number of generic parameter.
147
148 feature -- Access
149
150 hash_code: INTEGER
151 do
152 Result := {SHARED_HASH_CODE}.other_code
153 end
154
155 associated_class: CLASS_C
156 -- Associated class
157 do
158 Result := conformance_type.associated_class
159 end
160
161 associated_class_type (a_context_type: TYPE_A): CLASS_TYPE
162 -- Associated class
163 do
164 Result := conformance_type.associated_class_type (a_context_type)
165 end
166
167 generics: ARRAY [TYPE_A]
168 -- Actual generic types
169 do
170 if conformance_type /= Void then
171 Result := conformance_type.generics
172 end
173 end
174
175 description: GENERIC_DESC
176 do
177 create Result
178 Result.set_type_i (Current)
179 end
180
181 c_type: TYPE_C
182 do
183 if conformance_type /= Void then
184 Result := conformance_type.c_type
185 else
186 Result := reference_c_type
187 end
188 end
189
190 feature -- Comparison
191
192 is_equivalent (other: like Current): BOOLEAN
193 -- Is `other' equivalent to the current object ?
194 do
195 Result := same_as (other)
196 end
197
198 feature -- Output
199
200 dump: STRING
201 -- Dumped trace
202 local
203 actual_dump: STRING
204 do
205 actual_dump := conformance_type.dump
206 create Result.make (17 + actual_dump.count)
207 Result.append_character ('[')
208 if has_attached_mark then
209 Result.append_character ('!')
210 elseif has_detachable_mark then
211 Result.append_character ('?')
212 end
213 Result.append ("like Current] ")
214 Result.append (actual_dump)
215 end
216
217 ext_append_to (st: TEXT_FORMATTER; c: CLASS_C)
218 do
219 st.process_symbol_text ({SHARED_TEXT_ITEMS}.ti_L_bracket)
220 if has_attached_mark then
221 st.process_keyword_text ({SHARED_TEXT_ITEMS}.ti_attached_keyword, Void)
222 st.add_space
223 elseif has_detachable_mark then
224 st.process_keyword_text ({SHARED_TEXT_ITEMS}.ti_detachable_keyword, Void)
225 st.add_space
226 end
227 st.process_keyword_text ({SHARED_TEXT_ITEMS}.ti_Like_keyword, Void)
228 st.add_space
229 st.process_keyword_text ({SHARED_TEXT_ITEMS}.ti_Current, Void)
230 st.process_symbol_text ({SHARED_TEXT_ITEMS}.ti_R_bracket)
231 st.add_space
232 conformance_type.ext_append_to (st, c)
233 end
234
235 feature -- IL code generation
236
237 minimum_interval_value: INTERVAL_VAL_B
238 require else
239 valid_type: conformance_type.is_integer or conformance_type.is_natural or conformance_type.is_character
240 do
241 Result := conformance_type.minimum_interval_value
242 end
243
244 maximum_interval_value: INTERVAL_VAL_B
245 require else
246 valid_type: conformance_type.is_integer or conformance_type.is_natural or conformance_type.is_character
247 do
248 Result := conformance_type.maximum_interval_value
249 end
250
251 heaviest (other: TYPE_A): TYPE_A
252 do
253 Result := conformance_type.heaviest (other)
254 end
255
256 is_optimized_as_frozen: BOOLEAN
257 do
258 Result := conformance_type.is_optimized_as_frozen
259 end
260
261 is_generated_as_single_type: BOOLEAN
262 -- Is associated type generated as a single type or as an interface type and
263 -- an implementation type.
264 do
265 Result := conformance_type.is_generated_as_single_type
266 end
267
268 feature -- Generic conformance
269
270 generated_id (final_mode: BOOLEAN; a_context_type: TYPE_A): NATURAL_16
271 -- Id of a `like xxx'.
272 do
273 Result := {SHARED_GEN_CONF_LEVEL}.like_current_type
274 end
275
276 generate_cid (buffer: GENERATION_BUFFER; final_mode, use_info: BOOLEAN; a_context_type: TYPE_A)
277 -- Generate mode dependent sequence of type id's
278 -- separated by commas. `use_info' is true iff
279 -- we generate code for a creation instruction.
280 do
281 generate_cid_prefix (buffer, Void)
282 if use_info then
283 create_info.generate_cid (buffer, final_mode)
284 else
285 conformance_type.generate_cid (buffer, final_mode, use_info, a_context_type)
286 end
287 end
288
289 generate_cid_array (buffer: GENERATION_BUFFER; final_mode, use_info: BOOLEAN; idx_cnt: COUNTER; a_context_type: TYPE_A)
290 do
291 generate_cid_prefix (buffer, idx_cnt)
292 if use_info then
293 create_info.generate_cid_array (buffer, final_mode, idx_cnt)
294 else
295 conformance_type.generate_cid_array (buffer, final_mode, use_info, idx_cnt, a_context_type)
296 end
297 end
298
299 generate_cid_init (buffer: GENERATION_BUFFER; final_mode, use_info: BOOLEAN; idx_cnt: COUNTER; a_level: NATURAL)
300 do
301 generate_cid_prefix (Void, idx_cnt)
302 if use_info then
303 create_info.generate_cid_init (buffer, final_mode, idx_cnt, a_level)
304 else
305 conformance_type.generate_cid_init (buffer, final_mode, use_info, idx_cnt, a_level)
306 end
307 end
308
309 make_type_byte_code (ba: BYTE_ARRAY; use_info: BOOLEAN; a_context_type: TYPE_A)
310 do
311 make_type_prefix_byte_code (ba)
312 if use_info then
313 create_info.make_type_byte_code (ba)
314 else
315 conformance_type.make_type_byte_code (ba, use_info, a_context_type)
316 end
317 end
318
319 generate_gen_type_il (il_generator: IL_CODE_GENERATOR; use_info: BOOLEAN)
320 -- `use_info' is true iff we generate code for a
321 -- creation instruction.
322 do
323 il_generator.generate_current_as_reference
324 il_generator.load_type
325 end
326
327 feature {TYPE_A} -- Helpers
328
329 internal_is_valid_for_class (a_class: CLASS_C): BOOLEAN
330 -- Is current type valid?
331 do
332 -- If no `conformance_type' is specified, then `like Current' makes sense.
333 -- If one is specified, then it should be correct.
334 Result := conformance_type = Void or else conformance_type.internal_is_valid_for_class (a_class)
335 end
336
337 internal_generic_derivation (a_level: INTEGER_32): TYPE_A
338 do
339 -- We keep the same level since we are merely forwarding the call.
340 Result := conformance_type.internal_generic_derivation (a_level)
341 end
342
343 internal_same_generic_derivation_as (current_type, other: TYPE_A; a_level: INTEGER_32): BOOLEAN
344 do
345 -- We keep the same level since we are merely forwarding the call.
346 Result := conformance_type.internal_same_generic_derivation_as (current_type, other, a_level)
347 end
348
349 feature {COMPILER_EXPORTER} -- Modification
350
351 set_actual_type (a: TYPE_A)
352 -- Assign `a' to `conformance_type'.
353 do
354 conformance_type := a.to_other_immediate_attachment (Current)
355 actual_type := Current
356 end
357
358 set_attached_mark
359 -- Mark type declaration as having an explicit attached mark.
360 do
361 Precursor
362 conformance_type := conformance_type.to_other_immediate_attachment (Current)
363 end
364
365 set_detachable_mark
366 -- Set class type declaration as having an explicit detachable mark.
367 do
368 Precursor
369 conformance_type := conformance_type.to_other_immediate_attachment (Current)
370 end
371
372 set_is_implicitly_attached
373 local
374 a: like conformance_type
375 do
376 Precursor
377 a := conformance_type
378 if a /= Void then
379 conformance_type := a.to_other_immediate_attachment (Current)
380 end
381 end
382
383 unset_is_implicitly_attached
384 local
385 a: like conformance_type
386 do
387 Precursor
388 a := conformance_type
389 if a /= Void then
390 conformance_type := a.to_other_immediate_attachment (Current)
391 end
392 end
393
394 feature {COMPILER_EXPORTER} -- Duplication
395
396 duplicate: LIKE_CURRENT
397 -- Duplication
398 do
399 Result := Precursor
400 -- Ensure `Result.actual_type = Result'
401 -- that is expected when working with attachment properties
402 Result.set_actual_type (conformance_type)
403 end
404
405 feature {COMPILER_EXPORTER} -- Primitives
406
407 formal_instantiation_in (type: TYPE_A; constraint: TYPE_A; written_id: INTEGER): TYPE_A
408 -- <Precursor>
409 do
410 -- Use original type.
411 Result := instantiation_in (type, written_id)
412 end
413
414 instantiation_in (type: TYPE_A; written_id: INTEGER): TYPE_A
415 -- Instantiation of Current in the context of `class_type',
416 -- assuming that Current is written in class of id `written_id'.
417 local
418 a: ATTACHABLE_TYPE_A
419 do
420 -- Special cases for calls on a target which is a manifest integer
421 -- that might be compatible with _8 or _16. The returned
422 -- `actual_type' should not take into consideration the
423 -- `compatibility_size' of `type', just its intrinsic type.
424 -- Because manifest integers are by default 32 bits, when
425 -- you apply a routine whose result is of type `like Current'
426 -- then it should really be a 32 bits integer. Note that in the
427 -- past we were keeping the size of the manifest integers and the
428 -- following code was accepted:
429 -- i16: INTEGER_16
430 -- i8: INTEGER_8
431 -- i16 := 0x00FF & i8
432 -- Now the code is rejected because target expect an INTEGER_16
433 -- and not an INTEGER, therefore the code needs to be fixed with:
434 -- i16 := (0x00FF).to_integer_16 & i8
435 -- or
436 -- i16 := (0x00FF & i8).to_integer_16
437 Result := type.intrinsic_type
438 if is_attached then
439 -- Adapt attachment marks as required.
440 Result := Result.to_other_attachment (Current)
441 elseif Result.is_attached then
442 -- Remove explicit "attached" mark.
443 if attached {ATTACHABLE_TYPE_A} Result as t then
444 a := t.duplicate
445 a.set_detachable_mark
446 Result := a
447 end
448 elseif Result.is_implicitly_attached then
449 Result := Result.as_implicitly_detachable
450 end
451 end
452
453 adapted_in, skeleton_adapted_in (a_class_type: CLASS_TYPE): CL_TYPE_A
454 -- Instantiation of Current in context of `other'.
455 do
456 Result := a_class_type.type
457 end
458
459 instantiated_in (class_type: TYPE_A): TYPE_A
460 -- Instantiation of Current in the context of `class_type'
461 -- assuming that Current is written in the associated class
462 -- of `class_type'.
463 local
464 l_like: like Current
465 do
466 Result := class_type
467 if Result.is_like_current then
468 -- We cannot allow aliasing as otherwise we might end up updating
469 -- `like Current' type that should not be updated (Allowing the
470 -- aliasing would break eweasel test#valid218).
471 create l_like
472 l_like.set_actual_type (class_type.conformance_type)
473 Result := l_like
474 end
475 Result := Result.to_other_attachment (Current)
476 end
477
478 evaluated_type_in_descendant (a_ancestor, a_descendant: CLASS_C; a_feature: FEATURE_I): LIKE_CURRENT
479 do
480 if a_ancestor /= a_descendant then
481 create Result
482 Result.set_actual_type (a_descendant.actual_type)
483 Result := Result.to_other_attachment (Current)
484 else
485 Result := Current
486 end
487 end
488
489 create_info, shared_create_info: CREATE_CURRENT
490 -- Byte code information for entity type creation
491 once
492 create Result
493 end
494
495 conform_to (a_context_class: CLASS_C; other: TYPE_A): BOOLEAN
496 -- Does `Current' conform to `other'?
497 do
498 Result := other.is_like_current or else conformance_type.conform_to (a_context_class, other.conformance_type)
499 end
500
501 convert_to (a_context_class: CLASS_C; a_target_type: TYPE_A): BOOLEAN
502 -- Does current convert to `a_target_type' in `a_context_class'?
503 -- Update `last_conversion_info' of AST_CONTEXT.
504 do
505 Result := conformance_type.convert_to (a_context_class, a_target_type)
506 end
507
508 meta_type: LIKE_CURRENT
509 -- Meta type.
510 do
511 -- Because `like Current' could possibly means a basic type
512 -- when processing an inherited routine using `like Current'
513 -- we keep LIKE_CURRENT for the metatype, but simply replace
514 -- its `conformance_type' with its `meta_type'.
515 create Result
516 Result.set_actual_type (conformance_type.meta_type)
517 end
518
519 note
520 copyright: "Copyright (c) 1984-2009, Eiffel Software"
521 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
522 licensing_options: "http://www.eiffel.com/licensing"
523 copying: "[
524 This file is part of Eiffel Software's Eiffel Development Environment.
525
526 Eiffel Software's Eiffel Development Environment is free
527 software; you can redistribute it and/or modify it under
528 the terms of the GNU General Public License as published
529 by the Free Software Foundation, version 2 of the License
530 (available at the URL listed under "license" above).
531
532 Eiffel Software's Eiffel Development Environment is
533 distributed in the hope that it will be useful, but
534 WITHOUT ANY WARRANTY; without even the implied warranty
535 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
536 See the GNU General Public License for more details.
537
538 You should have received a copy of the GNU General Public
539 License along with Eiffel Software's Eiffel Development
540 Environment; if not, write to the Free Software Foundation,
541 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
542 ]"
543 source: "[
544 Eiffel Software
545 356 Storke Road, Goleta, CA 93117 USA
546 Telephone 805-685-1006, Fax 805-685-6869
547 Website http://www.eiffel.com
548 Customer support http://support.eiffel.com
549 ]"
550
551 end

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23