/[eiffelstudio]/branches/CAT_mono/Src/Eiffel/eiffel/genericity/cl_type_i.e
ViewVC logotype

Contents of /branches/CAT_mono/Src/Eiffel/eiffel/genericity/cl_type_i.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 60994 - (show annotations)
Wed Jul 5 20:59:00 2006 UTC (13 years, 7 months ago) by manus
Original Path: trunk/Src/Eiffel/eiffel/genericity/cl_type_i.e
File size: 17266 byte(s)
Fixed bug#10520 and eweasel test#term142 when `separate' is used and causing `is_reference'
  to be False, when it should have been True. As a consequence we took a complex path in our
  code generation for assignment where we should not have since `separate' is a no-op.

1 indexing
2 description: "Type class."
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 CL_TYPE_I
9
10 inherit
11 TYPE_I
12 redefine
13 anchor_instantiation_in,
14 c_type,
15 conforms_to_array,
16 created_in,
17 generate_cid,
18 generate_cid_array,
19 generate_cid_init,
20 generate_gen_type_il,
21 generate_expanded_creation,
22 generate_expanded_initialization,
23 generated_id,
24 generic_derivation,
25 instantiated_description,
26 instantiation_in,
27 is_expanded,
28 is_explicit,
29 is_external,
30 is_frozen,
31 is_generated_as_single_type,
32 is_reference,
33 is_separate,
34 is_valid,
35 make_gen_type_byte_code,
36 same_as
37 end
38
39 SHARED_IL_CASING
40 export
41 {NONE} all
42 end
43
44 SHARED_GENERATION
45 export
46 {NONE} all
47 end
48
49 SHARED_DECLARATIONS
50 export
51 {NONE} all
52 end
53
54 create
55 make
56
57 feature {NONE} -- Initialization
58
59 make (id: INTEGER) is
60 -- Create new instance of `Current' with `class_id'
61 -- assigned with `id'.
62 require
63 valid_id: id > 0
64 do
65 class_id := id
66 ensure
67 class_id_set: class_id = id
68 end
69
70 feature -- Access
71
72 class_id: INTEGER
73 -- Base class id of the type class
74
75 meta_generic: META_GENERIC is
76 -- Meta generic array describing the type class
77 do
78 -- No meta generic in non-generic type
79 end
80
81 cr_info : CREATE_INFO
82 -- Additional information for the creation
83 -- of generic types with anchored parameters
84
85 true_generics : ARRAY [TYPE_I] is
86 -- Array of generics: no mapping reference -> REFERENCE_I
87 do
88 -- Non generic types don't have them
89 end
90
91 base_class: CLASS_C is
92 -- Base class associated to the class type
93 do
94 Result := System.class_of_id (class_id)
95 end
96
97 generic_derivation: CL_TYPE_I is
98 -- Precise generic derivation of current type.
99 -- That is to say given a type, it gives the associated TYPE_I
100 -- which can be used to search its associated CLASS_TYPE.
101 do
102 Result := Current
103 end
104
105 type_a: CL_TYPE_A is
106 do
107 create Result.make (class_id)
108 Result.set_mark (declaration_mark)
109 end
110
111 name: STRING is
112 -- String that should be displayed in debugger to represent `Current'.
113 do
114 Result := base_name
115 end
116
117 duplicate: like Current is
118 -- Duplication
119 do
120 Result := twin
121 end
122
123 instantiation_in (other: CLASS_TYPE): CL_TYPE_I is
124 -- Instantation of Current in `other'
125 do
126 Result := Current
127 end
128
129 anchor_instantiation_in (other: CLASS_TYPE): CL_TYPE_I is
130 -- Instantation of `like Current' parts of Current in `other'
131 do
132 Result := Current
133 end
134
135 created_in (other: CLASS_TYPE): TYPE_I is
136 -- Resulting type of Current as if it was used to create object in `other'.
137 do
138 Result := Current
139 if cr_info /= Void then
140 Result := cr_info.created_in (other)
141 end
142 end
143
144 il_type_name (a_prefix: STRING): STRING is
145 -- Class name of current type.
146 local
147 l_class_c: like base_class
148 l_is_precompiled: BOOLEAN
149 l_cl_type: like associated_class_type
150 do
151 l_class_c := base_class
152 if is_external then
153 Result := l_class_c.external_class_name.twin
154 else
155 l_is_precompiled := l_class_c.is_precompiled
156 if l_is_precompiled then
157 l_cl_type := associated_class_type
158 l_is_precompiled := l_cl_type.is_precompiled
159 if l_is_precompiled then
160 Result := l_cl_type.il_type_name (a_prefix)
161 end
162 end
163 if not l_is_precompiled then
164 if l_class_c.external_class_name.is_equal (l_class_c.name) then
165 Result := internal_il_type_name (l_class_c.name.twin, a_prefix)
166 else
167 Result := l_class_c.external_class_name.twin
168 if a_prefix /= Void then
169 if Result.item (Result.count) /= '.' then
170 Result.append_character ('.')
171 end
172 Result.append (a_prefix)
173 end
174 end
175 end
176 end
177 end
178
179 description, instantiated_description: ATTR_DESC is
180 -- Type description for skeletons
181 local
182 exp: EXPANDED_DESC
183 ref: REFERENCE_DESC
184 do
185 if is_expanded then
186 create exp
187 exp.set_cl_type_i (Current)
188 exp.set_type_i (Current)
189 Result := exp
190 else
191 Result := c_type.description
192 ref ?= Result
193 if ref /= Void then
194 ref.set_type_i (Current)
195 end
196 end
197 end
198
199 c_type: TYPE_C is
200 -- Associated C type
201 do
202 Result := Reference_c_type
203 end
204
205 associated_class_type: CLASS_TYPE is
206 -- Associated class type
207 require
208 has: has_associated_class_type
209 do
210 Result := base_class.types.search_item (Current)
211 ensure
212 result_not_void: Result /= Void
213 end
214
215 type_id: INTEGER is
216 -- Type id of the correponding class type
217 do
218 Result := associated_class_type.type_id
219 end
220
221 sk_value: INTEGER is
222 -- Generate SK value associated to the current type.
223 do
224 if is_expanded then
225 Result := Sk_exp | (type_id - 1)
226 else
227 Result := Sk_ref | (type_id - 1)
228 end
229 end
230
231 hash_code: INTEGER is
232 -- Hash code for current type
233 do
234 Result := Other_code + class_id
235 end
236
237 feature -- Status
238
239 element_type: INTEGER_8 is
240 -- Void element type
241 do
242 if is_expanded then
243 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_valuetype
244 else
245 if class_id = System.system_string_class.compiled_class.class_id then
246 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_string
247 elseif class_id = System.system_object_id or class_id = system.any_id then
248 -- For ANY or SYSTEM_OBJECT, we always generate a System.Object
249 -- signature since we can now assign SYSTEM_OBJECTs into ANYs.
250 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_object
251 else
252 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_class
253 end
254 end
255 end
256
257 tuple_code: INTEGER_8 is
258 -- Tuple code for class type
259 do
260 Result := {SHARED_GEN_CONF_LEVEL}.reference_tuple_code
261 end
262
263 has_no_mark: BOOLEAN is
264 -- Has class type no explicit mark?
265 do
266 Result := declaration_mark = {CL_TYPE_A}.no_mark
267 ensure
268 definition: Result = (declaration_mark = {CL_TYPE_A}.no_mark)
269 end
270
271 has_expanded_mark: BOOLEAN is
272 -- Is class type explicitly marked as expanded?
273 do
274 Result := declaration_mark = {CL_TYPE_A}.expanded_mark
275 ensure
276 definition: Result = (declaration_mark = {CL_TYPE_A}.expanded_mark)
277 end
278
279 has_reference_mark: BOOLEAN is
280 -- Is class type explicitly marked as reference?
281 do
282 Result := declaration_mark = {CL_TYPE_A}.reference_mark
283 ensure
284 definition: Result = (declaration_mark = {CL_TYPE_A}.reference_mark)
285 end
286
287 has_separate_mark: BOOLEAN is
288 -- Is class type explicitly marked as reference?
289 do
290 Result := declaration_mark = {CL_TYPE_A}.separate_mark
291 ensure
292 definition: Result = (declaration_mark = {CL_TYPE_A}.separate_mark)
293 end
294
295 is_expanded: BOOLEAN is
296 -- Is the type expanded?
297 do
298 -- Do not check for `has_separate_mark' because a separate class cannot be expanded.
299 Result := has_expanded_mark or else (has_no_mark and then base_class.is_expanded)
300 end
301
302 is_reference: BOOLEAN is
303 -- Is the type a reference type?
304 do
305 Result := has_reference_mark or else
306 ((has_no_mark or has_separate_mark) and then not base_class.is_expanded)
307 end
308
309 is_separate: BOOLEAN is
310 -- Is the type separate?
311 do
312 Result := has_separate_mark
313 end
314
315 is_enum: BOOLEAN is
316 -- Is current type an IL enum type?
317 -- Useful to find out if some call optimization can be done
318 -- in FEATURE_B.
319 require
320 il_generation: System.il_generation
321 do
322 Result := is_expanded and then base_class.is_enum
323 end
324
325 is_external: BOOLEAN is
326 -- Is current type based on an external class?
327 local
328 l_base_class: like base_class
329 do
330 -- All Eiffel basic types are externals, and only basic types used
331 -- as reference are not external.
332 l_base_class := base_class
333 Result := is_basic or (not l_base_class.is_basic and l_base_class.is_external)
334 end
335
336 is_frozen: BOOLEAN is
337 -- Is current type based on a frozen class?
338 do
339 Result := base_class.is_frozen
340 end
341
342 is_generated_as_single_type: BOOLEAN is
343 -- Is associated type generated as a single type or as an interface type and
344 -- an implementation type.
345 do
346 -- External classes have only one type.
347 Result := is_external
348 if not Result then
349 -- Classes that inherits from external classes
350 -- have only one generated type as well as expanded types.
351 Result := base_class.is_single or else is_expanded
352 end
353 end
354
355 is_valid: BOOLEAN is
356 -- Is the base class still in the system and matches its specification?
357 local
358 l_base_class: like base_class
359 do
360 l_base_class := base_class
361 Result := l_base_class /= Void and then (l_base_class.generics = Void)
362 end
363
364 is_explicit: BOOLEAN is
365 -- Is Current type fixed at compile time?
366 do
367 if cr_info /= Void then
368 Result := cr_info.is_explicit
369 else
370 Result := True
371 end
372 end
373
374 has_associated_class_type: BOOLEAN is
375 -- Has `Current' an associated class type?
376 do
377 Result := base_class.types.has_type (Current)
378 end
379
380 same_as (other: TYPE_I): BOOLEAN is
381 -- Is `other' equal to Current ?
382 local
383 other_cl_type: CL_TYPE_I
384 do
385 other_cl_type ?= other
386 Result := other_cl_type /= Void -- FIXME
387 and then other_cl_type.class_id = class_id
388 and then other_cl_type.is_expanded = is_expanded
389 and then other_cl_type.is_separate = is_separate
390 and then other_cl_type.meta_generic = Void
391 and then other_cl_type.true_generics = Void
392 end
393
394 has_actual (type: CL_TYPE_I): BOOLEAN is
395 -- Is `type' an (possibly nested) actual parameter of this type?
396 require
397 non_void_type: type /= Void
398 do
399 -- False here.
400 end
401
402 feature -- Setting
403
404 set_expanded_mark is
405 -- Set class type declaration as expanded.
406 do
407 declaration_mark := {CL_TYPE_A}.expanded_mark
408 ensure
409 has_expanded_mark: has_expanded_mark
410 end
411
412 set_reference_mark is
413 -- Set class type declaration as reference.
414 do
415 declaration_mark := {CL_TYPE_A}.reference_mark
416 ensure
417 has_reference_mark: has_reference_mark
418 end
419
420 set_separate_mark is
421 -- Set class type declaration as separate.
422 do
423 declaration_mark := {CL_TYPE_A}.separate_mark
424 ensure
425 has_separate_mark: has_separate_mark
426 end
427
428 set_cr_info (cinfo : CREATE_INFO) is
429 -- Set `cr_info' to `cinfo'.
430 require
431 create_info_not_void: cinfo /= Void
432 not_expanded: not is_expanded
433 do
434 cr_info := cinfo
435 ensure
436 cr_info_set : cr_info = cinfo
437 end
438
439 feature -- C generation
440
441 generate_expanded_creation (buffer: GENERATION_BUFFER; target_name: STRING) is
442 -- Generate creation of expanded object associated to Current.
443 do
444 associated_class_type.generate_expanded_creation (buffer, target_name)
445 end
446
447 generate_expanded_initialization (buffer: GENERATION_BUFFER; target_name: STRING) is
448 -- Generate creation of expanded object associated to Current.
449 do
450 associated_class_type.generate_expanded_initialization (buffer, target_name, target_name, True)
451 end
452
453 generate_cecil_value (buffer: GENERATION_BUFFER) is
454 -- Generate cecil value
455 do
456 if not is_expanded then
457 buffer.put_string ("SK_REF + (uint32) ")
458 else
459 buffer.put_string ("SK_EXP + (uint32) ")
460 end
461 buffer.put_type_id (associated_class_type.type_id)
462 end
463
464 feature -- Array optimization
465
466 conforms_to_array: BOOLEAN is
467 do
468 Result := base_class.conform_to (array_class_c)
469 end
470
471 feature {NONE} -- Array optimization
472
473 array_class_c: CLASS_C is
474 once
475 Result := System.array_class.compiled_class
476 end
477
478 feature -- Generic conformance
479
480 generated_id (final_mode : BOOLEAN) : INTEGER is
481
482 do
483 if final_mode then
484 Result := type_id - 1
485 else
486 Result := associated_class_type.static_type_id - 1
487 end
488 end
489
490 generate_cid (buffer : GENERATION_BUFFER; final_mode, use_info : BOOLEAN) is
491
492 do
493 if
494 use_info and then (cr_info /= Void)
495 and then not is_expanded
496 then
497 -- It's an anchored type
498 cr_info.generate_cid (buffer, final_mode)
499 else
500 buffer.put_integer (generated_id (final_mode))
501 buffer.put_character (',')
502 end
503 end
504
505 make_gen_type_byte_code (ba : BYTE_ARRAY; use_info : BOOLEAN) is
506 do
507 if
508 use_info and then (cr_info /= Void)
509 and then not is_expanded
510 then
511 -- It's an anchored type
512 cr_info.make_gen_type_byte_code (ba)
513 else
514 ba.append_short_integer (generated_id (False))
515 end
516 end
517
518 generate_cid_array (buffer : GENERATION_BUFFER;
519 final_mode, use_info : BOOLEAN; idx_cnt : COUNTER) is
520 local
521 dummy : INTEGER
522 do
523 if
524 use_info and then (cr_info /= Void)
525 and then not is_expanded
526 then
527 -- It's an anchored type
528 cr_info.generate_cid_array (buffer, final_mode, idx_cnt)
529 else
530 buffer.put_integer (generated_id (final_mode))
531 buffer.put_character (',')
532
533 -- Increment counter
534 dummy := idx_cnt.next
535 end
536 end
537
538 generate_cid_init (buffer : GENERATION_BUFFER;
539 final_mode, use_info : BOOLEAN; idx_cnt : COUNTER) is
540 local
541 dummy : INTEGER
542 do
543 if
544 use_info and then (cr_info /= Void)
545 and then not is_expanded
546 then
547 -- It's an anchored type
548 cr_info.generate_cid_init (buffer, final_mode, idx_cnt)
549 else
550 dummy := idx_cnt.next
551 end
552 end
553
554 feature -- Generic conformance for IL
555
556 generate_gen_type_il (il_generator: IL_CODE_GENERATOR; use_info : BOOLEAN) is
557 -- `use_info' is true iff we generate code for a
558 -- creation instruction.
559 do
560 if use_info and then cr_info /= Void then
561 -- It's an anchored type, we call feature
562 -- that will tell us the real type of the
563 -- anchor in the context of Current.
564 cr_info.generate_il_type
565 else
566 il_generator.generate_class_type_instance (Current)
567 end
568 end
569
570 feature {NONE} -- Implementation
571
572 base_name: STRING is
573 -- String that should be displayed in debugger to represent `Current'.
574 local
575 l_base_class: like base_class
576 do
577 create Result.make (32)
578 l_base_class := base_class
579 if is_expanded and not l_base_class.is_expanded then
580 Result.append ("expanded ")
581 elseif is_reference and l_base_class.is_expanded then
582 Result.append ("reference ")
583 elseif is_separate then
584 Result.append ("separate ")
585 end
586 Result.append (l_base_class.name)
587 end
588
589 frozen internal_il_type_name (a_base_name, a_prefix: STRING): STRING is
590 -- Full type name of `a_base_name' using `a_prefix' in IL code generation
591 -- with namespace specification
592 require
593 a_base_name_not_void: a_base_name /= Void
594 local
595 l_base_class: like base_class
596 do
597 l_base_class := base_class
598 -- Result needs to be in lower case because that's
599 -- what our casing conversion routines require to perform
600 -- a good job.
601 if is_expanded and then not l_base_class.is_expanded then
602 create Result.make (6 + a_base_name.count)
603 Result.append ("value_")
604 elseif not is_expanded and then l_base_class.is_expanded then
605 create Result.make (10 + a_base_name.count)
606 Result.append ("reference_")
607 else
608 create Result.make (a_base_name.count)
609 end
610 Result.append (a_base_name)
611 Result.to_lower
612 Result := il_casing.type_name (l_base_class.original_class.actual_namespace, a_prefix, Result, System.dotnet_naming_convention)
613 ensure
614 internal_il_type_name_not_void: Result /= Void
615 internal_il_type_name_not_empty: not Result.is_empty
616 end
617
618 feature {CL_TYPE_A, TUPLE_CLASS_B} -- Implementation: class type declaration marks
619
620 declaration_mark: NATURAL_8
621 -- Declaration mark associated with a class type (if any)
622
623 set_mark (mark: like declaration_mark) is
624 -- Set `declaration_mark' to the given value `mark'.
625 require
626 valid_declaration_mark:
627 mark = {CL_TYPE_A}.no_mark or mark = {CL_TYPE_A}.expanded_mark or
628 mark = {CL_TYPE_A}.reference_mark or mark = {CL_TYPE_A}.separate_mark
629 do
630 declaration_mark := mark
631 ensure
632 declaration_mark_set: declaration_mark = mark
633 end
634
635 invariant
636 class_id_positive: class_id > 0
637 valid_declaration_mark:
638 declaration_mark = {CL_TYPE_A}.no_mark or
639 declaration_mark = {CL_TYPE_A}.expanded_mark or
640 declaration_mark = {CL_TYPE_A}.reference_mark or
641 declaration_mark = {CL_TYPE_A}.separate_mark
642
643 indexing
644 copyright: "Copyright (c) 1984-2006, Eiffel Software"
645 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
646 licensing_options: "http://www.eiffel.com/licensing"
647 copying: "[
648 This file is part of Eiffel Software's Eiffel Development Environment.
649
650 Eiffel Software's Eiffel Development Environment is free
651 software; you can redistribute it and/or modify it under
652 the terms of the GNU General Public License as published
653 by the Free Software Foundation, version 2 of the License
654 (available at the URL listed under "license" above).
655
656 Eiffel Software's Eiffel Development Environment is
657 distributed in the hope that it will be useful, but
658 WITHOUT ANY WARRANTY; without even the implied warranty
659 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
660 See the GNU General Public License for more details.
661
662 You should have received a copy of the GNU General Public
663 License along with Eiffel Software's Eiffel Development
664 Environment; if not, write to the Free Software Foundation,
665 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
666 ]"
667 source: "[
668 Eiffel Software
669 356 Storke Road, Goleta, CA 93117 USA
670 Telephone 805-685-1006, Fax 805-685-6869
671 Website http://www.eiffel.com
672 Customer support http://support.eiffel.com
673 ]"
674
675 end

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23