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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23