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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 41824 - (hide annotations)
Sat Mar 6 01:51:40 2004 UTC (15 years, 11 months ago) by manus
Original Path: trunk/Src/bench/Eiffel/eiffel/genericity/cl_type_i.e
File size: 14832 byte(s)
Made sure that basic types get `is_expanded' set to True.
Switch meaning of `is_expanded' and `is_true_expanded'. Now base types are also `is_expanded'
  and only expanded types that are not basic are `is_true_expanded'.
Added proper redefinition of `generic_derivation', `name' and `instantiation_in'.
Simplified `associated_class_type' since now the expanded and the reference
  version of a class do not use the same CLASS_TYPE instance, therefore no
  special trick is needed before doing the search.
Added `is_generated_as_single_type' for IL code generation to see if a CLASS_TYPE
  should be generated as just a .NET class or as a collection of interface/implementation.
Reviewed naming convention for IL code generation when you use a reference type as expanded
  and vice versa. Now we prepend the class name with either `VALUE_' or `REFERENCE_'.
Added invariant about `class_id' being positive.

1 manus 26913 indexing
2     description: "Type class."
3     date: "$Date$"
4     revision: "$Revision$"
5 grator 18
6     class CL_TYPE_I
7    
8     inherit
9     TYPE_I
10     redefine
11     is_reference,
12 manus 41824 is_expanded,
13 xavierl 4623 is_separate,
14 grator 236 is_valid,
15 manus 11218 is_explicit,
16 manus 28380 is_external,
17 grator 18 same_as,
18     c_type,
19 manus 10818 conforms_to_array,
20     generated_id,
21 manus 11298 generate_cid,
22 manus 14013 make_gen_type_byte_code,
23     generate_cid_array,
24 manus 30169 generate_cid_init,
25 manus 35665 generate_gen_type_il,
26 manus 41824 generate_expanded_creation,
27     instantiation_in,
28     generic_derivation,
29     is_generated_as_single_type
30 grator 18 end
31    
32 manus 33952 SHARED_IL_CASING
33     export
34     {NONE} all
35     end
36    
37 manus 35665 SHARED_GENERATION
38     export
39     {NONE} all
40     end
41    
42     SHARED_DECLARATIONS
43     export
44     {NONE} all
45     end
46    
47 manus 30224 create
48     make
49    
50     feature {NONE} -- Initialization
51    
52     make (id: INTEGER) is
53 manus 30293 -- Create new instance of `Current' with `class_id'
54 manus 30224 -- assigned with `id'.
55     require
56     valid_id: id > 0
57     do
58 manus 30293 class_id := id
59 manus 41824 if is_basic then
60     -- We know for sure that it is expanded then.
61     is_expanded := True
62     end
63 manus 30224 ensure
64 manus 30293 class_id_set: class_id = id
65 manus 30224 end
66    
67 manus 26913 feature -- Access
68 grator 18
69 manus 30293 class_id: INTEGER
70 grator 18 -- Base class id of the type class
71    
72     meta_generic: META_GENERIC is
73     -- Meta generic array describing the type class
74     do
75     -- No meta generic in non-generic type
76 manus 9655 end
77 grator 18
78 manus 10890 cr_info : CREATE_INFO
79     -- Additional information for the creation
80     -- of generic types with anchored parameters
81    
82 manus 10818 true_generics : ARRAY [TYPE_I] is
83     -- Array of generics: no mapping reference -> REFERENCE_I
84     do
85     -- Non generic types don't have them
86     end
87    
88 grator 18 base_class: CLASS_C is
89     -- Base class associated to the class type
90     do
91 manus 30293 Result := System.class_of_id (class_id)
92 manus 9655 end
93 grator 18
94 manus 41824 generic_derivation: CL_TYPE_I is
95     -- Precise generic derivation of current type.
96     -- That is to say given a type, it gives the associated TYPE_I
97     -- which can be used to search its associated CLASS_TYPE.
98     do
99     Result := Current
100     end
101    
102 manus 26913 type_a: CL_TYPE_A is
103 grator 236 do
104 manus 30293 create Result.make (class_id)
105 manus 41824 Result.set_is_expanded (is_expanded)
106 manus 26913 Result.set_is_separate (is_separate)
107 manus 9655 end
108 grator 236
109 manus 41824 name: STRING is
110     -- String that should be displayed in debugger to represent `Current'.
111     local
112     l_base_class: like base_class
113     do
114     create Result.make (32)
115     l_base_class := base_class
116     if is_expanded and not l_base_class.is_expanded then
117     Result.append ("expanded ")
118     elseif not is_expanded and l_base_class.is_expanded then
119     Result.append ("reference ")
120     elseif is_separate then
121     Result.append ("separate ")
122     end
123     Result.append (l_base_class.name_in_upper)
124     end
125    
126     instantiation_in (other: GEN_TYPE_I): CL_TYPE_I is
127     -- Instantation of Current in `other'
128     do
129     Result := Current
130     end
131    
132 manus 33952 il_type_name (a_prefix: STRING): STRING is
133 manus 26913 -- Class name of current type.
134 manus 29681 local
135     l_class_c: like base_class
136 manus 34253 l_is_precompiled: BOOLEAN
137     l_cl_type: like associated_class_type
138 grator 18 do
139 manus 29681 l_class_c := base_class
140 manus 41824 if is_external then
141 manus 40771 Result := l_class_c.external_class_name.twin
142 manus 29681 else
143 manus 34253 l_is_precompiled := l_class_c.is_precompiled
144     if l_is_precompiled then
145     l_cl_type := associated_class_type
146     l_is_precompiled := l_cl_type.is_precompiled
147     if l_is_precompiled then
148     Result := associated_class_type.il_type_name (a_prefix)
149     end
150     end
151     if not l_is_precompiled then
152 manus 40771 Result := internal_il_type_name (l_class_c.name.twin, a_prefix)
153 manus 34253 end
154 manus 29681 end
155 manus 11218 end
156    
157 grator 18 description: ATTR_DESC is
158     -- Type description for skeletons
159     local
160 michaels 7681 exp: EXPANDED_DESC
161     ref: REFERENCE_DESC
162 grator 485 do
163 manus 41824 if is_expanded then
164 julieng 37663 create exp
165 manus 32282 exp.set_class_type (base_class.types.search_item (Current))
166 manus 13232 exp.set_type_i (Current)
167 manus 9655 Result := exp
168 grator 18 else
169 manus 9655 Result := c_type.description
170     end
171 michaels 7681
172     ref ?= Result
173     if ref /= Void then
174 manus 34621 ref.set_type_i (Current)
175 michaels 7681 end
176 manus 9655 end
177 grator 18
178     c_type: TYPE_C is
179     -- Associated C type
180     do
181 manus 9655 Result := Reference_c_type
182     end
183 manus 28618
184 grator 18 associated_class_type: CLASS_TYPE is
185     -- Associated class type
186 michaels 7681 require
187 manus 16188 -- has: has_associated_class_type
188 grator 485 do
189 manus 41824 Result := base_class.types.search_item (Current)
190 manus 9655 end
191 grator 18
192     type_id: INTEGER is
193     -- Type id of the correponding class type
194     do
195 manus 9655 Result := associated_class_type.type_id
196     end
197 grator 18
198 manus 26913 sk_value: INTEGER is
199     -- Generate SK value associated to the current type.
200 grator 18 do
201 manus 41824 if is_expanded then
202     Result := Sk_exp | (type_id - 1)
203     else
204 manus 31263 Result := Sk_ref | (type_id - 1)
205 manus 9655 end
206     end
207 grator 18
208 manus 26913 cecil_value: INTEGER is
209     do
210 manus 41824 if not is_expanded then
211 manus 26913 Result := Sk_dtype
212     else
213 manus 31263 Result := Sk_exp | class_id
214 manus 26913 end
215     end
216    
217 grator 18 hash_code: INTEGER is
218     -- Hash code for current type
219     do
220 manus 30293 Result := Other_code + class_id
221 manus 9655 end
222 grator 18
223 manus 26913 feature -- Status
224    
225 manus 31541 element_type: INTEGER_8 is
226     -- Void element type
227     do
228 manus 41824 if is_expanded then
229 manus 31580 -- We only support expanded for external class at the moment.
230 manus 31541 Result := feature {MD_SIGNATURE_CONSTANTS}.Element_type_valuetype
231     else
232 manus 37130 if class_id = System.system_string_class.compiled_class.class_id then
233 manus 31541 Result := feature {MD_SIGNATURE_CONSTANTS}.Element_type_string
234 manus 37130 elseif class_id = System.system_object_id then
235 manus 31541 Result := feature {MD_SIGNATURE_CONSTANTS}.Element_type_object
236     else
237     Result := feature {MD_SIGNATURE_CONSTANTS}.Element_type_class
238     end
239     end
240     end
241    
242 manus 41824 tuple_code: INTEGER_8 is
243     -- Tuple code for class type
244     do
245     Result := feature {SHARED_GEN_CONF_LEVEL}.reference_tuple_code
246     end
247    
248     is_expanded: BOOLEAN
249 manus 26913 -- Is the type expanded?
250    
251     is_separate: BOOLEAN
252     -- Is the type separate?
253    
254     is_enum: BOOLEAN is
255     -- Is current type an IL enum type?
256     -- Useful to find out if some call optimization can be done
257     -- in FEATURE_B.
258     require
259     il_generation: System.il_generation
260 grator 18 do
261 manus 41824 Result := is_expanded and then base_class.is_enum
262 manus 26913 end
263    
264 manus 28380 is_external: BOOLEAN is
265 manus 41824 -- Is current type based on an external class?
266     local
267     l_base_class: like base_class
268 manus 28380 do
269 manus 41824 -- All Eiffel basic types are externals, and only basic types used
270     -- as reference are not external.
271     l_base_class := base_class
272     Result := is_basic or (not l_base_class.is_basic and l_base_class.is_external)
273 manus 28380 end
274 manus 41824
275     is_generated_as_single_type: BOOLEAN is
276     -- Is associated type generated as a single type or as an interface type and
277     -- an implementation type.
278     local
279     l_class: CLASS_C
280     do
281     -- Expanded types do not have an interface since no polymorphic calls
282     -- are done on them.
283     Result := is_expanded
284     if not Result then
285     l_class := base_class
286     -- When `base_class' is a basic class and that we are here, it means
287     -- that we are handling the reference version of the basic type, which
288     -- needs to be generated with the interface type and the implementation type
289     if not l_class.is_basic then
290     -- External classes, or classes marked `frozen', or that
291     -- inherites from external classes have only one generated type.
292     Result := l_class.is_single or l_class.is_frozen or l_class.is_external
293     end
294     end
295     end
296 manus 28380
297 manus 26913 is_valid: BOOLEAN is
298 manus 35544 -- Is the base class still in the system and matches its specification?
299 manus 41824 local
300     l_base_class: like base_class
301 manus 26913 do
302 manus 41824 l_base_class := base_class
303     Result := l_base_class /= Void and then (l_base_class.generics = Void)
304 manus 26913 end
305    
306     is_reference: BOOLEAN is
307     -- Is the type a reference type ?
308     do
309 manus 41824 Result := not is_expanded
310 manus 26913 end;
311    
312     is_explicit: BOOLEAN is
313 manus 39713 -- Is Current type fixed at compile time?
314 manus 26913 do
315 manus 39713 if cr_info /= Void then
316     Result := cr_info.is_explicit
317     else
318     Result := True
319     end
320 manus 26913 end
321    
322     has_associated_class_type: BOOLEAN is
323     -- Has `Current' an associated class type?
324     do
325 manus 41824 Result := base_class.types.has_type (Current)
326 manus 9655 end
327 grator 18
328 manus 26913 same_as (other: TYPE_I): BOOLEAN is
329     -- Is `other' equal to Current ?
330     local
331     other_cl_type: CL_TYPE_I
332 grator 508 do
333 manus 26913 other_cl_type ?= other
334     Result := other_cl_type /= Void -- FIXME
335 manus 30293 and then other_cl_type.class_id = class_id
336 manus 41824 and then other_cl_type.is_expanded = is_expanded
337 manus 26913 and then other_cl_type.is_separate = is_separate
338     and then other_cl_type.meta_generic = Void
339     and then other_cl_type.true_generics = Void
340     end
341    
342     feature -- Setting
343    
344 manus 41824 set_is_expanded (b: BOOLEAN) is
345     -- Assign `b' to `is_expanded'.
346 manus 26913 do
347 manus 41824 is_expanded := b
348 manus 35178 ensure
349 manus 41824 is_expanded_set: is_expanded = b
350 manus 26913 end
351    
352     set_is_separate (b: BOOLEAN) is
353     -- Assign `b' to `is_separate'.
354     do
355     is_separate := b
356 manus 35178 ensure
357     is_separate_set: is_separate = b
358 manus 26913 end
359    
360     set_cr_info (cinfo : CREATE_INFO) is
361     -- Set `cr_info' to `cinfo'.
362 manus 30224 require
363     create_info_not_void: cinfo /= Void
364 manus 41824 not_expanded: not is_expanded
365 manus 26913 do
366     cr_info := cinfo
367     ensure
368     cr_info_set : cr_info = cinfo
369     end
370    
371     feature -- C generation
372    
373 manus 35665 generate_expanded_creation (byte_code: BYTE_CODE; reg: REGISTRABLE; workbench_mode: BOOLEAN) is
374     -- Generate creation of expanded object associated to Current.
375     local
376     gen_type: GEN_TYPE_I
377     written_class: CLASS_C
378     class_type, written_type: CLASS_TYPE
379     creation_feature: FEATURE_I
380     c_name: STRING
381     buffer: GENERATION_BUFFER
382     do
383     buffer := byte_code.buffer
384    
385     gen_type ?= Current
386    
387     if gen_type /= Void then
388     byte_code.generate_block_open
389     byte_code.generate_gen_type_conversion (gen_type)
390     end
391     reg.print_register
392     if workbench_mode then
393     -- RTLX is a macro used to create
394     -- expanded types
395     if gen_type /= Void then
396     buffer.putstring (" = RTLX(typres")
397     else
398     buffer.putstring (" = RTLX(RTUD(")
399     buffer.generate_type_id (associated_class_type.static_type_id)
400     buffer.putchar (')')
401     end
402     else
403     if gen_type /= Void then
404     buffer.putstring (" = RTLN(typres")
405     else
406     buffer.putstring (" = RTLN(")
407     buffer.putint (type_id - 1)
408     end
409     class_type := associated_class_type
410     creation_feature := class_type.associated_class.creation_feature
411     if creation_feature /= Void then
412     written_class := System.class_of_id (creation_feature.written_in)
413     if written_class.generics = Void then
414     written_type := written_class.types.first
415     else
416     written_type :=
417     written_class.meta_type (class_type.type).associated_class_type
418     end
419     c_name := Encoder.feature_name (written_type.static_type_id,
420     creation_feature.body_index)
421 manus 35702 buffer.putstring (");")
422     buffer.new_line
423 manus 35665 buffer.putstring (c_name)
424     buffer.putchar ('(')
425     reg.print_register
426     Extern_declarations.add_routine_with_signature (Void_c_type,
427     c_name, <<"EIF_REFERENCE">>)
428     end
429     end
430     buffer.putchar (')')
431     buffer.putchar (';')
432    
433     if gen_type /= Void then
434     byte_code.generate_block_close
435     end
436     buffer.new_line
437     end
438    
439 manus 26913 generate_cecil_value (buffer: GENERATION_BUFFER) is
440     -- Generate cecil value
441     do
442 manus 41824 if not is_expanded then
443 manus 26913 buffer.putstring ("SK_DTYPE")
444 grator 508 else
445 manus 26913 buffer.putstring ("SK_EXP + (uint32) ")
446 manus 34563 buffer.putint (associated_class_type.type_id - 1)
447 manus 9655 end
448     end
449 grator 508
450 grator 930 feature -- Array optimization
451    
452     conforms_to_array: BOOLEAN is
453     do
454     Result := base_class.conform_to (array_class_c)
455 manus 9655 end
456 grator 930
457     feature {NONE} -- Array optimization
458    
459     array_class_c: CLASS_C is
460     once
461     Result := System.array_class.compiled_class
462 manus 9655 end
463 grator 930
464 manus 10818 feature -- Generic conformance
465    
466     generated_id (final_mode : BOOLEAN) : INTEGER is
467 manus 11298
468 manus 10818 do
469 manus 11298 if final_mode then
470     Result := type_id - 1
471 manus 10818 else
472 manus 41824 Result := associated_class_type.static_type_id - 1
473 manus 10818 end
474     end
475    
476 manus 11599 generate_cid (buffer : GENERATION_BUFFER; final_mode, use_info : BOOLEAN) is
477 manus 11298
478 manus 10818 do
479 manus 11209 if
480     use_info and then (cr_info /= Void)
481 manus 26913 and then not is_expanded
482 manus 11209 then
483     -- It's an anchored type
484 manus 11599 cr_info.generate_cid (buffer, final_mode)
485 manus 39412 else
486     buffer.putint (generated_id (final_mode))
487     buffer.putstring (", ")
488 manus 10890 end
489 manus 10818 end
490    
491 manus 10890 make_gen_type_byte_code (ba : BYTE_ARRAY; use_info : BOOLEAN) is
492 manus 10818 do
493 manus 11209 if
494     use_info and then (cr_info /= Void)
495 manus 26913 and then not is_expanded
496 manus 11209 then
497     -- It's an anchored type
498 manus 10890 cr_info.make_gen_type_byte_code (ba)
499 manus 39412 else
500     ba.append_short_integer (generated_id (False))
501 manus 10890 end
502 manus 10818 end
503    
504 manus 14013 generate_cid_array (buffer : GENERATION_BUFFER;
505     final_mode, use_info : BOOLEAN; idx_cnt : COUNTER) is
506     local
507     dummy : INTEGER
508     do
509     if
510     use_info and then (cr_info /= Void)
511 manus 26913 and then not is_expanded
512 manus 14013 then
513 manus 39412 -- It's an anchored type
514 manus 14013 cr_info.generate_cid_array (buffer, final_mode, idx_cnt)
515 manus 39412 else
516     buffer.putint (generated_id (final_mode))
517     buffer.putstring (", ")
518    
519     -- Increment counter
520     dummy := idx_cnt.next
521 manus 14013 end
522     end
523    
524     generate_cid_init (buffer : GENERATION_BUFFER;
525     final_mode, use_info : BOOLEAN; idx_cnt : COUNTER) is
526     local
527     dummy : INTEGER
528     do
529     if
530     use_info and then (cr_info /= Void)
531 manus 26913 and then not is_expanded
532 manus 14013 then
533     -- It's an anchored type
534     cr_info.generate_cid_init (buffer, final_mode, idx_cnt)
535 manus 39412 else
536     dummy := idx_cnt.next
537 manus 14013 end
538     end
539 manus 30169
540     feature -- Generic conformance for IL
541    
542     generate_gen_type_il (il_generator: IL_CODE_GENERATOR; use_info : BOOLEAN) is
543     -- `use_info' is true iff we generate code for a
544     -- creation instruction.
545     do
546     if use_info and then cr_info /= Void then
547 manus 30582 -- It's an anchored type, we call feature
548     -- that will tell us the real type of the
549     -- anchor in the context of Current.
550     cr_info.generate_il_type
551     else
552     il_generator.generate_class_type_instance (Current)
553 manus 30169 end
554     end
555    
556 manus 33952 feature {NONE} -- Implementation
557    
558 manus 41824 frozen internal_il_type_name (a_base_name, a_prefix: STRING): STRING is
559 manus 33952 -- Full type name of `a_base_name' using `a_prefix' in IL code generation
560     -- with namespace specification
561     require
562     a_base_name_not_void: a_base_name /= Void
563     local
564     l_name: STRING
565 manus 41824 l_base_class: like base_class
566 manus 33952 do
567 manus 41824 l_base_class := base_class
568     -- Result needs to be in lower case because that's
569     -- what our casing conversion routines require to perform
570     -- a good job.
571     if
572     (is_expanded and l_base_class.is_expanded) or
573     (not is_expanded and not l_base_class.is_expanded)
574     then
575     Result := a_base_name.as_lower
576     else
577     if is_expanded then
578     create Result.make (6 + a_base_name.count)
579     Result.append ("VALUE_")
580     else
581     create Result.make (10 + a_base_name.count)
582     Result.append ("REFERENCE_")
583     end
584     Result.append (a_base_name)
585     Result.to_lower
586     end
587     l_name := l_base_class.lace_class.actual_namespace
588 manus 33952 if a_prefix /= Void then
589     if l_name.is_empty then
590     l_name := a_prefix + "."
591     else
592 manus 34253 l_name := il_casing.namespace_casing (System.dotnet_naming_convention,
593     l_name) + "." + a_prefix + "."
594 manus 33952 end
595     else
596     if not l_name.is_empty then
597 manus 34253 l_name := il_casing.namespace_casing (System.dotnet_naming_convention,
598     l_name) + "."
599 manus 33952 end
600     end
601 manus 34253 Result := l_name + il_casing.pascal_casing (System.dotnet_naming_convention,
602     Result, feature {IL_CASING_CONVERSION}.upper_case)
603 manus 33952 ensure
604     internal_il_type_name_not_void: Result /= Void
605     internal_il_type_name_not_empty: not Result.is_empty
606     end
607    
608 manus 41824 invariant
609     class_id_positive: class_id > 0
610    
611 grator 18 end

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23