/[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 64191 - (show annotations)
Thu Oct 5 21:04:08 2006 UTC (13 years, 4 months ago) by manus
Original Path: trunk/Src/Eiffel/eiffel/genericity/cl_type_i.e
File size: 19895 byte(s)
Merged from Eiffel_57:
  Fixed `il_type_name' to properly generate the class name when an external class name is
  specified. Before if you specified A.B you would get for the implementation class A.B.Impl
  which does not follow the normal pattern, instead we should get A.Impl.B. This is now the
  case with this fix.

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23