/[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 73697 - (show annotations)
Fri May 23 18:22:30 2008 UTC (11 years, 7 months ago) by manus
File size: 17716 byte(s)
Properly implemented the ~ operator on .NET.
Fixed .NET code generation which was generating incorrect code for the basic type when we changed the
  signature from `like Current' to the basic type. The issue is that our code generation was not good
  at changing the expanded status of an argument in a signature as this was not detected.
  To make this work, I also changed the code generation of basic type so that they use the basic type
  .NET equivalent rather than the value type we generate for all the signatures (see
  {BASIC_A}.generic_derivation change).
  And also changed a few things here and there for some various transformation of values from ref to
  basic and reverse.
Also if an inherited routine of an expanded class was calling a routine whose signature was changed
  in the expanded type (e.g. `infix "&"' in INTEGER_32 calling `bit_and' which is redefined) then
  we were calling the new `bit_and' routine but still using its inherited signature thus generating
  the wrong argument passing. So we fixed that by changing {CALL_ACCESS_B}.byte_node to update the
  call to the descendant signature but this caused eweasel test#exec060 to now fails. We tried to
  fix it but could not for the time being. The only result of that change is in {BYTE_CONTEXT}.real_type
  which has been factorized to use {BYTE_CONTEXT}.creation_type which now has a slightly different
  code for resolving types when handling inherited code. Other eweasel tests affected by this change
  but that are passing are test#incr288, test#expanded007 and test#melt069.
Had to change FEATURE_I.access to call the new {TYPE_A}.context_free_type instead of {TYPE_A}.deep_actual_type
  because otherwise the code generation in workbench mode for .NET of `abs_ref' in INTEGER would 
  be incorrect for the postcondition. Basically `context_free_type' only keeps `like Current' and gets
  rid of all the other anchors. The name is not that great since it is not completely free from context,
  but could not find one that express this.
 
