/[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 41824 - (show 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 indexing
2 description: "Type class."
3 date: "$Date$"
4 revision: "$Revision$"
5
6 class CL_TYPE_I
7
8 inherit
9 TYPE_I
10 redefine
11 is_reference,
12 is_expanded,
13 is_separate,
14 is_valid,
15 is_explicit,
16 is_external,
17 same_as,
18 c_type,
19 conforms_to_array,
20 generated_id,
21 generate_cid,
22 make_gen_type_byte_code,
23 generate_cid_array,
24 generate_cid_init,
25 generate_gen_type_il,
26 generate_expanded_creation,
27 instantiation_in,
28 generic_derivation,
29 is_generated_as_single_type
30 end
31
32 SHARED_IL_CASING
33 export
34 {NONE} all
35 end
36
37 SHARED_GENERATION
38 export
39 {NONE} all
40 end
41
42 SHARED_DECLARATIONS
43 export
44 {NONE} all
45 end
46
47 create
48 make
49
50 feature {NONE} -- Initialization
51
52 make (id: INTEGER) is
53 -- Create new instance of `Current' with `class_id'
54 -- assigned with `id'.
55 require
56 valid_id: id > 0
57 do
58 class_id := id
59 if is_basic then
60 -- We know for sure that it is expanded then.
61 is_expanded := True
62 end
63 ensure
64 class_id_set: class_id = id
65 end
66
67 feature -- Access
68
69 class_id: INTEGER
70 -- 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 end
77
78 cr_info : CREATE_INFO
79 -- Additional information for the creation
80 -- of generic types with anchored parameters
81
82 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 base_class: CLASS_C is
89 -- Base class associated to the class type
90 do
91 Result := System.class_of_id (class_id)
92 end
93
94 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 type_a: CL_TYPE_A is
103 do
104 create Result.make (class_id)
105 Result.set_is_expanded (is_expanded)
106 Result.set_is_separate (is_separate)
107 end
108
109 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 il_type_name (a_prefix: STRING): STRING is
133 -- Class name of current type.
134 local
135 l_class_c: like base_class
136 l_is_precompiled: BOOLEAN
137 l_cl_type: like associated_class_type
138 do
139 l_class_c := base_class
140 if is_external then
141 Result := l_class_c.external_class_name.twin
142 else
143 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 Result := internal_il_type_name (l_class_c.name.twin, a_prefix)
153 end
154 end
155 end
156
157 description: ATTR_DESC is
158 -- Type description for skeletons
159 local
160 exp: EXPANDED_DESC
161 ref: REFERENCE_DESC
162 do
163 if is_expanded then
164 create exp
165 exp.set_class_type (base_class.types.search_item (Current))
166 exp.set_type_i (Current)
167 Result := exp
168 else
169 Result := c_type.description
170 end
171
172 ref ?= Result
173 if ref /= Void then
174 ref.set_type_i (Current)
175 end
176 end
177
178 c_type: TYPE_C is
179 -- Associated C type
180 do
181 Result := Reference_c_type
182 end
183
184 associated_class_type: CLASS_TYPE is
185 -- Associated class type
186 require
187 -- has: has_associated_class_type
188 do
189 Result := base_class.types.search_item (Current)
190 end
191
192 type_id: INTEGER is
193 -- Type id of the correponding class type
194 do
195 Result := associated_class_type.type_id
196 end
197
198 sk_value: INTEGER is
199 -- Generate SK value associated to the current type.
200 do
201 if is_expanded then
202 Result := Sk_exp | (type_id - 1)
203 else
204 Result := Sk_ref | (type_id - 1)
205 end
206 end
207
208 cecil_value: INTEGER is
209 do
210 if not is_expanded then
211 Result := Sk_dtype
212 else
213 Result := Sk_exp | class_id
214 end
215 end
216
217 hash_code: INTEGER is
218 -- Hash code for current type
219 do
220 Result := Other_code + class_id
221 end
222
223 feature -- Status
224
225 element_type: INTEGER_8 is
226 -- Void element type
227 do
228 if is_expanded then
229 -- We only support expanded for external class at the moment.
230 Result := feature {MD_SIGNATURE_CONSTANTS}.Element_type_valuetype
231 else
232 if class_id = System.system_string_class.compiled_class.class_id then
233 Result := feature {MD_SIGNATURE_CONSTANTS}.Element_type_string
234 elseif class_id = System.system_object_id then
235 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 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 -- 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 do
261 Result := is_expanded and then base_class.is_enum
262 end
263
264 is_external: BOOLEAN is
265 -- Is current type based on an external class?
266 local
267 l_base_class: like base_class
268 do
269 -- 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 end
274
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
297 is_valid: BOOLEAN is
298 -- Is the base class still in the system and matches its specification?
299 local
300 l_base_class: like base_class
301 do
302 l_base_class := base_class
303 Result := l_base_class /= Void and then (l_base_class.generics = Void)
304 end
305
306 is_reference: BOOLEAN is
307 -- Is the type a reference type ?
308 do
309 Result := not is_expanded
310 end;
311
312 is_explicit: BOOLEAN is
313 -- Is Current type fixed at compile time?
314 do
315 if cr_info /= Void then
316 Result := cr_info.is_explicit
317 else
318 Result := True
319 end
320 end
321
322 has_associated_class_type: BOOLEAN is
323 -- Has `Current' an associated class type?
324 do
325 Result := base_class.types.has_type (Current)
326 end
327
328 same_as (other: TYPE_I): BOOLEAN is
329 -- Is `other' equal to Current ?
330 local
331 other_cl_type: CL_TYPE_I
332 do
333 other_cl_type ?= other
334 Result := other_cl_type /= Void -- FIXME
335 and then other_cl_type.class_id = class_id
336 and then other_cl_type.is_expanded = is_expanded
337 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 set_is_expanded (b: BOOLEAN) is
345 -- Assign `b' to `is_expanded'.
346 do
347 is_expanded := b
348 ensure
349 is_expanded_set: is_expanded = b
350 end
351
352 set_is_separate (b: BOOLEAN) is
353 -- Assign `b' to `is_separate'.
354 do
355 is_separate := b
356 ensure
357 is_separate_set: is_separate = b
358 end
359
360 set_cr_info (cinfo : CREATE_INFO) is
361 -- Set `cr_info' to `cinfo'.
362 require
363 create_info_not_void: cinfo /= Void
364 not_expanded: not is_expanded
365 do
366 cr_info := cinfo
367 ensure
368 cr_info_set : cr_info = cinfo
369 end
370
371 feature -- C generation
372
373 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 buffer.putstring (");")
422 buffer.new_line
423 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 generate_cecil_value (buffer: GENERATION_BUFFER) is
440 -- Generate cecil value
441 do
442 if not is_expanded then
443 buffer.putstring ("SK_DTYPE")
444 else
445 buffer.putstring ("SK_EXP + (uint32) ")
446 buffer.putint (associated_class_type.type_id - 1)
447 end
448 end
449
450 feature -- Array optimization
451
452 conforms_to_array: BOOLEAN is
453 do
454 Result := base_class.conform_to (array_class_c)
455 end
456
457 feature {NONE} -- Array optimization
458
459 array_class_c: CLASS_C is
460 once
461 Result := System.array_class.compiled_class
462 end
463
464 feature -- Generic conformance
465
466 generated_id (final_mode : BOOLEAN) : INTEGER is
467
468 do
469 if final_mode then
470 Result := type_id - 1
471 else
472 Result := associated_class_type.static_type_id - 1
473 end
474 end
475
476 generate_cid (buffer : GENERATION_BUFFER; final_mode, use_info : BOOLEAN) is
477
478 do
479 if
480 use_info and then (cr_info /= Void)
481 and then not is_expanded
482 then
483 -- It's an anchored type
484 cr_info.generate_cid (buffer, final_mode)
485 else
486 buffer.putint (generated_id (final_mode))
487 buffer.putstring (", ")
488 end
489 end
490
491 make_gen_type_byte_code (ba : BYTE_ARRAY; use_info : BOOLEAN) is
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.make_gen_type_byte_code (ba)
499 else
500 ba.append_short_integer (generated_id (False))
501 end
502 end
503
504 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 and then not is_expanded
512 then
513 -- It's an anchored type
514 cr_info.generate_cid_array (buffer, final_mode, idx_cnt)
515 else
516 buffer.putint (generated_id (final_mode))
517 buffer.putstring (", ")
518
519 -- Increment counter
520 dummy := idx_cnt.next
521 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 and then not is_expanded
532 then
533 -- It's an anchored type
534 cr_info.generate_cid_init (buffer, final_mode, idx_cnt)
535 else
536 dummy := idx_cnt.next
537 end
538 end
539
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 -- 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 end
554 end
555
556 feature {NONE} -- Implementation
557
558 frozen internal_il_type_name (a_base_name, a_prefix: STRING): STRING is
559 -- 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 l_base_class: like base_class
566 do
567 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 if a_prefix /= Void then
589 if l_name.is_empty then
590 l_name := a_prefix + "."
591 else
592 l_name := il_casing.namespace_casing (System.dotnet_naming_convention,
593 l_name) + "." + a_prefix + "."
594 end
595 else
596 if not l_name.is_empty then
597 l_name := il_casing.namespace_casing (System.dotnet_naming_convention,
598 l_name) + "."
599 end
600 end
601 Result := l_name + il_casing.pascal_casing (System.dotnet_naming_convention,
602 Result, feature {IL_CASING_CONVERSION}.upper_case)
603 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 invariant
609 class_id_positive: class_id > 0
610
611 end

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23