/[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 62805 - (show annotations)
Mon Aug 21 12:50:52 2006 UTC (13 years, 6 months ago) by alexk
Original Path: trunk/Src/Eiffel/eiffel/genericity/cl_type_i.e
File size: 17755 byte(s)
Factored out code that records type information about generic types in byte code.
Changed implementation of {TYPED_POINTER_I}.type_a to follow the
implementation of {GEN_TYPE_I}.type_a where "meta_generic" is used instead
of "true_generics" (this fixes test#term133).

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23