Added some validity precondition in TYPE_A for `dispatch_anchors', `is_equivalent', `is_safe_equivalent'
  and `equivalent'. Updated REFERENCE_DESC to reflect that change.

1 indexing
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,
21 generated_id, generate_cid, generate_cid_array, generate_cid_init,
22 make_gen_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) is
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 is
43 -- <Precursor>
44 do
45 Result := conformance_type.deep_actual_type
46 end
47
48 context_free_type: like Current is
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 is
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 is
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 is
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 is True
76 -- Is the current type an anchored type on Current ?
77
78 is_explicit: BOOLEAN is 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 is
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 is
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 is
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 is False
115 -- Is type external?
116
117 is_none: BOOLEAN is False
118 -- Is current actual type NONE?
119
120 is_type_set: BOOLEAN is
121 -- <Precursor>
122 do
123 Result := conformance_type /= Void and then conformance_type.is_type_set
124 end
125
126 is_basic: BOOLEAN is
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 is
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 is True
146 --| A current type always has the right number of generic parameter.
147
148 feature -- Access
149
150 hash_code: INTEGER is
151 do
152 Result := {SHARED_HASH_CODE}.other_code
153 end
154
155 associated_class: CLASS_C is
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 is
162 -- Associated class
163 do
164 Result := conformance_type.associated_class_type (a_context_type)
165 end
166
167 generics: ARRAY [TYPE_A] is
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 is
176 do
177 create Result
178 Result.set_type_i (Current)
179 end
180
181 c_type: TYPE_C is
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 is
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 is
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) is
218 do
219 st.process_symbol_text ({SHARED_TEXT_ITEMS}.ti_L_bracket)
220 if has_attached_mark then
221 st.process_symbol_text ({SHARED_TEXT_ITEMS}.ti_exclamation)
222 elseif has_detachable_mark then
223 st.process_symbol_text ({SHARED_TEXT_ITEMS}.ti_question)
224 end
225 st.process_keyword_text ({SHARED_TEXT_ITEMS}.ti_Like_keyword, Void)
226 st.add_space
227 st.process_keyword_text ({SHARED_TEXT_ITEMS}.ti_Current, Void)
228 st.process_symbol_text ({SHARED_TEXT_ITEMS}.ti_R_bracket)
229 st.add_space
230 conformance_type.ext_append_to (st, c)
231 end
232
233 feature -- IL code generation
234
235 minimum_interval_value: INTERVAL_VAL_B is
236 require else
237 valid_type: conformance_type.is_integer or conformance_type.is_natural or conformance_type.is_character
238 do
239 Result := conformance_type.minimum_interval_value
240 end
241
242 maximum_interval_value: INTERVAL_VAL_B is
243 require else
244 valid_type: conformance_type.is_integer or conformance_type.is_natural or conformance_type.is_character
245 do
246 Result := conformance_type.maximum_interval_value
247 end
248
249 heaviest (other: TYPE_A): TYPE_A
250 do
251 Result := conformance_type.heaviest (other)
252 end
253
254 is_optimized_as_frozen: BOOLEAN is
255 do
256 Result := conformance_type.is_optimized_as_frozen
257 end
258
259 is_generated_as_single_type: BOOLEAN is
260 -- Is associated type generated as a single type or as an interface type and
261 -- an implementation type.
262 do
263 Result := conformance_type.is_generated_as_single_type
264 end
265
266 feature -- Generic conformance
267
268 generated_id (final_mode: BOOLEAN; a_context_type: TYPE_A): NATURAL_16 is
269 -- Id of a `like xxx'.
270 do
271 Result := {SHARED_GEN_CONF_LEVEL}.like_current_type
272 end
273
274 generate_cid (buffer: GENERATION_BUFFER; final_mode, use_info: BOOLEAN; a_context_type: TYPE_A) is
275 -- Generate mode dependent sequence of type id's
276 -- separated by commas. `use_info' is true iff
277 -- we generate code for a creation instruction.
278 do
279 if use_info then
280 create_info.generate_cid (buffer, final_mode)
281 else
282 conformance_type.generate_cid (buffer, final_mode, use_info, a_context_type)
283 end
284 end
285
286 generate_cid_array (buffer: GENERATION_BUFFER; final_mode, use_info: BOOLEAN; idx_cnt: COUNTER; a_context_type: TYPE_A) is
287 do
288 if use_info then
289 create_info.generate_cid_array (buffer, final_mode, idx_cnt)
290 else
291 conformance_type.generate_cid_array (buffer, final_mode, use_info, idx_cnt, a_context_type)
292 end
293 end
294
295 generate_cid_init (buffer: GENERATION_BUFFER; final_mode, use_info: BOOLEAN; idx_cnt: COUNTER; a_level: NATURAL) is
296 do
297 if use_info then
298 create_info.generate_cid_init (buffer, final_mode, idx_cnt, a_level)
299 else
300 conformance_type.generate_cid_init (buffer, final_mode, use_info, idx_cnt, a_level)
301 end
302 end
303
304 make_gen_type_byte_code (ba: BYTE_ARRAY; use_info: BOOLEAN; a_context_type: TYPE_A) is
305 do
306 if use_info then
307 create_info.make_gen_type_byte_code (ba)
308 else
309 conformance_type.make_gen_type_byte_code (ba, use_info, a_context_type)
310 end
311 end
312
313 generate_gen_type_il (il_generator: IL_CODE_GENERATOR; use_info: BOOLEAN) is
314 -- `use_info' is true iff we generate code for a
315 -- creation instruction.
316 do
317 il_generator.generate_current_as_reference
318 il_generator.load_type
319 end
320
321 feature {TYPE_A} -- Helpers
322
323 internal_is_valid_for_class (a_class: CLASS_C): BOOLEAN is
324 -- Is current type valid?
325 do
326 -- If no `conformance_type' is specified, then `like Current' makes sense.
327 -- If one is specified, then it should be correct.
328 Result := conformance_type = Void or else conformance_type.internal_is_valid_for_class (a_class)
329 end
330
331 internal_generic_derivation (a_level: INTEGER_32): TYPE_A is
332 do
333 -- We keep the same level since we are merely forwarding the call.
334 Result := conformance_type.internal_generic_derivation (a_level)
335 end
336
337 internal_same_generic_derivation_as (current_type, other: TYPE_A; a_level: INTEGER_32): BOOLEAN is
338 do
339 -- We keep the same level since we are merely forwarding the call.
340 Result := conformance_type.internal_same_generic_derivation_as (current_type, other, a_level)
341 end
342
343 feature {COMPILER_EXPORTER} -- Modification
344
345 set_actual_type (a: TYPE_A) is
346 -- Assign `a' to `conformance_type'.
347 do
348 if has_attached_mark then
349 if not a.is_attached then
350 conformance_type := a.as_attached
351 else
352 conformance_type := a
353 end
354 elseif is_implicitly_attached then
355 if not a.is_attached and then not a.is_implicitly_attached then
356 conformance_type := a.as_implicitly_attached
357 else
358 conformance_type := a
359 end
360 elseif has_detachable_mark then
361 if not a.is_expanded and then (a.is_attached or else a.is_implicitly_attached) then
362 conformance_type := a.as_detachable
363 else
364 conformance_type := a
365 end
366 else
367 if not is_implicitly_attached and then a.is_implicitly_attached then
368 conformance_type := a.as_implicitly_detachable
369 else
370 conformance_type := a
371 end
372 end
373 actual_type := Current
374 end
375
376 set_attached_mark is
377 -- Mark type declaration as having an explicit attached mark.
378 do
379 Precursor
380 if not conformance_type.is_attached then
381 conformance_type := conformance_type.as_attached
382 end
383 end
384
385 set_detachable_mark is
386 -- Set class type declaration as having an explicit detachable mark.
387 do
388 Precursor
389 if not is_expanded and then (conformance_type.is_attached or else conformance_type.is_implicitly_attached) then
390 conformance_type := conformance_type.as_detachable
391 end
392 end
393
394 set_is_implicitly_attached
395 local
396 a: like conformance_type
397 do
398 Precursor
399 a := conformance_type
400 if a /= Void and then not a.is_attached and then not a.is_implicitly_attached then
401 conformance_type := a.as_implicitly_attached
402 end
403 end
404
405 unset_is_implicitly_attached
406 local
407 a: like conformance_type
408 do
409 Precursor
410 a := conformance_type
411 if a /= Void and then not a.is_attached and then a.is_implicitly_attached then
412 conformance_type := a.as_implicitly_detachable
413 end
414 end
415
416 feature {COMPILER_EXPORTER} -- Duplication
417
418 duplicate: LIKE_CURRENT
419 -- Duplication
420 do
421 Result := Precursor
422 -- Ensure `Result.actual_type = Result'
423 -- that is expected when working with attachment properties
424 Result.set_actual_type (conformance_type)
425 end
426
427 feature {COMPILER_EXPORTER} -- Primitives
428
429 instantiation_in (type: TYPE_A; written_id: INTEGER): TYPE_A is
430 -- Instantiation of Current in the context of `class_type',
431 -- assuming that Current is written in class of id `written_id'.
432 do
433 -- Special cases for calls on a target which is a manifest integer
434 -- that might be compatible with _8 or _16. The returned
435 -- `actual_type' should not take into consideration the
436 -- `compatibility_size' of `type', just its intrinsic type.
437 -- Because manifest integers are by default 32 bits, when
438 -- you apply a routine whose result is of type `like Current'
439 -- then it should really be a 32 bits integer. Note that in the
440 -- past we were keeping the size of the manifest integers and the
441 -- following code was accepted:
442 -- i16: INTEGER_16
443 -- i8: INTEGER_8
444 -- i16 := 0x00FF & i8
445 -- Now the code is rejected because target expect an INTEGER_16
446 -- and not an INTEGER, therefore the code needs to be fixed with:
447 -- i16 := (0x00FF).to_integer_16 & i8
448 -- or
449 -- i16 := (0x00FF & i8).to_integer_16
450 Result := type.intrinsic_type
451 if has_attached_mark then
452 if not Result.is_attached then
453 Result := Result.as_attached
454 end
455 elseif is_implicitly_attached then
456 if not Result.is_attached and then not Result.is_implicitly_attached then
457 Result := Result.as_implicitly_attached
458 end
459 elseif has_detachable_mark then
460 if not Result.is_expanded and then (Result.is_attached or else Result.is_implicitly_attached) then
461 Result := Result.as_detachable
462 end
463 elseif not is_implicitly_attached and then Result.is_implicitly_attached then
464 Result := Result.as_implicitly_detachable
465 end
466 end
467
468 adapted_in, skeleton_adapted_in (a_class_type: CLASS_TYPE): CL_TYPE_A is
469 -- Instantiation of Current in context of `other'.
470 do
471 Result := a_class_type.type
472 end
473
474 instantiated_in (class_type: TYPE_A): TYPE_A is
475 -- Instantiation of Current in the context of `class_type'
476 -- assuming that Current is written in the associated class
477 -- of `class_type'.
478 local
479 l_like: like Current
480 do
481 Result := class_type
482 if Result.is_like_current then
483 -- We cannot allow aliasing as otherwise we might end up updating
484 -- `like Current' type that should not be updated (Allowing the
485 -- aliasing would break eweasel test#valid218).
486 create l_like
487 l_like.set_actual_type (class_type.conformance_type)
488 Result := l_like
489 end
490 if has_attached_mark then
491 if not Result.is_attached then
492 Result := Result.as_attached
493 end
494 elseif is_implicitly_attached then
495 if not Result.is_attached and then not Result.is_implicitly_attached then
496 Result := Result.as_implicitly_attached
497 end
498 elseif has_detachable_mark then
499 if not Result.is_expanded and then (Result.is_attached or else Result.is_implicitly_attached) then
500 Result := Result.as_detachable
501 end
502 elseif not is_implicitly_attached and then Result.is_implicitly_attached then
503 Result := Result.as_implicitly_detachable
504 end
505 end
506
507 evaluated_type_in_descendant (a_ancestor, a_descendant: CLASS_C; a_feature: FEATURE_I): LIKE_CURRENT is
508 do
509 if a_ancestor /= a_descendant then
510 create Result
511 Result.set_actual_type (a_descendant.actual_type)
512 if has_attached_mark then
513 Result.set_attached_mark
514 elseif has_detachable_mark then
515 Result.set_detachable_mark
516 end
517 else
518 Result := Current
519 end
520 end
521
522 create_info, shared_create_info: CREATE_CURRENT is
523 -- Byte code information for entity type creation
524 once
525 create Result
526 end
527
528 conform_to (other: TYPE_A): BOOLEAN is
529 -- Does `Current' conform to `other'?
530 do
531 Result := other.is_like_current or else conformance_type.conform_to (other.conformance_type)
532 end
533
534 convert_to (a_context_class: CLASS_C; a_target_type: TYPE_A): BOOLEAN is
535 -- Does current convert to `a_target_type' in `a_context_class'?
536 -- Update `last_conversion_info' of AST_CONTEXT.
537 do
538 Result := conformance_type.convert_to (a_context_class, a_target_type)
539 end
540
541 meta_type: LIKE_CURRENT is
542 -- Meta type.
543 do
544 -- Because `like Current' could possibly means a basic type
545 -- when processing an inherited routine using `like Current'
546 -- we keep LIKE_CURRENT for the metatype, but simply replace
547 -- its `conformance_type' with its `meta_type'.
548 create Result
549 Result.set_actual_type (conformance_type.meta_type)
550 end
551
552 indexing
553 copyright: "Copyright (c) 1984-2007, Eiffel Software"
554 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
555 licensing_options: "http://www.eiffel.com/licensing"
556 copying: "[
557 This file is part of Eiffel Software's Eiffel Development Environment.
558
559 Eiffel Software's Eiffel Development Environment is free
560 software; you can redistribute it and/or modify it under
561 the terms of the GNU General Public License as published
562 by the Free Software Foundation, version 2 of the License
563 (available at the URL listed under "license" above).
564
565 Eiffel Software's Eiffel Development Environment is
566 distributed in the hope that it will be useful, but
567 WITHOUT ANY WARRANTY; without even the implied warranty
568 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
569 See the GNU General Public License for more details.
570
571 You should have received a copy of the GNU General Public
572 License along with Eiffel Software's Eiffel Development
573 Environment; if not, write to the Free Software Foundation,
574 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
575 ]"
576 source: "[
577 Eiffel Software
578 356 Storke Road, Goleta, CA 93117 USA
579 Telephone 805-685-1006, Fax 805-685-6869
580 Website http://www.eiffel.com
581 Customer support http://support.eiffel.com
582 ]"
583
584 end

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23