/[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 56011 - (show annotations)
Mon Dec 5 17:36:00 2005 UTC (14 years, 2 months ago) by alexk
Original Path: trunk/Src/bench/Eiffel/eiffel/genericity/cl_type_i.e
File size: 14979 byte(s)
Recorded explicit class type declaration rather than a calculated one to
avoid issues with recompiling classes that change their expandedness
status.
Initialized class types associated with a class using `update_types' to
ensure that all structures (e.g., `derivations') are updated as well.
Used instantiation procedure unconditionally to cover the case of "like
Current" type.
Made a feature `duplicate' available in CL_TYPE_I to avoid using reverse
assignment.
Ensured that parent types are reference.
Created generic attribute descriptor not only for types that depend on
formal generic but also for those depending on anchored type ("like
Current").

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23