/[eiffelstudio]/branches/CAT_mono/Src/Eiffel/eiffel/interface/feature_i.e
ViewVC logotype

Contents of /branches/CAT_mono/Src/Eiffel/eiffel/interface/feature_i.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 69686 - (show annotations)
Wed Jul 25 18:35:45 2007 UTC (12 years, 4 months ago) by juliant
File size: 76723 byte(s)
fixed missing locals
1 indexing
2 description: "Instance of an Eiffel feature: for every inherited feature there is%N%
3 %an instance of FEATURE_I with its final name, the class name where it%N%
4 %is written, the body id of its content and the routine table ids to%N%
5 %which the feature is attached.%N%
6 %Attribute `type' is the real type of the feature in the class where it%N%
7 %is inherited (or written), that means there is no more anchored type."
8 legal: "See notice at end of class."
9 status: "See notice at end of class."
10 date: "$Date$"
11 version: "$Revision$"
12
13 deferred class FEATURE_I
14
15 inherit
16 SHARED_WORKBENCH
17
18 SHARED_SERVER
19 export
20 {ANY} all
21 end
22
23 SHARED_INSTANTIATOR
24
25 SHARED_ERROR_HANDLER
26
27 SHARED_TYPES
28
29 SHARED_EVALUATOR
30
31 SHARED_TABLE
32
33 SHARED_AST_CONTEXT
34
35 SHARED_BYTE_CONTEXT
36 rename
37 context as byte_context
38 end
39
40 SHARED_PATTERN_TABLE
41
42 SHARED_INST_CONTEXT
43
44 SHARED_ID_TABLES
45 export
46 {ANY} Body_index_table, Original_body_index_table
47 end
48
49 SHARED_ARRAY_BYTE
50
51 SHARED_EXEC_TABLE
52
53 HASHABLE
54 rename
55 hash_code as feature_name_id
56 end
57
58 COMPILER_EXPORTER
59
60 SHARED_NAMES_HEAP
61
62 DEBUG_OUTPUT
63
64 COMPARABLE
65 undefine
66 is_equal
67 end
68
69 SHARED_STATELESS_VISITOR
70 export
71 {NONE} all
72 end
73
74 REFACTORING_HELPER
75 export
76 {NONE} all
77 end
78
79 SHARED_IL_CASING
80 export
81 {NONE} all
82 end
83
84 SHARED_INLINE_AGENT_LOOKUP
85
86 feature -- Access
87
88 feature_name: STRING is
89 -- Final name of feature.
90 require
91 feature_name_id_set: feature_name_id > 0
92 do
93 Result := Names_heap.item (feature_name_id)
94 ensure
95 feature_name_not_void: Result /= Void
96 feature_name_not_empty: not Result.is_empty
97 end
98
99 alias_name: STRING is
100 -- Alias name of feature (if any).
101 do
102 if alias_name_id > 0 then
103 Result := Names_heap.item (alias_name_id)
104 end
105 end
106
107 assigner_name: STRING is
108 -- Associated assigner name (if any).
109 do
110 if assigner_name_id /= 0 then
111 Result := names_heap.item (assigner_name_id)
112 end
113 end
114
115 feature_name_id: INTEGER
116 -- Id of `feature_name' in `Names_heap' table.
117
118 alias_name_id: INTEGER
119 -- Id of `alias_name' in `Names_heap' table
120
121 assigner_name_id: INTEGER is
122 -- Id of `assigner_name' in `Names_heap' table
123 do
124 -- 0 (no assigner) by default
125 ensure
126 valid_result: Result /= 0 implies names_heap.valid_index (Result)
127 end
128
129 feature_id: INTEGER
130 -- Feature id: first key in feature call hash table
131 -- of a class: two features of different names have two
132 -- different feature ids.
133
134 written_in: INTEGER
135 -- Class id where feature is written
136
137 body_index: INTEGER
138 -- Index of body id
139
140 pattern_id: INTEGER
141 -- Id of feature pattern
142
143 rout_id_set: ROUT_ID_SET
144 -- Routine table to which feature belongs to.
145
146 export_status: EXPORT_I
147 -- Export status of feature
148
149 origin_feature_id: INTEGER
150 -- Feature ID of Current in associated CLASS_INTERFACE
151 -- that defines it.
152 -- Used for MSIL code generation only.
153
154 origin_class_id: INTEGER
155 -- Class ID of class defining Current in associated CLASS_INTERFACE
156 -- that defines it.
157 -- Used for MSIL code generation only.
158
159 written_feature_id: INTEGER
160 -- Feature ID of Current in associated CLASS_C of ID `written_in'
161 -- that gives a body.
162 -- Used for MSIL code generation only.
163
164 frozen is_origin: BOOLEAN is
165 -- Is feature an origin?
166 do
167 Result := feature_flags & is_origin_mask = is_origin_mask
168 end
169
170 frozen is_frozen: BOOLEAN is
171 -- Is feature frozen?
172 do
173 Result := feature_flags & is_frozen_mask = is_frozen_mask
174 end
175
176 frozen is_empty: BOOLEAN is
177 -- Is feature with an empty body?
178 do
179 Result := feature_flags & is_empty_mask = is_empty_mask
180 end
181
182 frozen is_infix: BOOLEAN is
183 -- Is feature an infixed one ?
184 do
185 Result := feature_flags & is_infix_mask = is_infix_mask
186 end
187
188 frozen is_prefix: BOOLEAN is
189 -- Is feature a prefixed one ?
190 do
191 Result := feature_flags & is_prefix_mask = is_prefix_mask
192 end
193
194 frozen is_bracket: BOOLEAN is
195 -- Is feature a bracket one ?
196 do
197 Result := feature_flags & is_bracket_mask = is_bracket_mask
198 end
199
200 frozen is_binary: BOOLEAN is
201 -- Is feature a binary one?
202 do
203 Result := feature_flags & is_binary_mask = is_binary_mask
204 end
205
206 frozen is_unary: BOOLEAN is
207 -- Is feature an unary one?
208 do
209 Result := feature_flags & is_unary_mask = is_unary_mask
210 end
211
212 frozen has_convert_mark: BOOLEAN is
213 -- Does binary feature have a convert mark?
214 do
215 Result := feature_flags & has_convert_mark_mask = has_convert_mark_mask
216 end
217
218 frozen is_selected: BOOLEAN is
219 -- Is feature selected?
220 do
221 -- FIXME: Manu 11/21/2001.
222 -- Not used at the moment.
223 end
224
225 has_formal: BOOLEAN is
226 -- Is formal type present in the feature signature at the top level?
227 -- (Formals used as parameters of generic class types do not count.)
228 local
229 a: like arguments
230 do
231 if type.type_i.is_formal then
232 Result := True
233 else
234 a := arguments
235 if a /= Void then
236 from
237 a.start
238 until
239 a.after
240 loop
241 if a.item.type_i.is_formal then
242 Result := True
243 a.finish
244 end
245 a.forth
246 end
247 end
248 end
249 end
250
251 generic_fingerprint: STRING is
252 -- Fingerprint of the feature signature that distinguishes
253 -- between formal generic and non-formal-generic types.
254 local
255 digit: NATURAL_8
256 a: like arguments
257 i: NATURAL_8
258 z: INTEGER
259 do
260 create Result.make_empty
261 if type.type_i.is_formal then
262 digit := 1
263 end
264 a := arguments
265 if a /= Void then
266 from
267 i := 2
268 a.start
269 until
270 a.after
271 loop
272 if a.item.type_i.is_formal then
273 digit := digit + i
274 end
275 i := i |<< 1
276 if i >= 16 then
277 -- Add a digit to the result.
278 Result.append_character (digit.to_hex_character)
279 if digit = 0 then
280 z := z + 1
281 else
282 z := 0
283 end
284 digit := 0
285 i := 1
286 end
287 a.forth
288 end
289 end
290 if digit /= 0 then
291 Result.append_character (digit.to_hex_character)
292 elseif z > 0 then
293 -- Remove trailing zeroes.
294 Result.remove_tail (z)
295 end
296 end
297
298 extension: EXTERNAL_EXT_I is
299 -- Encapsulation of the external extension
300 do
301 end
302
303 external_name: STRING is
304 -- External name
305 require
306 external_name_id_set: external_name_id > 0
307 do
308 Result := Names_heap.item (external_name_id)
309 ensure
310 Result_not_void: Result /= Void
311 Result_not_empty: not Result.is_empty
312 end;
313
314 external_name_id: INTEGER is
315 -- External name of feature if any generation.
316 do
317 Result := private_external_name_id
318 if Result = 0 then
319 Result := feature_name_id
320 end
321 end
322
323 is_inline_agent: BOOLEAN is
324 -- is the feature an inline agent
325 do
326 Result := inline_agent_nr /= 0
327 end
328
329 enclosing_body_id: INTEGER
330 -- The body id of the enclosing feature of an inline agent
331
332 enclosing_feature: FEATURE_I is
333 -- Gives the (real) feature in which this features is defined.
334 -- If the feature has no enclosing feature, a reference to itself is returned.
335 local
336 l_written_class: CLASS_C
337 do
338 if is_inline_agent then
339 l_written_class := written_class;
340 Result := l_written_class.feature_i_with_body_index (enclosing_body_id)
341 if Result = Void then
342 Result := l_written_class.invariant_feature
343 end
344 else
345 Result := Current
346 end
347 ensure
348 Result /= Void and not Result.is_inline_agent
349 end
350
351 inline_agent_nr: INTEGER
352 -- the number of this inline agent in the enclosing feature
353
354 supports_step_in: BOOLEAN
355 -- Is it possible to step into this feature or set breakpoints in it?
356 do
357 Result := not (enclosing_feature.is_invariant or else is_fake_inline_agent)
358 end
359
360 feature -- Comparison
361
362 infix "<" (other: FEATURE_I): BOOLEAN is
363 -- Comparison of FEATURE_I based on their name.
364 local
365 l_name, l_other_name: like feature_name
366 do
367 l_name := feature_name
368 l_other_name := other.feature_name
369 if l_name = Void then
370 Result := other.feature_name /= Void
371 else
372 Result := l_other_name /= Void and l_name < l_other_name
373 end
374 end
375
376 is_same_alias (other: FEATURE_I): BOOLEAN is
377 -- Does current have the same alias as `other'?
378 require
379 other_not_void: other /= Void
380 do
381 Result :=
382 alias_name_id = other.alias_name_id and then
383 has_convert_mark = other.has_convert_mark
384 end
385
386 is_same_assigner (other: FEATURE_I; tbl: FEATURE_TABLE): BOOLEAN is
387 -- Does current have the same assigner command (if any) as `other'?
388 require
389 other_not_void: other /= Void
390 tbl_not_void: tbl /= Void
391 local
392 origin_table: HASH_TABLE [FEATURE_I, INTEGER]
393 assigner_command: FEATURE_I
394 other_assigner_command: FEATURE_I
395 do
396 -- If either of the feature has no assigner command, we treat them as having
397 -- the same assigner command
398 if assigner_name_id = 0 or else other.assigner_name_id = 0 then
399 Result := True
400 else
401 origin_table := tbl.origin_table
402 if written_in = system.current_class.class_id then
403 assigner_command := tbl.item_id (assigner_name_id)
404 else
405 assigner_command := written_class.feature_named (assigner_name)
406 end
407 if assigner_command = Void then
408 -- Assigner command is not found
409 error_handler.insert_error (create {VFAC1}.make (system.current_class, Current))
410 else
411 assigner_command := origin_table.item (assigner_command.rout_id_set.first)
412 if other.written_in = system.current_class.class_id then
413 other_assigner_command := tbl.item_id (other.assigner_name_id)
414 else
415 other_assigner_command := other.written_class.feature_named (other.assigner_name)
416 end
417 check
418 other_assigner_command_not_void: other_assigner_command /= Void
419 end
420 other_assigner_command := origin_table.item (other_assigner_command.rout_id_set.first)
421 Result := assigner_command = other_assigner_command
422 end
423 end
424 end
425
426 feature -- Debugger access
427
428 number_of_breakpoint_slots: INTEGER is
429 -- Number of breakpoint slots in feature (:::)
430 -- It includes pre/postcondition (inner & herited)
431 -- and rescue clause.
432 --
433 --|---------------------------------------------------------
434 --| Note from Arnaud PICHERY [ aranud@mail.dotcom.fr ] |
435 --|---------------------------------------------------------
436 --| If the feature inherits from one routine that has no |
437 --| precondition, the precondition for this routine will |
438 --| always be true and thus will not be generated by the |
439 --| compiler. So, we do not count the preconditions if one |
440 --| of the inherited routines has an empty precondition |
441 --| clause. |
442 --|---------------------------------------------------------
443 local
444 l_body: like real_body
445 l_routine: ROUTINE_AS
446 do
447 l_body := real_body
448
449 if l_body /= Void then
450 l_routine ?= l_body.content
451 Result := l_routine.number_of_breakpoint_slots
452 end
453 Result := Result.max (1)
454 end
455
456 first_breakpoint_slot_index: INTEGER is
457 -- Index of the first breakpoin-slot. Includes inherited and inner assertions
458 local
459 l_body: like real_body
460 l_routine: ROUTINE_AS
461 l_internal: INTERNAL_AS
462 do
463 l_body := real_body
464 if l_body /= Void then
465 l_routine ?= l_body.content
466 if l_routine /= Void then
467 l_internal ?= l_routine.routine_body
468 if l_internal /= Void then
469 if l_internal.is_empty then
470 Result := number_of_breakpoint_slots
471 else
472 Result := l_internal.first_breakpoint_slot_index
473 end
474 end
475 end
476 end
477 Result := Result.max (1)
478 end
479
480 feature -- Status
481
482 to_melt_in (a_class: CLASS_C): BOOLEAN is
483 -- Has current feature to be melted in class `a_class' ?
484 require
485 good_argument: a_class /= Void
486 do
487 Result := a_class.class_id = written_in
488 end
489
490 to_generate_in (a_class: CLASS_C): BOOLEAN is
491 -- Has current feature to be generated in class `a_class' ?
492 require
493 good_argument: a_class /= Void
494 do
495 Result := a_class.class_id = written_in
496 end
497
498 frozen to_implement_in (a_class: CLASS_C): BOOLEAN is
499 -- Does Current feature need to be exposed in interface
500 -- used for IL generation?
501 require
502 a_class_not_void: a_class /= Void
503 do
504 Result := a_class.class_id = written_in
505 end
506
507 feature -- Setting
508
509 set_feature_id (i: INTEGER) is
510 -- Assign `i' to `feature_id'
511 do
512 feature_id := i
513 end
514
515 set_body_index (i: INTEGER) is
516 -- Assign `i' to `body_index'.
517 do
518 body_index := i
519 end
520
521 set_pattern_id (i: INTEGER) is
522 -- Assign `i' to `pattern_id'.
523 do
524 pattern_id := i
525 end
526
527 set_feature_name (s: STRING) is
528 -- Assign `s' to `feature_name'.
529 -- `set_renamed_name' is needed for C external
530 -- routines that can't be renamed.
531 require
532 s_not_void: s /= Void
533 s_not_empty: not s.is_empty
534 local
535 l_names_heap: like Names_heap
536 do
537 l_names_heap := Names_heap
538 l_names_heap.put (s)
539 feature_name_id := l_names_heap.found_item
540 ensure
541 feature_name_set: equal (feature_name, s)
542 end
543
544 set_feature_name_id, set_renamed_name_id (id: INTEGER; alias_id: INTEGER) is
545 -- Assign `id' to `feature_name_id'.
546 require
547 valid_id: Names_heap.valid_index (id)
548 valid_alias_id: Names_heap.valid_index (alias_id)
549 do
550 feature_name_id := id
551 alias_name_id := alias_id
552 ensure
553 feature_name_id_set: feature_name_id = id
554 alias_name_id_set: alias_name_id = alias_id
555 end
556
557 set_written_in (a_class_id: like written_in) is
558 -- Assign `a_class_id' to `written_in'.
559 require
560 a_class_id_not_void: a_class_id > 0
561 do
562 written_in := a_class_id
563 ensure
564 written_in_set: written_in = a_class_id
565 end
566
567 set_written_feature_id (a_feature_id: like written_feature_id) is
568 -- Assign `a_feature_id' to `written_feature_id'.
569 require
570 valid_feature_id: a_feature_id >= 0
571 do
572 written_feature_id := a_feature_id
573 ensure
574 written_feature_id_set: written_feature_id = a_feature_id
575 end
576
577 set_origin_feature_id (a_feature_id: like origin_feature_id) is
578 -- Assign `a_feature_id' to `origin_feature_id'.
579 require
580 valid_feature_id: a_feature_id >= 0
581 do
582 origin_feature_id := a_feature_id
583 ensure
584 origin_feature_id_set: origin_feature_id = a_feature_id
585 end
586
587 set_origin_class_id (a_class_id: like origin_class_id) is
588 -- Assign `a_class_id' to `origin_class_id'.
589 require
590 valid_feature_id: a_class_id >= 0
591 do
592 origin_class_id := a_class_id
593 ensure
594 origin_class_id_set: origin_class_id = a_class_id
595 end
596
597 set_export_status (e: EXPORT_I) is
598 -- Assign `e' to `export_status'.
599 do
600 export_status := e
601 ensure
602 export_status_set: export_status = e
603 end
604
605 frozen set_is_origin (b: BOOLEAN) is
606 -- Assign `b' to `is_origin'.
607 do
608 feature_flags := feature_flags.set_bit_with_mask (b, is_origin_mask)
609 ensure
610 is_origin_set: is_origin = b
611 end
612
613 frozen set_is_empty (b : BOOLEAN) is
614 -- Set `is_empty' to `b'
615 do
616 feature_flags := feature_flags.set_bit_with_mask (b, is_empty_mask)
617 ensure
618 is_empty_set: is_empty = b
619 end
620
621 frozen set_is_frozen (b: BOOLEAN) is
622 -- Assign `b' to `is_frozen'.
623 --|Note: nothing to do with melted/frozen features
624 do
625 feature_flags := feature_flags.set_bit_with_mask (b, is_frozen_mask)
626 ensure
627 is_frozen_set: is_frozen = b
628 end
629
630 frozen set_is_infix (b: BOOLEAN) is
631 -- Assign `b' to `is_infix'.
632 do
633 feature_flags := feature_flags.set_bit_with_mask (b, is_infix_mask)
634 ensure
635 is_infix_set: is_infix = b
636 end
637
638 frozen set_is_prefix (b: BOOLEAN) is
639 -- Assign `b' to `is_prefix'.
640 do
641 feature_flags := feature_flags.set_bit_with_mask (b, is_prefix_mask)
642 ensure
643 is_prefix_set: is_prefix = b
644 end
645
646 frozen set_is_bracket (b: BOOLEAN) is
647 -- Assign `b' to `is_bracket'.
648 do
649 feature_flags := feature_flags.set_bit_with_mask (b, is_bracket_mask)
650 ensure
651 is_bracket_set: is_bracket = b
652 end
653
654 frozen set_is_binary (b: BOOLEAN) is
655 -- Assign `b' to `is_binary'.
656 do
657 feature_flags := feature_flags.set_bit_with_mask (b, is_binary_mask)
658 ensure
659 is_binary_set: is_binary = b
660 end
661
662 frozen set_is_unary (b: BOOLEAN) is
663 -- Assign `b' to `is_unary'.
664 do
665 feature_flags := feature_flags.set_bit_with_mask (b, is_unary_mask)
666 ensure
667 is_unary_set: is_unary = b
668 end
669
670 frozen set_has_convert_mark (b: BOOLEAN) is
671 -- Assign `b' to `has_convert_mark'.
672 do
673 feature_flags := feature_flags.set_bit_with_mask (b, has_convert_mark_mask)
674 ensure
675 has_convert_mark_set: has_convert_mark = b
676 end
677
678 frozen set_is_require_else (b: BOOLEAN) is
679 -- Assign `b' to `is_require_else'.
680 do
681 feature_flags := feature_flags.set_bit_with_mask (b, is_require_else_mask)
682 ensure
683 is_require_else_set: is_require_else = b
684 end
685
686 frozen set_is_ensure_then (b: BOOLEAN) is
687 -- Assign `b' to `is_ensure_then'.
688 do
689 feature_flags := feature_flags.set_bit_with_mask (b, is_ensure_then_mask)
690 ensure
691 is_ensure_then_set: is_ensure_then = b
692 end
693
694 frozen set_is_fake_inline_agent (b: BOOLEAN) is
695 -- Assign `b' to `is_fake_inline_agent'.
696 do
697 feature_flags := feature_flags.set_bit_with_mask (b, is_fake_inline_agent_mask)
698 ensure
699 is_fake_inline_agent_set: is_fake_inline_agent = b
700 end
701
702 frozen set_has_rescue_clause (b: BOOLEAN) is
703 -- Assign `b' to `has_rescue_clause'.
704 do
705 feature_flags := feature_flags.set_bit_with_mask (b, has_rescue_clause_mask)
706 ensure
707 has_rescue_clause_set: has_rescue_clause = b
708 end
709
710 set_is_selected (b: BOOLEAN) is
711 -- Assign `b' to `is_selected'.
712 do
713 -- FIXME: Manu 11/21/2001
714 -- Not used currently used
715 -- is_selected := b
716 end
717
718 set_has_property (v: BOOLEAN) is
719 -- Set `has_property' to `v'.
720 do
721 feature_flags := feature_flags.set_bit_with_mask (v, has_property_mask)
722 ensure
723 has_property_set: has_property = v
724 end
725
726 set_has_property_getter (v: BOOLEAN) is
727 -- Set `has_property_getter' to `v'.
728 do
729 feature_flags := feature_flags.set_bit_with_mask (v, has_property_getter_mask)
730 ensure
731 has_property_getter_set: has_property_getter = v
732 end
733
734 set_has_property_setter (v: BOOLEAN) is
735 -- Set `has_property_setter' to `v'.
736 do
737 feature_flags := feature_flags.set_bit_with_mask (v, has_property_setter_mask)
738 ensure
739 has_property_setter_set: has_property_setter = v
740 end
741
742 set_rout_id_set (set: like rout_id_set) is
743 -- Assign `set' to `rout_id_set'.
744 do
745 rout_id_set := set
746 end
747
748 set_private_external_name_id (n_id: like private_external_name_id) is
749 -- Assign `n_id' to `private_external_name_id'.
750 require
751 valid_n: n_id > 0
752 do
753 private_external_name_id := n_id
754 ensure
755 private_external_name_set: private_external_name_id = n_id
756 end
757
758 generation_class_id: INTEGER is
759 -- Id of class where feature has to be generated in
760 do
761 Result := written_in
762 end
763
764 duplicate: like Current is
765 -- Clone
766 do
767 Result := twin
768 end
769
770 duplicate_arguments is
771 -- Do a clone of arguments (for replication)
772 do
773 -- Do nothing
774 end
775
776 set_inline_agent (a_enclosing_body_id, a_inline_agent_nr: INTEGER) is
777 -- Define this feature as an inline agent
778 require
779 enclosing_body_id_valid: a_enclosing_body_id > 0
780 inline_agent_nr_valid: (is_fake_inline_agent implies a_inline_agent_nr = -1) and
781 not is_fake_inline_agent implies a_inline_agent_nr > 0
782 do
783 inline_agent_nr := a_inline_agent_nr
784 enclosing_body_id := a_enclosing_body_id
785 end
786
787 feature -- Incrementality
788
789 equiv (other: FEATURE_I): BOOLEAN is
790 -- Incrementality test on instance of FEATURE_I during
791 -- second pass.
792 require
793 good_argument: other /= Void
794 do
795 Result := written_in = other.written_in
796 and then is_selected = other.is_selected
797 and then rout_id_set.same_as (other.rout_id_set)
798 and then is_origin = other.is_origin
799 and then is_frozen = other.is_frozen
800 and then is_deferred = other.is_deferred
801 and then is_external = other.is_external
802 and then export_status.same_as (other.export_status)
803 and then same_signature (other)
804 and then has_precondition = other.has_precondition
805 and then has_postcondition = other.has_postcondition
806 and then is_once = other.is_once
807 and then is_process_relative = other.is_process_relative
808 and then is_constant = other.is_constant
809 and then alias_name_id = other.alias_name_id
810 and then has_convert_mark = other.has_convert_mark
811 and then assigner_name_id = other.assigner_name_id
812 and then has_property = other.has_property
813 and then (has_property implies property_name.is_equal (other.property_name))
814 and then has_property_getter = other.has_property_getter
815 and then has_property_setter = other.has_property_setter
816 debug ("ACTIVITY")
817 if not Result then
818 io.error.put_boolean (written_in = other.written_in) io.error.put_new_line;
819 io.error.put_boolean (is_selected = other.is_selected) io.error.put_new_line;
820 io.error.put_boolean (rout_id_set.same_as (other.rout_id_set)) io.error.put_new_line;
821 io.error.put_boolean (is_origin = other.is_origin) io.error.put_new_line;
822 io.error.put_boolean (is_frozen = other.is_frozen) io.error.put_new_line;
823 io.error.put_boolean (is_deferred = other.is_deferred) io.error.put_new_line;
824 io.error.put_boolean (is_external = other.is_external) io.error.put_new_line;
825 io.error.put_boolean (export_status.same_as (other.export_status)) io.error.put_new_line;
826 io.error.put_boolean (same_signature (other)) io.error.put_new_line;
827 io.error.put_boolean (has_precondition = other.has_precondition) io.error.put_new_line;
828 io.error.put_boolean (has_postcondition = other.has_postcondition) io.error.put_new_line;
829 io.error.put_boolean (is_once = other.is_once) io.error.put_new_line;
830 end
831 end
832 if Result then
833 if assert_id_set /= Void then
834 Result := assert_id_set.same_as (other.assert_id_set)
835 else
836 Result := (other.assert_id_set = Void)
837 end
838 end
839
840 if Result and then rout_id_set.first = System.default_rescue_id then
841 -- This is the default rescue feature.
842 -- Test whether emptiness of body has changed.
843 Result := (is_empty = other.is_empty)
844 end
845
846 if Result and then rout_id_set.first = System.default_create_id then
847 -- This is the default create feature.
848 -- Test whether emptiness of body has changed.
849 Result := (is_empty = other.is_empty)
850 end
851
852 debug ("ACTIVITY")
853 if not Result then
854 io.error.put_string ("%T%T")
855 io.error.put_string (feature_name)
856 io.error.put_string (" is not equiv%N")
857 end
858 end
859 end
860
861 select_table_equiv (other: FEATURE_I): BOOLEAN is
862 -- Incrementality of select table
863 require
864 good_argumnet: other /= Void
865
866 do
867 Result := written_in = other.written_in
868 and then rout_id_set.same_as (other.rout_id_set)
869 and then is_origin = other.is_origin
870 and then body_index = other.body_index
871 and then type.is_safe_equivalent (other.type)
872 end
873
874 is_valid: BOOLEAN is
875 -- Is feature still valid?
876 -- Incrementality: The types of arguments and/or result
877 -- are still defined in system
878 local
879 type_a: TYPE_A
880 do
881 type_a ?= type
882 Result := type_a.is_valid
883 if Result and then has_arguments then
884 Result := arguments.is_valid
885 end
886 end
887
888 same_class_type (other: FEATURE_I): BOOLEAN is
889 -- Has `other' same resulting type than Current ?
890 require
891 good_argument: other /= Void
892 same_names: other.feature_name_id = feature_name_id
893 do
894 Result := type.same_as (other.type)
895 end
896
897 same_interface (other: FEATURE_I): BOOLEAN is
898 -- Has `other' same interface than Current ?
899 -- [Semnatic for second pass is `old_feat.same_interface (new)']
900 require
901 good_argument: other /= Void
902 -- export_statuses_exist: not (export_status = Void
903 -- or else other.export_status = Void)
904 do
905 -- Still an attribute
906 Result := is_attribute = other.is_attribute
907
908 -- Same alias
909 if Result then
910 Result := alias_name_id = other.alias_name_id
911 if Result then
912 Result := has_convert_mark = other.has_convert_mark
913 end
914 end
915
916 -- Same assigner procedure
917 if Result then
918 Result := assigner_name_id = other.assigner_name_id
919 end
920
921 -- Same return type
922 Result := Result and then type.same_as (other.type)
923 -- and then export_status.equiv (other.export_status)
924
925 -- Same arguments if any
926 if Result then
927 if argument_count = 0 then
928 Result := other.argument_count = 0
929 else
930 Result := argument_count = other.argument_count
931 and then arguments.same_interface (other.arguments)
932 end
933 end
934
935 -- Still a once
936 Result := Result and then is_once = other.is_once
937 end
938
939 feature -- creation of default rescue clause
940
941 create_default_rescue (def_resc_name_id: INTEGER) is
942 -- Create default_rescue clause if necessary
943 require
944 valid_feature_name_id : def_resc_name_id > 0
945 local
946 my_body : like body
947 do
948 if
949 not (is_attribute or is_constant or
950 is_external or is_deferred)
951 then
952 my_body := body
953 if (my_body /= Void) then
954 my_body.create_default_rescue (def_resc_name_id)
955 end
956 end
957 end
958
959 feature -- Type id
960
961 written_type (class_type: CLASS_TYPE): CLASS_TYPE is
962 -- Written type of feature in context of
963 -- type `class_type'.
964 require
965 good_argument: class_type /= Void
966 conformance: class_type.associated_class.conform_to (written_class)
967 do
968 Result := written_class.meta_type (class_type)
969 end
970
971 feature -- Conveniences
972
973 assert_id_set: ASSERT_ID_SET is
974 -- Assertions to which procedure belongs to
975 -- (To be redefined in PROCEDURE_I).
976 do
977 -- Do nothing
978 end
979
980 is_obsolete: BOOLEAN is
981 -- Is Current feature obsolete?
982 do
983 Result := obsolete_message /= Void
984 end
985
986 obsolete_message: STRING is
987 -- Obsolete message
988 -- (Void if Current is not obsolete)
989 do
990 -- Do nothing
991 end
992
993 has_arguments: BOOLEAN is
994 -- Has current feature some formal arguments ?
995 do
996 Result := arguments /= Void
997 end
998
999 is_replicated: BOOLEAN is
1000 -- Is Current feature conceptually replicated?
1001 do
1002 -- Do nothig
1003 end
1004
1005 is_routine: BOOLEAN is
1006 -- Is current feature a routine ?
1007 do
1008 -- Do nothing
1009 end
1010
1011 is_function: BOOLEAN is
1012 -- Is current feature a function ?
1013 do
1014 -- Do nothing
1015 end
1016
1017 is_type_feature: BOOLEAN is
1018 -- Is current an instance of TYPE_FEATURE_I?
1019 do
1020 -- Do nothing
1021 end
1022
1023 is_attribute: BOOLEAN is
1024 -- Is current feature an attribute ?
1025 do
1026 -- Do nothing
1027 end
1028
1029 is_constant: BOOLEAN is
1030 -- Is current feature a constant ?
1031 do
1032 -- Do nothing
1033 end
1034
1035 is_once: BOOLEAN is
1036 -- Is current feature a once one ?
1037 do
1038 -- Do nothing
1039 end
1040
1041 is_do: BOOLEAN is
1042 -- Is current feature a do one ?
1043 do
1044 -- Do nothing
1045 end
1046
1047 is_deferred: BOOLEAN is
1048 -- Is current feature a deferred one ?
1049 do
1050 -- Do nothing
1051 end
1052
1053 is_unique: BOOLEAN is
1054 -- Is current feature a unique constant ?
1055 do
1056 -- Do nothing
1057 end
1058
1059 is_external: BOOLEAN is
1060 -- Is current feature an external one ?
1061 do
1062 -- Do nothing
1063 end
1064
1065 has_return_value: BOOLEAN is
1066 -- Does current return a value?
1067 do
1068 Result := is_constant or is_attribute or is_function
1069 ensure
1070 validity: Result implies (is_constant or is_attribute or is_function)
1071 end
1072
1073 frozen is_il_external: BOOLEAN is
1074 -- Is current feature a C external one?
1075 local
1076 ext: IL_EXTENSION_I
1077 l_const: CONSTANT_I
1078 do
1079 ext ?= extension
1080 Result := ext /= Void
1081 if not Result then
1082 l_const ?= Current
1083 if l_const /= Void then
1084 Result := l_const.written_class.is_external
1085 end
1086 end
1087 ensure
1088 not_is_c_external: Result implies not is_c_external
1089 end
1090
1091 frozen is_c_external: BOOLEAN is
1092 -- Is current feature a C external one?
1093 local
1094 ext: EXTERNAL_EXT_I
1095 do
1096 ext := extension
1097 Result := ext /= Void and then not ext.is_il
1098 ensure
1099 not_is_il_external: Result implies not is_il_external
1100 end
1101
1102 is_process_relative: BOOLEAN is
1103 -- Is feature process-wide (rather than thread-local)?
1104 -- (Usually applies to once routines.)
1105 do
1106 -- False by default
1107 end
1108
1109 has_static_access: BOOLEAN is
1110 -- Can Current be access in a static manner?
1111 local
1112 l_ext: IL_EXTENSION_I
1113 do
1114 Result := (is_constant and not is_once)
1115 if not Result then
1116 if System.il_generation then
1117 l_ext ?= extension
1118 -- Static access only if it is a C external (l_ext = Void)
1119 -- or if IL external does not need an object.
1120 Result :=
1121 (l_ext = Void and (is_external and not has_assertion)) or
1122 (l_ext /= Void and then not l_ext.need_current (l_ext.type))
1123 else
1124 Result := is_external and not has_assertion
1125 end
1126 end
1127 end
1128
1129 frozen has_precondition: BOOLEAN is
1130 -- Is feature declaring some preconditions ?
1131 do
1132 Result := feature_flags & has_precondition_mask = has_precondition_mask
1133 end
1134
1135 frozen has_postcondition: BOOLEAN is
1136 -- Is feature declaring some postconditions ?
1137 do
1138 Result := feature_flags & has_postcondition_mask = has_postcondition_mask
1139 end
1140
1141 has_assertion: BOOLEAN is
1142 -- Is feature declaring some pre or post conditions ?
1143 do
1144 Result := has_postcondition or else has_precondition
1145 end
1146
1147 frozen is_require_else: BOOLEAN is
1148 -- Is precondition block of feature a redefined one ?
1149 do
1150 Result := feature_flags & is_require_else_mask = is_require_else_mask
1151 end
1152
1153 frozen is_ensure_then: BOOLEAN is
1154 -- Is postcondition block of feature a redefined one ?
1155 do
1156 Result := feature_flags & is_ensure_then_mask = is_ensure_then_mask
1157 end
1158
1159 frozen is_fake_inline_agent: BOOLEAN is
1160 -- Is postcondition block of feature a redefined one ?
1161 do
1162 Result := feature_flags & is_fake_inline_agent_mask = is_fake_inline_agent_mask
1163 end
1164
1165 frozen has_rescue_clause: BOOLEAN is
1166 -- Has rescue clause ?
1167 do
1168 Result := feature_flags & has_rescue_clause_mask = has_rescue_clause_mask
1169 end
1170
1171 is_invariant: BOOLEAN is
1172 -- Is this feature the invariant feature of its eiffel class ?
1173 do
1174 Result := False
1175 end
1176
1177 can_be_encapsulated: BOOLEAN is
1178 -- Is current feature a feature that can be encapsulated?
1179 -- Eg: attribute or constant.
1180 do
1181 end
1182
1183 redefinable: BOOLEAN is
1184 -- Is feature redefinable ?
1185 do
1186 Result := not is_frozen
1187 end
1188
1189 undefinable: BOOLEAN is
1190 -- Is feature undefinable ?
1191 do
1192 Result := redefinable
1193 end
1194
1195 has_property: BOOLEAN is
1196 -- Does feature have an associated property?
1197 do
1198 Result := feature_flags & has_property_mask = has_property_mask
1199 end
1200
1201 has_property_getter: BOOLEAN is
1202 -- Does feature have an associated property getter?
1203 do
1204 Result := feature_flags & has_property_getter_mask = has_property_getter_mask
1205 end
1206
1207 has_property_setter: BOOLEAN is
1208 -- Does feature have an associated property setter?
1209 do
1210 Result := feature_flags & has_property_setter_mask = has_property_setter_mask
1211 end
1212
1213 property_name: STRING is
1214 -- IL property name.
1215 do
1216 if byte_server.has (body_index) then
1217 Result := byte_server.item (body_index).property_name
1218 end
1219 if Result = Void or else Result.is_empty then
1220 -- Explicit property name is not specified
1221 Result := il_casing.pascal_casing (system.dotnet_naming_convention, feature_name, {IL_CASING_CONVERSION}.lower_case)
1222 end
1223 ensure
1224 result_attached: Result /= Void
1225 end
1226
1227 type: TYPE_A is
1228 -- Result type of feature
1229 do
1230 Result := void_type
1231 end
1232
1233 set_type (t: like type; a: like assigner_name_id) is
1234 -- Assign `t' to `type' and `a' to `assigner_name_id'.
1235 require
1236 valid_a: a /= 0 implies names_heap.valid_index (a)
1237 do
1238 -- Do nothing
1239 end
1240
1241 arguments: FEAT_ARG is
1242 -- Argument types
1243 do
1244 -- No arguments
1245 end
1246
1247 set_assert_id_set (set: like assert_id_set) is
1248 -- Assign `set' to assert_id_set.
1249 do
1250 -- Do nothing
1251 end
1252
1253 argument_count: INTEGER is
1254 -- Number of arguments of feature
1255 do
1256 if arguments /= Void then
1257 Result := arguments.count
1258 end
1259 end
1260
1261 written_class: CLASS_C is
1262 -- Class where feature is written in
1263 require
1264 good_written_in: written_in /= 0
1265 do
1266 Result := System.class_of_id (written_in)
1267 ensure
1268 written_class_not_void: Result /= Void
1269 end
1270
1271 feature -- Export checking
1272
1273 -- has_special_export: BOOLEAN is
1274 -- -- The export status is special, i.e. feature
1275 -- -- is not exported to all other classes.
1276 -- -- A call to this feature must be recorded specially
1277 -- -- in dependances for incrementality purpose:
1278 -- -- If hierarchy changes, call may be invalid.
1279 -- require
1280 -- has_export_status: export_status /= Void
1281 -- do
1282 -- Result := not export_status.is_all
1283 -- end
1284
1285 is_exported_for (client: CLASS_C): BOOLEAN is
1286 -- Is current feature exported to class `client' ?
1287 require
1288 good_argument: client /= Void
1289 has_export_status: export_status /= Void
1290 do
1291 Result := export_status.valid_for (client)
1292 end
1293
1294 record_suppliers (feat_depend: FEATURE_DEPENDANCE) is
1295 -- Record suppliers ids in `feat_depend'
1296 require
1297 good_arg: feat_depend /= Void
1298 local
1299 type_a: TYPE_A
1300 do
1301 -- Create the supplier set for the feature
1302 type_a := type
1303 if type_a /= Void then
1304 if type_a.has_associated_class then
1305 feat_depend.add_supplier (type_a.associated_class)
1306 end
1307 type_a.update_dependance (feat_depend)
1308 end
1309 if has_arguments then
1310 from
1311 arguments.start
1312 until
1313 arguments.after
1314 loop
1315 type_a := arguments.item
1316 if type_a.has_associated_class then
1317 feat_depend.add_supplier (type_a.associated_class)
1318 end
1319 arguments.forth
1320 end
1321 end
1322 end
1323
1324 suppliers: TWO_WAY_SORTED_SET [INTEGER] is
1325 -- Class ids of all suppliers of feature
1326 require
1327 Tmp_depend_server.has (written_in) or else
1328 Depend_server.has (written_in)
1329 local
1330 class_dependance: CLASS_DEPENDANCE
1331 do
1332 if Tmp_depend_server.has (written_in) then
1333 class_dependance := Tmp_depend_server.item (written_in)
1334 else
1335 class_dependance := Depend_server.item (written_in)
1336 end
1337 Result := class_dependance.item (body_index).suppliers
1338 end
1339
1340 feature -- Check
1341
1342 real_body: BODY_AS is
1343 -- Body of feature
1344 local
1345 feat_as: FEATURE_AS
1346 l_enclosing_feature: FEATURE_I
1347 do
1348 if is_inline_agent then
1349 if not is_fake_inline_agent then
1350 l_enclosing_feature := enclosing_feature
1351 if l_enclosing_feature.is_invariant then
1352 Result := inline_agent_lookup.lookup_inline_agent_of_invariant (
1353 inv_ast_server.item (written_in), inline_agent_nr)
1354 else
1355 Result := inline_agent_lookup.lookup_inline_agent_of_feature (
1356 l_enclosing_feature.body, inline_agent_nr)
1357 end
1358 end
1359 else
1360 feat_as := body
1361 if feat_as /= Void then
1362 Result := feat_as.body
1363 end
1364 end
1365 end
1366
1367 body: FEATURE_AS is
1368 -- Body of feature
1369 local
1370 class_ast: CLASS_AS
1371 bid: INTEGER
1372 do
1373 if body_index > 0 then
1374 bid := body_index
1375 if Tmp_ast_server.body_has (bid) then
1376 Result := Tmp_ast_server.body_item (bid)
1377 elseif Body_server.server_has (bid) then
1378 Result := Body_server.server_item (bid)
1379 end
1380 end
1381 if Result = Void then
1382 if Tmp_ast_server.has (written_in) then
1383 -- Means a degree 4 error has occurred so the
1384 -- best we can do is to search through the
1385 -- class ast and find the feature as
1386 class_ast := Tmp_ast_server.item (written_in)
1387 Result ?= class_ast.feature_with_name (feature_name_id)
1388 end
1389 end
1390 end
1391
1392 -- Note: `require else' can be used even if feature has no
1393 -- precursor. There is no problem to raise an error in normal case,
1394 -- only case where we cannot do anything is when aliases are used
1395 -- and one name references a feature with a predecessor and not
1396 -- other one
1397
1398 -- Used to be called from `type_check':
1399 --
1400 -- check_assertions is
1401 -- -- Raise an error if "require else" or "ensure then" is used
1402 -- -- but feature has no ancestor
1403 -- do
1404 -- end
1405
1406 check_local_names (a_body: BODY_AS) is
1407 -- Check conflicts between local names and feature names
1408 -- for an unchanged feature
1409 do
1410 end
1411
1412 feature -- IL code generation
1413
1414 generate_il is
1415 -- Generate IL code for current feature.
1416 local
1417 byte_code: BYTE_CODE
1418 do
1419 if not is_attribute and then not is_external then
1420 byte_code := Byte_server.item (body_index)
1421 byte_context.set_byte_code (byte_code)
1422 byte_context.set_current_feature (Current)
1423 byte_code.generate_il
1424 byte_context.clear_feature_data
1425 end
1426 end
1427
1428 custom_attributes: BYTE_LIST [BYTE_NODE] is
1429 -- Custom attributes of Current if any.
1430 local
1431 byte_code: BYTE_CODE
1432 do
1433 if not is_attribute and then not is_external and then not is_il_external then
1434 if Byte_server.has (body_index) then
1435 byte_code := Byte_server.item (body_index)
1436 Result := byte_code.custom_attributes
1437 end
1438 end
1439 end
1440
1441 class_custom_attributes: BYTE_LIST [BYTE_NODE] is
1442 -- Class custom attributes of Current if any.
1443 local
1444 byte_code: BYTE_CODE
1445 do
1446 if not is_attribute and then not is_external and then not is_il_external then
1447 if Byte_server.has (body_index) then
1448 byte_code := Byte_server.item (body_index)
1449 Result := byte_code.class_custom_attributes
1450 end
1451 end
1452 end
1453
1454 interface_custom_attributes: BYTE_LIST [BYTE_NODE] is
1455 -- Interface custom attributes of Current if any.
1456 local
1457 byte_code: BYTE_CODE
1458 do
1459 if not is_attribute and then not is_external and then not is_il_external then
1460 if Byte_server.has (body_index) then
1461 byte_code := Byte_server.item (body_index)
1462 Result := byte_code.interface_custom_attributes
1463 end
1464 end
1465 end
1466
1467 property_custom_attributes: BYTE_LIST [BYTE_NODE] is
1468 -- Custom attributes of Current if any.
1469 do
1470 if Byte_server.has (body_index) then
1471 Result := Byte_server.item (body_index).property_custom_attributes
1472 end
1473 end
1474
1475 feature -- Byte code computation
1476
1477 melt (exec: EXECUTION_UNIT) is
1478 -- Generate byte code for current feature
1479 -- [To be redefined in CONSTANT_I, ATTRIBUTE_I and in EXTERNAL_I].
1480 require
1481 good_argument: exec /= Void
1482 local
1483 byte_code: BYTE_CODE
1484 melted_feature: MELT_FEATURE
1485 do
1486 byte_code := Byte_server.item (body_index)
1487
1488 byte_context.set_byte_code (byte_code)
1489 byte_context.set_current_feature (Current)
1490
1491 Byte_array.clear
1492 byte_code.set_real_body_id (exec.real_body_id)
1493 byte_code.make_byte_code (Byte_array)
1494 byte_context.clear_feature_data
1495
1496 melted_feature := Byte_array.melted_feature
1497 melted_feature.set_real_body_id (exec.real_body_id)
1498
1499 if not System.freeze then
1500 Tmp_m_feature_server.put (melted_feature)
1501 end
1502
1503 Execution_table.mark_melted (exec)
1504 end
1505
1506 feature -- Polymorphism
1507
1508 has_entry: BOOLEAN is
1509 -- Has feature an associated polymorphic unit ?
1510 do
1511 Result := True
1512 end
1513
1514 new_poly_table (rout_id: INTEGER): POLY_TABLE [ENTRY] is
1515 -- New polymorphic table
1516 require
1517 positive_rout_id: rout_id > 0
1518 valid_rout_id: rout_id_set.has (rout_id)
1519 local
1520 seed: FEATURE_I
1521 do
1522 if not is_attribute or else not Routine_id_counter.is_attribute (rout_id) then
1523 -- This is a routine.
1524 -- The seed is a routine as well.
1525 create {ROUT_TABLE} Result.make (rout_id)
1526 elseif has_formal then
1527 -- This is an attribute of a formal generic type.
1528 -- The seed is also of a formal generic type.
1529 create {GENERIC_ATTRIBUTE_TABLE} Result.make (rout_id)
1530 else
1531 seed := system.seed_of_routine_id (rout_id)
1532 if seed = Current or else not seed.has_formal then
1533 -- This is an attribute that is not of a formal generic type
1534 -- and its seed is not of a formal generic type.
1535 create {ATTR_TABLE [ATTR_ENTRY]} Result.make (rout_id)
1536 else
1537 -- This is an attribute with a seed of a formal generic type.
1538 create {GENERIC_ATTRIBUTE_TABLE} Result.make (rout_id)
1539 end
1540 end
1541 end
1542
1543 new_entry (rout_id: INTEGER): ENTRY is
1544 -- New polymorphic unit
1545 require
1546 rout_id_not_void: rout_id /= 0
1547 local
1548 r: like new_rout_entry
1549 do
1550 if is_attribute and then Routine_id_counter.is_attribute (rout_id) then
1551 if has_formal or else byte_context.workbench_mode then
1552 r := new_rout_entry
1553 r.set_is_attribute
1554 Result := r
1555 else
1556 Result := new_attr_entry
1557 end
1558 else
1559 Result := new_rout_entry
1560 end
1561 end
1562
1563 new_rout_entry: ROUT_ENTRY is
1564 -- New routine unit
1565 require
1566 not_deferred: not is_deferred
1567 do
1568 create Result
1569 Result.set_body_index (body_index)
1570 Result.set_type_a (type.actual_type)
1571 Result.set_written_in (written_in)
1572 Result.set_pattern_id (pattern_id)
1573 Result.set_feature_id (feature_id)
1574 end
1575
1576 new_attr_entry: ATTR_ENTRY is
1577 -- New attribute unit
1578 require
1579 is_attribute: is_attribute
1580 do
1581 create Result
1582 Result.set_type_a (type.actual_type)
1583 Result.set_feature_id (feature_id)
1584 end
1585
1586 poly_equiv (other: FEATURE_I): BOOLEAN is
1587 -- Is `other' equivalent to Current from polymorphic table
1588 -- implementation point of view ?
1589 require
1590 good_argument: other /= Void
1591 local
1592 is_attr: BOOLEAN
1593 do
1594 is_attr := is_attribute
1595 Result := other.is_attribute = is_attr
1596 and then
1597 type.actual_type.same_as (other.type.actual_type)
1598 if Result then
1599 if is_attr then
1600 Result := feature_id = other.feature_id
1601 else
1602 Result := written_in = other.written_in
1603 and then body_index = other.body_index
1604 and then pattern_id = other.pattern_id
1605 end
1606 end
1607 end
1608
1609 feature -- Signature instantiation
1610
1611 instantiate (parent_type: TYPE_A) is
1612 -- Instantiated signature in context of `parent_type'.
1613 require
1614 good_argument: parent_type /= Void
1615 is_solved: type.is_solved
1616 local
1617 i, nb: INTEGER
1618 old_type: TYPE_A
1619 do
1620 -- Instantiation of the type
1621 old_type ?= type
1622 set_type (old_type.instantiated_in (parent_type), assigner_name_id)
1623 -- Instantiation of the arguments
1624 from
1625 i := 1
1626 nb := argument_count
1627 until
1628 i > nb
1629 loop
1630 old_type ?= arguments.i_th (i)
1631 arguments.put_i_th (old_type.instantiated_in (parent_type), i)
1632 i := i + 1
1633 end
1634 end
1635
1636 instantiation_in (descendant_type: TYPE_A) is
1637 -- Instantiated signature in context of `descendant_type'.
1638 require
1639 good_argument: descendant_type /= Void
1640 is_solved: type.is_solved
1641 local
1642 i, nb: INTEGER
1643 old_type: TYPE_A
1644 do
1645 -- Instantiation of the type
1646 old_type ?= type
1647 set_type (old_type.instantiation_in (descendant_type, written_in), assigner_name_id)
1648 -- Instantiation of the arguments
1649 from
1650 i := 1
1651 nb := argument_count
1652 until
1653 i > nb
1654 loop
1655 old_type ?= arguments.i_th (i)
1656 arguments.put_i_th (old_type.instantiation_in (descendant_type, written_in), i)
1657 i := i + 1
1658 end
1659 end
1660
1661 feature -- Signature checking
1662
1663 check_argument_names (feat_table: FEATURE_TABLE) is
1664 -- Check argument names
1665 require
1666 argument_names_exists: arguments.argument_names /= Void
1667 written_in_class: written_in = feat_table.feat_tbl_id
1668 -- The feature must be written in the associated class
1669 -- of `feat_table'.
1670 local
1671 args: like arguments
1672 arg_id: INTEGER
1673 vreg: VREG
1674 vrfa: VRFA
1675 vpir: VPIR1
1676 i, nb: INTEGER
1677 do
1678 from
1679 args := arguments
1680 i := 1
1681 nb := args.count
1682 until
1683 i > nb
1684 loop
1685 arg_id := args.item_id (i)
1686 -- Searching to find after the current item another one
1687 -- with the same name.
1688 -- We do `i + 1' for the start index because we need to go
1689 -- one step further (+ 1)
1690 if args.argument_position_id (arg_id, i + 1) /= 0 then
1691 -- Two arguments with the same name
1692 create vreg
1693 vreg.set_class (written_class)
1694 vreg.set_feature (Current)
1695 vreg.set_entity_name (Names_heap.item (arg_id))
1696 Error_handler.insert_error (vreg)
1697 end
1698 if feat_table.has_key_id (arg_id) then
1699 -- An argument name is a feature name of the feature
1700 -- table.
1701 create vrfa
1702 vrfa.set_class (written_class)
1703 vrfa.set_feature (Current)
1704 vrfa.set_other_feature (feat_table.found_item)
1705 Error_handler.insert_error (vrfa)
1706 end
1707 if context.is_name_used (arg_id) then
1708 -- An argument name is an argument name of an enclosing feature
1709 create vpir
1710 vpir.set_entity_name (arg_id)
1711 vpir.set_class (written_class)
1712 vpir.set_feature (Current)
1713 Error_handler.insert_error (vpir)
1714 end
1715
1716 i := i + 1
1717 end
1718 end
1719
1720 check_types (feat_table: FEATURE_TABLE) is
1721 -- Check type and arguments types. The objective is
1722 -- to deal with anchored types and genericity. All anchored
1723 -- types are interpreted here and generic parameter
1724 -- instantiated if possible.
1725 local
1726 solved_type: TYPE_A
1727 vffd5: VFFD5
1728 vffd6: VFFD6
1729 vffd7: VFFD7
1730 l_class: CLASS_C
1731 do
1732 l_class := feat_table.associated_class
1733 context.initialize (l_class, l_class.actual_type, feat_table)
1734 context.set_current_feature (Current)
1735 if type.has_like and then is_once then
1736 -- We have an anchored type.
1737 -- Check if the feature is not a once feature
1738 create vffd7
1739 vffd7.set_class (written_class)
1740 vffd7.set_feature_name (feature_name)
1741 Error_handler.insert_error (vffd7)
1742 end
1743 -- Process an actual type for the feature interpret
1744 -- anchored types.
1745 type_a_checker.init_with_feature_table (Current, feat_table, Void, error_handler)
1746 solved_type := type_a_checker.check_and_solved (type, Void)
1747
1748 if feat_table.associated_class = written_class then
1749 type_a_checker.check_type_validity (solved_type, Void)
1750 end
1751
1752 set_type (solved_type, assigner_name_id)
1753 -- Instantitate the feature type in the context of the
1754 -- actual type of the class associated to `feat_table'.
1755
1756 if is_once and then solved_type.has_formal_generic then
1757 -- A once funtion cannot have a type with formal generics
1758 create vffd7
1759 vffd7.set_class (written_class)
1760 vffd7.set_feature_name (feature_name)
1761 Error_handler.insert_error (vffd7)
1762 end
1763 solved_type.check_for_obsolete_class (feat_table.associated_class)
1764
1765 if
1766 is_infix and then
1767 ((argument_count /= 1) or else (type = Void_type))
1768 then
1769 -- Infixed features should have only one argument
1770 -- and must have a return type.
1771 create vffd6
1772 vffd6.set_class (written_class)
1773 vffd6.set_feature_name (feature_name)
1774 Error_handler.insert_error (vffd6)
1775 end
1776 if
1777 is_prefix and then
1778 ((argument_count /= 0) or else (type = Void_type))
1779 then
1780 -- Prefixed features shouldn't have any argument
1781 -- and must have a return type.
1782 create vffd5
1783 vffd5.set_class (written_class)
1784 vffd5.set_feature_name (feature_name)
1785 Error_handler.insert_error (vffd5)
1786 end
1787
1788 if arguments /= Void then
1789 -- Check types of arguments
1790 arguments.check_types (feat_table, Current)
1791 end
1792 end
1793
1794 check_expanded (class_c: CLASS_C) is
1795 -- Check expanded validity rules
1796 require
1797 class_c_not_void: class_c /= Void
1798 type /= Void
1799 local
1800 solved_type: TYPE_A
1801 vtec: VTEC
1802 do
1803 debug ("CHECK_EXPANDED")
1804 io.error.put_string ("Check expanded of ")
1805 io.error.put_string (feature_name)
1806 io.error.put_new_line
1807 end
1808 if class_c.class_id = written_in then
1809 -- Check validity of an expanded result type
1810
1811 -- `set_type' has been called in `check_types' so
1812 -- the reverse assignment is valid.
1813 solved_type ?= type.actual_type
1814 if solved_type.has_expanded then
1815 if solved_type.expanded_deferred then
1816 create {VTEC1} vtec
1817 elseif not solved_type.valid_expanded_creation (class_c) then
1818 create {VTEC2} vtec
1819 elseif system.il_generation and then not solved_type.is_ancestor_valid then
1820 -- Expanded type cannot be based on a class with external ancestor.
1821 create {VTEC3} vtec
1822 end
1823 if vtec /= Void then
1824 -- Report error
1825 vtec.set_class (written_class)
1826 vtec.set_feature (Current)
1827 vtec.set_entity_name (feature_name)
1828 Error_handler.insert_error (vtec)
1829 end
1830 end
1831 if solved_type.has_generics then
1832 system.expanded_checker.check_actual_type (solved_type)
1833 end
1834 if arguments /= Void then
1835 arguments.check_expanded (class_c, Current)
1836 end
1837 end
1838 end
1839
1840 check_signature (old_feature: FEATURE_I; tbl: FEATURE_TABLE) is
1841 -- Check signature conformance beetween Current
1842 -- and inherited feature in `inherit_info' from which Current
1843 -- is a redefinition.
1844 require
1845 old_feature_not_void: old_feature /= Void
1846 tbl_not_void: tbl /= Void
1847 local
1848 old_type, new_type: TYPE_A
1849 l_old_conformance_type, l_new_conformance_type: TYPE_A
1850 i, arg_count: INTEGER
1851 old_arguments: like arguments
1852 current_class: CLASS_C
1853 vdrd51: VDRD51
1854 vdrd52: VDRD52
1855 vdrd53: VDRD53
1856 vdrd6: VDRD6
1857 vdrd7: VDRD7
1858 ve02: VE02
1859 ve02a: VE02A
1860 do
1861 debug ("ACTIVITY")
1862 io.error.put_string ("Check signature of ")
1863 io.error.put_string (feature_name)
1864 io.error.put_new_line
1865 end
1866 current_class := System.current_class
1867
1868 -- Check if an attribute is redefined in an attribute
1869 -- of the same expandedness status
1870 if old_feature.is_attribute and then
1871 (not is_attribute or else
1872 old_feature.type.is_expanded /= type.is_expanded or else
1873 old_feature.type.is_reference /= type.is_reference)
1874 then
1875 create vdrd6
1876 vdrd6.init (old_feature, Current)
1877 Error_handler.insert_error (vdrd6)
1878 end
1879
1880 -- Check if an effective feature is not redefined in a
1881 -- non-effective feature
1882 if (not old_feature.is_deferred) and then is_deferred then
1883 create vdrd7
1884 vdrd7.set_class (current_class)
1885 vdrd7.init (old_feature, Current)
1886 Error_handler.insert_error (vdrd7)
1887 end
1888
1889 old_type ?= old_feature.type
1890 old_type := old_type.actual_argument_type (special_arguments).actual_type
1891 -- `new_type' is the actual type of the redefinition already
1892 -- instantiated
1893 new_type := type.actual_type
1894 debug ("ACTIVITY")
1895 io.error.put_string ("Types:%N")
1896 if old_type /= Void then
1897 io.error.put_string ("old type:%N")
1898 io.error.put_string (old_type.dump)
1899 io.error.put_new_line
1900 end
1901 if new_type /= Void then
1902 io.error.put_string ("new type:%N")
1903 io.error.put_string (new_type.dump)
1904 io.error.put_new_line
1905 else
1906 io.error.put_string ("New type: VOID%Ntype:")
1907 io.error.put_string (type.dump)
1908 io.error.put_new_line
1909 io.error.put_string (type.out)
1910 io.error.put_new_line
1911 end
1912 io.error.put_new_line
1913 end
1914
1915 if not new_type.conform_to (old_type) then
1916 create vdrd51
1917 vdrd51.init (old_feature, Current)
1918 Error_handler.insert_error (vdrd51)
1919 elseif
1920 new_type.is_expanded /= old_type.is_expanded
1921 then
1922 create ve02
1923 ve02.init (old_feature, Current)
1924 -- ve02.set_type (new_type)
1925 -- ve02.set_precursor_type (old_type)
1926 Error_handler.insert_error (ve02)
1927 end
1928
1929 -- Check the argument count
1930 if argument_count /= old_feature.argument_count then
1931 create vdrd52
1932 vdrd52.init (old_feature, Current)
1933 Error_handler.insert_error (vdrd52)
1934 else
1935 -- Check the argument conformance
1936 from
1937 i := 1
1938 arg_count := argument_count
1939 old_arguments := old_feature.arguments
1940 until
1941 i > arg_count
1942 loop
1943 old_type ?= old_arguments.i_th (i)
1944 old_type := old_type.actual_argument_type (special_arguments).actual_type
1945 new_type := arguments.i_th (i).actual_type
1946 debug ("ACTIVITY")
1947 io.error.put_string ("Types:%N")
1948 if old_type /= Void then
1949 io.error.put_string ("old type:%N")
1950 io.error.put_string (old_type.dump)
1951 io.error.put_new_line
1952 end
1953 if new_type /= Void then
1954 io.error.put_string ("new type:%N")
1955 io.error.put_string (new_type.dump)
1956 io.error.put_new_line
1957 end
1958 io.error.put_new_line
1959 end
1960 if not new_type.conform_to (old_type) then
1961 create vdrd53
1962 vdrd53.init (old_feature, Current)
1963 Error_handler.insert_error (vdrd53)
1964 elseif
1965 new_type.is_expanded /= old_type.is_expanded
1966 then
1967 create ve02a
1968 ve02a.init (old_feature, Current)
1969 -- ve02a.set_type (new_type)
1970 -- ve02a.set_precursor_type (old_type)
1971 ve02a.set_argument_number (i)
1972 Error_handler.insert_error (ve02a)
1973 end
1974
1975 l_old_conformance_type := old_type.conformance_type
1976 l_new_conformance_type := new_type.conformance_type
1977
1978 -- Check if it feature contains formals
1979 if
1980 old_type.is_formal or else
1981 new_type.is_formal or else
1982 l_old_conformance_type.is_formal or else
1983 l_new_conformance_type.is_formal
1984 then
1985 system.set_routine_has_formal (rout_id_set, True)
1986 end
1987
1988 -- Check if it is a covariant redeclaration
1989 if
1990 old_type.is_like_current or else
1991 new_type.is_like_current or else
1992 not l_old_conformance_type.same_as (l_new_conformance_type)
1993 then
1994 system.set_routine_covariantly_redefined (rout_id_set, True)
1995 end
1996
1997 i := i + 1
1998 end
1999 end
2000 -- Check aliases
2001 if not is_same_alias (old_feature) then
2002 -- Report that aliases are not the same
2003 Error_handler.insert_error (create {VDRD7_NEW}.make (system.current_class, Current, old_feature))
2004 end
2005 -- Check assigner procedure
2006 if not is_same_assigner (old_feature, tbl) then
2007 -- Report that assigner commands are not the same
2008 Error_handler.insert_error (create {VDRD8_NEW}.make (system.current_class, Current, old_feature))
2009 end
2010 end
2011
2012 check_same_signature (old_feature: FEATURE_I) is
2013 -- Check signature equality beetween Current
2014 -- and inherited feature in `inherit_info' from which Current
2015 -- is a join.
2016 require
2017 good_argument: old_feature /= Void
2018 is_deferred
2019 old_feature.is_deferred
2020 old_feature_is_solved: old_feature.type.is_solved
2021 local
2022 old_type, new_type: TYPE_A
2023 i, arg_count: INTEGER
2024 old_arguments: like arguments
2025 vdjr: VDJR
2026 vdjr1: VDJR1
2027 vdjr2: VDJR2
2028 do
2029 -- Check the result type conformance
2030 -- `old_type' is the instantiated inherited type in the
2031 -- context of the class where the join takes place:
2032 -- i.e the class relative to `written_in'.
2033 old_type ?= old_feature.type
2034 -- `new_type' is the actual type of the join already
2035 -- instantiated
2036 new_type ?= type
2037 if not new_type.is_safe_equivalent (old_type) then
2038 create vdjr1
2039 vdjr1.init (old_feature, Current)
2040 vdjr1.set_type (new_type)
2041 vdjr1.set_old_type (old_type)
2042 Error_handler.insert_error (vdjr1)
2043 end
2044
2045 -- Check the argument count
2046 if argument_count /= old_feature.argument_count then
2047 create vdjr
2048 vdjr.init (old_feature, Current)
2049 Error_handler.insert_error (vdjr)
2050 else
2051
2052 -- Check the argument equality
2053 from
2054 i := 1
2055 arg_count := argument_count
2056 old_arguments := old_feature.arguments
2057 until
2058 i > arg_count
2059 loop
2060 old_type ?= old_arguments.i_th (i)
2061 new_type ?= arguments.i_th (i)
2062 if not new_type.is_safe_equivalent (old_type) then
2063 create vdjr2
2064 vdjr2.init (old_feature, Current)
2065 vdjr2.set_type (new_type)
2066 vdjr2.set_old_type (old_type)
2067 vdjr2.set_argument_number (i)
2068 Error_handler.insert_error (vdjr2)
2069 end
2070 i := i + 1
2071 end
2072 end
2073 -- Check aliases
2074 if not is_same_alias (old_feature) then
2075 -- Report that aliases are not the same
2076 Error_handler.insert_error (create {VDJR2_NEW}.make (system.current_class, Current, old_feature))
2077 end
2078 end
2079
2080 special_arguments: ARRAY [TYPE_A] is
2081 local
2082 i, nb: INTEGER
2083 do
2084 from
2085 fixme ("we should resolve argument types early on in `init_arg' from PROCEDURE_I")
2086 nb := argument_count
2087 create Result.make (1, nb)
2088 i := 1
2089 nb := nb + 1
2090 until
2091 i = nb
2092 loop
2093 Result.put (arguments.i_th (i).actual_type, i)
2094 i := i + 1
2095 end
2096 end
2097
2098 has_same_il_signature (a_parent_type, a_written_type: CL_TYPE_A; old_feature: FEATURE_I): BOOLEAN is
2099 -- Is current feature defined in `a_written_type' same as `old_feature'
2100 -- defined in `a_parent_type'?
2101 require
2102 a_parent_type_not_void: a_parent_type /= Void
2103 a_written_type_not_void: a_written_type /= Void
2104 old_feature_not_void: old_feature /= Void
2105 il_generation: System.il_generation
2106 local
2107 old_type, new_type: TYPE_A
2108 i, arg_count, id: INTEGER
2109 old_arguments: like arguments
2110 do
2111 id := a_written_type.class_id
2112 old_type ?= old_feature.type
2113 old_type := old_type.actual_argument_type (special_arguments).
2114 instantiation_in (a_written_type, a_written_type.class_id).actual_type
2115
2116 new_type := type.actual_type
2117
2118 -- Check exact match of signature for IL generation.
2119 Result := old_type.same_as (new_type)
2120
2121 -- Check the argument conformance
2122 from
2123 i := 1
2124 arg_count := argument_count
2125 old_arguments := old_feature.arguments
2126 until
2127 i > arg_count
2128 loop
2129 old_type ?= old_arguments.i_th (i)
2130 old_type := old_type.actual_argument_type (special_arguments).
2131 instantiation_in (a_written_type, a_written_type.class_id).actual_type
2132
2133 new_type := arguments.i_th (i).actual_type
2134 -- Check exact match of signature for IL generation.
2135 Result := Result and then old_type.same_as (new_type)
2136
2137 i := i + 1
2138 end
2139 end
2140
2141 solve_types (feat_tbl: FEATURE_TABLE) is
2142 -- Evaluates signature types in context of `feat_tbl'.
2143 -- | Take care of possible anchored types
2144 do
2145
2146 set_type
2147 (Result_evaluator.evaluated_type (type, feat_tbl, Current), assigner_name_id)
2148 if arguments /= Void then
2149 arguments.solve_types (feat_tbl, Current)
2150 end
2151 end
2152
2153 same_signature (other: FEATURE_I): BOOLEAN is
2154 -- Has `other' same signature than Current ?
2155 require
2156 good_argument: other /= Void
2157 same_feature_names: feature_name_id = other.feature_name_id
2158 local
2159 i, nb: INTEGER
2160 do
2161 Result := type.is_safe_equivalent (other.type)
2162 from
2163 nb := argument_count
2164 Result := Result and then nb = other.argument_count
2165 nb := argument_count
2166 i := 1
2167 until
2168 i > nb or else not Result
2169 loop
2170 Result := arguments.i_th (i).is_safe_equivalent (other.arguments.i_th (i))
2171 i := i + 1
2172 end
2173 end
2174
2175 argument_position (arg_id: INTEGER): INTEGER is
2176 -- Position of argument `arg_id' in list of arguments
2177 -- of current feature. 0 if none or not found.
2178 require
2179 arg_id_not_void: arg_id >= 0
2180 do
2181 if arguments /= Void then
2182 Result := arguments.argument_position_id (arg_id, 1)
2183 end
2184 end
2185
2186 has_argument_name (arg_id: INTEGER): BOOLEAN is
2187 -- Has current feature an argument named `arg_id" ?
2188 require
2189 arg_id_positive: arg_id > 0
2190 do
2191 if arguments /= Void then
2192 Result := arguments.argument_position_id (arg_id, 1) /= 0
2193 end
2194 end
2195
2196 property_setter_in (class_type: CLASS_TYPE): FEATURE_I is
2197 -- Find an associated property setter in `class_type'.
2198 require
2199 class_type_attached: class_type /= Void
2200 local
2201 f: FEATURE_I
2202 do
2203 if type.is_void then
2204 f := Current
2205 elseif assigner_name_id /= 0 then
2206 f := written_class.feature_table.item_id (assigner_name_id)
2207 else
2208 f := ancestor_property_setter_in (class_type.associated_class)
2209 end
2210 if f /= Void then
2211 Result := class_type.associated_class.feature_of_rout_id (f.rout_id_set.first)
2212 end
2213 ensure
2214 result_attached: (type.is_void or else assigner_name_id /= 0) implies Result /= Void
2215 end
2216
2217 ancestor_property_setter_in (c: CLASS_C): FEATURE_I is
2218 -- Find an property setter routine in some ancestor class of the class `c'.
2219 require
2220 c_not_void: c /= Void
2221 local
2222 parent_classes: FIXED_LIST [CLASS_C]
2223 parent_class: CLASS_C
2224 routine_id: INTEGER
2225 c_id: like origin_class_id
2226 f_id: like origin_feature_id
2227 do
2228 if type.is_void then
2229 Result := c.feature_of_rout_id (rout_id_set.first)
2230 elseif assigner_name_id /= 0 then
2231 Result := written_class.feature_table.item_id (assigner_name_id)
2232 else
2233 c_id := origin_class_id
2234 if c_id = 0 then
2235 c_id := written_in
2236 f_id := feature_id
2237 else
2238 f_id := origin_feature_id
2239 end
2240 routine_id := system.class_of_id (c_id).feature_of_feature_id (f_id).rout_id_set.first
2241 parent_classes := c.parents_classes
2242 if parent_classes /= Void then
2243 from
2244 parent_classes.start
2245 until
2246 parent_classes.after or else Result /= Void
2247 loop
2248 parent_class := parent_classes.item
2249 Result := parent_class.feature_of_rout_id (routine_id)
2250 if Result /= Void then
2251 Result := Result.ancestor_property_setter_in (parent_class)
2252 end
2253 parent_classes.forth
2254 end
2255 end
2256 end
2257 ensure
2258 result_attached: (type.is_void or else assigner_name_id /= 0) implies Result /= Void
2259 end
2260
2261 check_assigner (feature_table: FEATURE_TABLE) is
2262 -- Check if associated assigner is valid.
2263 require
2264 feature_table_not_void: feature_table /= Void
2265 has_assigner: assigner_name_id /= 0
2266 local
2267 assigner: FEATURE_I
2268 assigner_arguments: like arguments
2269 query_arguments: like arguments
2270 vfac: VFAC
2271 do
2272 if system.current_class.class_id = written_in then
2273 -- Lookup feature in `feature_table' as feature table in the current class is not set yet.
2274 assigner := feature_table.item_id (assigner_name_id)
2275 else
2276 assigner := feature_table.origin_table.item
2277 (written_class.feature_named (assigner_name).rout_id_set.first)
2278 end
2279 if assigner = Void or else assigner.has_return_value then
2280 create {VFAC1} vfac.make (system.current_class, Current)
2281 elseif assigner.argument_count /= argument_count + 1 then
2282 create {VFAC2} vfac.make (system.current_class, Current)
2283 elseif not assigner.arguments.first.actual_type.same_as (type.actual_type) then
2284 create {VFAC3} vfac.make (system.current_class, Current)
2285 elseif argument_count > 0 then
2286 assigner_arguments := assigner.arguments
2287 query_arguments := arguments
2288 from
2289 assigner_arguments.start
2290 -- Skip first argument
2291 assigner_arguments.forth
2292 query_arguments.start
2293 until
2294 assigner_arguments.after
2295 loop
2296 if not assigner_arguments.item.actual_type.same_as (query_arguments.item.actual_type) then
2297 create {VFAC4} vfac.make (system.current_class, Current)
2298 assigner_arguments.finish
2299 query_arguments.finish
2300 end
2301 assigner_arguments.forth
2302 query_arguments.forth
2303 end
2304 end
2305 if vfac /= Void then
2306 if assigner /= Void then
2307 vfac.set_assigner (assigner.api_feature (system.current_class.class_id))
2308 end
2309 error_handler.insert_error (vfac)
2310 end
2311 end
2312
2313 feature -- Undefinition
2314
2315 new_deferred: DEF_PROC_I is
2316 -- New deferred feature for undefinition
2317 require
2318 not is_deferred
2319 redefinable
2320 local
2321 ext: EXTERNAL_I
2322 do
2323 if is_function then
2324 create {DEF_FUNC_I} Result
2325 else
2326 create Result
2327 end
2328 Result.set_type (type, assigner_name_id)
2329 Result.set_arguments (arguments)
2330 Result.set_written_in (written_in)
2331 Result.set_origin_feature_id (origin_feature_id)
2332 Result.set_origin_class_id (origin_class_id)
2333 Result.set_rout_id_set (rout_id_set)
2334 Result.set_assert_id_set (assert_id_set)
2335 Result.set_is_selected (is_selected)
2336 Result.set_is_infix (is_infix)
2337 Result.set_is_prefix (is_prefix)
2338 Result.set_is_frozen (is_frozen)
2339 Result.set_feature_name_id (feature_name_id, alias_name_id)
2340 Result.set_feature_id (feature_id)
2341 Result.set_pattern_id (pattern_id)
2342 Result.set_is_require_else (is_require_else)
2343 Result.set_is_ensure_then (is_ensure_then)
2344 Result.set_export_status (export_status)
2345 Result.set_body_index (body_index)
2346 Result.set_has_postcondition (has_postcondition)
2347 Result.set_has_precondition (has_precondition)
2348 Result.set_is_bracket (is_bracket)
2349 Result.set_is_binary (is_binary)
2350 Result.set_is_unary (is_unary)
2351 Result.set_has_convert_mark (has_convert_mark)
2352 Result.set_has_rescue_clause (has_rescue_clause)
2353
2354 if is_external then
2355 ext ?= Current
2356 if ext.extension.is_il then
2357 Result.set_extension (ext.extension)
2358 end
2359 end
2360 ensure
2361 Result_exists: Result /= Void
2362 Result_is_deferred: Result.is_deferred
2363 end
2364
2365 new_rout_id: INTEGER is
2366 -- New routine id
2367 do
2368 Result := Routine_id_counter.next_rout_id
2369 end
2370
2371 Routine_id_counter: ROUTINE_COUNTER is
2372 -- Routine id counter
2373 once
2374 Result := System.routine_id_counter
2375 end
2376
2377 feature -- Replication
2378
2379 code_id: INTEGER is
2380 -- Code id for inheritance analysis
2381 do
2382 Result := body_index
2383 end
2384
2385 set_code_id (i: INTEGER) is
2386 -- Assign `i' to code_id.
2387 do
2388 -- Do nothing
2389 end
2390
2391 access_in: INTEGER is
2392 -- Id of class where current feature can be accessed
2393 -- through its routine id
2394 -- Useful for replication
2395 do
2396 Result := written_in
2397 end
2398
2399 replicated: FEATURE_I is
2400 -- Replicated feature
2401 deferred
2402 ensure
2403 Result /= Void
2404 end
2405
2406 new_code_id: INTEGER is
2407 -- New code id
2408 do
2409 Result := System.body_index_counter.next_id
2410 end
2411
2412 unselected (in: INTEGER): FEATURE_I is
2413 -- Unselected feature
2414 require
2415 in_not_void: in /= 0
2416 deferred
2417 ensure
2418 Result_exists: Result /= Void
2419 end
2420
2421 is_unselected: BOOLEAN is
2422 -- Is current feature an unselected one ?
2423 do
2424 -- Do nothing
2425 end
2426
2427 transfer_to (other: FEATURE_I) is
2428 -- Transfer of datas from Current into `other'.
2429 require
2430 other_exists: other /= Void
2431 do
2432 other.set_body_index (body_index)
2433 other.set_export_status (export_status)
2434 other.set_feature_id (feature_id)
2435 other.set_feature_name_id (feature_name_id, alias_name_id)
2436 other.set_is_frozen (is_frozen)
2437 other.set_is_infix (is_infix)
2438 other.set_is_prefix (is_prefix)
2439 other.set_is_selected (is_selected)
2440 other.set_pattern_id (pattern_id)
2441 other.set_rout_id_set (rout_id_set)
2442 other.set_written_in (written_in)
2443 other.set_written_feature_id (written_feature_id)
2444 other.set_is_origin (is_origin)
2445 other.set_origin_feature_id (origin_feature_id)
2446 other.set_origin_class_id (origin_class_id)
2447 other.set_is_bracket (is_bracket)
2448 other.set_is_binary (is_binary)
2449 other.set_is_unary (is_unary)
2450 other.set_has_convert_mark (has_convert_mark)
2451 end
2452
2453 feature -- Genericity
2454
2455 update_instantiator2 (a_class: CLASS_C) is
2456 -- Look for generic/expanded types in result and arguments in order
2457 -- to update instantiator.
2458 require
2459 good_argument: a_class /= Void
2460 good_context: a_class.changed
2461 local
2462 i, arg_count: INTEGER
2463 do
2464 Instantiator.dispatch (type.actual_type, a_class)
2465 from
2466 i := 1
2467 arg_count := argument_count
2468 until
2469 i > arg_count
2470 loop
2471 Instantiator.dispatch (arguments.i_th (i).actual_type, a_class)
2472 i := i + 1
2473 end
2474 end
2475
2476 feature -- Pattern
2477
2478 pattern: PATTERN is
2479 -- Feature pattern
2480 do
2481 create Result.make (type.actual_type.meta_type)
2482 if argument_count > 0 then
2483 Result.set_argument_types (arguments.pattern_types)
2484 end
2485 end
2486
2487 process_pattern is
2488 -- Process pattern of Current feature
2489 local
2490 p: PATTERN_TABLE
2491 do
2492 p := Pattern_table
2493 p.insert (generation_class_id, pattern)
2494 pattern_id := p.last_pattern_id
2495 end
2496
2497 feature -- Dead code removal
2498
2499 used: BOOLEAN is
2500 -- Is feature used ?
2501 do
2502 if is_inline_agent then
2503 Result := enclosing_feature.used
2504 else
2505 -- In final mode dead code removal process is on.
2506 -- In workbench mode all features are considered
2507 -- used.
2508 Result := byte_context.workbench_mode
2509 or else
2510 System.is_used (Current)
2511 end
2512 end
2513
2514 feature -- Byte code access
2515
2516 frozen access (access_type: TYPE_I; is_qualified: BOOLEAN): ACCESS_B is
2517 -- Byte code access for current feature
2518 require
2519 access_type_not_void: access_type /= Void
2520 do
2521 Result := access_for_feature (access_type, Void, is_qualified)
2522 ensure
2523 Result_exists: Result /= Void
2524 end
2525
2526 frozen access_for_multi_constraint (access_type: TYPE_I; a_static_type: TYPE_I; is_qualified: BOOLEAN): ACCESS_B is
2527 -- Creates a byte code access for a multi constraint target.
2528 -- `a_static_type' is the type where the feature is from.
2529 -- It is NOT a static call that will be generated, but a dynamic one. It is only needed for W_bench.
2530 require
2531 access_type_not_void: access_type /= Void
2532 do
2533 Result := access (access_type, is_qualified)
2534 check Result /= Void end
2535 Result.set_multi_constraint_static (a_static_type)
2536 ensure
2537 Result_exists: Result /= Void
2538 end
2539
2540 access_for_feature (access_type: TYPE_I; static_type: TYPE_I; is_qualified: BOOLEAN): ACCESS_B is
2541 -- Byte code access for current feature. Dynamic binding if
2542 -- `static_type' is Void, otherwise static binding on `static_type'.
2543 require
2544 access_type_not_void: access_type /= Void
2545 local
2546 is_in_op: BOOLEAN
2547 do
2548 is_in_op := written_in = System.function_class_id or else
2549 written_in = System.predicate_class_id or else
2550 written_in = System.procedure_class_id
2551
2552 if is_in_op then
2553 if equal (feature_name, "call") then
2554 create {AGENT_CALL_B} Result.make (Current, access_type, static_type, False)
2555 elseif equal (feature_name, "item") then
2556 create {AGENT_CALL_B} Result.make (Current, access_type, static_type, True)
2557 end
2558 end
2559
2560 if Result = Void then
2561 if written_in = System.any_id then
2562 -- Feature written in ANY.
2563 create {ANY_FEATURE_B} Result.make (Current, access_type, static_type)
2564 else
2565 create {FEATURE_B} Result.make (Current, access_type, static_type)
2566 end
2567 end
2568 ensure
2569 Result_exists: Result /= Void
2570 end
2571
2572 feature {NONE} -- log file
2573
2574 add_in_log (class_type: CLASS_TYPE; encoded_name: STRING) is
2575 do
2576 System.used_features_log_file.add (class_type, feature_name, encoded_name)
2577 end
2578
2579 feature -- C code generation
2580
2581 generate (class_type: CLASS_TYPE; buffer: GENERATION_BUFFER) is
2582 -- Generate feature written in `class_type' in `buffer'.
2583 require
2584 valid_buffer: buffer /= Void
2585 written_in_type: class_type.associated_class.class_id = generation_class_id
2586 not_deferred: not is_deferred
2587 local
2588 byte_code: BYTE_CODE
2589 tmp_body_index: INTEGER
2590 do
2591 if used then
2592 -- `generate' from BYTE_CODE will log the feature name
2593 -- and encoded name in `used_features_log_file' from SYSTEM_I
2594 generate_header (buffer)
2595
2596 tmp_body_index := body_index
2597 if Tmp_opt_byte_server.has (tmp_body_index) then
2598 byte_code := Tmp_opt_byte_server.disk_item (tmp_body_index)
2599 else
2600 byte_code := Byte_server.disk_item (tmp_body_index)
2601 end
2602
2603 -- Generation of C code for an Eiffel feature written in
2604 -- the associated class of the current type.
2605 byte_context.set_byte_code (byte_code)
2606
2607 if System.in_final_mode and then System.inlining_on then
2608 byte_code := byte_code.inlined_byte_code
2609 end
2610
2611 -- Generation of the C routine
2612 byte_context.set_current_feature (Current)
2613 byte_code.analyze
2614 byte_code.set_real_body_id (real_body_id (class_type))
2615 byte_code.generate
2616 byte_context.clear_feature_data
2617
2618 else
2619 System.removed_log_file.add (class_type, feature_name)
2620 end
2621 end
2622
2623 generate_header (buffer: GENERATION_BUFFER) is
2624 -- Generate a header before body of feature
2625 require
2626 valid_buffer: buffer /= Void
2627 do
2628 buffer.put_string ("/* ")
2629 buffer.put_string (feature_name)
2630 buffer.put_string (" */%N%N")
2631 end
2632
2633 feature -- Debug purpose
2634
2635 trace is
2636 -- Debug purpose
2637 do
2638 io.error.put_string ("feature name: ")
2639 io.error.put_string (feature_name)
2640 io.error.put_character (' ')
2641 rout_id_set.trace
2642 io.error.put_string (" {")
2643 io.error.put_string ("fid = ")
2644 io.error.put_integer (feature_id)
2645 io.error.put_string ("}");
2646 io.error.put_string (" {")
2647 io.error.put_string ("body_index = ")
2648 io.error.put_integer (body_index)
2649 io.error.put_string ("}");
2650 io.error.put_string (" {")
2651 io.error.put_string ("written in = ")
2652 io.error.put_string (written_class.name)
2653 io.error.put_string ("}");
2654 io.error.put_string (" {")
2655 io.error.put_string ("body_index = ")
2656 if body_index > 0 then
2657 io.error.put_integer (body_index)
2658 else
2659 io.error.put_integer (0)
2660 end
2661 io.error.put_new_line
2662 end
2663
2664 feature -- Debugging
2665
2666 is_debuggable: BOOLEAN is
2667 local
2668 wc: CLASS_C
2669 do
2670 if (not is_external)
2671 and then (not is_attribute)
2672 and then (not is_constant)
2673 and then (not is_deferred)
2674 and then (not is_unique)
2675 then
2676 wc := written_class
2677 Result := (not wc.is_basic)
2678 and then (wc.has_types)
2679 end
2680 end
2681
2682 real_body_id (class_type: CLASS_TYPE): INTEGER is
2683 -- Real body id at compilation time for `class_type'.
2684 -- This id might be obsolete after supermelting this feature.
2685 --| In latter case, new real body id is kept
2686 --| in DEBUGGABLE objects.
2687 require
2688 valid_body_id: valid_body_id
2689 local
2690 exec_unit: EXECUTION_UNIT
2691 old_group: CONF_GROUP
2692 do
2693 old_group := Inst_context.group
2694 Inst_context.set_group (written_class.group)
2695
2696 -- Search for associated EXECUTION_UNIT
2697 create exec_unit.make (class_type)
2698 exec_unit.set_body_index (body_index)
2699 -- `exec_unit' can be absent in `Execution_table' if a feature is just added
2700 if Execution_table.has (exec_unit) then
2701 Execution_table.search (exec_unit)
2702 exec_unit := Execution_table.last_unit
2703 Result := exec_unit.real_body_id
2704 end
2705 Inst_context.set_group (old_group)
2706 end
2707
2708 valid_body_id: BOOLEAN is
2709 -- Use of this routine as precondition for real_body_id.
2710 do
2711 Result := ((not is_attribute)
2712 and then (not is_constant)
2713 and then (not is_deferred)
2714 and then (not is_unique)
2715 and then written_class.has_types)
2716 or else
2717 (is_constant and is_once)
2718 end
2719
2720 feature -- Api creation
2721
2722 e_feature: E_FEATURE is
2723 do
2724 Result := api_feature (written_in)
2725 end
2726
2727 api_feature (a_class_id: INTEGER): E_FEATURE is
2728 -- API representation of Current
2729 require
2730 a_class_id_positive: a_class_id > 0
2731 local
2732 e_routine: E_ROUTINE
2733 do
2734 Result := new_api_feature
2735 Result.set_written_feature_id (written_feature_id)
2736 Result.set_written_in (written_in)
2737 Result.set_associated_class_id (a_class_id)
2738 Result.set_body_index (body_index)
2739 Result.set_is_origin (is_origin)
2740 Result.set_export_status (export_status)
2741 Result.set_is_frozen (is_frozen)
2742 Result.set_is_infix (is_infix)
2743 Result.set_is_prefix (is_prefix)
2744 Result.set_rout_id_set (rout_id_set)
2745 Result.set_is_il_external (is_il_external)
2746 if is_inline_agent then
2747 e_routine ?= Result
2748 e_routine.set_enclosing_body_id (enclosing_body_id)
2749 e_routine.set_inline_agent_nr (inline_agent_nr)
2750 end
2751 end
2752
2753 feature {NONE} -- Implementation
2754
2755 new_api_feature: E_FEATURE is
2756 -- API feature creation
2757 deferred
2758 ensure
2759 non_void_result: Result /= Void
2760 end
2761
2762 feature_flags: INTEGER_32
2763 -- Property of Current feature, i.e. frozen,
2764 -- infix, origin, prefix, selected...
2765
2766 is_frozen_mask: INTEGER_32 is 0x0001
2767 is_origin_mask: INTEGER_32 is 0x0002
2768 is_empty_mask: INTEGER_32 is 0x0004
2769 is_infix_mask: INTEGER_32 is 0x0008
2770 is_prefix_mask: INTEGER_32 is 0x0010
2771 is_require_else_mask: INTEGER_32 is 0x0020
2772 is_ensure_then_mask: INTEGER_32 is 0x0040
2773 has_precondition_mask: INTEGER_32 is 0x0080
2774 has_postcondition_mask: INTEGER_32 is 0x0100
2775 is_bracket_mask: INTEGER_32 is 0x0200
2776 is_binary_mask: INTEGER_32 is 0x0400
2777 is_unary_mask: INTEGER_32 is 0x0800
2778 has_convert_mark_mask: INTEGER_32 is 0x1000
2779 has_property_mask: INTEGER_32 is 0x2000
2780 has_property_getter_mask: INTEGER_32 is 0x4000
2781 has_property_setter_mask: INTEGER_32 is 0x8000
2782 is_fake_inline_agent_mask: INTEGER_32 is 0x10000
2783 has_rescue_clause_mask: INTEGER_32 is 0x20000
2784 -- Mask used for each feature property.
2785
2786 feature {INHERIT_TABLE} -- Access
2787
2788 private_external_name_id: INTEGER
2789 -- External name id of feature if any in IL generation.
2790
2791 private_external_name: STRING is
2792 -- External name of feature if any in IL generation.
2793 require
2794 valid_private_external_name_id: private_external_name_id > 0
2795 do
2796 Result := Names_heap.item (private_external_name_id)
2797 ensure
2798 Result_not_void: Result /= Void
2799 Result_not_empty: not Result.is_empty
2800 end
2801
2802 feature {NONE} -- Debug output
2803
2804 debug_output: STRING is
2805 -- Textual representation of current feature for debugging.
2806 do
2807 Result := feature_name
2808 if Result = Void then
2809 Result := "Name not yet assigned"
2810 end
2811 end
2812
2813 invariant
2814 valid_enclosing_feature: is_inline_agent implies enclosing_body_id > 0
2815 valid_inline_agent_nr: is_inline_agent implies inline_agent_nr > 0
2816
2817 indexing
2818 copyright: "Copyright (c) 1984-2006, Eiffel Software"
2819 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
2820 licensing_options: "http://www.eiffel.com/licensing"
2821 copying: "[
2822 This file is part of Eiffel Software's Eiffel Development Environment.
2823
2824 Eiffel Software's Eiffel Development Environment is free
2825 software; you can redistribute it and/or modify it under
2826 the terms of the GNU General Public License as published
2827 by the Free Software Foundation, version 2 of the License
2828 (available at the URL listed under "license" above).
2829
2830 Eiffel Software's Eiffel Development Environment is
2831 distributed in the hope that it will be useful, but
2832 WITHOUT ANY WARRANTY; without even the implied warranty
2833 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
2834 See the GNU General Public License for more details.
2835
2836 You should have received a copy of the GNU General Public
2837 License along with Eiffel Software's Eiffel Development
2838 Environment; if not, write to the Free Software Foundation,
2839 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2840 ]"
2841 source: "[
2842 Eiffel Software
2843 356 Storke Road, Goleta, CA 93117 USA
2844 Telephone 805-685-1006, Fax 805-685-6869
2845 Website http://www.eiffel.com
2846 Customer support http://support.eiffel.com
2847 ]"
2848
2849 end

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23