/[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 56356 - (show annotations)
Fri Dec 23 11:15:48 2005 UTC (14 years, 2 months ago) by alexk
Original Path: trunk/Src/bench/Eiffel/eiffel/genericity/cl_type_i.e
File size: 15239 byte(s)
Added a feature to evaluate the type of an expression in a given class
assuming that the context type is fixed. This is used to evaluate types in
the code of inherited features generated for expanded types.
Changed code generation for creation to take expandedness status of the
creation type into account.
Added a feature that loads a current object as a reference one regardless
of its actual expandedness status.
Added features to evaluate context type of a call as well as a type from a
possibly inherited code in the context type for which the code generation
is performed.
Taken expandedness status of a root class into account.

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23