/[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 43828 - (show annotations)
Tue Jun 15 18:15:36 2004 UTC (15 years, 8 months ago) by manus
Original Path: trunk/Src/bench/Eiffel/eiffel/genericity/cl_type_i.e
File size: 13752 byte(s)
Redefined `dump' in GEN_TYPE_I to be correct, that is to say it will display
  the actual generic derivation, i.e. type of `associated_class_type'.
Changed signature of `instantiation_in' and `complete_instantiation_in' to
  take a CLASS_TYPE rather than a GEN_TYPE_I. This made a huge simplification
  in the code and made it clearer to understand that it was only used to find
  out the type in a given generic derivation and not in any kind of `GEN_TYPE_I'.
  By doing this work, we were able to easily fix eweasel test `exec181'.
In FORMAL_I, it showed that `complete_instantiation_in' did not have
  to do any special work, it just needed to take the information directly
  from the CLASS_TYPE_.
It enabled us to have a proper implementation of `generic_derivation' for
  generic types where `meta_generic' and `true_generics' are properly initialized.
New creation procedure for GEN_TYPE_I and descendants to help us add some
  invariants about `meta_generic' and `true_generics'.

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23