/[eiffelstudio]/branches/CAT_mono/Src/Eiffel/eiffel/inheritance/inherit_table.e
ViewVC logotype

Contents of /branches/CAT_mono/Src/Eiffel/eiffel/inheritance/inherit_table.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: 52285 byte(s)
fixed missing locals
1 indexing
2 description: "[
3 Table of inherited features indexed by name ID: feature `pass2' is
4 second pass of compiler.
5 ]"
6 legal: "See notice at end of class."
7 status: "See notice at end of class."
8 date: "$Date$"
9 revision: "$Revision$"
10
11 class
12 INHERIT_TABLE
13
14 inherit
15 HASH_TABLE [INHERIT_FEAT, INTEGER]
16 rename
17 make as extend_tbl_make,
18 merge as extend_table_merge
19 end
20
21 SHARED_SERVER
22 export
23 {ANY} all
24 undefine
25 copy, is_equal
26 end
27
28 SHARED_SELECTED
29 undefine
30 copy, is_equal
31 end
32
33 SHARED_ERROR_HANDLER
34 export
35 {ANY} error_handler
36 undefine
37 copy, is_equal
38 end
39
40 SHARED_INST_CONTEXT
41 undefine
42 copy, is_equal
43 end
44
45 SHARED_ORIGIN_TABLE
46 undefine
47 copy, is_equal
48 end
49
50 SHARED_ID_TABLES
51 undefine
52 copy, is_equal
53 end
54
55 SHARED_DEGREES
56 undefine
57 copy, is_equal
58 end
59
60 SHARED_RESCUE_STATUS
61 undefine
62 copy, is_equal
63 end
64
65 SHARED_STATELESS_VISITOR
66 export
67 {NONE} all
68 undefine
69 copy, is_equal
70 end
71
72 SHARED_IL_CASING
73 export
74 {NONE} all
75 undefine
76 copy, is_equal
77 end
78
79 SHARED_NAMES_HEAP
80 export
81 {NONE} all
82 undefine
83 copy, is_equal
84 end
85
86 COMPILER_EXPORTER
87 undefine
88 copy, is_equal
89 end
90
91 create
92 make
93
94 feature {NONE} -- Initialization
95
96 make (n: INTEGER) is
97 -- Hash table creation
98 do
99 default_size := n
100 extend_tbl_make (n)
101 create inherited_features.make (n)
102 create changed_features.make (100)
103 create origins.make (100)
104 end
105
106 feature
107
108 default_size: INTEGER
109 -- Default size for `inherited_features'.
110
111 inherited_features: FEATURE_TABLE;
112 -- Table of inherited features.
113 -- It is calculated by feature `analyse'.
114
115 a_class: CLASS_C;
116 -- Current class to analyze
117
118 feature_table: FEATURE_TABLE;
119 -- Previous feature table of the class `a_class': processed
120 -- by feature `analyze_declarations'; if the class has never
121 -- been compiled before, this attribute will be created
122 -- and empty before the analysis of the local declarations
123
124 previous_feature_table: FEATURE_TABLE;
125 -- Previous feature table processed during a second pass,
126 -- and put in the temporary server only.
127 --| Useful for the processing of feature ids
128
129 class_info: CLASS_INFO;
130 -- Information about current class analyzed: it contains
131 -- a compild form of parents, a reference on the feature
132 -- list produced by the first pass and indexes left by
133 -- the temporary AST server (`Tmp_ast_server') when the
134 -- abstract syntax tree of the current analyzed class
135 -- has been put in it.
136 -- (actually we have here the offsets in the (future) file
137 -- ".AST" of the abstract represention of the features).
138
139 parents: PARENT_LIST;
140 -- Compiled form of the parents of the current analyzed class
141
142 changed_features: ARRAYED_LIST [INTEGER];
143 -- Changed features of `a_class'.
144
145 invariant_changed: BOOLEAN;
146 -- Did the invariant clause changed ?
147
148 invariant_removed: BOOLEAN;
149 -- Is the invariant clause removed ?
150
151 origins: ARRAYED_LIST [INTEGER];
152 -- Origin features name list for pattern processing
153
154 supplier_status_modified: BOOLEAN;
155 -- The status (expanded, deferred) of a supplier has changed
156
157 assert_prop_list: LINKED_LIST [INTEGER];
158 -- List of routine ids for assertion modifications
159
160 adaptations: LINKED_LIST [FEATURE_ADAPTATION] is
161 -- List of redefinitions and joins
162 once
163 create Result.make
164 end;
165
166 pass2_control: PASS2_CONTROL
167 -- Second pass controler, needs to be an attribute since
168 -- used by `pass2' and `feature_unit'.
169
170 pass2 (pass_c: CLASS_C; is_supplier_status_modified: BOOLEAN) is
171 -- Second pass of the compiler on class `cl'. The ultimate
172 -- goal here is to calculate the feature table `inherited_features'.
173 require
174 pass_c_not_void: pass_c /= Void
175 class_info_exists: Class_info_server.has (pass_c.class_id);
176 local
177 class_id: INTEGER;
178 resulting_table: like inherited_features;
179 pass3_control: PASS3_CONTROL;
180 depend_unit: DEPEND_UNIT;
181 old_creators, new_creators: HASH_TABLE [EXPORT_I, STRING];
182 old_convert_to, old_convert_from: DS_HASH_TABLE [INTEGER, NAMED_TYPE_A]
183 creation_name: STRING;
184 equiv_tables: BOOLEAN;
185 do
186 a_class := pass_c
187 -- Store previous data
188 old_creators := a_class.creators
189 old_convert_to := a_class.convert_to
190 old_convert_from := a_class.convert_from
191
192 create pass2_control.make
193
194 if System.il_generation then
195 a_class.init_class_interface
196 end
197
198 supplier_status_modified := is_supplier_status_modified;
199
200 -- Initialization of the context for evaluation of actual
201 -- types
202 Inst_context.set_group (a_class.group)
203
204 -- Empty the selection control list
205 Selected.wipe_out;
206 class_id := a_class.class_id;
207
208 -- Look for the interpreted class information left
209 -- by the first pass if the class has syntactically changed.
210 class_info := Class_info_server.item (class_id)
211
212 -- Extract `computed_parents' from current class an reset
213 -- it as it is not needed that we store this information
214 -- since it is only used in `pass2'.
215 parents := a_class.computed_parents
216
217 -- Compute attribute `feature_table'.
218 compute_feature_table;
219
220 -- Check generic parents of the class
221 a_class.check_parents
222
223 -- Merge parents table: the topological sort and the
224 -- sort of list `changed_classes' of the system ensures
225 -- that the second pass has been applied to the parents
226 -- of class `cl' before.
227 -- We also check if renamed features are available
228 parents.merge_and_check_renamings (Current)
229
230 Error_handler.checksum;
231 -- Treat the renamings
232 --| Needs to be done twice
233 --| a is processed
234 --| if `rename b as a' is done afterwards, we need to
235 --| reprocess the inherit_feat for a again.
236 check_renamings;
237 check_renamings;
238 -- Analyze features inherited under the same final name
239 analyze;
240 -- Check adaptation clauses of parents
241 parents.check_validity2;
242 -- Check-sum error after analysis fo the inherited
243 -- features
244 Error_handler.checksum;
245
246 -- Analyze local features
247 if a_class.changed then
248 -- Remove all changed features if any
249 a_class.changed_features.clear_all;
250 -- Class `a_class' is syntactically changed
251 analyze_declarations;
252 -- No update of `Instantiator' if there is an error
253 Error_handler.checksum;
254 -- Look for generic types in the inheritance clause
255 -- of a syntactically changed class
256 a_class.update_instantiator1;
257 else
258 -- The class didn't syntactically changed but, one
259 -- or more ancestor has a new feature table.
260 recompute_declarations;
261 end;
262
263 -- Check the redefine and select clause, and kepp track
264 -- of possible joins between deferred features
265 check_validity2;
266
267 -- Computes a good size for the feature table
268 resulting_table := inherited_features.twin
269
270 -- Check redeclarations into an attribute
271 check_redeclarations (resulting_table);
272
273 -- Check sum
274 Error_handler.checksum;
275
276 -- Compute selection table
277 Origin_table.compute_feature_table (parents, feature_table, resulting_table);
278 resulting_table.set_origin_table (Origin_table.computed);
279 -- Check sum error: because of possible bad selections,
280 -- anchored types on features could not be evaluated here.
281 Error_handler.checksum;
282
283 -- Check types in the feature table
284 resulting_table.check_table;
285 -- Check the adaptations
286 check_validity3 (resulting_table);
287 -- Check useless selections
288 parents.check_validity4;
289
290 -- Creators processing
291 a_class.set_creators (class_info.creation_table (resulting_table));
292 -- No update of `Instantiator' if there is an error
293 Error_handler.checksum;
294
295 -- Convertibility processing
296 -- Note: Manu 04/23/2003: Do we need to make a once of `CONVERTIBILITY_CHECKER'?
297 -- At the moment no as it does not seem expensive to create it all the time.
298 (create {CONVERTIBILITY_CHECKER}).init_and_check_convert_tables (
299 a_class, resulting_table, class_info.convertors)
300 Error_handler.checksum
301
302 -- Track generic types in the result and arguments of
303 -- features of a changed class
304 if a_class.changed then
305 -- Generic types tracking
306 resulting_table.update_instantiator2;
307 -- Compute invariant clause
308 compute_invariant;
309 end;
310
311 -- Check sum error
312 Error_handler.checksum;
313 check
314 No_error: not Error_handler.has_error;
315 end;
316
317 -- Pass2 controler evaluation
318 feature_table.fill_pass2_control (pass2_control, resulting_table);
319 if previous_feature_table /= Void then
320 -- Add the modifications done since the last unsuccessful compilation
321 previous_feature_table.fill_pass2_control (pass2_control, resulting_table);
322 end;
323
324 -- Process externals
325 if a_class.changed then
326 pass2_control.process_externals
327 end;
328
329 -- Insert the changed creators in the propagators list
330 new_creators := a_class.creators;
331 if old_creators = Void then
332 if
333 new_creators /= Void
334 or else (a_class.is_deferred and then pass_c.deferred_modified)
335 then
336 -- the clients using !! without a creation routine
337 -- must be recompiled
338 debug ("ACTIVITY")
339 io.error.put_string ("Insert -1 in the propagators%N");
340 if new_creators /= Void then
341 io.error.put_string ("Creators have been added");
342 else
343 io.error.put_string ("The class is now deferred%N");
344 end;
345 end;
346 if a_class.is_used_as_expanded then
347 create depend_unit.make_expanded_unit (a_class.class_id);
348 pass2_control.propagators.extend (depend_unit)
349 end;
350 create depend_unit.make_creation_unit (a_class.class_id);
351 pass2_control.propagators.extend (depend_unit)
352 end;
353 else
354 from
355 old_creators.start
356 until
357 old_creators.after
358 loop
359 creation_name := old_creators.key_for_iteration;
360 if
361 new_creators = Void
362 or else
363 not new_creators.has (creation_name)
364 or else
365 -- The new export status is more restrictive than the old one
366 not old_creators.item_for_iteration.equiv (new_creators.item (creation_name))
367 then
368 if resulting_table.has (creation_name) then
369 -- The routine is not a creation routine any more
370 -- or the export status has changed
371 debug ("ACTIVITY")
372 io.error.put_string ("Creators: ");
373 io.error.put_string (creation_name);
374 io.error.put_string (" inserted in pass2_control.propagators%N");
375 end;
376 create depend_unit.make (a_class.class_id, resulting_table.found_item);
377 pass2_control.propagators.extend (depend_unit);
378 end;
379 end;
380 old_creators.forth
381 end;
382 if a_class.is_used_as_expanded and then
383 (new_creators = Void or else new_creators.count > 1)
384 then
385 create depend_unit.make_expanded_unit (a_class.class_id);
386 pass2_control.propagators.extend (depend_unit)
387 end;
388 old_creators := Void
389 end;
390
391 -- Insert removed routines from convert clauses into propagators list.
392 if old_convert_to /= Void then
393 update_convert_clause (old_convert_to, a_class.convert_to, resulting_table)
394 end
395 if old_convert_from /= Void then
396 update_convert_clause (old_convert_from, a_class.convert_from, resulting_table)
397 end
398
399 -- Remember the removed features written in `a_class'
400 pass3_control := a_class.propagators;
401 pass3_control.set_removed_features (pass2_control.removed_features);
402 pass3_control.set_invariant_changed (invariant_changed);
403 pass3_control.set_invariant_removed (invariant_removed);
404
405 -- Update the assert_id_set of redefined features.
406 update_inherited_assertions;
407
408 if previous_feature_table /= Void then
409 -- If there is a table in the tmp server,
410 -- the propagation is done again only if the new
411 -- table is different.
412 equiv_tables := resulting_table.equiv (previous_feature_table, pass2_control)
413 else
414 -- There is no table in the tmp server, see if the
415 -- new feature table is equivalent to the old one
416 equiv_tables := resulting_table.equiv (feature_table, pass2_control);
417 end;
418
419 -- Propagation
420 Degree_4.propagate (pass_c, resulting_table, equiv_tables,
421 pass2_control, assert_prop_list);
422 assert_prop_list := Void;
423
424 -- Process paterns of origin features
425 process_pattern (resulting_table);
426
427 -- Ensure a wrapper is generated for attributes of a formal generic type.
428 mark_generic_attribute_seeds (resulting_table)
429
430 -- Line removed by Frederic Deramat 15/04/92.
431 --
432 -- *** resulting_table.process_polymorphism (feature_table); ***
433 --
434 -- The "polymorphical tables" are not generated in workbench mode
435 -- anymore (replaced by "offset descriptors"). Nevertheless, the
436 -- facility is still used to produce finalized code, but
437 -- "polymorphical tables" are in no case stored to disk (only
438 -- generated temporarily in final mode in order to generate the
439 -- static C routine tables.
440
441 if System.il_generation then -- and then not a_class.is_external then
442 a_class.class_interface.process_features (resulting_table)
443 end
444
445 -- Instantiate generic parameter in context of current
446 -- class.
447 a_class.update_generic_features
448
449 -- Find main_parent of current class.
450 if System.il_generation then
451 compute_main_parent (resulting_table)
452 end
453
454 -- Put the resulting table in the temporary feature table
455 -- server.
456 Tmp_feat_tbl_server.put (resulting_table);
457 debug ("HAS_CALLS", "TRACE_TABLE")
458 resulting_table.trace_replications;
459 resulting_table.trace;
460 end;
461 -- Update table `changed_features' of `a_class'.
462 update_changed_features;
463 clear;
464 ensure
465 No_error: not Error_handler.has_error;
466 rescue
467 if Rescue_status.is_error_exception then
468 -- Error happened during second pass: clear the
469 -- structure
470 clear;
471 if a_class.changed then
472 -- Reset the old creation table
473 a_class.set_creators (old_creators);
474 end;
475 end;
476 end;
477
478 compute_feature_table is
479 -- Compute attribute `feature_table'. Look for a previous
480 -- feature table.
481 require
482 a_class /= Void
483 local
484 id: INTEGER;
485 do
486 id := a_class.class_id;
487 -- Look for a previous feature table in server `Feat_tbl_server'
488 -- nb: we don't have to look for it in the temporary server
489 -- for feature table here, that's why we are using feature
490 -- `server_item' of class FEAT_TBL_SERVER.
491 if Feat_tbl_server.server_has (id) then
492 -- We have a previous compiled class
493 feature_table := Feat_tbl_server.server_item (id);
494 feature_table.update_table;
495 else
496 -- No previous compilation
497 feature_table := Empty_table;
498 end;
499 -- Prepare `inherited_features'.
500 inherited_features.set_feat_tbl_id (id);
501 -- Compute `previous_feature_table'.
502 if Tmp_feat_tbl_server.has (id) then
503 -- There was an error and a feature table has been already
504 -- computed for this class.
505 previous_feature_table := Tmp_feat_tbl_server.item (id);
506 previous_feature_table.update_table;
507 end;
508 end;
509
510 Empty_table: FEATURE_TABLE is
511 -- Empty feature table
512 local
513 select_table: SELECT_TABLE;
514 once
515 create select_table.make (1);
516 create Result.make (1);
517 Result.set_origin_table (select_table);
518 end;
519
520 merge (parent_c: PARENT_C) is
521 -- Merge feature table of parent `cl' into
522 -- a data structure to analyse.
523 local
524 parent: CLASS_C
525 -- Parent class
526 parent_table: FEATURE_TABLE;
527 -- Feature table of the parent `parent_c'
528 info: INHERIT_INFO
529 -- Information on one inherited feature
530 feature_i: FEATURE_I
531 -- Inherited feature
532 parent_type: LIKE_CURRENT
533 -- "like Current" type of `parent_c'
534 do
535 from
536 parent := parent_c.parent
537 create parent_type
538 parent_type.set_actual_type (parent_c.parent_type)
539 -- Look for the parent table on the disk
540 parent_table := Feat_tbl_server.item (parent.class_id)
541 check
542 parent_table_exists: parent_table /= Void;
543 -- Because of topological sort, the parents are
544 -- necessary analyzed (if needed) before class
545 -- `a_class'. Redefinition of feature `item' in
546 -- class FEAT_TBL_SERVER will look for the table
547 -- in the file `Tmp_feat_tbl_file' and then
548 -- in the file `Feat_tbl_file'.
549 end;
550
551 -- Iteration on the parent feature table
552 parent_table.start;
553 until
554 parent_table.after
555 loop
556 -- Take one feature
557 feature_i := parent_table.item_for_iteration.duplicate
558
559 -- Instantiation of the feature in its parent
560 feature_i.instantiate (parent_type)
561
562 -- Creation of an inherited feature information unit
563 create info.make (feature_i)
564 info.set_parent (parent_c)
565
566 -- Add the information to the concerned instance of
567 -- INHERIT_FEAT
568 add_inherited_feature (info, feature_i.feature_name_id)
569 parent_table.forth
570 end
571 end
572
573 add_inherited_feature (info: INHERIT_INFO; feature_name_id: INTEGER) is
574 -- Add an inherited feature in the table.
575 local
576 l: INHERIT_FEAT
577 do
578 l := item (feature_name_id)
579 if l = Void then
580 -- Take a new object from the free list
581 create l.make
582 put (l, feature_name_id)
583 end
584 -- Add the information to the concerned instance of
585 -- INHERIT_FEAT
586 l.insert (info)
587 end
588
589 check_renamings is
590 -- Check all the renamings made in the table of
591 -- inherited features
592 local
593 l: like linear_representation
594 do
595 from
596 l := linear_representation
597 l.start
598 until
599 l.after
600 loop
601 -- Check the renamings on one name
602 l.item.check_renamings
603 l.forth
604 end
605 end
606
607 analyze is
608 -- Analyze inherited features: the renamings must have
609 -- been treated before
610 require
611 a_class /= Void;
612 feature_table /= Void;
613 local
614 feature_name_id: INTEGER;
615 inherit_feat: INHERIT_FEAT;
616 inherited_info: INHERIT_INFO;
617 feature_i: FEATURE_I;
618 def: DEFINITION;
619 do
620 from
621 -- Iteration on the structure
622 start
623 until
624 after
625 loop
626 -- Calculates an inherited feature: instance of
627 -- FEATURE_I
628 inherit_feat := item_for_iteration;
629 feature_name_id := key_for_iteration;
630
631 -- Calculates attribute `inherited_feature' of
632 -- instance `inherit_feat'.
633 inherit_feat.process (a_class, feature_name_id)
634 inherited_info := inherit_feat.inherited_info;
635 if inherited_info /= Void then
636 -- Class inherit from a feature coming from one
637 -- parent.
638 feature_i := inherited_info.a_feature;
639 -- Feature name
640 feature_i.set_feature_name_id (feature_name_id, feature_i.alias_name_id)
641 -- initialization of an inherited feature
642 init_inherited_feature (feature_i, inherit_feat);
643 -- Insertion in the origin table
644 inherited_info.set_a_feature (feature_i);
645 if not feature_i.is_deferred
646 and then
647 inherit_feat.nb_deferred > 0
648 then
649 -- Case of an implementation of inherited deferred
650 -- features by an inherited non-deferred feature
651 create def.make (inherit_feat, feature_i);
652 -- Reset assertions of `feature_i'
653 adaptations.put_front (def);
654 else
655 Origin_table.insert (inherited_info);
656 end;
657 end;
658 forth
659 end;
660 end;
661
662 analyze_declarations is
663 -- Analyze local declarations written in the class for a
664 -- syntactically changed class.
665 local
666 feature_clause: FEATURE_CLAUSE_AS;
667 features: EIFFEL_LIST [FEATURE_AS];
668 -- Reference on the feature list produced by the first pass
669 single_feature: FEATURE_AS;
670 -- Single standard Eiffel feature
671 name_list: EIFFEL_LIST [FEATURE_NAME];
672 -- Attribute list names
673 feature_i: FEATURE_I;
674 feat_name: FEATURE_NAME;
675 clauses: EIFFEL_LIST [FEATURE_CLAUSE_AS];
676 l_export_status: EXPORT_I;
677 property_name: STRING
678 property_names: HASH_TABLE [FEATURE_I, STRING]
679 do
680 clauses := class_info.features;
681 if clauses /= Void then
682 if system.il_generation then
683 create property_names.make (0)
684 end
685 from
686 clauses.start
687 until
688 clauses.after
689 loop
690 feature_clause := clauses.item;
691 -- Evaluation of the export status
692 l_export_status := export_status_generator.
693 feature_clause_export_status (a_class, feature_clause)
694 from
695 -- Iteration of the feature written in class
696 -- `a_class'.
697 features := feature_clause.features;
698 features.start;
699 until
700 features.after
701 loop
702 single_feature := features.item;
703 from
704 name_list := single_feature.feature_names;
705 name_list.start;
706 until
707 name_list.after
708 loop
709 feat_name := name_list.item;
710 -- Computes an internal name for the feature
711 -- taking care of prefix/infix notations
712 feature_i := feature_unit (single_feature, feat_name);
713 -- Attributes `body_index', `feature_name' and
714 -- `written_in' are ok now. If it is an old
715 -- instance of FEATURE_I from a previous
716 -- compilation, we know if it was an origin.
717 analyze_local (feature_i, feature_i.feature_name_id)
718 -- Set the export status
719 feature_i.set_export_status (l_export_status);
720 if property_names /= Void then
721 -- Check that there are no property name clashes
722 if feature_i.has_property then
723 property_name := single_feature.property_name
724 if property_name = Void or else property_name.is_empty then
725 -- Use implicit property name.
726 property_name := il_casing.pascal_casing
727 (system.dotnet_naming_convention, feature_i.feature_name, {IL_CASING_CONVERSION}.lower_case)
728 end
729 if property_names.has (property_name) then
730 error_handler.insert_error (create {VIPM}.make
731 (a_class, feature_i, property_names.item (property_name), property_name))
732 else
733 property_names.put (feature_i, property_name)
734 end
735 -- Check that there are no property setters with
736 -- several arguments as order of the arguments is
737 -- different in Eiffel and IL.
738 if feature_i.has_property_setter and then
739 (feature_i.type.is_void and then feature_i.argument_count /= 1 or else
740 not feature_i.type.is_void and then feature_i.argument_count > 0)
741 then
742 error_handler.insert_error (create {VIPS}.make (a_class, feature_i))
743 end
744 end
745 end
746 name_list.forth;
747 end;
748
749 features.forth;
750 end;
751 clauses.forth;
752 end;
753 end;
754 end;
755
756 recompute_declarations is
757 -- Recompute local declarations for a non-syntactically changed
758 -- class.
759 require
760 good_class: a_class /= Void;
761 non_syntactically_changed: a_class.changed2;
762 local
763 feature_i: FEATURE_I;
764 feature_name_id: INTEGER;
765 id: INTEGER;
766 do
767 from
768 id := a_class.class_id;
769 feature_table.start;
770 until
771 feature_table.after
772 loop
773 feature_i := feature_table.item_for_iteration;
774 if feature_i.written_in = id then
775 feature_name_id := feature_table.key_for_iteration;
776 -- recompute a former local declaration
777 analyze_local (feature_i.duplicate, feature_name_id);
778 end;
779 feature_table.forth;
780 end;
781 end;
782
783 analyze_local (feature_i: FEATURE_I; feature_name_id: INTEGER) is
784 -- Analyze local declaration of class `a_class' named
785 -- `feat_name' which abstract representation is `yacc_feature'.
786 require
787 good_feature: feature_i /= Void;
788 good_feature_name_id: feature_name_id > 0
789 local
790 inherit_feat: INHERIT_FEAT;
791 -- Possible inherited features
792 old_feature: FEATURE_I;
793 new_rout_id: INTEGER;
794 new_rout_id_set: ROUT_ID_SET;
795 redef: REDEFINITION;
796 info, inherited_info: INHERIT_INFO;
797 vmfn: VMFN;
798 vmfn1: VMFN1;
799 compute_new_rout_id: BOOLEAN;
800 do
801 -- Now, compute the routine id set of the feature.
802 inherit_feat := item (feature_name_id);
803
804 -- Find out if there previously was a feature with name
805 -- `feature_name'
806 old_feature := feature_table.item_id (feature_name_id);
807
808 if inherit_feat = Void then
809 -- No feature inherited under name `feature_name'. This
810 -- deserves a brand new origin.
811 if feature_i.is_origin then
812 -- An old feature from a previous compilation was
813 -- an origin. Keep the current routine id.
814 new_rout_id_set := feature_i.rout_id_set;
815 check
816 rout_id_set_exists: new_rout_id_set /= Void;
817 has_only_one: new_rout_id_set.count = 1;
818 end;
819 new_rout_id := new_rout_id_set.first;
820 if feature_i.is_attribute then
821 compute_new_rout_id := not Routine_id_counter.is_attribute (new_rout_id)
822 else
823 compute_new_rout_id := Routine_id_counter.is_attribute (new_rout_id)
824 end;
825 else
826 if
827 old_feature /= Void and then not old_feature.is_origin
828 then
829 -- We changed the origin of the feature, we need to
830 -- mark the feature as changed since its assertions
831 -- could have been changed even though its body did
832 -- not changed
833 changed_features.extend (feature_name_id)
834 end
835 feature_i.set_is_origin (True);
836 compute_new_rout_id := True;
837 end;
838 if compute_new_rout_id then
839 create new_rout_id_set.make
840 new_rout_id := feature_i.new_rout_id;
841 new_rout_id_set.put (new_rout_id);
842 feature_i.set_rout_id_set (new_rout_id_set);
843 end;
844 -- Insertion into the system routine info table.
845 System.rout_info_table.put (new_rout_id, a_class);
846 create info.make (feature_i)
847 else
848 -- This is either an explicit redefinition through
849 -- the redefine clause or an implicit redefinition like
850 -- an implementation of deferred features
851 inherited_info := inherit_feat.inherited_info;
852 if inherited_info = Void then
853 -- Implicit or explicit redefinition
854 new_rout_id_set := inherit_feat.rout_id_set.twin
855 -- This is not an origin.
856 feature_i.set_is_origin (False);
857 if
858 old_feature /= Void and then old_feature.is_origin
859 then
860 -- We changed the origin of the feature, we need to
861 -- mark the feature as changed since its assertions
862 -- could have been changed even though its body did
863 -- not change.
864 changed_features.extend (feature_name_id)
865 end
866 -- Routine id set for the redefinition
867 feature_i.set_rout_id_set (new_rout_id_set);
868 -- Mark the redefinition to be done.
869 -- We pass `feature_i' as creation routine to
870 -- satisfy INHERIT_INFO invariant, but this is
871 -- not the correct value. The correct one will
872 -- will be set later by one of the routine that
873 -- calls `set_a_feature' from INHERIT_INFO.
874 create info.make (feature_i)
875 inherit_feat.set_inherited_info (info);
876 -- Store the redefintion for later
877 create redef.make (inherit_feat, feature_i);
878 adaptations.put_front (redef);
879 elseif inherited_info.parent = Void then
880 -- The feature has two implementations in the class
881 create vmfn;
882 vmfn.set_class (a_class);
883 vmfn.set_a_feature (feature_i);
884 vmfn.set_inherited_feature (inherited_features.item_id (feature_name_id));
885 Error_handler.insert_error (vmfn);
886 else
887 -- Name clash: a non-deferred feature is inherited
888 create vmfn1;
889 vmfn1.set_class (a_class);
890 vmfn1.set_a_feature (feature_i);
891 vmfn1.set_inherited_feature (inherited_info.a_feature);
892 vmfn1.set_parent (inherited_info.parent.parent);
893 Error_handler.insert_error (vmfn1);
894 end;
895 end;
896 if info /= Void then
897 if old_feature = Void then
898 -- Since the old feature table hasn't a feature named
899 -- `feature_name', new feature id for the feature
900 give_new_feature_id (feature_i);
901 else
902 -- Take the previous feature id
903 feature_i.set_feature_id (old_feature.feature_id);
904 if old_feature.written_in = a_class.class_id then
905 if
906 (feature_i.is_attribute and not old_feature.is_attribute) or else
907 (feature_i.is_deferred and then not old_feature.is_deferred) or else
908 (feature_i.is_attribute and old_feature.is_attribute and
909 feature_i.is_origin /= old_feature.is_origin)
910 then
911 System.execution_table.add_dead_function (old_feature.body_index)
912 end
913 end;
914 end;
915 -- Put new feature in `inherited_features'.
916 insert_feature (feature_i);
917 -- Put the new feature written in the current class
918 -- in the origin table
919 if redef = Void then
920 info.set_a_feature (feature_i);
921 Origin_table.insert (info);
922 end;
923 end;
924 -- Keep track of the origin features for pattern
925 -- processing
926 origins.extend (feature_i.feature_name_id);
927 end;
928
929 feature_unit (yacc_feature: FEATURE_AS; feat: FEATURE_NAME): FEATURE_I is
930 -- Feature correponding to declaration `yacc_feature'.
931 -- If we found a feature named `feature_name' in a previous
932 -- feature table, don't change of feature id. If this previous
933 -- feature didn't change, keep the body id, otherwise compute
934 -- a new body id.
935 require
936 syntactically_changed: a_class.changed;
937 local
938 feature_i: FEATURE_I;
939 unique_feature: UNIQUE_I;
940 -- Feature coming from a previous recompilation
941 body_index: INTEGER;
942 -- Body index of a previous compiled feature
943 old_description, old_tmp_description: FEATURE_AS;
944 -- Abstract representation of a previous compiled feature
945 is_the_same: BOOLEAN;
946 -- Is the parsed feature the same than a previous
947 -- compiled one ?
948 feature_name_id: INTEGER;
949 integer_value: INTEGER_CONSTANT;
950 -- Internal name of the feature
951 vffd4: VFFD4;
952 external_i: EXTERNAL_I;
953 do
954 feature_name_id := feat.internal_name.name_id
955 debug ("ACTIVITY")
956 io.error.put_string ("FEATURE_UNIT on ");
957 io.error.put_string (feat.internal_name.name);
958 io.error.put_new_line;
959 end;
960
961 Result := feature_i_generator.new_feature (yacc_feature, feature_name_id, a_class)
962 Result.set_feature_name_id (feature_name_id, feat.internal_alias_name_id)
963 Result.set_written_in (a_class.class_id)
964 Result.set_is_frozen (feat.is_frozen)
965 Result.set_is_infix (feat.is_infix)
966 Result.set_is_prefix (feat.is_prefix)
967 Result.set_is_bracket (feat.is_bracket)
968 Result.set_is_binary (feat.is_binary)
969 Result.set_is_unary (feat.is_unary)
970 Result.set_has_convert_mark (feat.has_convert_mark)
971
972 if Result.is_unique then
973 -- Unique value processing
974 unique_feature ?= Result;
975 create integer_value.make_with_value (
976 Tmp_ast_server.unique_values_item (a_class.class_id).item (Result.feature_name.string_representation))
977 if integer_value.valid_type (unique_feature.type) then
978 integer_value.set_real_type (unique_feature.type)
979 else
980 -- The value cannot be represented using specified integer type.
981 error_handler.insert_error (create {VQUI2}.make (a_class, Result.feature_name, Result.type))
982 end
983 unique_feature.set_value (integer_value)
984 elseif Result.is_c_external then
985 -- Track new externals introduced in the class. Freeze is taken care by
986 -- EXTERNALS.is_equivalent queried by SYSTEM_I.
987 external_i ?= Result
988 pass2_control.add_external (external_i)
989 end
990
991 -- Look for a previous definition of the feature
992 feature_i := feature_table.item_id (feature_name_id);
993
994 if feature_i /= Void then
995 if feature_i.written_in = a_class.class_id then
996 -- same feature, reuse body_index
997 body_index := feature_i.body_index
998
999 -- Found a feature of same name and written in the
1000 -- same class.
1001 check
1002 has_body: body_server.server_has (body_index)
1003 end
1004 old_description := Body_server.server_item (body_index)
1005 if old_description = Void then
1006 -- This should not happen, but if it does.
1007 is_the_same := False
1008 else
1009 if Tmp_ast_server.body_has (body_index) then
1010 old_tmp_description := Tmp_ast_server.body_item (body_index)
1011 end
1012
1013 -- Incrementality of the workbench is here: we
1014 -- compare the content of a new feature and the
1015 -- one of an old feature.
1016 is_the_same := old_description.is_assertion_equiv (yacc_feature) and
1017 (old_tmp_description /= Void implies old_tmp_description.is_assertion_equiv (yacc_feature))
1018 end
1019
1020 if not is_the_same then
1021 -- assertions have changed
1022 create assert_prop_list.make;
1023 assert_prop_list.compare_objects;
1024 assert_prop_list.extend (feature_i.rout_id_set.first)
1025
1026 -- FIXME: Manu 08/05/2004: It is a pain to have to freeze each
1027 -- time you change an assertion from an external routine, but
1028 -- this is required for the moment (as call to external routine
1029 -- is not done in generated byte code).
1030 -- The solution is to separate the Eiffel encapsulation from
1031 -- the external encapsulation and have the melted code call the
1032 -- tiny external encapsulation.
1033 if feature_i.is_external then
1034 System.request_freeze
1035 end
1036 else
1037 is_the_same := old_description.is_body_equiv (yacc_feature) and
1038 (old_tmp_description /= Void implies old_tmp_description.is_body_equiv (yacc_feature))
1039 -- Same interface does NOT work: the types must be resolved first
1040 -- The check is done later anyway
1041
1042 --and then Result.same_interface (feature_i);
1043 if is_the_same and unique_feature /= Void then
1044 is_the_same := feature_i.is_unique and then
1045 unique_feature.same_value (feature_i)
1046 end;
1047 end;
1048
1049 -- If old representation written in the class,
1050 -- keep the fact the old feature from a previous
1051 -- is an origin or not.
1052 Result.set_is_origin (feature_i.is_origin);
1053 Result.set_rout_id_set (feature_i.rout_id_set.twin)
1054 Result.set_is_selected (feature_i.is_selected);
1055 else
1056 -- new feature => new body_index
1057 body_index := Body_index_counter.next_id
1058 end
1059
1060 Result.set_body_index (body_index)
1061 if
1062 not is_the_same or else
1063 (supplier_status_modified and then
1064 not Degree_4.changed_status.disjoint (feature_i.suppliers))
1065 -- The status of one of the suppliers of the feature has changed
1066 then
1067 debug ("ACTIVITY")
1068 io.error.put_string ("Is the same ");
1069 io.error.put_boolean (is_the_same);
1070 io.error.put_string ("%Nsupplier_status_modified ");
1071 io.error.put_boolean (supplier_status_modified);
1072 io.error.put_string ("%Nchanged status ");
1073 io.error.put_boolean (not Degree_4.changed_status.disjoint (feature_i.suppliers));
1074 io.error.put_string ("%Nold_feature_in_class ");
1075 io.error.put_new_line;
1076 end;
1077
1078 -- Update `read_info' in BODY_SERVER
1079 if body_index > 0 then
1080 Tmp_ast_server.body_force (yacc_feature, body_index)
1081 Tmp_ast_server.reactivate (body_index)
1082 else
1083 check
1084 feature_is_il_external: feature_i.extension /= Void
1085 and then feature_i.extension.is_il
1086 end
1087 Tmp_ast_server.body_force (yacc_feature, external_body_index)
1088 end
1089
1090 -- Insert the changed feature in the table of
1091 -- changed features of class `a_class'.
1092 changed_features.extend (feature_name_id);
1093 else
1094 -- Update `read_info' in BODY_SERVER
1095 Tmp_ast_server.body_force (yacc_feature, body_index)
1096 Tmp_ast_server.reactivate (body_index)
1097 end;
1098 else
1099 Result.set_body_index (Body_index_counter.next_id)
1100 Tmp_ast_server.body_force (yacc_feature, Result.body_index)
1101
1102 -- Insert the changed feature in the table of changed
1103 -- features of `a_class'.
1104 changed_features.extend (feature_name_id);
1105 end;
1106
1107 -- Check incompatibily between `frozen' and `deferred'
1108 if Result.is_frozen and then Result.is_deferred then
1109 -- A deferred feature cannot be frozen
1110 create vffd4;
1111 vffd4.set_class (Result.written_class);
1112 vffd4.set_feature_name (Result.feature_name);
1113 Error_handler.insert_error (vffd4);
1114 end;
1115 end;
1116
1117 clear is
1118 -- Clear the second pass processor
1119 do
1120 previous_feature_table := Void;
1121 feature_table := Void;
1122 parents := Void;
1123 Origin_table.clear_all;
1124 adaptations.wipe_out;
1125 changed_features.wipe_out;
1126 origins.wipe_out;
1127 invariant_changed := False;
1128 invariant_removed := False;
1129 assert_prop_list := Void;
1130
1131 clear_all
1132 if capacity > 200 then
1133 extend_tbl_make (default_size)
1134 end
1135 create inherited_features.make (default_size)
1136 end;
1137
1138 process_pattern (resulting_table: FEATURE_TABLE) is
1139 -- Process pattern of features listed in `origins'.
1140 -- [We just have to compute pattern ids for origin features
1141 -- since for inherited features it is transmitted automatically
1142 -- by duplication of instances of FEATURE_I. For redeclarations,
1143 -- Through redeclarations, the pattern id cannot change: so
1144 -- the pattern id is updated in descendants of FEATURE_ADAPTATION]
1145 require
1146 good_argument: resulting_table /= Void;
1147 local
1148 a_feature: FEATURE_I;
1149 sys: SYSTEM_I
1150 l_origins: like origins
1151 do
1152 from
1153 sys := System
1154 l_origins := origins
1155 l_origins.start
1156 until
1157 l_origins.after
1158 loop
1159 a_feature := resulting_table.item_id (l_origins.item);
1160 a_feature.process_pattern;
1161 l_origins.forth;
1162 end;
1163 end;
1164
1165 update_inherited_assertions is
1166 -- Update assert_id_set for redefined or merged routines
1167 -- in adaptations.
1168 local
1169 redefined_features: REDEF_FEAT;
1170 do
1171 create redefined_features;
1172 redefined_features.process (adaptations);
1173 end;
1174
1175 update_changed_features is
1176 -- Update table `changed_features' of `a_class' after a
1177 -- successful second pass
1178 require
1179 no_error: not Error_handler.has_error;
1180 local
1181 feature_name_id: INTEGER
1182 class_id: INTEGER
1183 do
1184 from
1185 class_id := a_class.class_id
1186 changed_features.start
1187 until
1188 changed_features.after
1189 loop
1190 feature_name_id := changed_features.item;
1191 a_class.insert_changed_feature (feature_name_id);
1192 changed_features.forth;
1193 end;
1194 end;
1195
1196 update_convert_clause (
1197 a_old_convert, a_new_convert: DS_HASH_TABLE [INTEGER, NAMED_TYPE_A];
1198 a_resulting_table: FEATURE_TABLE)
1199 is
1200 -- Take into account incremental changes in `convert' clauses.
1201 require
1202 a_class_not_void: a_class /= Void
1203 a_old_convert_not_void: a_old_convert /= Void
1204 a_resulting_table_not_void: a_resulting_table /= Void
1205 local
1206 l_feat_name_id: INTEGER
1207 l_depend_unit: DEPEND_UNIT
1208 do
1209 if a_new_convert = Void or else not a_old_convert.is_equal (a_new_convert) then
1210 -- Old convert clause is different from new one. For each routines previously
1211 -- specified in `a_old_convert' and not specified in `a_new_convert',
1212 -- we need to progagate to the classes that were using those routines
1213 -- so that the code is recompiled at degree 3 (for type checking purpose only).
1214 from
1215 a_old_convert.start
1216 until
1217 a_old_convert.after
1218 loop
1219 l_feat_name_id := a_old_convert.item_for_iteration
1220 a_resulting_table.search_id (l_feat_name_id)
1221 if
1222 a_resulting_table.found and
1223 (a_new_convert = Void or else not a_new_convert.has_item (l_feat_name_id))
1224 then
1225 create l_depend_unit.make (a_class.class_id, a_resulting_table.found_item)
1226 pass2_control.propagators.extend (l_depend_unit)
1227 end
1228 a_old_convert.forth
1229 end
1230 end
1231 end
1232
1233 Routine_id_counter: ROUTINE_COUNTER is
1234 -- Counter for routine ids
1235 once
1236 Result := System.routine_id_counter;
1237 end;
1238
1239 Body_index_counter: BODY_INDEX_COUNTER is
1240 -- Counter for bodies index
1241 once
1242 Result := System.body_index_counter;
1243 end;
1244
1245 check_validity2 is
1246 -- Check if redefinitions are effectively done and does
1247 -- joins an deferred features if needed
1248 require
1249 inherited_features /= Void;
1250 local
1251 inherited_feature: FEATURE_I;
1252 deferred_info, inherited_info: INHERIT_INFO;
1253 inherit_feat: INHERIT_FEAT;
1254 feature_name_id: INTEGER;
1255 join: JOIN;
1256 vdrs4: VDRS4;
1257 do
1258 from
1259 start
1260 until
1261 after
1262 loop
1263 inherit_feat := item_for_iteration;
1264 inherited_info := inherit_feat.inherited_info;
1265 if inherited_info = Void then
1266 if inherit_feat.nb_features > 0 then
1267 -- Cannot find a redefinition
1268 create vdrs4;
1269 vdrs4.set_class (a_class);
1270 vdrs4.set_feature_name (Names_heap.item (key_for_iteration))
1271 Error_handler.insert_error (vdrs4);
1272 else
1273 -- Case of deferred features only
1274 check
1275 not inherit_feat.is_empty;
1276 end;
1277 feature_name_id := key_for_iteration;
1278 deferred_info := inherit_feat.deferred_features.first;
1279 -- New inherited feature
1280 inherited_feature := deferred_info.a_feature
1281 inherited_feature.set_feature_name_id (feature_name_id, inherited_feature.alias_name_id)
1282 -- Initialization of an inherited feature
1283 init_inherited_feature (inherited_feature, inherit_feat);
1284 -- Insertion in the origin table
1285 inherited_info := deferred_info.twin
1286 inherited_info.set_a_feature (inherited_feature);
1287 Origin_table.insert (inherited_info);
1288 if inherit_feat.nb_deferred > 1 then
1289 -- Keep track of the feature adaptation.
1290 -- The deferred features must have the same
1291 -- signature
1292 create join.make (inherit_feat, inherited_feature);
1293 adaptations.put_front (join);
1294 debug ("ACTIVITY")
1295 io.put_string ("joining feature: ");
1296 io.put_string (inherited_feature.feature_name);
1297 io.put_string ("%N%Tfrom class: ");
1298 io.put_string (inherited_feature.written_class.name);
1299 io.put_new_line;
1300 end;
1301 end;
1302 end;
1303 end;
1304 forth;
1305 end;
1306 end;
1307
1308 init_inherited_feature (f: FEATURE_I; inherit_feat: INHERIT_FEAT) is
1309 -- Initialization of an inherited feature
1310 require
1311 f_not_void: f /= Void
1312 inherit_feat_not_void: inherit_feat /= Void
1313 local
1314 inherit_info: INHERIT_INFO
1315 rout_ids: ROUT_ID_SET
1316 old_feature: FEATURE_I
1317 feature_name_id: INTEGER
1318 do
1319 -- It is no more an origin
1320 f.set_is_origin (False)
1321 f.set_has_property (False)
1322 if a_class.is_single then
1323 -- Feature getters and setters may have been generated.
1324 inherit_info := inherit_feat.inherited_info
1325 if inherit_info /= Void and then inherit_info.parent.parent.is_single then
1326 f.set_has_property_getter (False)
1327 f.set_has_property_setter (False)
1328 end
1329 end
1330
1331 -- Check the routine table ids
1332 rout_ids := inherit_feat.rout_id_set
1333 f.set_rout_id_set (rout_ids.twin)
1334 -- Process feature id
1335 feature_name_id := f.feature_name_id
1336 old_feature := feature_table.item_id (feature_name_id)
1337 if old_feature = Void then
1338 -- New feature id since the old feature table
1339 -- doesn't have an entry `feature_name'
1340 give_new_feature_id (f)
1341
1342 -- We reactivate `body_index' in case `old_feature' is Void because
1343 -- it was removed in `compute_feature_table' as it was not valid
1344 -- anymore (Most likely because its signature had some classes
1345 -- which have been moved to a different location and those
1346 -- classes have now a different `class_id' which makes it not a
1347 -- valid feature anymore).
1348 --| The only issue when performing this call is that in a compilation
1349 --| from scratch it is useless, but we do not have much choice in
1350 --| case of incremental compilation.
1351 Tmp_ast_server.reactivate (f.body_index)
1352 else
1353 -- Take the old feature id
1354 f.set_feature_id (old_feature.feature_id)
1355 if
1356 old_feature.can_be_encapsulated and then
1357 old_feature.to_generate_in (a_class)
1358 then
1359 -- If it is an attribute that was generated in `a_class',
1360 -- we have to redo mark it dead as an encapsulation. `is_valid'
1361 -- on its execution unit will tell us if we still need the
1362 -- encapsulation or not.
1363 system.execution_table.add_dead_function (old_feature.body_index)
1364 end
1365 end
1366 -- Concatenation of the export statuses of all the
1367 -- precursors of the inherited feature: take care of new
1368 -- adapted export status specified in inheritance clause
1369 f.set_export_status (inherit_feat.exports (feature_name_id))
1370 -- Insert it in the table `inherited_features'.
1371 inherited_features.put (f, feature_name_id)
1372 check_alias_name_conflict (f)
1373 end
1374
1375 give_new_feature_id (f: FEATURE_I) is
1376 -- Give a new feature id to `f'.
1377 require
1378 good_argument: f /= Void;
1379 has_a_new_name: not feature_table.has_id (f.feature_name_id);
1380 local
1381 new_feature_id: INTEGER;
1382 old_feature: FEATURE_I;
1383 do
1384 if previous_feature_table /= Void then
1385 old_feature := previous_feature_table.item_id (f.feature_name_id);
1386 if old_feature /= Void then
1387 -- Keep the feature id, because byte code for client
1388 -- features using this new feature name could have been
1389 -- already computed.
1390 new_feature_id := old_feature.feature_id
1391 else
1392 new_feature_id := a_class.feature_id_counter.next;
1393 end
1394 else
1395 new_feature_id := a_class.feature_id_counter.next;
1396 end;
1397 f.set_feature_id (new_feature_id);
1398 end;
1399
1400 check_validity3 (resulting_table: FEATURE_TABLE) is
1401 -- Check the signature conformance of the redefinitions and
1402 -- validity of joins; check assigner command validity.
1403 local
1404 f: FEATURE_I
1405 l_args: FEAT_ARG
1406 l_type: TYPE_A
1407 do
1408 from
1409 adaptations.start
1410 until
1411 adaptations.after
1412 loop
1413 adaptations.item.check_adaptation (resulting_table)
1414 adaptations.forth
1415 end
1416 from
1417 resulting_table.start
1418 until
1419 resulting_table.after
1420 loop
1421 f := resulting_table.item_for_iteration
1422 if f.assigner_name_id /= 0 then
1423 f.check_assigner (resulting_table)
1424 end
1425 l_args := f.arguments
1426 if l_args /= Void then
1427 from
1428 l_args.start
1429 until
1430 l_args.after
1431 loop
1432 l_type := l_args.item
1433 if l_type.is_like_current then
1434 system.set_routine_covariantly_redefined (f.rout_id_set, True)
1435 elseif l_type.is_formal or else l_type.conformance_type.is_formal then
1436 system.set_routine_has_formal (f.rout_id_set, True)
1437 elseif l_type.is_like then
1438
1439 end
1440 l_args.forth
1441 end
1442 end
1443 resulting_table.forth
1444 end
1445 end
1446
1447 check_redeclarations (resulting_table: FEATURE_TABLE) is
1448 -- Check redeclarations into an attribute.
1449 do
1450 from
1451 adaptations.start;
1452 until
1453 adaptations.after
1454 loop
1455 adaptations.item.check_redeclaration
1456 (resulting_table, feature_table, origins, Origin_table);
1457 adaptations.forth;
1458 end;
1459 end;
1460
1461 insert_feature (f: FEATURE_I) is
1462 -- Insert `f' in `inherited_feature'
1463 require
1464 good_argument: f /= Void
1465 local
1466 feature_name_id: INTEGER
1467 vmfn: VMFN
1468 do
1469 feature_name_id := f.feature_name_id
1470 inherited_features.put (f, feature_name_id)
1471 if inherited_features.conflict then
1472 create vmfn
1473 vmfn.set_class (a_class)
1474 vmfn.set_a_feature (f)
1475 vmfn.set_inherited_feature (inherited_features.item_id (feature_name_id))
1476 Error_handler.insert_error (vmfn)
1477 else
1478 check_alias_name_conflict (f)
1479 end
1480 end
1481
1482 compute_invariant is
1483 -- Compute invariant clause
1484 require
1485 good_context: not (a_class = Void or else class_info = Void);
1486 changed: a_class.changed;
1487 local
1488 class_id: INTEGER;
1489 -- information left by the temporary server `Tmp_ast_server'
1490 -- and stored in `class_info'
1491 old_invar_clause, invar_clause: INVARIANT_AS;
1492 old_clause_exists, clause_exists: BOOLEAN;
1493 do
1494 -- First: check is the invariant clause of the current
1495 -- class has syntactically changed. If yes, flag
1496 -- `changed5' of `a_class' is set to True.
1497 class_id := a_class.class_id;
1498 -- Look in the non-temporary invariant AST server for
1499 -- for an old invariant clause
1500 old_clause_exists := Inv_ast_server.server_has (class_id);
1501 clause_exists := Tmp_ast_server.invariant_has (class_id)
1502 if clause_exists then
1503 -- The changed class `a_class' has an invariant clause
1504 if old_clause_exists then
1505 -- Evaluation of an old invariant clause in order
1506 -- to see if it has changed
1507 old_invar_clause := Inv_ast_server.server_item (class_id);
1508 invar_clause := Tmp_ast_server.invariant_item (class_id);
1509
1510 -- Incrementality test on invariant clause
1511 if invar_clause = Void then
1512 invariant_changed := old_invar_clause /= Void
1513 else
1514 invariant_changed := not (
1515 old_invar_clause /= Void and then
1516 invar_clause.is_equivalent (old_invar_clause))
1517 end
1518 else
1519 invariant_changed := True;
1520 end;
1521 elseif old_clause_exists or a_class.has_invariant then
1522 invariant_removed := True;
1523 tmp_ast_server.invariant_remove (class_id)
1524 end;
1525 end;
1526
1527 feature {NONE} -- Implementation
1528
1529 compute_main_parent (a_feat_tbl: FEATURE_TABLE) is
1530 -- Set `number_of_features' and `main_parent' of `a_class'
1531 require
1532 a_feat_tbl_not_void: a_feat_tbl /= Void
1533 il_generation: System.il_generation
1534 local
1535 l_parent, l_main_parent: CLASS_C
1536 l_number_of_features, l_max: INTEGER
1537 do
1538 from
1539 parents.start
1540 until
1541 parents.after
1542 loop
1543 l_parent := parents.item.parent
1544 if l_parent.is_single or (l_parent.is_external and not l_parent.is_interface) then
1545 -- We cannot optimize here, we have to take it
1546 -- as main parent even if there is no feature in it.
1547 l_main_parent := l_parent
1548 parents.finish
1549 else
1550 l_number_of_features := l_parent.feature_table.count
1551 if l_number_of_features > l_max then
1552 l_main_parent := parents.item.parent
1553 l_max := l_number_of_features
1554 end
1555 end
1556 parents.forth
1557 end
1558 if l_main_parent = Void then
1559 -- No parents, means that we are handling ANY.
1560 l_main_parent := a_class
1561 end
1562 a_class.set_main_parent (l_main_parent)
1563 a_class.set_number_of_features (a_feat_tbl.count)
1564 ensure
1565 main_parent_set: a_class.main_parent /= Void
1566 nb_features_set: a_class.number_of_features = a_feat_tbl.count
1567 end
1568
1569 check_alias_name_conflict (f: FEATURE_I) is
1570 -- Check if feature `f' has an alias name and that after adding it to `inherited_features'
1571 -- `inherited_features.is_alias_conflict' is set to `true'. Report error in this case.
1572 local
1573 alias_name_id: INTEGER
1574 vfav: VFAV
1575 do
1576 alias_name_id := f.alias_name_id
1577 if alias_name_id > 0 and then inherited_features.is_alias_conflict then
1578 if f.is_bracket then
1579 create {VFAV2} vfav
1580 else
1581 create {VFAV1} vfav
1582 end
1583 vfav.set_class (a_class)
1584 vfav.set_a_feature (f)
1585 vfav.set_inherited_feature (inherited_features.item_alias_id (alias_name_id))
1586 Error_handler.insert_error (vfav)
1587 end
1588 end
1589
1590 mark_generic_attribute_seeds (resulting_table: FEATURE_TABLE) is
1591 -- Mark attributes that are seeds of generic types to generate
1592 -- wrappers for them.
1593 require
1594 resulting_table_attached: resulting_table /= Void
1595 local
1596 f: FEATURE_I
1597 a: ATTRIBUTE_I
1598 do
1599 from
1600 resulting_table.start
1601 until
1602 resulting_table.after
1603 loop
1604 f := resulting_table.item_for_iteration
1605 if f.is_attribute and then f.is_origin and then f.rout_id_set.count = 1 and then f.has_formal then
1606 a ?= f
1607 check
1608 a_attached: a /= Void
1609 end
1610 a.set_generate_in (f.written_in)
1611 end
1612 resulting_table.forth
1613 end
1614 end
1615
1616 feature {NONE} -- Temporary body index
1617
1618 external_body_index: INTEGER is
1619 -- Dummy body index to be used when someone redefine an external feature
1620 -- with no body (i.e. an IL external).
1621 once
1622 Result := Body_index_counter.next_id
1623 ensure
1624 external_body_index_positive: Result > 0
1625 end
1626
1627 indexing
1628 copyright: "Copyright (c) 1984-2007, Eiffel Software"
1629 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
1630 licensing_options: "http://www.eiffel.com/licensing"
1631 copying: "[
1632 This file is part of Eiffel Software's Eiffel Development Environment.
1633
1634 Eiffel Software's Eiffel Development Environment is free
1635 software; you can redistribute it and/or modify it under
1636 the terms of the GNU General Public License as published
1637 by the Free Software Foundation, version 2 of the License
1638 (available at the URL listed under "license" above).
1639
1640 Eiffel Software's Eiffel Development Environment is
1641 distributed in the hope that it will be useful, but
1642 WITHOUT ANY WARRANTY; without even the implied warranty
1643 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1644 See the GNU General Public License for more details.
1645
1646 You should have received a copy of the GNU General Public
1647 License along with Eiffel Software's Eiffel Development
1648 Environment; if not, write to the Free Software Foundation,
1649 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1650 ]"
1651 source: "[
1652 Eiffel Software
1653 356 Storke Road, Goleta, CA 93117 USA
1654 Telephone 805-685-1006, Fax 805-685-6869
1655 Website http://www.eiffel.com
1656 Customer support http://support.eiffel.com
1657 ]"
1658
1659 end
1660

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23