/[eiffelstudio]/branches/CAT_mono/Src/Eiffel/eiffel/AST/visitor/ast_feature_checker_generator.e
ViewVC logotype

Contents of /branches/CAT_mono/Src/Eiffel/eiffel/AST/visitor/ast_feature_checker_generator.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 69844 - (show annotations)
Fri Aug 3 00:52:36 2007 UTC (12 years, 4 months ago) by martins
File size: 266693 byte(s)
added new line to error output
and special treatment of like current as it is not yet marked monomorph automatically
1 indexing
2 description: "Perform type checking as well as generation of BYTE_NODE tree."
3 legal: "See notice at end of class."
4 status: "See notice at end of class."
5 date: "$Date$"
6 revision: "$Revision$"
7
8 class
9 AST_FEATURE_CHECKER_GENERATOR
10
11 inherit
12 AST_VISITOR
13
14 AST_FEATURE_CHECKER_EXPORT
15
16 EIFFEL_LAYOUT
17 export
18 {NONE} all
19 end
20
21 REFACTORING_HELPER
22 export
23 {NONE} all
24 end
25
26 SHARED_TYPES
27 export
28 {NONE} all
29 end
30
31 SHARED_ERROR_HANDLER
32 export
33 {NONE} all
34 end
35
36 COMPILER_EXPORTER
37 export
38 {NONE} all
39 end
40
41 SHARED_WORKBENCH
42 export
43 {NONE} all
44 end
45
46 SHARED_INSTANTIATOR
47 export
48 {NONE} all
49 end
50
51 SHARED_EVALUATOR
52 export
53 {NONE} all
54 end
55
56 SHARED_NAMES_HEAP
57 export
58 {NONE} all
59 end
60
61 SHARED_INSPECT
62 export
63 {NONE} all
64 end
65
66 SYNTAX_STRINGS
67 export
68 {NONE} all
69 end
70
71 SHARED_SERVER
72 export
73 {NONE} all
74 end
75
76 SHARED_TMP_SERVER
77 export
78 {NONE} all
79 end
80
81 CONF_CONSTANTS
82 export
83 {NONE} all
84 end
85
86 SHARED_DEGREES
87 export
88 {NONE} all
89 end
90
91 PREDEFINED_NAMES
92 export
93 {NONE} all
94 end
95
96 REFACTORING_HELPER
97 export
98 {NONE} all
99 end
100
101 feature -- Initialization
102
103 init (a_context: AST_CONTEXT) is
104 do
105 if type_a_checker = Void then
106 create type_a_checker
107 end
108 if inherited_type_a_checker = Void then
109 create inherited_type_a_checker
110 end
111 if type_a_generator = Void then
112 create type_a_generator
113 end
114 if byte_anchor = Void then
115 create byte_anchor
116 end
117 context := a_context
118 end
119
120 feature -- Type checking
121
122 type_check_only (a_feature: FEATURE_I; a_code_inherited: BOOLEAN) is
123 -- Type check `a_feature'.
124 require
125 a_feature_not_void: a_feature /= Void
126 do
127 fixme (once "Make sure to use `a_code_inherited' to properly initialize our type checker.")
128 type_a_checker.init_for_checking (a_feature, context.current_class, context.supplier_ids, error_handler)
129 a_feature.record_suppliers (context.supplier_ids)
130 current_feature := a_feature
131 reset
132 is_byte_node_enabled := False
133 break_point_slot_count := 0
134 process_inherited_assertions (a_feature, True)
135 if a_code_inherited then
136 inherited_type_a_checker.init_for_checking (a_feature, context.written_class, Void, Void)
137 if not a_feature.is_deferred then
138 is_inherited := True
139 a_feature.body.process (Current)
140 is_inherited := False
141 end
142 else
143 a_feature.body.process (Current)
144 end
145 is_byte_node_enabled := False
146 process_inherited_assertions (a_feature, False)
147 end
148
149 type_check_and_code (a_feature: FEATURE_I) is
150 -- Type check `a_feature'.
151 require
152 a_feature_not_void: a_feature /= Void
153 local
154 rout_as: ROUTINE_AS
155 do
156 type_a_checker.init_for_checking (a_feature, context.current_class, context.supplier_ids, error_handler)
157 a_feature.record_suppliers (context.supplier_ids)
158 current_feature := a_feature
159 reset
160 is_byte_node_enabled := False
161 break_point_slot_count := 0
162 process_inherited_assertions (a_feature, True)
163 is_byte_node_enabled := True
164 a_feature.body.process (Current)
165 is_byte_node_enabled := False
166 process_inherited_assertions (a_feature, False)
167
168 if a_feature.real_body /= Void then
169 rout_as ?= a_feature.real_body.content
170 if rout_as /= Void then
171 if break_point_slot_count > 0 then
172 --| FIXME(jfiat:2007/01/26):
173 --| It occurs `break_point_slot_count' = 0 at this point
174 --| but just before we set rout_as.number_of_breakpoint_slots
175 --| had been set to non zero value
176 --| Check why we have this kind of issue.
177 rout_as.set_number_of_breakpoint_slots (break_point_slot_count)
178 end
179 end
180 end
181 end
182
183 expression_type_check_and_code (a_feature: FEATURE_I; an_exp: EXPR_AS) is
184 -- Type check `an_exp' in the context of `a_feature'.
185 require
186 a_feature_not_void: a_feature /= Void
187 an_exp_not_void: an_exp /= Void
188 local
189 l_exp_call: EXPR_CALL_AS
190 l_instr_as: INSTR_CALL_AS
191 errlst: LIST [ERROR]
192 errcur: CURSOR
193 l_vkcn_error: VKCN
194 l_has_vkcn_error: BOOLEAN
195 retried: BOOLEAN
196 do
197 if not retried then
198 expression_or_instruction_type_check_and_code (a_feature, an_exp)
199 end
200 if retried or error_handler.has_error then
201 --| Check if any VKCN error
202 errlst := error_handler.error_list
203 errcur := errlst.cursor
204 from
205 errlst.start
206 l_has_vkcn_error := False
207 until
208 errlst.after or l_has_vkcn_error
209 loop
210 l_vkcn_error ?= errlst.item
211 l_has_vkcn_error := l_vkcn_error /= Void
212 errlst.forth
213 end
214 errlst.go_to (errcur)
215
216 --| If any VKCN .. then let's try to check it as an instruction
217 if l_has_vkcn_error then
218 l_exp_call ?= an_exp
219 if l_exp_call /= Void then
220 error_handler.wipe_out
221 create l_instr_as.initialize (l_exp_call.call)
222 expression_or_instruction_type_check_and_code (a_feature, l_instr_as)
223 end
224 end
225 end
226 rescue
227 if not retried then
228 retried := True
229 retry
230 end
231 end
232
233 expression_or_instruction_type_check_and_code (a_feature: FEATURE_I; an_ast: AST_EIFFEL) is
234 -- Type check `an_ast' in the context of `a_feature'.
235 require
236 a_feature_not_void: a_feature /= Void
237 an_ast_not_void: an_ast /= Void
238 local
239 l_cl, l_wc: CLASS_C
240 l_ft: FEATURE_TABLE
241 l_ctx: AST_CONTEXT
242 do
243 reset
244 is_byte_node_enabled := True
245 current_feature := a_feature
246
247 l_cl := context.current_class
248 l_wc := current_feature.written_class
249 if l_wc /= l_cl then
250 l_ft := context.current_feature_table
251 l_ctx := context.twin
252 context.initialize (l_wc, l_wc.actual_type, l_ft)
253 type_a_checker.init_for_checking (a_feature, l_wc, Void, error_handler)
254 an_ast.process (Current)
255 reset
256 is_inherited := True
257 context.restore (l_ctx)
258 end
259 type_a_checker.init_for_checking (a_feature, l_cl, Void, error_handler)
260 an_ast.process (Current)
261 end
262
263 invariant_type_check (a_feature: FEATURE_I; a_clause: INVARIANT_AS; a_generate_code: BOOLEAN) is
264 -- Type check `a_feature'.
265 require
266 a_feature_not_void: a_feature /= Void
267 a_clause_not_void: a_clause /= Void
268 local
269 l_list: BYTE_LIST [BYTE_NODE]
270 l_invariant: INVARIANT_B
271 do
272 type_a_checker.init_for_checking (a_feature, context.current_class, context.supplier_ids, error_handler)
273 is_byte_node_enabled := a_generate_code
274 current_feature := a_feature
275 reset
276 a_clause.process (Current)
277 if a_generate_code then
278 l_list ?= last_byte_node
279 create l_invariant
280 l_invariant.set_class_id (context.current_class.class_id)
281 l_invariant.set_byte_list (l_list)
282 l_invariant.set_once_manifest_string_count (a_clause.once_manifest_string_count)
283 last_byte_node := l_invariant
284 end
285 end
286
287 custom_attributes_type_check_and_code (a_feature: FEATURE_I; a_cas: EIFFEL_LIST [CUSTOM_ATTRIBUTE_AS]) is
288 -- Type check `a_cas' for `a_feature'.
289 require
290 a_feature_not_void: a_feature /= Void
291 a_cas_not_void: a_cas /= Void
292 do
293 type_a_checker.init_for_checking (a_feature, context.current_class, context.supplier_ids, error_handler)
294 is_byte_node_enabled := True
295 current_feature := a_feature
296 reset
297 a_cas.process (Current)
298 end
299
300 check_local_names (a_procedure: PROCEDURE_I; a_node: BODY_AS) is
301 -- Check validity of the names of the locals of `a_procedure'.
302 -- Useful when a feature has been added, we need to make sure that
303 -- locals of existing features have a different name.
304 require
305 a_procedure_not_void: a_procedure /= Void
306 a_node_not_void: a_node /= Void
307 local
308 l_routine: ROUTINE_AS
309 l_id_list: ARRAYED_LIST [INTEGER]
310 l_feat_tbl: FEATURE_TABLE
311 l_vrle1: VRLE1
312 l_vpir: VPIR1
313 l_local_name_id: INTEGER
314 do
315 l_routine ?= a_node.content
316 if l_routine /= Void then
317 if l_routine.locals /= Void and not l_routine.locals.is_empty then
318 from
319 l_feat_tbl := context.current_class.feature_table
320 l_routine.locals.start
321 until
322 l_routine.locals.after
323 loop
324 from
325 l_id_list := l_routine.locals.item.id_list
326 l_id_list.start
327 until
328 l_id_list.after
329 loop
330 l_local_name_id := l_id_list.item
331 if not is_inherited and then l_feat_tbl.has_id (l_local_name_id) then
332 -- The local name is a feature name of the
333 -- current analyzed class.
334 create l_vrle1
335 context.init_error (l_vrle1)
336 l_vrle1.set_local_name (l_local_name_id)
337 l_vrle1.set_location (l_routine.locals.item.start_location)
338 error_handler.insert_error (l_vrle1)
339 elseif context.is_name_used (l_local_name_id) then
340 create l_vpir
341 context.init_error (l_vpir)
342 l_vpir.set_entity_name (l_local_name_id)
343 l_vpir.set_class (context.current_class)
344 l_vpir.set_feature (context.current_feature)
345 error_handler.insert_error (l_vpir)
346 end
347 l_id_list.forth
348 end
349 l_routine.locals.forth
350 end
351 end
352 end
353 end
354
355 feature {AST_FEATURE_CHECKER_GENERATOR} -- Internal type checking
356
357 check_body (a_feature: FEATURE_I; a_body: BODY_AS; a_is_byte_node_enabled, a_is_inherited, a_is_for_inline_agent: BOOLEAN) is
358 -- Type check `a_feature' which represents an inline agent `a_body'.
359 require
360 a_feature_not_void: a_feature /= Void
361 local
362 l_routine_as: ROUTINE_AS
363 l_vpir: VPIR3
364 l_written_class: CLASS_C
365 do
366 break_point_slot_count := 0
367 l_routine_as ?= a_body.content
368 if not a_is_inherited and then a_is_for_inline_agent then
369 if l_routine_as /= Void then
370 if l_routine_as.is_deferred or l_routine_as.is_external or l_routine_as.is_once then
371 create l_vpir
372 l_vpir.set_class (context.current_class)
373 l_vpir.set_feature (context.current_feature)
374 l_vpir.set_location (a_body.start_location)
375 error_handler.insert_error (l_vpir)
376 end
377 else
378 create l_vpir
379 l_vpir.set_class (context.current_class)
380 l_vpir.set_feature (context.current_feature)
381 l_vpir.set_location (a_body.start_location)
382 error_handler.insert_error (l_vpir)
383 end
384 error_handler.checksum
385 end
386 type_a_checker.init_for_checking (a_feature, context.current_class, context.supplier_ids, error_handler)
387 a_feature.record_suppliers (context.supplier_ids)
388 current_feature := a_feature
389 reset
390 is_byte_node_enabled := a_is_byte_node_enabled
391 is_inherited := a_is_inherited
392 l_written_class := context.written_class
393 a_feature.check_types (context.current_feature_table)
394 context.set_written_class (l_written_class)
395 error_handler.checksum
396 if not is_inherited then
397 if a_feature.has_arguments then
398 a_feature.check_argument_names (context.current_feature_table)
399 end
400 end
401 error_handler.checksum
402 a_body.process (Current)
403 if not is_inherited then
404 a_feature.check_local_names (a_body)
405 end
406 error_handler.checksum
407 end
408
409 feature -- Status report
410
411 byte_code: BYTE_CODE is
412 -- Last computed BYTE_CODE instance if any.
413 do
414 Result ?= last_byte_node
415 end
416
417 inline_agent_byte_codes: LINKED_LIST [BYTE_CODE]
418 -- List of computed inline agent byte nodes if any.
419
420 invariant_byte_code: INVARIANT_B is
421 -- Last computed invariant byte node if any.
422 do
423 Result ?= last_byte_node
424 end
425
426 last_byte_node: BYTE_NODE
427 -- Last computed BYTE_NODE after a call to one of the `process_xx' routine
428
429 last_calls_target_type: TYPE_A
430 -- Static type of last feature call.
431 -- In case of multiple constrained formal generics there are several static types possible.
432 -- MTNASK: current_target_type could be used instead, for now i don't want to interfere with that...
433
434 feature {NONE} -- Implementation: Access
435
436 type_a_generator: AST_TYPE_A_GENERATOR
437 -- To convert TYPE_AS into TYPE_A
438
439 inherited_type_a_checker, type_a_checker: TYPE_A_CHECKER
440 -- To check a type
441
442 byte_anchor: AST_BYTE_NODE_ANCHOR
443 -- To get node type for UNARY_AS and BINARY_AS nodes
444
445 feature {NONE} -- Implementation: Context
446
447 current_feature: FEATURE_I
448 -- Feature which is checked
449
450 feature {AST_FEATURE_CHECKER_GENERATOR}
451
452 is_inherited: BOOLEAN
453 -- Is code being processed inherited?
454
455 feature {NONE} -- Implementation: State
456
457 is_byte_node_enabled: BOOLEAN
458 -- Are we also doing BYTE_NODE generation as well as type checking?
459
460 has_loop: BOOLEAN
461 -- Does Current have a loop instruction?
462
463 once_manifest_string_index: INTEGER
464 -- Index of once manifest strings from the beginning
465 -- of the current routine or of the current class invariant
466
467 is_in_rescue: BOOLEAN
468 -- Flag to ensure that `retry' instruction appears only in a rescue clause.
469
470 is_in_creation_expression: BOOLEAN
471 -- Are we type checking a creation expression?
472 -- Usefull, for not checking VAPE error in precondition
473 -- using creation expression, since type checking
474 -- on CREATION_EXPR_AS will report a not sufficiently
475 -- exported creation routine.
476
477 is_target_of_creation_instruction: BOOLEAN
478 -- Are we type checking the call to the creation routine?
479
480 check_for_vaol: BOOLEAN
481 -- Is current checking for VAOL error?
482
483 depend_unit_level: INTEGER_8
484 -- Current level used to create new instances of DEPEND_UNIT.
485
486 context: AST_CONTEXT
487 -- Context in which current checking is done
488
489 is_checking_postcondition: BOOLEAN is
490 -- Are we currently checking a postcondition.
491 -- Needed to ensure that old expression only appears in
492 -- postconditions
493 do
494 Result := (depend_unit_level & {DEPEND_UNIT}.is_in_ensure_flag) =
495 {DEPEND_UNIT}.is_in_ensure_flag
496 end
497
498 is_checking_invariant: BOOLEAN is
499 -- Level of analysis for access, When analyzing an access id,
500 -- (instance of ACCESS_ID_AS), locals, arguments
501 -- are not taken into account if set to True.
502 -- Useful for analyzing class invariant.
503 -- [Set on when analyzing invariants].
504 do
505 Result := (depend_unit_level & {DEPEND_UNIT}.is_in_invariant_flag) =
506 {DEPEND_UNIT}.is_in_invariant_flag
507 end
508
509 is_checking_precondition: BOOLEAN is
510 -- Level for analysis of precondition
511 do
512 Result := (depend_unit_level & {DEPEND_UNIT}.is_in_require_flag) =
513 {DEPEND_UNIT}.is_in_require_flag
514 end
515
516 is_checking_check: BOOLEAN is
517 -- Level for analyzis of check clauses
518 do
519 Result := (depend_unit_level & {DEPEND_UNIT}.is_in_check_flag) =
520 {DEPEND_UNIT}.is_in_check_flag
521 end
522
523 is_in_assignment: BOOLEAN is
524 -- Level for analysis of target of an assignment
525 do
526 Result := (depend_unit_level & {DEPEND_UNIT}.is_in_assignment_flag) =
527 {DEPEND_UNIT}.is_in_assignment_flag
528 end
529
530 last_expressions_type: ARRAY [TYPE_A]
531 -- Last computed types of a list of expressions
532
533 last_tuple_type: TUPLE_TYPE_A
534 -- Type of last computed manifest tuple
535
536 last_type: TYPE_A
537 -- Type of last computed expression
538
539 current_target_type: TYPE_A
540 -- Type of target of expression being processed
541 -- Only useful for type checking of manifest array.
542
543 old_expressions: LINKED_LIST [UN_OLD_B]
544 -- List of old expressions found during feature type checking
545
546 is_type_compatible: BOOLEAN
547 -- Is `last_type' compatible with type passed to `process_type_compatibility'?
548
549 last_assigner_command: FEATURE_I
550 -- Last assigner command associated with a feature
551
552 is_assigner_call: BOOLEAN
553 -- Is an assigner call being processed?
554
555 is_qualified_call: BOOLEAN
556 -- Is a qualified call being processed?
557
558 is_checking_cas: BOOLEAN
559 -- Is a custom attribute being processed?
560
561 feature {NONE} -- Implementation: Access
562
563 last_access_writable: BOOLEAN
564 -- Is last ACCESS_AS node creatable?
565
566 last_actual_feature_name: STRING
567 -- Whenever a feature name is required, use this to select the actually correct one.
568 --| If last_original_feature_name is 0 then last_feature_name will be selected
569 require
570 at_least_one_name_available: last_original_feature_name_id /= 0 or last_feature_name_id /= 0
571 do
572 if last_original_feature_name_id = 0 then
573 Result := last_feature_name
574 else
575 Result := last_original_feature_name
576 end
577 ensure
578 Result_not_void: Result /= Void
579 end
580
581 last_actual_feature_name_id: INTEGER
582 -- Whenever a feature name is required, use this to select the actually correct one.
583 --| If last_original_feature_name is 0 then last_feature_name will be selected
584 require
585 at_least_one_name_available: last_original_feature_name_id /= 0 or last_feature_name_id /= 0
586 do
587 Result := last_original_feature_name_id
588 if Result = 0 then
589 Result := last_feature_name_id
590 end
591 ensure
592 Result_not_zero: Result /= 0
593 end
594
595 last_original_feature_name: STRING
596 -- Original name of last ACCESS_AS (`last_feature_name' might be different and depending
597 -- on what usage is intended this or the other might be the one to use)
598 require
599 last_original_feature_name_id_not_negative: last_original_feature_name_id >= 0
600 do
601 Result := names_heap.item (last_original_feature_name_id)
602 ensure
603 Result_correct: last_original_feature_name_id /= 0 implies Result /= Void
604 end
605
606 last_original_feature_name_id: INTEGER
607 -- Names_heap Id of original name of last ACCESS_AS (`last_feature_name' might be different and depending
608 -- on what usage is intended this or the other might be the one to use)
609
610 last_feature_name: STRING
611 -- Actual name of last ACCESS_AS (might be different from original name
612 -- in case an overloading resolution or a renaming of a formal constraint took place)
613 require
614 last_feature_name_id_not_zero: last_feature_name_id /= 0
615 do
616 Result := names_heap.item (last_feature_name_id)
617 ensure
618 Result_correct: Result /= Void
619 end
620
621 last_feature_name_id: INTEGER
622 -- Names_heap Id of `last_feature_name'
623
624 is_last_access_tuple_access: BOOLEAN
625 -- Is last ACCESS_AS node an access to a TUPLE element?
626
627 feature -- Settings
628
629 reset is
630 -- Reset all attributes to their default value
631 do
632 old_expressions := Void
633 reset_types
634 has_loop := False
635 once_manifest_string_index := 0
636 is_in_rescue := False
637 is_in_creation_expression := False
638 is_target_of_creation_instruction := False
639 check_for_vaol := False
640 depend_unit_level := 0
641 last_access_writable := False
642 last_original_feature_name_id := 0
643 last_feature_name_id := 0
644 last_calls_target_type := Void
645 is_type_compatible := False
646 last_assigner_command := Void
647 is_inherited := False
648 inline_agent_byte_codes := Void
649 end
650
651 reset_types is
652 -- Reset attributes storing types to Void
653 do
654 last_tuple_type := Void
655 last_type := Void
656 last_calls_target_type := Void
657 last_expressions_type := Void
658 current_target_type := Void
659 end
660
661 reset_for_unqualified_call_checking is
662 do
663 last_type := context.current_class_type
664 end
665
666 set_is_checking_postcondition (b: BOOLEAN) is
667 -- Assign `b' to `is_checking_postcondition'.
668 do
669 if b then
670 depend_unit_level := depend_unit_level | {DEPEND_UNIT}.is_in_ensure_flag
671 else
672 depend_unit_level := depend_unit_level &
673 {DEPEND_UNIT}.is_in_ensure_flag.bit_not
674 end
675 ensure
676 is_checking_postcondition_set: is_checking_postcondition = b
677 end
678
679 set_is_checking_invariant (b: BOOLEAN) is
680 -- Assign `b' to `is_checking_invariant'.
681 do
682 if b then
683 depend_unit_level := depend_unit_level | {DEPEND_UNIT}.is_in_invariant_flag
684 else
685 depend_unit_level := depend_unit_level &
686 {DEPEND_UNIT}.is_in_invariant_flag.bit_not
687 end
688 ensure
689 is_checking_invariant_set: is_checking_invariant = b
690 end
691
692 set_is_checking_precondition (b: BOOLEAN) is
693 -- Assign `b' to `is_checking_precondition'.
694 -- Also set `b' to check_for_vape.
695 do
696 if b then
697 depend_unit_level := depend_unit_level | {DEPEND_UNIT}.is_in_require_flag
698 else
699 depend_unit_level := depend_unit_level &
700 {DEPEND_UNIT}.is_in_require_flag.bit_not
701 end
702 ensure
703 is_checking_precondition_set: is_checking_precondition = b
704 end
705
706 set_is_checking_check (b: BOOLEAN) is
707 -- Assign `b' to `is_checking_check'.
708 do
709 if b then
710 depend_unit_level := depend_unit_level | {DEPEND_UNIT}.is_in_check_flag
711 else
712 depend_unit_level := depend_unit_level &
713 {DEPEND_UNIT}.is_in_check_flag.bit_not
714 end
715 ensure
716 is_checking_check_set: is_checking_check = b
717 end
718
719 set_is_in_assignment (b: BOOLEAN) is
720 -- Assign `b' to `is_in_assignment'.
721 do
722 if b then
723 depend_unit_level := depend_unit_level | {DEPEND_UNIT}.is_in_assignment_flag
724 else
725 depend_unit_level := depend_unit_level &
726 {DEPEND_UNIT}.is_in_assignment_flag.bit_not
727 end
728 ensure
729 is_in_assignment_set: is_in_assignment = b
730 end
731
732 set_current_feature (a_feature: FEATURE_I) is
733 -- Assign `a_feature' to `current_feature'.
734 do
735 current_feature := a_feature
736 ensure
737 is_current_feature_set: current_feature = a_feature
738 end
739
740 feature -- Roundtrip
741
742 process_keyword_as (l_as: KEYWORD_AS) is
743 -- Process `l_as'.
744 do
745 end
746
747 process_symbol_as (l_as: SYMBOL_AS) is
748 -- Process `l_as'.
749 do
750 end
751
752 process_break_as (l_as: BREAK_AS) is
753 -- Process `l_as'.
754 do
755 end
756
757 process_leaf_stub_as (l_as: LEAF_STUB_AS) is
758 -- Process `l_as'.
759 do
760 end
761
762 process_symbol_stub_as (l_as: SYMBOL_STUB_AS) is
763 -- Process `l_as'.
764 do
765 end
766
767 process_none_id_as (l_as: NONE_ID_AS) is
768 -- Process `l_as'.
769 do
770 process_id_as (l_as)
771 end
772
773 process_typed_char_as (l_as: TYPED_CHAR_AS) is
774 -- Process `l_as'.
775 do
776 process_char_as (l_as)
777 end
778
779 process_agent_routine_creation_as (l_as: AGENT_ROUTINE_CREATION_AS) is
780 -- Process `l_as'.
781 do
782 process_routine_creation_as (l_as)
783 end
784
785 process_tilda_routine_creation_as (l_as: TILDA_ROUTINE_CREATION_AS) is
786 -- Process `l_as'.
787 do
788 process_routine_creation_as (l_as)
789 end
790
791 process_inline_agent_creation_as (l_as: INLINE_AGENT_CREATION_AS) is
792 -- Process `l_as'.
793 local
794 l_feature_name: ID_AS
795 l_context: like context
796 l_feature_as: FEATURE_AS
797 l_feature_generator: AST_FEATURE_I_GENERATOR
798 l_feature, l_cur_feature, l_enclosing_feature: FEATURE_I
799 l_feature_names: EIFFEL_LIST [FEATURE_NAME]
800 l_cur_class: EIFFEL_CLASS_C
801 l_body_code: BYTE_CODE
802 l_loc: LOCATION_AS
803 l_new_feature_dep: FEATURE_DEPENDANCE
804 l_feature_checker: AST_FEATURE_CHECKER_GENERATOR
805 l_used_argument_names: SEARCH_TABLE [INTEGER]
806 l_used_local_names: SEARCH_TABLE [INTEGER]
807 l_arg_names: SPECIAL [INTEGER]
808 l_locals: EIFFEL_LIST [TYPE_DEC_AS]
809 i: INTEGER
810 l_routine: ROUTINE_AS
811 l_id_list: IDENTIFIER_LIST
812 do
813 l_cur_class ?= context.current_class
814
815 if is_inherited then
816 -- We have to retrieve the FEATURE_I object from the class where the inline agent is
817 -- written, since those are not inherited.
818 l_feature :=
819 system.class_of_id (l_as.class_id).eiffel_class_c.inline_agent_of_rout_id (l_as.inl_rout_id).duplicate
820 l_feature.instantiation_in (context.current_class_type.conformance_type)
821 else
822 if is_byte_node_enabled then
823
824 -- This is the first place, where inline agents are looked at as features.
825 -- They are ignored by degree 2. So a new FEATURE_I has to be created
826 create l_feature_names.make (0)
827 create l_feature_as.initialize (l_feature_names, l_as.body, Void, 0, 0)
828
829 create l_feature_generator
830 l_feature := l_feature_generator.new_feature (l_feature_as, 0, l_cur_class)
831 l_enclosing_feature := init_inline_agent_feature (l_feature, Void)
832 l_cur_feature := context.current_feature
833
834 if is_byte_node_enabled then
835
836 create l_feature_name.initialize_from_id (l_feature.feature_name_id)
837 l_loc := l_as.start_location
838 l_feature_name.set_position (l_loc.line, l_loc.column, l_loc.position, 0)
839 l_as.set_feature_name (l_feature_name)
840 end
841 else
842 l_cur_feature := context.current_feature
843 if l_cur_feature = Void then
844 l_enclosing_feature := l_cur_class.invariant_feature
845 else
846 l_enclosing_feature := l_cur_feature.enclosing_feature
847 end
848 l_feature := l_cur_class.inline_agent_with_nr (l_enclosing_feature.body_index, context.inline_agent_counter.next)
849 end
850 end
851
852 -- The context is modified, for the processing of the body of the inline agent.
853 l_context := context.save
854
855 if not is_inherited then
856 create l_used_argument_names.make (1)
857 if l_cur_feature /= Void and then l_cur_feature.argument_count > 0 then
858 from
859 l_arg_names := context.current_feature.arguments.argument_names
860 i := l_arg_names.lower
861 until
862 i > l_arg_names.upper
863 loop
864 l_used_argument_names.force (l_arg_names.item (i))
865 i := i + 1
866 end
867 end
868
869 if l_context.used_argument_names /= Void then
870 l_used_argument_names.merge (l_context.used_argument_names)
871 end
872 context.set_used_argument_names (l_used_argument_names)
873
874 create l_used_local_names.make (1)
875 if l_cur_feature /= Void then
876 if l_cur_feature.is_inline_agent then
877 l_routine ?= context.current_inline_agent_body.content
878 else
879 l_routine ?= l_cur_feature.real_body.content
880 end
881 if l_routine /= Void then
882 l_locals := l_routine.locals
883 if l_locals /= Void and not l_locals.is_empty then
884 from
885 l_locals.start
886 until
887 l_locals.after
888 loop
889 l_id_list := l_locals.item.id_list
890 from
891 l_id_list.start
892 until
893 l_id_list.after
894 loop
895 l_used_local_names.force (l_id_list.item.item)
896 l_id_list.forth
897 end
898 l_locals.forth
899 end
900 end
901 end
902 end
903
904 if l_context.used_local_names /= Void then
905 l_used_local_names.merge (l_context.used_local_names)
906 end
907 context.set_used_local_names (l_used_local_names)
908 end
909
910 context.set_current_feature (l_feature)
911
912 create l_feature_checker
913 l_feature_checker.init (context)
914 context.set_current_inline_agent_body (l_as.body)
915 l_feature_checker.check_body (
916 l_feature, l_as.body, is_byte_node_enabled, is_inherited, True)
917
918 l_body_code ?= l_feature_checker.last_byte_node
919
920 l_new_feature_dep := context.supplier_ids
921 context.restore (l_context)
922 l_context := Void
923
924 if not is_inherited then
925
926 if is_byte_node_enabled then
927
928 l_body_code.set_start_line_number (l_as.body.start_location.line)
929 -- When an inline agent X of an enclosing feature f is a client of
930 -- feature g, we make the enclosing feature f a client of g.
931 if inline_agent_byte_codes = Void then
932 create inline_agent_byte_codes.make
933 end
934 inline_agent_byte_codes.extend (l_body_code)
935 if l_feature_checker.inline_agent_byte_codes /= Void then
936 inline_agent_byte_codes.append (l_feature_checker.inline_agent_byte_codes)
937 end
938 init_inline_agent_dep (l_feature, l_new_feature_dep)
939 end
940 l_as.set_inl_class_id (l_feature.written_in)
941 l_as.set_inl_rout_id (l_feature.rout_id_set.first)
942 end
943 -- Now as the features is generated the inline agent creation is
944 -- threaten like a normal routine creation
945 process_routine_creation_as_ext (l_as, l_feature)
946 rescue
947 if l_context /= Void then
948 context.restore (l_context)
949 end
950 if
951 l_cur_class /= Void and then l_feature /= Void and
952 then
953 not is_inherited and then is_byte_node_enabled
954 then
955 if l_cur_class.inline_agent_table.has (l_feature.feature_name_id) then
956 l_cur_class.inline_agent_table.remove (l_feature.feature_name_id)
957 end
958 end
959 end
960
961 process_create_creation_as (l_as: CREATE_CREATION_AS) is
962 -- Process `l_as'.
963 do
964 process_creation_as (l_as)
965 end
966
967 process_bang_creation_as (l_as: BANG_CREATION_AS) is
968 -- Process `l_as'.
969 do
970 process_creation_as (l_as)
971 end
972
973 process_create_creation_expr_as (l_as: CREATE_CREATION_EXPR_AS) is
974 -- Process `l_as'.
975 do
976 process_creation_expr_as (l_as)
977 end
978
979 process_bang_creation_expr_as (l_as: BANG_CREATION_EXPR_AS) is
980 -- Process `l_as'.
981 do
982 process_creation_expr_as (l_as)
983 end
984
985 feature -- Implementation
986
987 process_custom_attribute_as (l_as: CUSTOM_ATTRIBUTE_AS) is
988 local
989 l_creation: CREATION_EXPR_B
990 l_creation_type: CL_TYPE_A
991 l_ca_b: CUSTOM_ATTRIBUTE_B
992 do
993 check dotnet_generation: system.il_generation end
994 is_checking_cas := True
995 l_as.creation_expr.process (Current)
996 l_creation_type ?= last_type
997 if
998 l_creation_type = Void or else not l_creation_type.has_like or else
999 l_creation_type.has_formal_generic
1000 then
1001 fixme ("Generate an error here as it should be a valid type")
1002 end
1003 if is_byte_node_enabled then
1004 l_creation ?= last_byte_node
1005 create l_ca_b.make (l_creation)
1006 if l_as.tuple /= Void then
1007 check_tuple_validity_for_ca (l_creation_type, l_as.tuple, l_ca_b)
1008 end
1009 last_byte_node := l_ca_b
1010 elseif l_as.tuple /= Void then
1011 check_tuple_validity_for_ca (l_creation_type, l_as.tuple, Void)
1012 end
1013 reset_types
1014 is_checking_cas := False
1015 ensure then
1016 is_checking_cas_reset: not is_checking_cas
1017 rescue
1018 -- If an exception occurs while type checking the custom attribute
1019 -- we need to satisfy our post-condition before passing the exception
1020 -- to our caller.
1021 is_checking_cas := False
1022 end
1023
1024 process_id_as (l_as: ID_AS) is
1025 do
1026 -- Nothing to be done
1027 end
1028
1029 process_integer_as (l_as: INTEGER_CONSTANT) is
1030 do
1031 last_type := l_as.manifest_type
1032 if is_byte_node_enabled then
1033 last_byte_node := l_as
1034 end
1035 end
1036
1037 process_static_access_as (l_as: STATIC_ACCESS_AS) is
1038 local
1039 l_type: TYPE_A
1040 l_needs_byte_node: BOOLEAN
1041 l_vsta1: VSTA1
1042 l_feature: FEATURE_I
1043 do
1044 l_needs_byte_node := is_byte_node_enabled
1045 l_as.class_type.process (Current)
1046 l_type := last_type
1047
1048 -- Check validity of type declaration for static access
1049 if l_type.is_none then
1050 create l_vsta1.make (l_type.dump, l_as.feature_name.name)
1051 l_vsta1.set_class (context.current_class)
1052 l_vsta1.set_location (l_as.class_type.start_location)
1053 error_handler.insert_error (l_vsta1)
1054 error_handler.raise_error
1055 end
1056
1057 instantiator.dispatch (l_type, context.current_class)
1058
1059 if is_inherited then
1060 l_feature := last_type.associated_class.feature_of_rout_id (l_as.routine_ids.first)
1061 end
1062
1063 process_call (l_type, Void, l_as.feature_name, l_feature, l_as.parameters, True, False, True, False)
1064 error_handler.checksum
1065
1066 if not is_inherited then
1067 l_as.set_routine_ids (last_routine_id_set)
1068 l_as.set_class_id (last_calls_target_type.associated_class.class_id)
1069 end
1070 end
1071
1072 process_call (
1073 a_type, a_precursor_type: TYPE_A; a_name: ID_AS; a_feature: FEATURE_I;
1074 a_params: EIFFEL_LIST [EXPR_AS]; is_static, is_agent, is_qualified, is_precursor: BOOLEAN)
1075 is
1076 -- Process call to `a_name' in context of `a_type' with `a_params' if ANY.
1077 -- If `is_static' it is a static call.
1078 --
1079 -- `a_type': Target on which feature is called
1080 -- `a_precursor_type': Target type of precursor call, i.e Precursor {A_PRECURSOR_TARGET_TYPE} (a_params)
1081 -- `a_name': Name of called feature
1082 -- `a_feature': Feature object if alredy known
1083 -- `a_params': List of parameters to the call
1084 -- `is_static': Indicates a static call (C external or constant)
1085 -- `is_qualified': True => Call of the form 'a.b' / False => Call of the form 'b'
1086 -- `is_precursor': True => Call of the form Precursor {A_PRECURSOR_TYPE} (a_params)
1087 require
1088 a_type_not_void: a_type /= Void
1089 a_precursor_type_not_void: is_precursor implies a_precursor_type /= Void
1090 a_name_not_void: a_feature = Void implies a_name /= Void
1091 local
1092 l_arg_nodes: BYTE_LIST [EXPR_B]
1093 l_arg_types, l_conformance_arg_types: like last_expressions_type
1094 l_formal_arg_type, l_like_arg_type: TYPE_A
1095 l_like_argument: LIKE_ARGUMENT
1096 l_cl_type_a: CL_TYPE_A
1097 l_feature: FEATURE_I
1098 l_seed: FEATURE_I
1099 i, l_actual_count, l_formal_count: INTEGER
1100 -- Id of the class type on the stack
1101 l_arg_type: TYPE_A
1102 l_last_type: TYPE_A
1103 l_last_constrained: TYPE_A
1104 l_last_type_set: TYPE_SET_A
1105 -- Type onto the stack
1106 l_last_id: INTEGER
1107 -- Id of the class correponding to `l_last_type'
1108 l_last_class: CLASS_C
1109 l_context_current_class: CLASS_C
1110 l_depend_unit: DEPEND_UNIT
1111 l_access: ACCESS_B
1112 l_ext: EXTERNAL_B
1113 l_vuar1: VUAR1
1114 l_vuex: VUEX
1115 l_vkcn3: VKCN3
1116 l_obs_warn: OBS_FEAT_WARN
1117 l_vape: VAPE
1118 l_open_type: OPEN_TYPE_A
1119 l_is_in_creation_expression, l_is_target_of_creation_instruction: BOOLEAN
1120 l_feature_name: ID_AS
1121 l_parameters: EIFFEL_LIST [EXPR_AS]
1122 l_needs_byte_node: BOOLEAN
1123 l_conv_info: CONVERSION_INFO
1124 l_expr: EXPR_B
1125 l_result_type, l_pure_result_type: TYPE_A
1126 l_generated_result_type: TYPE_A
1127 l_veen: VEEN
1128 l_vsta2: VSTA2
1129 l_vica2: VICA2
1130 l_cl_type_i: CL_TYPE_I
1131 l_parameter: PARAMETER_B
1132 l_parameter_list: BYTE_LIST [PARAMETER_B]
1133 l_is_assigner_call, l_is_last_access_tuple_access: BOOLEAN
1134 l_named_tuple: NAMED_TUPLE_TYPE_A
1135 l_label_pos: INTEGER
1136 l_formal: FORMAL_A
1137 l_last_feature_table: FEATURE_TABLE
1138 l_is_multiple_constraint_case: BOOLEAN
1139 l_result_tuple: TUPLE[feature_item: FEATURE_I; class_type_of_feature: CL_TYPE_A; features_found_count: INTEGER; constraint_position: INTEGER]
1140 l_last_original_feature_name_id: INTEGER
1141 l_tuple_access_b: TUPLE_ACCESS_B
1142 l_vtmc1: VTMC1
1143 l_gen_type: GEN_TYPE_A
1144 l_cat_call_warning: CAT_CALL_WARNING
1145 do
1146 -- Reset
1147 if a_feature = Void then
1148 last_calls_target_type := Void
1149 end
1150 l_needs_byte_node := is_byte_node_enabled
1151
1152 -- Retrieve if we are type checking a routine that is the creation
1153 -- routine of a creation expression. As soon as we know this, we
1154 -- reset `l_is_in_creation_expression' to False, so that if any parameter
1155 -- of the creation routine is also a creation expression we perform
1156 -- a correct type checking of the VAPE errors.
1157 l_is_in_creation_expression := is_in_creation_expression
1158 l_is_target_of_creation_instruction := is_target_of_creation_instruction
1159 is_in_creation_expression := False
1160 is_target_of_creation_instruction := False
1161 is_last_access_tuple_access := False
1162
1163 -- Reset assigner call flag
1164 l_is_assigner_call := is_assigner_call
1165 is_assigner_call := False
1166
1167 -- `a_name' can be void for inline agents
1168 if a_name /= Void then
1169 l_feature_name := a_name
1170 -- We need to store the original name as it may change due to
1171 -- renamings applied of multi constraint formal generics.
1172 l_last_original_feature_name_id := a_name.name_id
1173 last_original_feature_name_id := l_last_original_feature_name_id
1174 check
1175 last_original_feature_name_correct: last_original_feature_name = a_name.name
1176 end
1177 else
1178 last_original_feature_name_id := 0
1179 end
1180
1181 l_context_current_class := context.current_class
1182
1183 l_last_type := a_type.actual_type
1184 if not l_last_type.is_formal then
1185 if l_last_type.is_void then
1186 -- No call when target is a procedure
1187 create l_vkcn3
1188 context.init_error (l_vkcn3)
1189 l_vkcn3.set_location (l_feature_name)
1190 error_handler.insert_error (l_vkcn3)
1191 -- Cannot go on here
1192 error_handler.raise_error
1193 end
1194 -- We have no formal, therefore we don't need to recompute `l_last_constrained'
1195 l_last_constrained := l_last_type
1196 -- Protect if constrained type is NONE.
1197 if l_last_constrained.has_associated_class then
1198 l_last_class := l_last_type.associated_class
1199 l_last_id := l_last_class.class_id
1200 l_last_feature_table := l_last_class.feature_table
1201 else
1202 check l_last_constrained_is_none: l_last_constrained.is_none end
1203 end
1204 else
1205 l_formal ?= l_last_type
1206 if not l_formal.is_single_constraint_without_renaming (l_context_current_class) then
1207 l_last_type_set := l_last_type.to_type_set.constraining_types (l_context_current_class)
1208 -- from now on we know that we have multiple constraints
1209 -- we cannot compute `l_last_class', `l_last_id', ... as we do not know which
1210 -- which type to take out of the type set. we know it after we computed the feature.
1211 l_is_multiple_constraint_case := True
1212 else
1213 -- Resolve formal type
1214 l_last_constrained := l_formal.constrained_type (l_context_current_class)
1215 -- Protect if constrained type is NONE.
1216 if l_last_constrained.has_associated_class then
1217 l_last_class := l_last_constrained.associated_class
1218 l_last_id := l_last_class.class_id
1219 l_last_feature_table := l_last_class.feature_table
1220 else
1221 check l_last_constrained_is_none: l_last_constrained.is_none end
1222 end
1223 end
1224 end
1225 -- Check for `NONE'
1226 if
1227 (l_last_constrained /= Void and then l_last_constrained.is_none) or
1228 (l_last_type_set /= Void and then l_last_type_set.has_none)
1229 then
1230 create l_vuex.make_for_none (l_feature_name.name)
1231 context.init_error (l_vuex)
1232 l_vuex.set_location (l_feature_name)
1233 error_handler.insert_error (l_vuex)
1234 -- Cannot go on here
1235 error_handler.raise_error
1236 end
1237
1238 l_parameters := a_params
1239 if l_parameters /= Void then
1240 l_actual_count := l_parameters.count
1241 end
1242
1243 if a_feature /= Void then
1244 l_feature := a_feature
1245 if l_is_multiple_constraint_case then
1246 l_last_constrained := last_calls_target_type
1247 elseif l_formal /= Void then
1248 l_last_constrained := l_formal.constrained_type (l_context_current_class)
1249 else
1250 l_last_constrained := a_type
1251 end
1252
1253 check has_associated_class: l_last_constrained.has_associated_class end
1254 l_last_class := l_last_constrained.associated_class
1255 l_last_id := l_last_class.class_id
1256 else
1257 if l_is_multiple_constraint_case then
1258 check type_set_available: l_last_type_set /= Void end
1259 check no_last_constraint: l_last_constrained = Void end
1260 check no_last_class: l_last_class = Void end
1261 check no_last_id: l_last_id = 0 end
1262 -- NOTE: The look-up for overlaoded functions for .NET is not done because it's not used so often.
1263 l_result_tuple := l_last_type_set.feature_i_state_by_name_id (l_feature_name.name_id)
1264 -- If there we did not found a feature it could still be a tuple item.
1265 if l_result_tuple.features_found_count > 1 then
1266 raise_vtmc_error (l_feature_name, l_formal.position, l_context_current_class)
1267 end
1268 l_feature := l_result_tuple.feature_item
1269 l_last_constrained := l_result_tuple.class_type_of_feature
1270 -- If no feature was found it is void.
1271 if l_last_constrained /= Void then
1272 l_last_class := l_last_constrained.associated_class
1273 l_last_id := l_last_class.class_id
1274 end
1275 else
1276 check no_type_set_available: l_last_type_set = Void end
1277 check last_constrained_available: l_last_constrained /= Void end
1278 check last_class_available: l_last_class /= Void end
1279 check last_class_id_available: l_last_id > 0 end
1280 -- Look for a feature in the class associated to the
1281 -- last actual type onto the context type stack. If it
1282 -- is a generic take the associated constraint.
1283 if l_last_feature_table.has_overloaded (l_feature_name.name_id) then
1284 -- Evaluate parameters. This is needed for overloading resolution.
1285 -- Note: if one parameter is a manifest array, then its type is resolved
1286 -- without context.
1287 if l_parameters /= Void then
1288 l_actual_count := l_parameters.count
1289 current_target_type := Void
1290 process_expressions_list (l_parameters)
1291 l_arg_types := last_expressions_type
1292 if l_needs_byte_node then
1293 l_arg_nodes ?= last_byte_node
1294 end
1295 end
1296 l_feature := overloaded_feature (l_last_type, l_last_class, l_arg_types,
1297 l_feature_name, is_static)
1298 if l_feature /= Void then
1299 -- Update `l_feature_name' with appropriate resolved name.
1300 -- Otherwise some routine using `l_feature_name' will fail although
1301 -- it succeeds here (e.g. CREATION_EXPR_AS and CREATION_AS)
1302 create l_feature_name.initialize_from_id (l_feature.feature_name_id)
1303 end
1304 else
1305 l_feature := l_last_feature_table.item_id (l_feature_name.name_id)
1306 end
1307 end
1308 end
1309
1310 check
1311 -- If we found a feature all the necessary information should be computed.
1312 state_correct: l_feature /= Void implies (
1313 l_last_constrained /= Void and then
1314 l_last_class /= Void and then
1315 l_last_id > 0)
1316 end
1317
1318 -- No feature was found, so if the target of the call is a named tuple
1319 -- then it might be a call on one of its label.
1320 --| This we only check in the case of single cosntraint formals.
1321 --| It does not make any sense to check it for multi constraints as
1322 --| one is not allowed to inherit from `TUPLE'.
1323
1324 if l_feature = Void then
1325 l_named_tuple ?= l_last_type
1326 if l_named_tuple /= Void then
1327 l_label_pos := l_named_tuple.label_position_by_id (l_feature_name.name_id)
1328 if l_label_pos > 0 then
1329 last_type := l_named_tuple.generics.item (l_label_pos)
1330 l_is_last_access_tuple_access := True
1331 last_feature_name_id := l_feature_name.name_id
1332 -- No renaming possible (from RENAMED_TYPE_A [TYPE_A]), they are the same
1333 last_original_feature_name_id := last_feature_name_id
1334 check
1335 last_feature_name_correct: last_feature_name = l_feature_name.name
1336 end
1337 if l_needs_byte_node then
1338 create {TUPLE_ACCESS_B} l_tuple_access_b.make (l_named_tuple.type_i, l_label_pos)
1339 last_byte_node := l_tuple_access_b
1340 last_byte_node.set_line_number (l_feature_name.line)
1341 end
1342 end
1343 end
1344 elseif not system.il_generation then
1345 if l_feature.is_inline_agent then
1346 l_seed := l_feature
1347 else
1348 l_seed := system.seed_of_routine_id (l_feature.rout_id_set.first)
1349 end
1350 end
1351 if not l_is_last_access_tuple_access then
1352 if l_feature /= Void and then (not is_static or else l_feature.has_static_access) then
1353 -- Attachments type check
1354 l_formal_count := l_feature.argument_count
1355 if is_agent and l_actual_count = 0 and l_formal_count > 0 then
1356 -- Delayed call with all arguments open.
1357 -- Create l_parameters.
1358 from
1359 create l_parameters.make_filled (l_formal_count)
1360 l_parameters.start
1361 until
1362 l_parameters.after
1363 loop
1364 l_parameters.put (create {OPERAND_AS}.initialize (Void, Void, Void))
1365 l_parameters.forth
1366 end
1367 l_actual_count := l_formal_count
1368 current_target_type := Void
1369 process_expressions_list (l_parameters)
1370 l_arg_types := last_expressions_type
1371 if l_needs_byte_node then
1372 l_arg_nodes ?= last_byte_node
1373 end
1374 l_parameters.start
1375 end
1376 if l_actual_count /= l_formal_count then
1377 create l_vuar1
1378 context.init_error (l_vuar1)
1379 l_vuar1.set_called_feature (l_feature, l_last_id)
1380 l_vuar1.set_argument_count (l_actual_count)
1381 l_vuar1.set_formal_count (l_feature.argument_count)
1382 l_vuar1.set_location (l_feature_name)
1383 error_handler.insert_error (l_vuar1)
1384 -- Cannot go on here: too dangerous
1385 error_handler.raise_error
1386 elseif l_parameters /= Void then
1387 if l_needs_byte_node then
1388 create l_parameter_list.make (l_actual_count)
1389 end
1390 if l_arg_types /= Void then
1391 -- Parameters have been evaluated, nothing to be done.
1392 -- Case for overloaded routine call or agent with all open arguments.
1393 l_actual_count := l_actual_count + 1 -- Optimization for loop exit
1394 else
1395 -- Parameters haven't yet evaluated
1396 from
1397 i := 1
1398 create l_arg_types.make (1, l_actual_count)
1399 if l_needs_byte_node then
1400 create l_arg_nodes.make (l_actual_count)
1401 end
1402 l_actual_count := l_actual_count + 1 -- Optimization for loop exit
1403 until
1404 i = l_actual_count
1405 loop
1406 -- Get formal argument type.
1407 l_formal_arg_type := l_feature.arguments.i_th (i)
1408
1409 reset_for_unqualified_call_checking
1410 if l_formal_arg_type.is_like_argument then
1411 -- To bad we are not able to evaluate with a target context a manifest array
1412 -- passed as argument where formal is an anchor type.
1413 current_target_type := Void
1414 else
1415 current_target_type :=
1416 l_formal_arg_type.instantiation_in (l_last_type, l_last_id).actual_type
1417 end
1418 l_parameters.i_th (i).process (Current)
1419 l_arg_types.put (last_type, i)
1420 if l_needs_byte_node then
1421 l_expr ?= last_byte_node
1422 l_arg_nodes.extend (l_expr)
1423 end
1424 i := i + 1
1425 end
1426 end
1427
1428 -- Conformance checking of arguments
1429 from
1430 i := 1
1431 until
1432 i = l_actual_count
1433 loop
1434 -- Get actual argument type.
1435 l_arg_type := l_arg_types.item (i)
1436
1437 -- Get formal argument type.
1438 l_formal_arg_type := l_feature.arguments.i_th (i)
1439
1440 -- Take care of anchoring to argument
1441 if l_formal_arg_type.is_like_argument then
1442 l_like_arg_type := l_formal_arg_type.actual_argument_type (l_arg_types)
1443 l_like_arg_type :=
1444 l_like_arg_type.instantiation_in (l_last_type, l_last_id).actual_type
1445 -- Check that `l_arg_type' is compatible to its `like argument'.
1446 -- Once this is done, then type checking is done on the real
1447 -- type of the routine, not the anchor.
1448 if
1449 not l_arg_type.conform_to (l_like_arg_type) and then
1450 not l_arg_type.convert_to (context.current_class, l_like_arg_type)
1451 then
1452 insert_vuar2_error (l_feature, l_parameters, l_last_id, i, l_arg_type,
1453 l_like_arg_type)
1454 end
1455 end
1456
1457 -- Adapted type in case it is a formal generic parameter or a like.
1458 l_formal_arg_type := adapted_type (l_formal_arg_type, l_last_type, l_last_constrained)
1459 -- Actual type of feature argument
1460 l_formal_arg_type := l_formal_arg_type.instantiation_in (l_last_type, l_last_id).actual_type
1461
1462 -- Variance check: First, check if argument is a formal.
1463 l_formal ?= l_formal_arg_type.conformance_type
1464 if l_formal /= Void then
1465 -- The actual generic parameter is a formal. If the actual generic parameter
1466 -- is marked as 'variant' we insert an error
1467 l_gen_type ?= l_last_constrained.conformance_type
1468 check
1469 -- l_gen_type can be Void only in one case:
1470 -- * If a call is made on a formal generic which has the argument `like Current':
1471 -- e.g. v: G; v.is_equal (v). Then the argument is formal but the target type is not a gen-type
1472 -- Otherwise, if the argument is a formal, the target is a gen type
1473 l_feature.arguments.i_th (i).is_like_current or else l_gen_type /= Void
1474 end
1475 if l_gen_type /= Void and then l_gen_type.is_covariant (l_formal.position) then
1476 insert_vuar3_error (l_feature, l_parameters, l_last_id, i, l_arg_type,
1477 l_formal)
1478 end
1479 end
1480
1481 -- `like Current' check: First, check if argument is a `like Current' somwhere in the chain of likes.
1482 if l_formal_arg_type.actual_type.is_like_current then
1483 -- The call is only allowed in one case:
1484 -- * It is called on a monomorphic type
1485 -- Note: This includes `Current' and therefore `like Current' also
1486 -- formals marked as frozen are ok
1487
1488 if not l_last_constrained.conformance_type.is_monomorph and then not l_last_constrained.actual_type.is_like_current then
1489 insert_vuar4_error (l_feature, l_parameters, l_last_id, i, l_last_constrained, l_arg_type, l_formal_arg_type)
1490 end
1491 end
1492 -- Conformance: take care of constrained genericity
1493 -- We must generate an error when `l_formal_arg_type' becomes
1494 -- an OPEN_TYPE_A, for example "~equal (?, b)" will
1495 -- check that the type of `b' conforms to type of `?'
1496 -- since `equal' is defined as `equal (a: ANY; b: like a)'.
1497 -- However `conform_to' does not work when parameter
1498 -- is an OPEN_TYPE_A type. Since this checks can only
1499 -- happens in type checking of an agent, we can do it
1500 -- at only one place, ie here.
1501 l_open_type ?= l_formal_arg_type
1502 if l_open_type /= Void or else not l_arg_type.conform_to (l_formal_arg_type) then
1503 if
1504 l_open_type = Void and
1505 l_arg_type.convert_to (context.current_class, l_formal_arg_type)
1506 then
1507 l_conv_info := context.last_conversion_info
1508 if l_conv_info.has_depend_unit then
1509 context.supplier_ids.extend (l_conv_info.depend_unit)
1510 end
1511
1512 -- Store conversion info for catcall check later on
1513 if l_conformance_arg_types = Void then
1514 l_conformance_arg_types := l_arg_types.twin
1515 end
1516 l_conformance_arg_types [i] := l_formal_arg_type
1517
1518 -- Generate conversion byte node only if we are not checking
1519 -- a custom attribute. Indeed in that case, we do not want those
1520 -- conversion routines, we will use the attachment type to figure
1521 -- out how the custom attribute will be generated.
1522 if l_needs_byte_node and not is_checking_cas then
1523 l_expr ?= l_arg_nodes.i_th (i)
1524 l_arg_nodes.put_i_th (l_conv_info.byte_node (l_expr), i)
1525 end
1526 elseif
1527 l_arg_type.is_expanded and then l_formal_arg_type.is_external and then
1528 l_arg_type.is_conformant_to (l_formal_arg_type)
1529 then
1530 -- No need for conversion, this is currently done at the code
1531 -- generation level to properly handle the generic case.
1532 -- If not done at the code generation, we would need the
1533 -- following lines.
1534 -- l_expr ?= l_arg_nodes.i_th (i)
1535 -- l_arg_nodes.put_i_th ((create {BOX_CONVERSION_INFO}.make (l_arg_type)).
1536 -- byte_node (l_expr), i)
1537 else
1538 insert_vuar2_error (l_feature, l_parameters, l_last_id, i, l_arg_type,
1539 l_formal_arg_type)
1540 end
1541 end
1542 if l_needs_byte_node then
1543 create l_parameter
1544 l_expr ?= l_arg_nodes.i_th (i)
1545 l_parameter.set_expression (l_expr)
1546 -- Partial solution to the case of using Precursor in an expanded
1547 -- class where some of the arguments are not expanded in the parent
1548 -- class but are now in the current class (a typical example is
1549 -- `prefix "not": like Current' defined in BOOLEAN_REF which is kept
1550 -- as is in BOOLEAN). We need to remember that the original type
1551 -- were not expanded otherwise we do not perform a proper code
1552 -- generation.
1553 -- This fix is incomplete since it does not take care of types
1554 -- that are redefined as expanded.
1555 if a_precursor_type /= Void and l_last_class.is_expanded then
1556 l_parameter.set_attachment_type (l_formal_arg_type.instantiation_in (a_precursor_type, a_precursor_type.associated_class.class_id).type_i)
1557 else
1558 l_parameter.set_attachment_type (l_formal_arg_type.type_i)
1559 if not system.il_generation then
1560 l_parameter.set_is_formal (l_seed.arguments.i_th (i).type_i.is_formal)
1561 end
1562 end
1563 l_parameter_list.extend (l_parameter)
1564
1565 if is_checking_cas then
1566 fixme ("[
1567 Validity checking should not be done when byte code generation
1568 is required. But unfortunately we need the compiled version to get
1569 information about the parameters.
1570 ]")
1571 if not l_expr.is_constant_expression then
1572 create l_vica2.make (context.current_class, current_feature)
1573 l_vica2.set_location (l_parameters.i_th (i).start_location)
1574 error_handler.insert_error (l_vica2)
1575 end
1576 end
1577 end
1578 i := i + 1
1579 end
1580 end
1581
1582 -- Reset original name because it was polluted by the argument checking
1583 last_original_feature_name_id := l_last_original_feature_name_id
1584 check
1585 last_original_feature_name_correct: a_name /= Void implies (last_original_feature_name = a_name.name)
1586 end
1587
1588 -- Get the type of Current feature.
1589 l_result_type := l_feature.type
1590 -- Adapted type in case it is a formal generic parameter or a like.
1591 l_result_type := adapted_type (l_result_type, l_last_type, l_last_constrained)
1592 if l_arg_types /= Void then
1593 l_pure_result_type := l_result_type
1594 l_result_type := l_result_type.actual_argument_type (l_arg_types)
1595 l_open_type ?= l_result_type
1596 if l_open_type /= Void then
1597 -- It means that the result type is a like argument. In that case,
1598 -- we take the static signature of the feature to evaluate `l_result_type'.
1599 -- This fix eweasel test#term141.
1600 l_result_type := l_pure_result_type.actual_argument_type (l_feature.arguments)
1601 end
1602 end
1603 l_result_type := l_result_type.instantiation_in (l_last_type, l_last_id).actual_type
1604 if l_arg_types /= Void and then l_pure_result_type.is_like_argument and then is_byte_node_enabled then
1605 -- Ensure the expandedness status of the result type matches
1606 -- the expandedness status of the argument it is anchored to (if any).
1607 l_like_argument ?= l_pure_result_type
1608 check
1609 l_like_argument_attached: l_like_argument /= Void
1610 end
1611 i := l_like_argument.position
1612 if l_feature.arguments.i_th (i).actual_type.is_reference and then l_result_type.is_expanded then
1613 l_cl_type_a ?= l_result_type
1614 if l_cl_type_a /= Void then
1615 l_generated_result_type := l_cl_type_a.reference_type
1616 end
1617 end
1618 end
1619 -- Export validity
1620 if
1621 not context.is_ignoring_export and is_qualified and
1622 not l_feature.is_exported_for (context.current_class)
1623 then
1624 create l_vuex
1625 context.init_error (l_vuex)
1626 l_vuex.set_static_class (l_last_class)
1627 l_vuex.set_exported_feature (l_feature)
1628 l_vuex.set_location (l_feature_name)
1629 error_handler.insert_error (l_vuex)
1630 end
1631 if
1632 l_feature.is_obsolete
1633 -- If the obsolete call is in an obsolete class,
1634 -- no message is displayed
1635 and then not context.current_class.is_obsolete
1636 -- The current feature is whether the invariant or
1637 -- a non obsolete feature
1638 and then (current_feature = Void or else
1639 not current_feature.is_obsolete)
1640 -- Inherited code is checked in parent class.
1641 and then not is_inherited
1642 -- Warning not disabled
1643 and then context.current_class.is_warning_enabled (w_obsolete_feature)
1644 then
1645 create l_obs_warn
1646 l_obs_warn.set_class (context.current_class)
1647 l_obs_warn.set_obsolete_class (l_last_constrained.associated_class)
1648 l_obs_warn.set_obsolete_feature (l_feature)
1649 l_obs_warn.set_feature (current_feature)
1650 error_handler.insert_warning (l_obs_warn)
1651 end
1652 if
1653 not System.do_not_check_vape and then is_checking_precondition and then
1654 not l_is_in_creation_expression and then
1655 not current_feature.export_status.is_subset (l_feature.export_status)
1656 then
1657 -- In precondition and checking for vape
1658 create l_vape
1659 context.init_error (l_vape)
1660 l_vape.set_exported_feature (l_feature)
1661 l_vape.set_location (l_feature_name)
1662 error_handler.insert_error (l_vape)
1663 error_handler.raise_error
1664 end
1665
1666 -- Supplier dependances update
1667 if not l_feature.is_inline_agent then
1668 if l_is_target_of_creation_instruction then
1669 create l_depend_unit.make_with_level (l_last_id, l_feature,
1670 {DEPEND_UNIT}.is_in_creation_flag | depend_unit_level)
1671 else
1672 if is_precursor then
1673 create l_depend_unit.make_with_level (a_precursor_type.associated_class.class_id, l_feature,
1674 depend_unit_level)
1675 context.supplier_ids.extend (l_depend_unit)
1676 end
1677 create l_depend_unit.make_with_level (l_last_id, l_feature, depend_unit_level)
1678 end
1679 context.supplier_ids.extend (l_depend_unit)
1680 end
1681
1682 if l_is_assigner_call then
1683 process_assigner_command (l_last_id, l_feature)
1684 end
1685
1686 if l_needs_byte_node then
1687 if l_generated_result_type = Void then
1688 l_generated_result_type := l_result_type
1689 end
1690 if not is_static then
1691 if is_precursor then
1692 l_cl_type_i ?= a_precursor_type.type_i
1693 l_access := l_feature.access_for_feature (l_generated_result_type.type_i, l_cl_type_i, False)
1694 -- Strange situation where Precursor is an external, then we do as if
1695 -- it was a static call.
1696 l_ext ?= l_access
1697 if l_ext /= Void then
1698 l_ext.enable_static_call
1699 end
1700 else
1701 if l_is_multiple_constraint_case then
1702 check not l_last_constrained.type_i.is_formal end
1703 l_access := l_feature.access_for_multi_constraint (l_generated_result_type.type_i, l_last_constrained.type_i, is_qualified)
1704 else
1705 l_access := l_feature.access (l_generated_result_type.type_i, is_qualified)
1706 end
1707 end
1708 else
1709 l_access := l_feature.access_for_feature (l_generated_result_type.type_i, a_type.type_i, is_qualified)
1710 if l_is_multiple_constraint_case then
1711 check not l_last_constrained.type_i.is_formal end
1712 l_access.set_multi_constraint_static (l_last_constrained.type_i)
1713 end
1714 l_ext ?= l_access
1715 if l_ext /= Void then
1716 l_ext.enable_static_call
1717 end
1718 end
1719 l_access.set_parameters (l_parameter_list)
1720 last_byte_node := l_access
1721 end
1722
1723 -- Check if cat-call detection is enabled for current context class
1724 if context.current_class.is_cat_call_detection then
1725 -- An error is added if all of the following conditions apply:
1726 -- * Qualified call:
1727 -- Unqualified calls don't need to be checked as their target, `Current', is monomorph
1728 -- * The feature is marked as manualy covariant (not "generic" or "like Current" covariance
1729 -- this has been handled before):
1730 -- features which are not marked covariant don't need to be checked
1731 -- * `l_last_type' is not monomorph or formal:
1732 -- Calls on monomorph types don't need to be checked. Formals are an exception as they
1733 -- can be derived with any type which fits their constraint, so even monomorph formals
1734 -- need to be checked
1735 -- * Not inline agent, static calls or frozen calls:
1736 -- There are no descendant features which could overwrite the arguments covariantly
1737 -- Note: The static and inline agent check is probably not necessary, as these features
1738 -- are not marked as covariant anyway. This is also true for frozen features:
1739 -- They can never be redefined covariantly.
1740 if
1741 is_qualified and then
1742 system.covariant_argument_index.is_covariantly_redefined (l_feature.rout_id_set.first, l_last_constrained.associated_class) and then
1743 (not l_last_type.is_monomorph or else l_last_type.is_formal)
1744 then
1745 check
1746 not_a_call_to_a_inline_agent: not l_feature.is_inline_agent
1747 not_a_static_call: not is_static
1748 not_a_frozen_feature: not l_feature.is_frozen
1749 end
1750
1751 -- Report an error
1752 create l_cat_call_warning.make (context.current_class, context.current_feature, l_feature_name)
1753 l_cat_call_warning.set_called_feature (l_feature)
1754 error_handler.insert_warning (l_cat_call_warning)
1755 end
1756 -- Statistics
1757 system.statistics.feature_calls := system.statistics.feature_calls + 1
1758 if l_feature.argument_count > 0 then
1759 system.statistics.feature_arguments := system.statistics.feature_arguments + 1
1760 end
1761 end
1762
1763 last_type := l_result_type
1764 last_calls_target_type := l_last_constrained
1765 last_access_writable := l_feature.is_attribute
1766 last_feature_name_id := l_feature.feature_name_id
1767 check
1768 last_feature_name_correct: last_feature_name = l_feature.feature_name
1769 end
1770 last_routine_id_set := l_feature.rout_id_set
1771 else
1772 -- `l_feature' was not valid for current, report
1773 -- corresponding error.
1774 if l_feature = Void then
1775 -- Not a valid feature name.
1776 -- In case of a multi constraint we throw a VTMC1 error instead of a VEEN.
1777 if l_is_multiple_constraint_case then
1778 create l_vtmc1
1779 context.init_error (l_vtmc1)
1780 l_vtmc1.set_feature_call_name (l_feature_name.name)
1781 l_vtmc1.set_location (l_feature_name)
1782 l_vtmc1.set_type_set (l_last_type_set)
1783 l_vtmc1.set_location (l_feature_name)
1784 error_handler.insert_error (l_vtmc1)
1785 error_handler.raise_error
1786 else
1787 create l_veen
1788 context.init_error (l_veen)
1789 l_veen.set_identifier (l_feature_name.name)
1790 l_veen.set_parameter_count (l_actual_count)
1791 l_veen.set_location (l_feature_name)
1792 error_handler.insert_error (l_veen)
1793 error_handler.raise_error
1794 end
1795 elseif is_static then
1796 -- Not a valid feature for static access.
1797 create l_vsta2
1798 context.init_error (l_vsta2)
1799 l_vsta2.set_non_static_feature (l_feature)
1800 l_vsta2.set_location (l_feature_name)
1801 error_handler.insert_error (l_vsta2)
1802 error_handler.raise_error
1803 end
1804 end
1805 end
1806 -- Finally update current to reflect if current call is a tuple
1807 -- access or not.
1808 is_last_access_tuple_access := l_is_last_access_tuple_access
1809 if l_is_last_access_tuple_access then
1810 -- Properly update current to show we have just accessed a tuple.
1811 last_access_writable := True
1812 last_routine_id_set := Void
1813 end
1814 ensure
1815 last_calls_target_type_proper_set: not (error_handler.has_error or is_last_access_tuple_access) implies last_calls_target_type /= Void
1816 end
1817
1818 process_feature_clause_as (l_as: FEATURE_CLAUSE_AS) is
1819 do
1820 -- Nothing to be done
1821 end
1822
1823 process_unique_as (l_as: UNIQUE_AS) is
1824 do
1825 -- Nothing to be done
1826 end
1827
1828 process_tuple_as (l_as: TUPLE_AS) is
1829 local
1830 l_tuple_type: TUPLE_TYPE_A
1831 l_list: BYTE_LIST [EXPR_B]
1832 do
1833 reset_for_unqualified_call_checking
1834
1835 -- Type check expression list
1836 process_expressions_list_for_tuple (l_as.expressions)
1837
1838 -- Update type stack
1839 create l_tuple_type.make (system.tuple_id, last_expressions_type)
1840 instantiator.dispatch (l_tuple_type, context.current_class)
1841 last_tuple_type := l_tuple_type
1842 last_type := l_tuple_type
1843
1844 if is_byte_node_enabled then
1845 l_list ?= last_byte_node
1846 create {TUPLE_CONST_B} last_byte_node.make (l_list, l_tuple_type.type_i)
1847 end
1848 ensure then
1849 last_tuple_type_set: last_tuple_type /= Void
1850 end
1851
1852 process_real_as (l_as: REAL_AS) is
1853 do
1854 if l_as.constant_type = Void then
1855 last_type := Real_64_type
1856 else
1857 fixme ("We should check that `constant_type' matches the real `value' and%
1858 %possibly remove `constant_type' from REAL_AS.")
1859 check_type (l_as.constant_type)
1860 end
1861 if is_byte_node_enabled then
1862 create {REAL_CONST_B} last_byte_node.make (l_as.value, last_type)
1863 end
1864 end
1865
1866 process_bool_as (l_as: BOOL_AS) is
1867 do
1868 last_type := Boolean_type
1869 if is_byte_node_enabled then
1870 create {BOOL_CONST_B} last_byte_node.make (l_as.value)
1871 end
1872 end
1873
1874 process_bit_const_as (l_as: BIT_CONST_AS) is
1875 do
1876 create {BITS_A} last_type.make (l_as.value.name.count)
1877 if is_byte_node_enabled then
1878 create {BIT_CONST_B} last_byte_node.make (l_as.value.name)
1879 end
1880 end
1881
1882 process_array_as (l_as: ARRAY_AS) is
1883 local
1884 i, nb: INTEGER
1885 l_array_type: GEN_TYPE_A
1886 l_generics: ARRAY [TYPE_A]
1887 l_type_a, l_element_type: TYPE_A
1888 l_list: BYTE_LIST [EXPR_B]
1889 l_gen_type: GEN_TYPE_A
1890 l_last_types: like last_expressions_type
1891 l_has_error: BOOLEAN
1892 l_has_array_target: BOOLEAN
1893 do
1894 reset_for_unqualified_call_checking
1895 -- Get target for manifest array creation (either through assignment or
1896 -- argument passing).
1897 l_gen_type ?= current_target_type
1898 -- Let's try to find the type of the manifest array.
1899 if l_gen_type /= Void then
1900 -- Check that it is either an ARRAY, or a NATIVE_ARRAY when used
1901 -- in a custom attribute.
1902 if
1903 l_gen_type.class_id = system.array_id or
1904 (is_checking_cas and then l_gen_type.class_id = system.native_array_id)
1905 then
1906 l_has_array_target := True
1907 -- Check that expressions' type matches element's type of `l_gen_type' array.
1908 l_element_type := l_gen_type.generics.item (1).actual_type
1909 end
1910 end
1911
1912 -- Type check expression list
1913 -- If there is a manifest array within a manifest array, we consider there is
1914 -- no target type specified.
1915 nb := l_as.expressions.count
1916 current_target_type := l_element_type
1917 process_expressions_list (l_as.expressions)
1918 l_last_types := last_expressions_type
1919
1920 if is_byte_node_enabled then
1921 l_list ?= last_byte_node
1922 end
1923
1924 -- Let's try to find the type of the manifest array.
1925 if l_has_array_target then
1926 -- Check that expressions' type matches element's type of `l_gen_type' array.
1927 l_type_a := l_element_type
1928 if nb > 0 then
1929 from
1930 i := 1
1931 until
1932 i > nb
1933 loop
1934 l_element_type := l_last_types.item (i)
1935 if not l_element_type.conform_to (l_type_a) then
1936 if l_element_type.convert_to (context.current_class, l_type_a) then
1937 if is_byte_node_enabled and not is_checking_cas then
1938 l_list.put_i_th (context.last_conversion_info.byte_node (
1939 l_list.i_th (i)), i)
1940 end
1941 else
1942 l_has_error := True
1943 i := nb + 1 -- Exit the loop
1944 end
1945 end
1946 i := i + 1
1947 end
1948 end
1949 if not l_has_error then
1950 -- We could keep `l_gen_type' for `l_array_type', but unfortunately it
1951 -- causes the eweasel test `term131' to fail because if it contains an
1952 -- anchor then it is not marked as used for dead code removal (because
1953 -- anchor appears in signature and signatures are not solved for dependances
1954 -- at degree 4) and we would crash while generating the table at the very
1955 -- end of finalization.
1956 -- For now we use `l_type_a.deep_actual_type' (which removes any usage of
1957 -- the anchor) to solve the problem.
1958 create l_generics.make (1, 1)
1959 l_generics.put (l_type_a.deep_actual_type, 1)
1960 if is_checking_cas then
1961 check l_gen_type.class_id = system.native_array_id end
1962 create {NATIVE_ARRAY_TYPE_A} l_array_type.make (system.native_array_id, l_generics)
1963 else
1964 create l_array_type.make (system.array_id, l_generics)
1965 end
1966 instantiator.dispatch (l_array_type, context.current_class)
1967 end
1968 end
1969 if l_array_type = Void then
1970 if nb > 0 then
1971 if is_checking_cas then
1972 -- `l_gen_type' is not an array type, so for now we compute as if
1973 -- there was no context the type of the manifest array by taking the lowest
1974 -- common type.
1975 from
1976 l_has_error := False
1977 -- Take first element in manifest array and let's suppose
1978 -- it is the lowest type.
1979 l_type_a := l_last_types.item (1)
1980 i := 2
1981 until
1982 i > nb
1983 loop
1984 l_element_type := l_last_types.item (i)
1985 -- Let's try to find the type to which everyone conforms to.
1986 -- If not found it will be ANY.
1987 if
1988 l_element_type.conform_to (l_type_a) or
1989 l_element_type.convert_to (context.current_class, l_type_a)
1990 then
1991 -- Nothing to be done
1992 elseif
1993 l_type_a.conform_to (l_element_type) or
1994 l_type_a.convert_to (context.current_class, l_element_type)
1995 then
1996 -- Found a lowest type.
1997 l_type_a := l_element_type
1998 else
1999 -- Cannot find a common type
2000 l_has_error := True
2001 i := nb + 1 -- Exit the loop
2002 end
2003 i := i + 1
2004 end
2005 else
2006 -- `l_gen_type' is not an array type, so for now we compute as if
2007 -- there was no context the type of the manifest array by taking the lowest
2008 -- common type.
2009 from
2010 l_has_error := False
2011 -- Take first element in manifest array and let's suppose
2012 -- it is the lowest type.
2013 l_type_a := l_last_types.item (1)
2014 i := 2
2015 until
2016 i > nb
2017 loop
2018 l_element_type := l_last_types.item (i)
2019 -- Let's try to find the type to which everyone conforms to.
2020 -- If not found it will be ANY.
2021 if l_element_type.conform_to (l_type_a) then
2022 -- Nothing to be done
2023 elseif l_type_a.conform_to (l_element_type) then
2024 -- Found a lowest type.
2025 l_type_a := l_element_type
2026 else
2027 -- Cannot find a common type
2028 l_has_error := True
2029 i := nb + 1 -- Exit the loop
2030 end
2031 i := i + 1
2032 end
2033 end
2034 if l_has_error then
2035 -- We could not find a common type, so let's iterate again to ensure that
2036 -- elements conform or convert to ANY.
2037 from
2038 i := 1
2039 l_has_error := False
2040 create {CL_TYPE_A} l_type_a.make (system.any_id)
2041 until
2042 i > nb
2043 loop
2044 l_element_type := l_last_types.item (i)
2045 if not l_element_type.conform_to (l_type_a) then
2046 if l_element_type.convert_to (context.current_class, l_type_a) then
2047 if is_byte_node_enabled and not is_checking_cas then
2048 l_list.put_i_th (context.last_conversion_info.byte_node (
2049 l_list.i_th (i)), i)
2050 end
2051 else
2052 l_has_error := True
2053 i := nb + 1 -- Exit the loop
2054 end
2055 end
2056 i := i + 1
2057 end
2058 end
2059 if not l_has_error then
2060 create l_generics.make (1, 1)
2061 l_generics.put (l_type_a, 1)
2062 create l_array_type.make (system.array_id, l_generics)
2063 instantiator.dispatch (l_array_type, context.current_class)
2064 end
2065 else
2066 -- Empty manifest array
2067 create l_generics.make (1, 1)
2068 l_generics.put (create {CL_TYPE_A}.make (system.any_id), 1)
2069 create l_array_type.make (system.array_id, l_generics)
2070 instantiator.dispatch (l_array_type, context.current_class)
2071 end
2072 end
2073
2074 if not l_has_error then
2075 -- Update type stack
2076 last_type := l_array_type
2077 l_as.set_array_type (last_type)
2078 if is_byte_node_enabled then
2079 create {ARRAY_CONST_B} last_byte_node.make (l_list,
2080 l_array_type.type_i, l_array_type.create_info)
2081 end
2082 else
2083 fixme ("Insert new validity error saying that manifest array is not valid")
2084 end
2085 end
2086
2087 process_char_as (l_as: CHAR_AS) is
2088 do
2089 if l_as.type = Void then
2090 if l_as.value.is_character_8 then
2091 last_type := character_type
2092 else
2093 last_type := Wide_char_type
2094 end
2095 else
2096 check_type (l_as.type)
2097 end
2098 if is_byte_node_enabled then
2099 create {CHAR_CONST_B} last_byte_node.make (l_as.value, last_type)
2100 end
2101 end
2102
2103 process_string_as (l_as: STRING_AS) is
2104 do
2105 last_type := string_type
2106 if is_byte_node_enabled then
2107 if l_as.is_once_string then
2108 once_manifest_string_index := once_manifest_string_index + 1
2109 create {ONCE_STRING_B} last_byte_node.make (l_as.value, once_manifest_string_index)
2110 else
2111 create {STRING_B} last_byte_node.make (l_as.value)
2112 end
2113 end
2114 end
2115
2116 process_verbatim_string_as (l_as: VERBATIM_STRING_AS) is
2117 do
2118 process_string_as (l_as)
2119 end
2120
2121 process_body_as (l_as: BODY_AS) is
2122 do
2123 safe_process (l_as.content)
2124 end
2125
2126 process_built_in_as (l_as: BUILT_IN_AS) is
2127 -- Process `l_as'.
2128 local
2129 l_external: EXTERNAL_I
2130 l_built_in_processor: BUILT_IN_PROCESSOR
2131 l_feature_as: FEATURE_AS
2132 l_feature_checker: AST_FEATURE_CHECKER_GENERATOR
2133 do
2134 if is_byte_node_enabled then
2135 l_external ?= current_feature
2136 -- If associated feature is not an external anymore, it means that it was interpreted
2137 -- by our compiler as a real `built_in'.
2138 if l_external = Void then
2139 create l_built_in_processor.make (context.current_class, current_feature.feature_name, system.il_generation)
2140 l_feature_as := l_built_in_processor.ast_node
2141 if l_feature_as /= Void and then l_feature_as.body.content /= Void then
2142 -- Only interprets the `built_in' implementation if this is not an attribute.
2143 create l_feature_checker
2144 l_feature_checker.init (context)
2145 l_feature_checker.check_body (current_feature,
2146 l_feature_as.body, True, False, False)
2147 last_byte_node := l_feature_checker.last_byte_node
2148 l_as.set_body (l_feature_as)
2149 else
2150 -- No implementation is provided, let's assume empty body.
2151 create {STD_BYTE_CODE} last_byte_node
2152 end
2153 else
2154 create {EXT_BYTE_CODE} last_byte_node.make (l_external.external_name_id)
2155 end
2156 end
2157 end
2158
2159 process_result_as (l_as: RESULT_AS) is
2160 local
2161 l_feat_type: TYPE_A
2162 l_vrle3: VRLE3
2163 l_has_error: BOOLEAN
2164 l_veen2a: VEEN2A
2165 do
2166 -- Error if in procedure or invariant
2167 l_has_error := is_checking_invariant
2168 if not l_has_error then
2169 l_feat_type := current_feature.type
2170 l_has_error := l_feat_type.actual_type.conform_to (Void_type)
2171 end
2172
2173 if l_has_error then
2174 create l_vrle3
2175 context.init_error (l_vrle3)
2176 l_vrle3.set_location (l_as.start_location)
2177 error_handler.insert_error (l_vrle3)
2178 -- Cannot go on here
2179 error_handler.raise_error
2180 else
2181 if is_checking_precondition then
2182 -- Result entity in precondition
2183 create l_veen2a
2184 context.init_error (l_veen2a)
2185 l_veen2a.set_location (l_as.start_location)
2186 error_handler.insert_error (l_veen2a)
2187 end
2188
2189 -- Update the type stack
2190 last_type := l_feat_type
2191 last_access_writable := True
2192 if is_byte_node_enabled then
2193 create {RESULT_B} last_byte_node
2194 end
2195 end
2196 end
2197
2198 process_current_as (l_as: CURRENT_AS) is
2199 do
2200 last_type := context.current_class_type
2201 if is_byte_node_enabled then
2202 create {CURRENT_B} last_byte_node
2203 end
2204 end
2205
2206 process_access_feat_as (l_as: ACCESS_FEAT_AS) is
2207 local
2208 l_type_a, l_last_type, l_last_constrained, l_feature_type, l_last_feature_type: TYPE_A
2209 l_last_class_id: INTEGER
2210 l_formal: FORMAL_A
2211 l_feature: FEATURE_I
2212 l_result: LIST [TUPLE [feature_i: FEATURE_I; cl_type: RENAMED_TYPE_A [TYPE_A]]]
2213 l_result_item: TUPLE [feature_i: FEATURE_I; cl_type: RENAMED_TYPE_A [TYPE_A]]
2214 l_type_a_is_multi_constrained: BOOLEAN
2215 l_type_set: TYPE_SET_A
2216 l_vtmc4: VTMC4
2217 do
2218 l_type_a := last_type.actual_type
2219 if l_type_a.is_formal then
2220 l_formal ?= l_type_a
2221 if l_formal.is_multi_constrained (context.current_class) then
2222 l_type_a_is_multi_constrained := True
2223 else
2224 l_type_a := l_formal.constrained_type (context.current_class)
2225 end
2226 end
2227
2228 if not l_type_a_is_multi_constrained then
2229 if not l_type_a.is_none and not l_type_a.is_void then
2230 if is_inherited and not l_as.is_tuple_access then
2231 -- Reuse the feature when it is really one, otherwise when it is a tuple
2232 -- access the call to `process_call' will do the right thing for inherited code.
2233 l_feature := l_type_a.associated_class.feature_of_rout_id (l_as.routine_ids.first)
2234 end
2235 end
2236 -- Type check the call
2237 process_call (last_type, Void, l_as.feature_name, l_feature, l_as.parameters,
2238 False, False, True, False)
2239 else
2240 -- Multi constraint case
2241 if is_inherited then
2242 -- This code here is very similar to some parts of `process_abstract_creation'.
2243 -- It has the very same issues as described there.
2244 fixme ("Related to fix me in `process_abstract_creation'")
2245
2246 -- Note: We do not need to protect against TUPLE access here since
2247 -- named tuples are not allowed in multiple-constraint.
2248
2249 -- We need to iterate through the type set to find the routine of ID
2250 l_formal ?= l_type_a
2251 check
2252 -- It should work as we are in the multi constraint case
2253 l_formal_not_void: l_formal /= Void
2254 end
2255 l_type_set := context.current_class.constraints (l_formal.position)
2256 l_type_set := l_type_set.constraining_types (context.current_class)
2257 l_result := l_type_set.feature_i_list_by_rout_id (l_as.routine_ids.first)
2258 check at_least_one_feature_found: l_result.count > 0 end
2259 -- As we inherited this feature there's the possiblity that now,
2260 from
2261 l_result.start
2262 l_last_type :=last_type
2263 until
2264 l_result.after or l_vtmc4 /= Void
2265 loop
2266 l_result_item := l_result.item
2267 l_feature := l_result_item.feature_i
2268 l_last_class_id := l_result_item.cl_type.associated_class.class_id
2269 l_last_constrained := l_result_item.cl_type.type
2270 -- Restore last_type
2271 last_calls_target_type := l_last_constrained
2272 -- Type check the call
2273 process_call (l_last_type, Void, l_as.feature_name, l_feature, l_as.parameters,
2274 False, False, True, False)
2275 l_result.forth
2276 -- We inherited this feature. Adapt it's type. DELETEME and the commented code below
2277 l_feature_type := last_type -- l_feature.type.instantiation_in (l_last_type, l_last_class_id).actual_type
2278 if l_last_feature_type /= Void and then l_last_feature_type.same_as (l_feature_type) then
2279 -- Ok, the two features have still the same return type.
2280 else
2281 -- The two features have redefined their return type differently.
2282 -- We don't allow this: Add an error, but continue checking as this only an additional
2283 -- check and does not break anything else.
2284 -- Note: If `like Current' is the type of the feature this is ok, as the type is adapted to the formal.
2285 create l_vtmc4
2286 l_vtmc4.set_class (context.current_class)
2287 l_vtmc4.set_written_class (system.class_of_id (l_as.class_id))
2288 l_vtmc4.set_feature (context.current_feature)
2289 l_vtmc4.set_location (l_as.start_location)
2290 l_vtmc4.set_feature_info (l_result)
2291 error_handler.insert_error (l_vtmc4)
2292 end
2293 end
2294 -- We inherited this feature. Adapt it's type.
2295 last_type := l_feature_type
2296
2297 else
2298 -- Type check the call
2299 process_call (last_type, Void, l_as.feature_name, l_feature, l_as.parameters,
2300 False, False, True, False)
2301 end
2302 end
2303
2304 error_handler.checksum
2305
2306 if not is_inherited then
2307 -- set some type attributes of the node
2308 if last_calls_target_type /= Void then
2309 l_as.set_class_id (last_calls_target_type.associated_class.class_id)
2310 else
2311 l_as.set_class_id (-1)
2312 end
2313 if last_routine_id_set /= Void then
2314 check
2315 not_is_tuple_access: not is_last_access_tuple_access
2316 end
2317 l_as.set_routine_ids (last_routine_id_set)
2318 else
2319 check
2320 is_tuple_access: is_last_access_tuple_access
2321 end
2322 l_as.enable_tuple_access
2323 end
2324 end
2325 end
2326
2327 process_access_inv_as (l_as: ACCESS_INV_AS) is
2328 local
2329 l_class_id: INTEGER
2330 l_type_a: TYPE_A
2331 l_feature: FEATURE_I
2332 do
2333 l_type_a := last_type.actual_type
2334 check
2335 not_formal: not l_type_a.is_formal
2336 end
2337 l_class_id := l_type_a.associated_class.class_id
2338 if is_inherited then
2339 l_feature := l_type_a.associated_class.feature_of_rout_id (l_as.routine_ids.first)
2340 end
2341 process_call (last_type, Void, l_as.feature_name, l_feature, l_as.parameters, False, False, False, False)
2342 error_handler.checksum
2343
2344 if not is_inherited then
2345 -- set some type attributes of the node
2346 l_as.set_class_id (l_class_id)
2347 l_as.set_routine_ids (last_routine_id_set)
2348 end
2349 end
2350
2351 process_access_id_as (l_as: ACCESS_ID_AS) is
2352 local
2353 l_arg_pos: INTEGER
2354 l_last_id: INTEGER
2355 l_local: LOCAL_B
2356 l_argument: ARGUMENT_B
2357 l_local_info: LOCAL_INFO
2358 l_feature: FEATURE_I
2359 l_has_vuar_error: BOOLEAN
2360 l_vuar1: VUAR1
2361 l_veen2b: VEEN2B
2362 l_needs_byte_node: BOOLEAN
2363 l_type: TYPE_A
2364 l_context_current_class: CLASS_C
2365 do
2366 l_context_current_class := context.current_class
2367 l_needs_byte_node := is_byte_node_enabled
2368 -- No need for `last_type.actual_type' as here `last_type' is equal to
2369 -- `context.current_class_type' since we start a feature call.
2370 check not_is_formal: not last_type.is_formal end
2371 l_last_id := last_type.associated_class.class_id
2372 check equivalent_ids: l_last_id = last_type.conformance_type.associated_class.class_id end
2373
2374 l_feature := current_feature
2375 -- Look for an argument
2376 if l_feature /= Void then
2377 if is_inherited then
2378 if l_as.is_argument then
2379 l_arg_pos := l_as.argument_position
2380 end
2381 else
2382 l_arg_pos := l_feature.argument_position (l_as.feature_name.name_id)
2383 end
2384 end
2385 if l_arg_pos /= 0 then
2386 -- Found argument
2387 l_type := l_feature.arguments.i_th (l_arg_pos)
2388 l_type := l_type.actual_type.instantiation_in (last_type, l_last_id)
2389 l_has_vuar_error := l_as.parameters /= Void
2390 if l_needs_byte_node then
2391 create l_argument
2392 l_argument.set_position (l_arg_pos)
2393 last_byte_node := l_argument
2394 end
2395 -- set some type attributes of the node
2396 if not is_inherited then
2397 l_as.enable_argument
2398 l_as.set_argument_position (l_arg_pos)
2399 l_as.set_class_id (class_id_of (l_type))
2400 end
2401 else
2402 -- Look for a local if not in a pre- or postcondition
2403 if not is_inherited or else l_as.is_local then
2404 l_local_info := context.locals.item (l_as.feature_name.name_id)
2405 end
2406 if l_local_info /= Void then
2407 -- Local found
2408 l_local_info.set_is_used (True)
2409 last_access_writable := True
2410 l_has_vuar_error := l_as.parameters /= Void
2411 l_type := l_local_info.type
2412 l_type := l_type.instantiation_in (last_type, l_last_id)
2413 if l_needs_byte_node then
2414 create l_local
2415 l_local.set_position (l_local_info.position)
2416 last_byte_node := l_local
2417 end
2418
2419 if is_checking_postcondition or else is_checking_precondition then
2420 -- Local in post- or precondition
2421 --|Note: this should not happen since
2422 --|in the context of assertions we would have
2423 --|ACCESS_ASSERT_AS and not ACCESS_ID_AS objects.
2424 --|(Fred)
2425 create l_veen2b
2426 context.init_error (l_veen2b)
2427 l_veen2b.set_identifier (l_as.feature_name.name)
2428 l_veen2b.set_location (l_as.feature_name)
2429 error_handler.insert_error (l_veen2b)
2430 end
2431 if not is_inherited then
2432 -- set some type attributes of the node
2433 l_as.enable_local
2434 l_as.set_class_id (class_id_of (l_type))
2435 end
2436 else
2437 -- Look for a feature
2438 l_feature := Void
2439 if is_inherited then
2440 check system.class_of_id (l_last_id) = last_type.associated_class end
2441 l_feature := system.class_of_id (l_last_id).feature_of_rout_id (l_as.routine_ids.first)
2442 end
2443 process_call (last_type, Void, l_as.feature_name, l_feature, l_as.parameters, False, False, False, False)
2444 l_type := last_type
2445 if not is_inherited then
2446 -- set some type attributes of the node
2447 l_as.set_class_id (l_last_id)
2448 l_as.set_routine_ids (last_routine_id_set)
2449 end
2450 end
2451 end
2452 if l_has_vuar_error then
2453 create l_vuar1
2454 if l_arg_pos /= 0 then
2455 l_vuar1.set_arg_name (l_as.feature_name.name)
2456 else
2457 l_vuar1.set_local_name (l_as.feature_name.name)
2458 end
2459 context.init_error (l_vuar1)
2460 l_vuar1.set_location (l_as.feature_name)
2461 error_handler.insert_error (l_vuar1)
2462 else
2463 last_type := l_type
2464 end
2465 error_handler.checksum
2466 end
2467
2468 process_access_assert_as (l_as: ACCESS_ASSERT_AS) is
2469 local
2470 l_arg_pos: INTEGER
2471 l_local_info: LOCAL_INFO
2472 l_argument: ARGUMENT_B
2473 l_arg_type: TYPE_A
2474 l_feature: FEATURE_I
2475 l_vuar1: VUAR1
2476 l_veen2b: VEEN2B
2477 l_last_id: INTEGER
2478 do
2479 -- No need for `last_type.actual_type' as here `last_type' is equal to
2480 -- `context.current_class_type' since we start a feature call.
2481 check not_is_formal: not last_type.is_formal end
2482 l_last_id := last_type.associated_class.class_id
2483 check equivalent_ids: l_last_id = last_type.associated_class.class_id end
2484
2485 l_feature := current_feature
2486 -- Look for an argument
2487 if is_inherited then
2488 l_arg_pos := l_as.argument_position
2489 else
2490 l_arg_pos := l_feature.argument_position (l_as.feature_name.name_id)
2491 end
2492 if l_arg_pos /= 0 then
2493 -- Found argument
2494 l_arg_type := l_feature.arguments.i_th (l_arg_pos)
2495
2496 last_type := l_arg_type.actual_type.instantiation_in (last_type, l_last_id)
2497 if l_as.parameters /= Void then
2498 create l_vuar1
2499 context.init_error (l_vuar1)
2500 l_vuar1.set_arg_name (l_as.feature_name.name)
2501 l_vuar1.set_location (l_as.feature_name)
2502 error_handler.insert_error (l_vuar1)
2503 end
2504 if is_byte_node_enabled then
2505 create l_argument
2506 l_argument.set_position (l_arg_pos)
2507 last_byte_node := l_argument
2508 end
2509 if not is_inherited then
2510 -- set some type attributes of the node
2511 l_as.enable_argument
2512 l_as.set_argument_position (l_arg_pos)
2513 l_as.set_class_id (class_id_of (last_type))
2514 end
2515 else
2516 -- Look for a local if in a pre- or postcondition
2517 if not is_inherited then
2518 l_local_info := context.locals.item (l_as.feature_name.name_id)
2519 end
2520 if l_local_info /= Void then
2521 -- Local found
2522 create l_veen2b
2523 context.init_error (l_veen2b)
2524 l_veen2b.set_identifier (l_as.feature_name.name)
2525 l_veen2b.set_location (l_as.feature_name)
2526 error_handler.insert_error (l_veen2b)
2527 else
2528 -- Look for a feature
2529 l_feature := Void
2530 if is_inherited then
2531 l_feature := system.class_of_id (l_last_id).feature_of_rout_id (l_as.routine_ids.first)
2532 end
2533 process_call (last_type, Void, l_as.feature_name, l_feature, l_as.parameters, False, False, False, False)
2534 if not is_inherited then
2535 -- set some type attributes of the node
2536 l_as.set_routine_ids (last_routine_id_set)
2537 l_as.set_class_id (l_last_id) -- last_type_of_call.associated_class.class_id -- seems to be wrong...
2538 end
2539 end
2540 end
2541 error_handler.checksum
2542 end
2543
2544 process_precursor_as (l_as: PRECURSOR_AS) is
2545 local
2546 l_vupr1: VUPR1
2547 l_vupr2: VUPR2
2548 l_vupr3: VUPR3
2549 l_pre_table: LINKED_LIST [PAIR[CL_TYPE_A, INTEGER]]
2550 l_feature_i: FEATURE_I
2551 l_parent_type: CL_TYPE_A
2552 l_parent_class: CLASS_C
2553 l_feat_ast: FEATURE_AS
2554 l_precursor_id: ID_AS
2555 l_instatiation_type: LIKE_CURRENT
2556 do
2557 if not is_inherited then
2558 if current_feature.is_invariant or else current_feature.is_inline_agent then
2559 create l_vupr1
2560 context.init_error (l_vupr1)
2561 error_handler.insert_error (l_vupr1)
2562 -- Cannot go on here.
2563 error_handler.raise_error
2564 else
2565 l_feat_ast := context.current_class.feature_with_name (current_feature.feature_name).ast
2566
2567 -- Check that feature has a unique name (vupr1)
2568 -- Check that we're in the body of a routine (l_vupr1).
2569 if
2570 l_feat_ast.feature_names.count > 1 or
2571 is_checking_precondition or is_checking_postcondition or is_checking_invariant
2572 then
2573 create l_vupr1
2574 context.init_error (l_vupr1)
2575 error_handler.insert_error (l_vupr1)
2576 -- Cannot go on here.
2577 error_handler.raise_error
2578 end
2579
2580 -- Create table of routine ids of all parents which have
2581 -- an effective precursor of the current feature.
2582 l_pre_table := precursor_table (l_as)
2583
2584 -- Check that current feature is a redefinition.
2585 if l_pre_table.count = 0 then
2586 if l_as.parent_base_class /= Void then
2587 -- The specified parent does not have
2588 -- an effective precursor.
2589 create l_vupr2
2590 context.init_error (l_vupr2)
2591 error_handler.insert_error (l_vupr2)
2592 -- Cannot go on here.
2593 error_handler.raise_error
2594 else
2595 -- No parent has an effective precursor
2596 -- (not a redefinition)
2597 create l_vupr3
2598 context.init_error (l_vupr3)
2599 error_handler.insert_error (l_vupr3)
2600 -- Cannot go on here.
2601 error_handler.raise_error
2602 end
2603 end
2604
2605 -- Check that an unqualified precursor construct
2606 -- is not ambiguous.
2607 if l_pre_table.count > 1 then
2608 -- Ambiguous construct
2609 create l_vupr3
2610 context.init_error (l_vupr3)
2611 error_handler.insert_error (l_vupr3)
2612 -- Cannot go on here.
2613 error_handler.raise_error
2614 end
2615
2616 -- Table has exactly one entry.
2617 l_pre_table.start
2618 l_parent_type := l_pre_table.item.first
2619 l_parent_class := l_parent_type.associated_class
2620 l_feature_i := l_parent_class.feature_table.feature_of_rout_id (l_pre_table.item.second)
2621 l_as.set_class_id (l_parent_class.class_id)
2622 l_as.set_routine_ids (l_feature_i.rout_id_set)
2623 end
2624 else
2625 l_parent_class := system.class_of_id (l_as.class_id)
2626 l_parent_type := l_parent_class.actual_type
2627 l_parent_type ?= l_parent_type.instantiation_in (
2628 context.current_class.actual_type, l_as.class_id)
2629 l_feature_i := l_parent_class.feature_of_rout_id (l_as.routine_ids.first)
2630 end
2631
2632 -- Update signature of parent `l_feature_i' in context of its instantiation
2633 -- in current class.
2634 l_feature_i := l_feature_i.duplicate
2635 -- Adapt `l_feature_i' to context of current class (e.g. if `l_parent_type' is
2636 -- generic then we need to resolve formals used in `l_feature_i' but the one from
2637 -- the instantiation `l_parent_type'.
2638 create l_instatiation_type
2639 l_instatiation_type.set_actual_type (l_parent_type)
2640 l_feature_i.instantiate (l_instatiation_type)
2641 -- Now that we have the fully instantiated type, we need to adapt it to
2642 -- the current class type (e.g. like Current).
2643 l_feature_i.instantiate (context.current_class_type)
2644
2645 create l_precursor_id.initialize_from_id (precursor_name_id)
2646 l_precursor_id.set_position (l_as.precursor_keyword.line, l_as.precursor_keyword.column,
2647 l_as.precursor_keyword.position, l_as.precursor_keyword.location_count)
2648 process_call (context.current_class_type, l_parent_type, l_precursor_id, l_feature_i,
2649 l_as.parameters, False, False, False, True)
2650 end
2651
2652 process_nested_expr_as (l_as: NESTED_EXPR_AS) is
2653 local
2654 l_target_type: TYPE_A
2655 l_target_expr: EXPR_B
2656 l_access_expr: ACCESS_EXPR_B
2657 l_call: CALL_B
2658 l_nested: NESTED_B
2659 l_is_qualified_call: BOOLEAN
2660 do
2661 -- Type check the target
2662 l_as.target.process (Current)
2663 l_target_type := last_type
2664 if is_byte_node_enabled then
2665 l_target_expr ?= last_byte_node
2666 create l_access_expr
2667 l_access_expr.set_expr (l_target_expr)
2668 end
2669
2670 -- Type check the message
2671 l_is_qualified_call := is_qualified_call
2672 is_qualified_call := True
2673 l_as.message.process (Current)
2674 is_qualified_call := l_is_qualified_call
2675 if is_byte_node_enabled then
2676 l_call ?= last_byte_node
2677 check
2678 l_call_not_void: l_call /= Void
2679 end
2680 create l_nested
2681 l_nested.set_target (l_access_expr)
2682 fixme ("Should we set `parent' on `l_access_expr' as we do for a NESTED_AS")
2683 l_nested.set_message (l_call)
2684 l_call.set_parent (l_nested)
2685 last_byte_node := l_nested
2686 end
2687 end
2688
2689 process_nested_as (l_as: NESTED_AS) is
2690 local
2691 l_target_access: ACCESS_B
2692 l_call: CALL_B
2693 l_nested: NESTED_B
2694 l_is_assigner_call: BOOLEAN
2695 l_is_qualified_call: BOOLEAN
2696 do
2697 -- Mask out assigner call flag for target of the call
2698 l_is_assigner_call := is_assigner_call
2699 is_assigner_call := False
2700 -- Type check the target
2701 l_as.target.process (Current)
2702 -- Restore assigner call flag for nested call
2703 is_assigner_call := l_is_assigner_call
2704 l_is_qualified_call := is_qualified_call
2705 is_qualified_call := True
2706 if not is_byte_node_enabled then
2707 -- Type check the message
2708 l_as.message.process (Current)
2709 else
2710 l_target_access ?= last_byte_node
2711
2712 -- Type check the message
2713 l_as.message.process (Current)
2714
2715 -- Create byte node.
2716 l_call ?= last_byte_node
2717 check
2718 l_call_not_void: l_call /= Void
2719 end
2720 create l_nested
2721 l_nested.set_target (l_target_access)
2722 l_nested.set_message (l_call)
2723
2724 l_target_access.set_parent (l_nested)
2725 l_call.set_parent (l_nested)
2726
2727 last_byte_node := l_nested
2728 end
2729 is_qualified_call := l_is_qualified_call
2730 end
2731
2732 process_routine_as (l_as: ROUTINE_AS) is
2733 local
2734 l_vxrc: VXRC
2735 l_byte_code: BYTE_CODE
2736 l_list: BYTE_LIST [BYTE_NODE]
2737 l_needs_byte_node: BOOLEAN
2738 do
2739 l_needs_byte_node := is_byte_node_enabled
2740
2741 -- Check local variables
2742 if l_as.locals /= Void then
2743 check_locals (l_as)
2744 end
2745 -- Check preconditions
2746 if l_as.precondition /= Void then
2747 -- Set Result access analysis level to `is_checking_precondition': locals
2748 -- and Result cannot be found in preconditions
2749 set_is_checking_precondition (True)
2750 l_as.precondition.process (Current)
2751 if l_needs_byte_node then
2752 l_list ?= last_byte_node
2753 end
2754 -- Reset the levels to default values
2755 set_is_checking_precondition (False)
2756 end
2757
2758 -- Check body
2759 l_as.routine_body.process (Current)
2760 if l_needs_byte_node then
2761 l_byte_code ?= last_byte_node
2762 context.init_byte_code (l_byte_code)
2763 l_byte_code.set_precondition (l_list)
2764 end
2765
2766 -- Check postconditions
2767 if l_as.postcondition /= Void then
2768 -- Set access id level analysis to `is_checking_postcondition': locals
2769 -- are not taken into account
2770 set_is_checking_postcondition (True)
2771 l_as.postcondition.process (Current)
2772 if l_needs_byte_node then
2773 l_list ?= last_byte_node
2774 l_byte_code.set_postcondition (l_list)
2775 end
2776 -- Reset the level
2777 set_is_checking_postcondition (False)
2778 end
2779
2780 -- Check rescue-clause
2781 if l_as.rescue_clause /= Void then
2782 -- A deferred or external feature cannot have a rescue
2783 -- clause
2784 if l_as.routine_body.is_deferred or else l_as.routine_body.is_external then
2785 create l_vxrc
2786 context.init_error (l_vxrc)
2787 l_vxrc.set_deferred (l_as.routine_body.is_deferred)
2788 l_vxrc.set_location (l_as.rescue_clause.start_location)
2789 error_handler.insert_error (l_vxrc)
2790 else
2791 -- Set mark of context
2792 is_in_rescue := True
2793 l_as.rescue_clause.process (Current)
2794 if l_needs_byte_node then
2795 l_list ?= last_byte_node
2796 l_byte_code.set_rescue_clause (l_list)
2797 end
2798 is_in_rescue := False
2799 end
2800 end
2801
2802 if l_as.locals /= Void and then context.current_class.is_warning_enabled (w_unused_local) then
2803 check_unused_locals (context.locals)
2804 end
2805
2806 if l_needs_byte_node then
2807 if old_expressions /= Void and then not old_expressions.is_empty then
2808 l_byte_code.set_old_expressions (old_expressions)
2809 end
2810 l_byte_code.set_end_location (l_as.end_location)
2811 l_byte_code.set_once_manifest_string_count (l_as.once_manifest_string_count)
2812 last_byte_node := l_byte_code
2813 end
2814 l_as.set_number_of_breakpoint_slots (break_point_slot_count)
2815 end
2816
2817 process_constant_as (l_as: CONSTANT_AS) is
2818 do
2819 -- Nothing to be done
2820 end
2821
2822 process_eiffel_list (l_as: EIFFEL_LIST [AST_EIFFEL]) is
2823 local
2824 l_cursor: INTEGER
2825 l_list: BYTE_LIST [BYTE_NODE]
2826 do
2827 l_cursor := l_as.index
2828 l_as.start
2829
2830 if is_byte_node_enabled then
2831 from
2832 create l_list.make (l_as.count)
2833 until
2834 l_as.after
2835 loop
2836 l_as.item.process (Current)
2837 l_list.extend (last_byte_node)
2838 l_as.forth
2839 end
2840 last_byte_node := l_list
2841 else
2842 from
2843 until
2844 l_as.after
2845 loop
2846 l_as.item.process (Current)
2847 l_as.forth
2848 end
2849 end
2850 l_as.go_i_th (l_cursor)
2851 end
2852
2853 process_indexing_clause_as (l_as: INDEXING_CLAUSE_AS) is
2854 do
2855 -- Nothing to be done
2856 end
2857
2858 process_operand_as (l_as: OPERAND_AS) is
2859 local
2860 l_class_type: TYPE_A
2861 do
2862 if l_as.target /= Void then
2863 l_as.target.process (Current)
2864 elseif l_as.expression /= Void then
2865 reset_for_unqualified_call_checking
2866 l_as.expression.process (Current)
2867 elseif l_as.class_type /= Void then
2868 l_as.class_type.process (Current)
2869 l_class_type := last_type
2870 instantiator.dispatch (l_class_type, context.current_class)
2871 if is_byte_node_enabled then
2872 create {OPERAND_B} last_byte_node
2873 end
2874 else
2875 create {OPEN_TYPE_A} last_type
2876 if is_byte_node_enabled then
2877 create {OPERAND_B} last_byte_node
2878 end
2879 end
2880 end
2881
2882 process_tagged_as (l_as: TAGGED_AS) is
2883 local
2884 l_vwbe3: VWBE3
2885 l_assert: ASSERT_B
2886 l_expr: EXPR_B
2887 do
2888 break_point_slot_count := break_point_slot_count + 1
2889
2890 reset_for_unqualified_call_checking
2891
2892 l_as.expr.process (Current)
2893
2894 -- Check if the type of the expression is boolean
2895 if not last_type.actual_type.is_boolean then
2896 create l_vwbe3
2897 context.init_error (l_vwbe3)
2898 l_vwbe3.set_type (last_type)
2899 l_vwbe3.set_location (l_as.expr.end_location)
2900 error_handler.insert_error (l_vwbe3)
2901 end
2902
2903 if is_byte_node_enabled then
2904 l_expr ?= last_byte_node
2905 check
2906 l_expr_not_void: l_expr /= Void
2907 end
2908 create l_assert
2909 if l_as.tag /= Void then
2910 l_assert.set_tag (l_as.tag.name)
2911 else
2912 l_assert.set_tag (Void)
2913 end
2914 l_assert.set_expr (l_expr)
2915 l_assert.set_line_number (l_as.expr.start_location.line)
2916 last_byte_node := l_assert
2917 end
2918 end
2919
2920 process_variant_as (l_as: VARIANT_AS) is
2921 local
2922 l_vave: VAVE
2923 l_assert: VARIANT_B
2924 l_expr: EXPR_B
2925 do
2926 reset_for_unqualified_call_checking
2927 l_as.expr.process (Current)
2928
2929 -- Check if the type of the expression is integer
2930 if not last_type.is_integer then
2931 create l_vave
2932 context.init_error (l_vave)
2933 l_vave.set_type (last_type)
2934 l_vave.set_location (l_as.expr.end_location)
2935 error_handler.insert_error (l_vave)
2936 end
2937
2938 if is_byte_node_enabled then
2939 l_expr ?= last_byte_node
2940 check
2941 l_expr_not_void: l_expr /= Void
2942 end
2943 create l_assert
2944 if l_as.tag /= Void then
2945 l_assert.set_tag (l_as.tag.name)
2946 else
2947 l_assert.set_tag (Void)
2948 end
2949 l_assert.set_expr (l_expr)
2950 l_assert.set_line_number (l_as.expr.start_location.line)
2951 last_byte_node := l_assert
2952 end
2953 end
2954
2955 process_un_strip_as (l_as: UN_STRIP_AS) is
2956 local
2957 l_id: INTEGER
2958 l_index: INTEGER
2959 l_feat_tbl: FEATURE_TABLE
2960 l_attribute_i: ATTRIBUTE_I
2961 l_depend_unit: DEPEND_UNIT
2962 l_vwst1: VWST1
2963 l_vwst2: VWST2
2964 l_strip: STRIP_B
2965 l_needs_byte_node: BOOLEAN
2966 do
2967 l_needs_byte_node := is_byte_node_enabled
2968 from
2969 if l_needs_byte_node then
2970 create l_strip.make
2971 end
2972 l_feat_tbl := context.current_class.feature_table
2973 l_as.id_list.start
2974 until
2975 l_as.id_list.after
2976 loop
2977 l_id := l_as.id_list.item
2978 l_index := l_as.id_list.index
2979 l_as.id_list.forth
2980 l_as.id_list.search (l_id)
2981 if not l_as.id_list.after then
2982 -- Id appears more than once in attribute list
2983 create l_vwst2
2984 context.init_error (l_vwst2)
2985 l_vwst2.set_attribute_name (Names_heap.item (l_id))
2986 l_vwst2.set_location (l_as.start_location)
2987 error_handler.insert_error (l_vwst2)
2988 else
2989 l_attribute_i ?= l_feat_tbl.item_id (l_id)
2990 if l_attribute_i = Void then
2991 create l_vwst1
2992 context.init_error (l_vwst1)
2993 l_vwst1.set_attribute_name (Names_heap.item (l_id))
2994 l_vwst1.set_location (l_as.start_location)
2995 error_handler.insert_error (l_vwst1)
2996 else
2997 create l_depend_unit.make (context.current_class.class_id,
2998 l_attribute_i)
2999 context.supplier_ids.extend (l_depend_unit)
3000 if l_needs_byte_node then
3001 l_strip.feature_ids.put (l_attribute_i.feature_id)
3002 end
3003 end
3004 end
3005 l_as.id_list.go_i_th (l_index)
3006 l_as.id_list.forth
3007 end
3008 last_type := strip_type
3009 if l_needs_byte_node then
3010 last_byte_node := l_strip
3011 end
3012 end
3013
3014 process_paran_as (l_as: PARAN_AS) is
3015 local
3016 l_expr: EXPR_B
3017 do
3018 l_as.expr.process (Current)
3019 if is_byte_node_enabled then
3020 l_expr ?= last_byte_node
3021 create {PARAN_B} last_byte_node.make (l_expr)
3022 end
3023 end
3024
3025 process_expr_call_as (l_as: EXPR_CALL_AS) is
3026 local
3027 l_vkcn3: VKCN3
3028 do
3029 reset_for_unqualified_call_checking
3030 l_as.call.process (Current)
3031 if last_type.is_void then
3032 create l_vkcn3
3033 context.init_error (l_vkcn3)
3034 l_vkcn3.set_location (l_as.call.end_location)
3035 error_handler.insert_error (l_vkcn3)
3036 error_handler.raise_error
3037 end
3038
3039 -- Nothing to be done for `last_byte_node' as it was computed in previous call
3040 -- `l_as.call.process'.
3041 end
3042
3043 process_expr_address_as (l_as: EXPR_ADDRESS_AS) is
3044 local
3045 l_expr: EXPR_B
3046 do
3047 l_as.expr.process (Current)
3048 last_type := pointer_type
3049 if is_byte_node_enabled then
3050 l_expr ?= last_byte_node
3051 create {EXPR_ADDRESS_B} last_byte_node.make (l_expr)
3052 end
3053 end
3054
3055 process_address_result_as (l_as: ADDRESS_RESULT_AS) is
3056 local
3057 l_vrle3: VRLE3
3058 l_veen2a: VEEN2A
3059 l_type: TYPE_A
3060 do
3061 if
3062 is_checking_invariant or else not current_feature.has_return_value
3063 then
3064 -- It means that we are in a location where `Result' is not
3065 -- acceptable (e.g. an invariant, or within the body of a procedure).
3066 create l_vrle3
3067 context.init_error (l_vrle3)
3068 l_vrle3.set_location (l_as.start_location)
3069 error_handler.insert_error (l_vrle3)
3070 -- Cannot go on here
3071 error_handler.raise_error
3072 elseif is_checking_precondition then
3073 -- Result entity in precondition
3074 create l_veen2a
3075 context.init_error (l_veen2a)
3076 l_veen2a.set_location (l_as.start_location)
3077 error_handler.insert_error (l_veen2a)
3078 end
3079 l_type := current_feature.type
3080 create {TYPED_POINTER_A} last_type.make_typed (l_type)
3081 if is_byte_node_enabled then
3082 create {HECTOR_B} last_byte_node.make (create {RESULT_B})
3083 end
3084 end
3085
3086 process_address_current_as (l_as: ADDRESS_CURRENT_AS) is
3087 local
3088 l_like_current: LIKE_CURRENT
3089 do
3090 l_like_current := context.current_class_type
3091 create {TYPED_POINTER_A} last_type.make_typed (l_like_current)
3092 if is_byte_node_enabled then
3093 create {HECTOR_B} last_byte_node.make (create {CURRENT_B})
3094 end
3095 end
3096
3097 process_address_as (l_as: ADDRESS_AS) is
3098 local
3099 l_access: ACCESS_B
3100 l_argument: ARGUMENT_B
3101 l_local: LOCAL_B
3102 l_local_info: LOCAL_INFO
3103 l_unsupported: NOT_SUPPORTED
3104 l_feature: FEATURE_I
3105 l_vzaa1: VZAA1
3106 l_veen: VEEN
3107 l_veen2b: VEEN2B
3108 l_arg_pos: INTEGER
3109 l_last_id: INTEGER
3110 l_type: TYPE_A
3111 l_depend_unit: DEPEND_UNIT
3112 l_needs_byte_node: BOOLEAN
3113 do
3114 l_needs_byte_node := is_byte_node_enabled
3115
3116 -- Initialization of the type stack
3117 reset_for_unqualified_call_checking
3118
3119 l_last_id := context.current_class.class_id
3120 if not is_inherited then
3121 l_as.set_class_id (l_last_id)
3122 end
3123
3124 l_feature := current_feature
3125 -- Look for an argument
3126 if l_feature /= Void then
3127 if is_inherited then
3128 if l_as.is_argument then
3129 l_arg_pos := l_as.argument_position
3130 end
3131 else
3132 l_arg_pos := l_feature.argument_position (l_as.feature_name.internal_name.name_id)
3133 end
3134 end
3135 if l_arg_pos /= 0 then
3136 -- Found argument
3137 l_type := l_feature.arguments.i_th (l_arg_pos)
3138 l_type := l_type.actual_type.instantiation_in (last_type, l_last_id)
3139 create {TYPED_POINTER_A} last_type.make_typed (l_type)
3140 if l_needs_byte_node then
3141 create l_argument
3142 l_argument.set_position (l_arg_pos)
3143 create {HECTOR_B} last_byte_node.make_with_type (l_argument, last_type.type_i)
3144 end
3145 if not is_inherited then
3146 l_as.enable_argument
3147 l_as.set_argument_position (l_arg_pos)
3148 end
3149 else
3150 -- Look for a local if not in a pre- or postcondition
3151 if not is_inherited or else l_as.is_local then
3152 l_local_info := context.locals.item (l_as.feature_name.internal_name.name_id)
3153 end
3154 if l_local_info /= Void then
3155 -- Local found
3156 l_local_info.set_is_used (True)
3157 l_type := l_local_info.type
3158 l_type := l_type.instantiation_in (last_type, l_last_id)
3159 create {TYPED_POINTER_A} last_type.make_typed (l_type)
3160 if l_needs_byte_node then
3161 create l_local
3162 l_local.set_position (l_local_info.position)
3163 create {HECTOR_B} last_byte_node.make_with_type (l_local, last_type.type_i)
3164 end
3165
3166 if is_checking_postcondition or else is_checking_precondition then
3167 -- Local in post- or precondition
3168 --|Note: this should not happen since
3169 --|in the context of assertions we would have
3170 --|ACCESS_ASSERT_AS and not ACCESS_ID_AS objects.
3171 --|(Fred)
3172 create l_veen2b
3173 context.init_error (l_veen2b)
3174 l_veen2b.set_identifier (l_as.feature_name.internal_name.name)
3175 l_veen2b.set_location (l_as.feature_name.start_location)
3176 error_handler.insert_error (l_veen2b)
3177 end
3178
3179 if not is_inherited then
3180 l_as.enable_local
3181 end
3182 else
3183 if is_inherited then
3184 l_feature := context.current_class.feature_of_rout_id (l_as.routine_ids.first)
3185 else
3186 l_feature := context.current_class.feature_table.item_id (l_as.feature_name.internal_name.name_id)
3187 end
3188 if l_feature = Void then
3189 create l_veen
3190 context.init_error (l_veen)
3191 l_veen.set_identifier (l_as.feature_name.internal_name.name)
3192 l_veen.set_location (l_as.feature_name.start_location)
3193 error_handler.insert_error (l_veen)
3194 else
3195 if l_feature.is_constant then
3196 create l_vzaa1
3197 context.init_error (l_vzaa1)
3198 l_vzaa1.set_address_name (l_as.feature_name.internal_name.name)
3199 l_vzaa1.set_location (l_as.feature_name.start_location)
3200 error_handler.insert_error (l_vzaa1)
3201 elseif l_feature.is_external then
3202 create l_unsupported
3203 context.init_error (l_unsupported)
3204 l_unsupported.set_message ("The $ operator is not supported on externals.")
3205 l_unsupported.set_location (l_as.feature_name.start_location)
3206 error_handler.insert_error (l_unsupported)
3207 elseif l_feature.is_attribute then
3208 l_type := l_feature.type.actual_type
3209 create {TYPED_POINTER_A} last_type.make_typed (l_type)
3210 else
3211 last_type := Pointer_type
3212 end
3213
3214 -- Dependance
3215 create l_depend_unit.make_with_level (l_last_id, l_feature, depend_unit_level)
3216 context.supplier_ids.extend (l_depend_unit)
3217
3218 if l_needs_byte_node then
3219 if l_feature.is_attribute then
3220 l_access := l_feature.access (l_type.type_i, False)
3221 create {HECTOR_B} last_byte_node.make_with_type (l_access, last_type.type_i)
3222 else
3223 create {ADDRESS_B} last_byte_node.make (context.current_class.class_id, l_feature)
3224 end
3225 end
3226 if not is_inherited then
3227 l_as.set_routine_ids (l_feature.rout_id_set)
3228 end
3229 end
3230 end
3231 end
3232 instantiator.dispatch (last_type, context.current_class)
3233 error_handler.checksum
3234 end
3235
3236 process_type_expr_as (l_as: TYPE_EXPR_AS) is
3237 local
3238 l_type: TYPE_A
3239 l_type_type: GEN_TYPE_A
3240 do
3241 l_as.type.process (Current)
3242 l_type := last_type
3243
3244 create l_type_type.make (system.type_class.compiled_class.class_id, << l_type >>)
3245 instantiator.dispatch (l_type_type, context.current_class)
3246 last_type := l_type_type
3247 if is_byte_node_enabled then
3248 create {TYPE_EXPR_B} last_byte_node.make (l_type_type.type_i)
3249 end
3250 end
3251
3252 process_routine_creation_as_ext (l_as: ROUTINE_CREATION_AS; a_feature: FEATURE_I) is
3253 local
3254 l_class: CLASS_C
3255 l_feature: FEATURE_I
3256 l_table: FEATURE_TABLE
3257 l_unsupported: NOT_SUPPORTED
3258 l_target_type: TYPE_A
3259 l_target_node: BYTE_NODE
3260 l_needs_byte_node: BOOLEAN
3261 l_feature_name: ID_AS
3262 l_access: ACCESS_B
3263 l_open: OPEN_TYPE_A
3264 l_named_tuple: NAMED_TUPLE_TYPE_A
3265 l_label_pos: INTEGER
3266 l_is_named_tuple: BOOLEAN
3267 do
3268 l_needs_byte_node := is_byte_node_enabled
3269
3270 -- Type check the target
3271 reset_for_unqualified_call_checking
3272
3273 if l_as.target = Void then
3274 -- Target is the closed operand `Current'.
3275 l_target_type := context.current_class_type
3276 if l_needs_byte_node then
3277 create {CURRENT_B} l_target_node
3278 end
3279 else
3280 l_as.target.process (Current)
3281 l_target_type := last_type
3282 l_open ?= l_target_type
3283 if l_open /= Void then
3284 -- Target is the open operand, but we artificially make its type
3285 -- to be the current type.
3286 l_target_type := context.current_class_type
3287 end
3288 if l_needs_byte_node then
3289 l_target_node := last_byte_node
3290 end
3291 end
3292
3293 l_feature_name := l_as.feature_name
3294
3295 if l_target_type.conformance_type.is_formal or l_target_type.conformance_type.is_basic then
3296 -- Not supported. May change in the future - M.S.
3297 -- Reason: We cannot call a feature with basic call target!
3298 create l_unsupported
3299 context.init_error (l_unsupported)
3300 l_unsupported.set_message ("Type of target in a agent call may not be a basic type or a formal.")
3301 if l_as.target /= Void then
3302 l_unsupported.set_location (l_as.target.start_location)
3303 else
3304 l_unsupported.set_location (l_feature_name)
3305 end
3306 error_handler.insert_error (l_unsupported)
3307 error_handler.raise_error
3308 end
3309
3310 if l_target_type.has_associated_class then
3311 l_class := l_target_type.associated_class
3312 l_table := l_class.feature_table
3313
3314 if is_inherited then
3315 if a_feature = Void then
3316 l_feature := l_class.feature_of_rout_id (l_as.routine_ids.first)
3317 else
3318 l_feature := a_feature
3319 end
3320 else
3321 if a_feature = Void then
3322 -- Note that the following can yield `Void' in case it is not a valid feature name or
3323 -- if it is a named tuple access. That's ok, since it is going to be properly
3324 -- handled by `process_call'.
3325 l_feature := l_table.item_id (l_feature_name.name_id)
3326 else
3327 l_feature := a_feature
3328 end
3329 end
3330 else
3331 l_feature := a_feature
3332 end
3333
3334 -- Type check the call
3335 process_call (l_target_type, Void, l_feature_name, l_feature, l_as.operands, False, True, l_as.has_target, False)
3336
3337 if l_feature = Void then
3338 l_named_tuple ?= l_target_type
3339 if l_named_tuple /= Void then
3340 l_label_pos := l_named_tuple.label_position (l_feature_name.name)
3341 if l_label_pos > 0 then
3342 l_is_named_tuple := True
3343 end
3344 end
3345 end
3346
3347 if l_feature = Void and then not l_is_named_tuple then
3348 create l_unsupported
3349 context.init_error (l_unsupported)
3350 l_unsupported.set_message ("Agent creation on `" + l_feature_name.name + "' is%
3351 % not supported because it is either an attribute, a constant or%
3352 % an external feature")
3353 l_unsupported.set_location (l_feature_name)
3354 error_handler.insert_error (l_unsupported)
3355 else
3356 if not is_inherited then
3357 l_as.set_class_id (l_class.class_id)
3358 if l_feature /= Void then
3359 l_as.set_routine_ids (l_feature.rout_id_set)
3360 end
3361 end
3362 l_access ?= last_byte_node
3363 if l_is_named_tuple or else l_feature.is_attribute or else l_feature.is_constant then
3364 is_byte_node_enabled := False
3365
3366 compute_routine (l_table, l_feature, True, False, l_class.class_id, l_target_type, last_type,
3367 l_as, l_access, l_target_node)
3368
3369 if l_needs_byte_node then
3370 is_byte_node_enabled := True
3371 if l_is_named_tuple then
3372 compute_named_tuple_fake_inline_agent (
3373 l_as, l_named_tuple, l_label_pos, l_target_node, l_target_type, last_type)
3374 else
3375 compute_feature_fake_inline_agent (
3376 l_as, l_feature, l_target_node, l_target_type, last_type)
3377 end
3378 end
3379 else
3380 compute_routine (l_table, l_feature, not l_feature.type.is_void,l_feature.has_arguments,
3381 l_class.class_id, l_target_type, last_type, l_as, l_access, l_target_node)
3382 end
3383 System.instantiator.dispatch (last_type, context.current_class)
3384 end
3385 error_handler.checksum
3386 end
3387
3388 process_routine_creation_as (l_as: ROUTINE_CREATION_AS) is
3389 do
3390 process_routine_creation_as_ext (l_as, Void)
3391 end
3392
3393 process_unary_as (l_as: UNARY_AS) is
3394 require
3395 l_as_not_void: l_as /= Void
3396 local
3397 l_prefix_feature: FEATURE_I
3398 l_prefix_feature_type, l_last_constrained: TYPE_A
3399 l_last_class: CLASS_C
3400 l_depend_unit: DEPEND_UNIT
3401 l_vwoe: VWOE
3402 l_vuex: VUEX
3403 l_vape: VAPE
3404 l_manifest: MANIFEST_INTEGER_A
3405 l_value: ATOMIC_AS
3406 l_needs_byte_node: BOOLEAN
3407 l_expr: EXPR_B
3408 l_access: ACCESS_B
3409 l_unary: UNARY_B
3410 l_is_assigner_call: BOOLEAN
3411 l_formal: FORMAL_A
3412 l_is_multi_constrained: BOOLEAN
3413 l_type_set: TYPE_SET_A
3414 l_result_tuple: TUPLE[feature_item: FEATURE_I; class_type_of_feature: CL_TYPE_A; features_found_count: INTEGER]
3415 l_context_current_class: CLASS_C
3416 do
3417 l_needs_byte_node := is_byte_node_enabled
3418
3419 -- Reset assigner call flag
3420 l_is_assigner_call := is_assigner_call
3421 is_assigner_call := False
3422 l_context_current_class := context.current_class
3423 -- Check operand
3424 l_as.expr.process (Current)
3425
3426 if l_needs_byte_node then
3427 l_expr ?= last_byte_node
3428 end
3429 last_type := last_type.actual_type
3430 l_formal ?= last_type
3431 if l_formal /= Void then
3432 if not l_formal.is_single_constraint_without_renaming (l_context_current_class) then
3433 l_is_multi_constrained := True
3434 else
3435 l_last_constrained := l_formal.constrained_type (context.current_class)
3436 end
3437 else
3438 l_last_constrained := last_type
3439 end
3440
3441 if l_is_multi_constrained then
3442 l_type_set := last_type.actual_type.to_type_set.constraining_types (l_context_current_class)
3443 l_result_tuple := l_type_set.feature_i_state_by_alias_name (l_as.prefix_feature_name)
3444 if l_result_tuple.features_found_count > 1 then
3445 raise_vtmc_error (create {ID_AS}.initialize (l_as.prefix_feature_name), l_formal.position, l_context_current_class)
3446 elseif l_result_tuple.features_found_count = 1 then
3447 l_last_class := l_result_tuple.class_type_of_feature.associated_class
3448 l_last_constrained := l_last_class.actual_type
3449 last_calls_target_type := l_last_constrained
3450 l_prefix_feature := l_result_tuple.feature_item
3451 end
3452 else
3453 check l_last_constrained /= Void end
3454 if l_last_constrained.is_none then
3455 -- If we have a formal constrained to NONE it should already be checked earlier.
3456 create l_vuex.make_for_none (l_as.prefix_feature_name)
3457 context.init_error (l_vuex)
3458 l_vuex.set_location (l_as.expr.end_location)
3459 error_handler.insert_error (l_vuex)
3460 -- Cannot go on here
3461 error_handler.raise_error
3462 end
3463
3464 l_last_class := l_last_constrained.associated_class
3465 l_prefix_feature := l_last_class.feature_table.alias_item (l_as.prefix_feature_name)
3466 end
3467
3468 if l_prefix_feature = Void then
3469 -- Error: not prefixed function found
3470 create l_vwoe
3471 context.init_error (l_vwoe)
3472 l_vwoe.set_other_class (l_last_class)
3473 l_vwoe.set_op_name (l_as.prefix_feature_name)
3474 l_vwoe.set_location (l_as.operator_location)
3475 error_handler.insert_error (l_vwoe)
3476 -- Cannot go on here.
3477 error_handler.raise_error
3478 end
3479 if not is_inherited then
3480 l_as.set_class_id (l_last_class.class_id)
3481 l_as.set_routine_ids (l_prefix_feature.rout_id_set)
3482 end
3483
3484 -- Export validity
3485 if
3486 not (context.is_ignoring_export or l_prefix_feature.is_exported_for (l_last_class))
3487 then
3488 create l_vuex
3489 context.init_error (l_vuex)
3490 l_vuex.set_static_class (l_last_class)
3491 l_vuex.set_exported_feature (l_prefix_feature)
3492 l_vuex.set_location (l_as.operator_location)
3493 error_handler.insert_error (l_vuex)
3494 error_handler.raise_error
3495 end
3496
3497 if
3498 not System.do_not_check_vape and then is_checking_precondition and then
3499 not current_feature.export_status.is_subset (l_prefix_feature.export_status)
3500 then
3501 -- In precondition and checking for vape
3502 create l_vape
3503 context.init_error (l_vape)
3504 l_vape.set_exported_feature (current_feature)
3505 l_vape.set_location (l_as.operator_location)
3506 error_handler.insert_error (l_vape)
3507 error_handler.raise_error
3508 end
3509
3510 -- Suppliers update
3511 create l_depend_unit.make_with_level (l_last_class.class_id, l_prefix_feature, depend_unit_level)
3512 context.supplier_ids.extend (l_depend_unit)
3513
3514 -- Assumes here that a prefix feature has no argument
3515 -- Update the type stack; instantiate the result of the
3516 -- refixed feature
3517 l_prefix_feature_type := l_prefix_feature.type
3518 if l_last_constrained.is_bits and then l_prefix_feature_type.is_like_current then
3519 -- For feature prefix "not" of symbolic class BIT_REF.
3520 l_prefix_feature_type := l_last_constrained
3521 else
3522 if l_as.is_minus then
3523 -- Let's say if it is a special case the negation of a positive
3524 -- value in which case we maintain the type of the expression.
3525 -- E.g. -127 is of type INTEGER_8, not of type INTEGER
3526 -- -128 is of type INTEGER_16, since 128 is an INTEGER_16
3527 -- -511 is of type INTEGER_16, not of type INTEGER
3528 --
3529 -- FIXME: Manu 02/06/2004: we do not attempt here to ensure
3530 -- that `-128' is of type INTEGER_8. We will have to wait for ETL3
3531 -- to tell us what we need to do. The current behavior preserve
3532 -- compatibility with older version of Eiffel (5.4 and earlier).
3533 l_manifest ?= l_last_constrained
3534 l_value ?= l_as.expr
3535 if l_value /= Void and l_manifest /= Void then
3536 l_prefix_feature_type := l_last_constrained
3537 else
3538 -- Usual case
3539 l_prefix_feature_type := l_prefix_feature_type.instantiation_in
3540 (last_type, l_last_class.class_id).actual_type
3541 end
3542 else
3543 -- Usual case
3544 l_prefix_feature_type := l_prefix_feature_type.instantiation_in
3545 (last_type, l_last_class.class_id).actual_type
3546 end
3547 end
3548 if l_is_assigner_call then
3549 process_assigner_command (l_last_class.class_id, l_prefix_feature)
3550 end
3551
3552 if l_needs_byte_node then
3553 l_access := l_prefix_feature.access (l_prefix_feature_type.type_i, True)
3554 -- If we have something like `a.f' where `a' is predefined
3555 -- and `f' is a constant then we simply generate a byte
3556 -- node that will be the constant only. Otherwise if `a' is
3557 -- not predefined and `f' is a constant, we generate the
3558 -- complete evaluation `a.f'. However during generation,
3559 -- we will do an optimization by hardwiring value of constant.
3560 if l_is_multi_constrained then
3561 l_access.set_multi_constraint_static (last_calls_target_type.type_i)
3562 end
3563 if not (l_access.is_constant and l_expr.is_predefined) then
3564 l_unary := byte_anchor.unary_node (l_as)
3565 l_unary.set_expr (l_expr)
3566 l_unary.init (l_access)
3567 last_byte_node := l_unary
3568 else
3569 last_byte_node := l_access
3570 end
3571 end
3572
3573 last_type := l_prefix_feature_type
3574 end
3575
3576 process_un_free_as (l_as: UN_FREE_AS) is
3577 do
3578 process_unary_as (l_as)
3579 end
3580
3581 process_un_minus_as (l_as: UN_MINUS_AS) is
3582 do
3583 process_unary_as (l_as)
3584 end
3585
3586 process_un_not_as (l_as: UN_NOT_AS) is
3587 do
3588 process_unary_as (l_as)
3589 end
3590
3591 process_un_old_as (l_as: UN_OLD_AS) is
3592 local
3593 l_vaol1: VAOL1
3594 l_vaol2: VAOL2
3595 l_saved_vaol_check: BOOLEAN
3596 l_expr: EXPR_B
3597 l_un_old: UN_OLD_B
3598 do
3599 if not is_checking_postcondition then
3600 -- Old expression found somewhere else that in a
3601 -- postcondition
3602 create l_vaol1
3603 context.init_error (l_vaol1)
3604 l_vaol1.set_location (l_as.expr.start_location)
3605 error_handler.insert_error (l_vaol1)
3606 error_handler.raise_error
3607 end
3608
3609 l_saved_vaol_check := check_for_vaol
3610 if not l_saved_vaol_check then
3611 -- Set flag for vaol check.
3612 -- Check for an old expression within
3613 -- an old expression.
3614 check_for_vaol := True
3615 end
3616 -- Expression type check
3617 l_as.expr.process (Current)
3618 if not l_saved_vaol_check then
3619 -- Reset flag for vaol check
3620 check_for_vaol := False
3621 end
3622
3623 if last_type.conform_to (Void_type) or else check_for_vaol then
3624 -- Not an expression
3625 create l_vaol2
3626 context.init_error (l_vaol2)
3627 l_vaol2.set_location (l_as.expr.end_location)
3628 error_handler.insert_error (l_vaol2)
3629 elseif is_byte_node_enabled then
3630 l_expr ?= last_byte_node
3631 create l_un_old
3632 l_un_old.set_expr (l_expr)
3633 if old_expressions = Void then
3634 create old_expressions.make
3635 end
3636 old_expressions.put_front (l_un_old)
3637 last_byte_node := l_un_old
3638 end
3639 if not is_inherited then
3640 l_as.set_class_id (class_id_of (last_type.actual_type))
3641 end
3642
3643 if not l_saved_vaol_check then
3644 -- Reset flag for vaol check
3645 check_for_vaol := False
3646 end
3647 end
3648
3649 process_un_plus_as (l_as: UN_PLUS_AS) is
3650 do
3651 process_unary_as (l_as)
3652 end
3653
3654 process_binary_as (l_as: BINARY_AS) is
3655 require
3656 l_as_not_void: l_as /= Void
3657 local
3658 l_infix_type: TYPE_A
3659 l_left_type, l_right_type: TYPE_A
3660 l_right_constrained, l_left_constrained: TYPE_A
3661 l_target_type: TYPE_A
3662 l_formal: FORMAL_A
3663 l_left_id: INTEGER
3664 l_depend_unit: DEPEND_UNIT
3665 l_vuex: VUEX
3666 l_error: ERROR
3667 l_target_conv_info: CONVERSION_INFO
3668 l_left_expr, l_right_expr: EXPR_B
3669 l_needs_byte_node: BOOLEAN
3670 l_binary: BINARY_B
3671 l_call_access: CALL_ACCESS_B
3672 l_is_assigner_call: BOOLEAN
3673 l_is_left_multi_constrained, l_is_right_multi_constrained: BOOLEAN
3674 l_class: CLASS_C
3675 l_context_current_class: CLASS_C
3676 do
3677 l_needs_byte_node := is_byte_node_enabled
3678 l_context_current_class := context.current_class
3679
3680 -- Reset assigner call
3681 l_is_assigner_call := is_assigner_call
3682 is_assigner_call := False
3683
3684 -- First type check the left operand
3685 l_as.left.process (Current)
3686 l_left_type := last_type.actual_type
3687 if l_left_type.is_formal then
3688 l_formal ?= l_left_type
3689 if l_formal.is_multi_constrained (l_context_current_class) then
3690 l_is_left_multi_constrained := True
3691 else
3692 l_left_constrained := l_formal.constrained_type (l_context_current_class)
3693 end
3694 else
3695 l_left_constrained := l_left_type
3696 end
3697
3698 if l_needs_byte_node then
3699 l_left_expr ?= last_byte_node
3700 end
3701
3702 if not l_is_left_multi_constrained then
3703 check l_left_constrained_attached: l_left_constrained /= Void end
3704 -- Check if target is not of type NONE
3705 if l_left_constrained.is_none then
3706 create l_vuex.make_for_none (l_as.infix_function_name)
3707 context.init_error (l_vuex)
3708 l_vuex.set_location (l_as.operator_location)
3709 error_handler.insert_error (l_vuex)
3710 error_handler.raise_error
3711 end
3712 end
3713
3714 -- Then type check the right operand
3715 l_as.right.process (Current)
3716 l_right_type := last_type.actual_type
3717 if l_right_type.is_formal then
3718 l_formal ?= l_right_type
3719 if l_formal.is_multi_constrained (l_context_current_class) then
3720 l_is_right_multi_constrained := True
3721 else
3722 l_right_constrained := l_formal.constrained_type (l_context_current_class)
3723 end
3724 else
3725 l_right_constrained := l_right_type
3726 end
3727
3728 if l_needs_byte_node then
3729 l_right_expr ?= last_byte_node
3730 end
3731
3732 -- Conformance: take care of constrained genericity and
3733 -- of the balancing rule for the simple numeric types
3734 if is_inherited then
3735 l_class := system.class_of_id (l_as.class_id)
3736 last_infix_feature := l_class.feature_of_rout_id (l_as.routine_ids.first)
3737 l_left_constrained := l_class.actual_type
3738 else
3739 if is_infix_valid (l_left_type, l_right_type, l_as.infix_function_name) then
3740 check last_calls_target_type /= Void end
3741 if l_left_constrained = Void then
3742 l_left_constrained := last_calls_target_type
3743 end
3744
3745 else
3746 l_error := last_infix_error
3747 if l_left_type.convert_to (context.current_class, l_right_type) then
3748 l_target_conv_info := context.last_conversion_info
3749 if is_infix_valid (l_right_type, l_right_type, l_as.infix_function_name) then
3750 l_right_constrained := last_calls_target_type
3751 l_left_constrained := l_right_constrained
3752 l_as.set_left_type_converted (True)
3753 else
3754 l_target_conv_info := Void
3755 end
3756 end
3757 end
3758 end
3759
3760 if last_infix_feature = Void then
3761 -- Raise error here
3762 l_error.set_location (l_as.operator_location)
3763 error_handler.insert_error (l_error)
3764 error_handler.raise_error
3765 else
3766 -- Process conversion if any.
3767 if l_target_conv_info /= Void then
3768 check
3769 no_conversion_if_right_type_is_formal: not l_right_type.is_formal
3770 therefore_l_right_constrained_not_void: l_right_constrained /= Void
3771 end
3772 l_left_id := l_right_constrained.associated_class.class_id
3773 if l_target_conv_info.has_depend_unit then
3774 context.supplier_ids.extend (l_target_conv_info.depend_unit)
3775 end
3776 l_target_type := l_target_conv_info.target_type
3777 if l_needs_byte_node then
3778 l_left_expr := l_target_conv_info.byte_node (l_left_expr)
3779 end
3780 else
3781 l_left_id := l_left_constrained.associated_class.class_id
3782 l_target_type := l_left_type
3783 end
3784
3785 if not is_inherited then
3786 -- Set type informations
3787 l_as.set_routine_ids (last_infix_feature.rout_id_set)
3788 l_as.set_class_id (l_left_id)
3789 end
3790
3791 if last_infix_argument_conversion_info /= Void then
3792 if last_infix_argument_conversion_info.has_depend_unit then
3793 context.supplier_ids.extend (last_infix_argument_conversion_info.depend_unit)
3794 end
3795 if l_needs_byte_node then
3796 l_right_expr ?= last_infix_argument_conversion_info.byte_node (l_right_expr)
3797 end
3798 end
3799
3800 -- Suppliers update
3801 create l_depend_unit.make_with_level (l_left_id, last_infix_feature, depend_unit_level)
3802 context.supplier_ids.extend (l_depend_unit)
3803
3804 -- Update the type stack: instantiate result type of the
3805 -- infixed feature
3806 l_infix_type := last_infix_feature.type
3807 if
3808 l_target_type.is_bits and then l_right_constrained.is_bits and then
3809 l_infix_type.is_like_current
3810 then
3811 -- For non-balanced features of symbolic class BIT_REF
3812 -- like infix "^" or infix "#"
3813 l_infix_type := l_target_type
3814 else
3815 -- Usual case
3816 l_infix_type := adapted_type (l_infix_type, l_left_type.actual_type, l_left_constrained)
3817 l_infix_type := l_infix_type.instantiation_in (l_target_type, l_left_id).actual_type
3818 end
3819
3820 if l_is_assigner_call then
3821 process_assigner_command (l_left_id, last_infix_feature)
3822 end
3823
3824 if l_needs_byte_node then
3825 l_binary := byte_anchor.binary_node (l_as)
3826 l_binary.set_left (l_left_expr)
3827 l_binary.set_right (l_right_expr)
3828
3829 l_call_access ?= last_infix_feature.access (l_infix_type.type_i, True)
3830 -- If we have a multi constrained formal we need to set the selected constrained type on which the call is done.
3831 if l_is_left_multi_constrained then
3832 l_call_access.set_multi_constraint_static (l_left_constrained.conformance_type.type_i)
3833 end
3834 l_binary.init (l_call_access)
3835 -- Add type to `parameters' in case we will need it later.
3836 l_binary.set_attachment (last_infix_arg_type.type_i)
3837 last_byte_node := l_binary
3838 end
3839 last_type := l_infix_type
3840 end
3841 last_infix_error := Void
3842 last_infix_feature := Void
3843 last_infix_arg_type := Void
3844 last_infix_argument_conversion_info := Void
3845 end
3846
3847 process_bin_and_then_as (l_as: BIN_AND_THEN_AS) is
3848 do
3849 process_binary_as (l_as)
3850 end
3851
3852 process_bin_free_as (l_as: BIN_FREE_AS) is
3853 do
3854 process_binary_as (l_as)
3855 end
3856
3857 process_bin_implies_as (l_as: BIN_IMPLIES_AS) is
3858 local
3859 l_implies: B_IMPLIES_B
3860 l_bool_val: VALUE_I
3861 l_old_expr: like old_expressions
3862 do
3863 l_old_expr := old_expressions
3864 old_expressions := Void
3865 process_binary_as (l_as)
3866 if is_byte_node_enabled then
3867 -- Special optimization, if the left-hand side is False, then
3868 -- expression is evaluated to True and we discard any new UN_OLD_AS
3869 -- expressions as they are not needed.
3870 l_implies ?= last_byte_node
3871 check
3872 l_implies_not_void: l_implies /= Void
3873 end
3874 l_bool_val := l_implies.left.evaluate
3875 if l_bool_val.is_boolean and then not l_bool_val.boolean_value then
3876 -- Expression can be simplified into a Boolean constant
3877 create {BOOL_CONST_B} last_byte_node.make (True)
3878 old_expressions := l_old_expr
3879 else
3880 -- Add any new UN_OLD_AS expression we found during type checking.
3881 if old_expressions = Void then
3882 old_expressions := l_old_expr
3883 elseif l_old_expr /= Void and old_expressions /= Void then
3884 old_expressions.append (l_old_expr)
3885 end
3886 end
3887 end
3888 end
3889
3890 process_bin_or_as (l_as: BIN_OR_AS) is
3891 do
3892 process_binary_as (l_as)
3893 end
3894
3895 process_bin_or_else_as (l_as: BIN_OR_ELSE_AS) is
3896 do
3897 process_binary_as (l_as)
3898 end
3899
3900 process_bin_xor_as (l_as: BIN_XOR_AS) is
3901 do
3902 process_binary_as (l_as)
3903 end
3904
3905 process_bin_ge_as (l_as: BIN_GE_AS) is
3906 do
3907 process_binary_as (l_as)
3908 end
3909
3910 process_bin_gt_as (l_as: BIN_GT_AS) is
3911 do
3912 process_binary_as (l_as)
3913 end
3914
3915 process_bin_le_as (l_as: BIN_LE_AS) is
3916 do
3917 process_binary_as (l_as)
3918 end
3919
3920 process_bin_lt_as (l_as: BIN_LT_AS) is
3921 do
3922 process_binary_as (l_as)
3923 end
3924
3925 process_bin_div_as (l_as: BIN_DIV_AS) is
3926 do
3927 process_binary_as (l_as)
3928 end
3929
3930 process_bin_minus_as (l_as: BIN_MINUS_AS) is
3931 do
3932 process_binary_as (l_as)
3933 end
3934
3935 process_bin_mod_as (l_as: BIN_MOD_AS) is
3936 do
3937 process_binary_as (l_as)
3938 end
3939
3940 process_bin_plus_as (l_as: BIN_PLUS_AS) is
3941 do
3942 process_binary_as (l_as)
3943 end
3944
3945 process_bin_power_as (l_as: BIN_POWER_AS) is
3946 do
3947 process_binary_as (l_as)
3948 end
3949
3950 process_bin_slash_as (l_as: BIN_SLASH_AS) is
3951 do
3952 process_binary_as (l_as)
3953 end
3954
3955 process_bin_star_as (l_as: BIN_STAR_AS) is
3956 do
3957 process_binary_as (l_as)
3958 end
3959
3960 process_bin_and_as (l_as: BIN_AND_AS) is
3961 do
3962 process_binary_as (l_as)
3963 end
3964
3965 process_bin_eq_as (l_as: BIN_EQ_AS) is
3966 local
3967 l_left_type, l_right_type: TYPE_A
3968 l_left_expr, l_right_expr: EXPR_B
3969 l_conv_info: CONVERSION_INFO
3970 l_binary: BINARY_B
3971 l_vweq: VWEQ
3972 l_needs_byte_node: BOOLEAN
3973 l_is_byte_node_simplified: BOOLEAN
3974 l_ne_as: BIN_NE_AS
3975 do
3976 l_needs_byte_node := is_byte_node_enabled
3977
3978 -- First type check the left member
3979 l_as.left.process (Current)
3980 l_left_type := last_type
3981 if l_needs_byte_node then
3982 l_left_expr ?= last_byte_node
3983 end
3984
3985 if not is_inherited then
3986 l_as.set_class_id (class_id_of (l_left_type))
3987 end
3988
3989 -- Then type check the right member
3990 l_as.right.process (Current)
3991 l_right_type := last_type
3992 if l_needs_byte_node then
3993 l_right_expr ?= last_byte_node
3994 end
3995
3996 -- Check if `l_left_type' conforms to `l_right_type' or if
3997 -- `l_right_type' conforms to `l_left_type'.
3998 if
3999 not (l_left_type.silent_conform_to (l_right_type.actual_type) or else
4000 l_right_type.silent_conform_to (l_left_type.actual_type))
4001 then
4002 if l_right_type.convert_to (context.current_class, l_left_type.actual_type) then
4003 l_conv_info := context.last_conversion_info
4004 if l_conv_info.has_depend_unit then
4005 context.supplier_ids.extend (l_conv_info.depend_unit)
4006 end
4007 if l_needs_byte_node then
4008 l_right_expr := l_conv_info.byte_node (l_right_expr)
4009 end
4010 else
4011 if l_left_type.convert_to (context.current_class, l_right_type.actual_type) then
4012 l_conv_info := context.last_conversion_info
4013 if l_conv_info.has_depend_unit then
4014 context.supplier_ids.extend (l_conv_info.depend_unit)
4015 end
4016 if l_needs_byte_node then
4017 l_left_expr := l_conv_info.byte_node (l_left_expr)
4018 end
4019 elseif not is_inherited then
4020 if context.current_class.is_warning_enabled (w_vweq) then
4021 create l_vweq
4022 context.init_error (l_vweq)
4023 l_vweq.set_left_type (l_left_type)
4024 l_vweq.set_right_type (l_right_type)
4025 l_vweq.set_location (l_as.operator_location)
4026 error_handler.insert_warning (l_vweq)
4027 end
4028 if l_left_type.is_basic and l_right_type.is_basic then
4029 -- Non-compatible basic type always implies a False/true comparison.
4030 l_is_byte_node_simplified := True
4031 end
4032 end
4033 end
4034 end
4035
4036 if l_needs_byte_node then
4037 if l_is_byte_node_simplified then
4038 l_ne_as ?= l_as
4039 if l_ne_as /= Void then
4040 create {BOOL_CONST_B} last_byte_node.make (True)
4041 else
4042 create {BOOL_CONST_B} last_byte_node.make (False)
4043 end
4044 else
4045 l_binary := byte_anchor.binary_node (l_as)
4046 l_binary.set_left (l_left_expr)
4047 l_binary.set_right (l_right_expr)
4048 last_byte_node := l_binary
4049 end
4050 end
4051
4052 last_type := boolean_type
4053 end
4054
4055 process_bin_ne_as (l_as: BIN_NE_AS) is
4056 do
4057 process_bin_eq_as (l_as)
4058 end
4059
4060 process_bracket_as (l_as: BRACKET_AS) is
4061 local
4062 was_assigner_call: BOOLEAN
4063 target_type: TYPE_A
4064 constrained_target_type: TYPE_A
4065 target_expr: EXPR_B
4066 target_access: ACCESS_EXPR_B
4067 target_class: CLASS_C
4068 bracket_feature: FEATURE_I
4069 id_feature_name: ID_AS
4070 location: LOCATION_AS
4071 call_b: CALL_B
4072 nested_b: NESTED_B
4073 vuex: VUEX
4074 vwbr: VWBR
4075 l_formal: FORMAL_A
4076 l_is_multi_constraint: BOOLEAN
4077 l_type_set: TYPE_SET_A
4078 l_result_tuple: TUPLE[feature_item: FEATURE_I; class_type_of_feature: CL_TYPE_A; features_found_count: INTEGER]
4079 l_context_current_class: CLASS_C
4080 l_last_class_id: INTEGER
4081 l_access_b: ACCESS_B
4082 l_is_qualified_call: BOOLEAN
4083 do
4084 -- Clean assigner call flag for bracket target
4085 was_assigner_call := is_assigner_call
4086 is_assigner_call := False
4087 l_context_current_class := context.current_class
4088 -- Check target
4089 l_as.target.process (Current)
4090 target_type := last_type.actual_type
4091 if is_byte_node_enabled then
4092 target_expr ?= last_byte_node
4093 end
4094
4095 check actual_type_called: target_type = target_type.actual_type end
4096 l_formal ?= target_type
4097 if l_formal /= Void then
4098 if l_formal.is_single_constraint_without_renaming (l_context_current_class) then
4099 constrained_target_type := l_formal.constrained_type (context.current_class)
4100 else
4101 l_is_multi_constraint := True
4102 end
4103 else
4104 check actual_type_called: target_type = target_type.actual_type end
4105 constrained_target_type := target_type
4106 end
4107
4108 if l_is_multi_constraint then
4109 l_type_set := l_formal.constrained_types (l_context_current_class)
4110 l_result_tuple := l_type_set.feature_i_state_by_alias_name (bracket_str)
4111 if l_result_tuple.features_found_count > 1 then
4112 raise_vtmc_error (create {ID_AS}.initialize (bracket_str), l_formal.position, l_context_current_class)
4113 elseif l_result_tuple.features_found_count = 1 then
4114 constrained_target_type := l_result_tuple.class_type_of_feature
4115 target_class := constrained_target_type.associated_class
4116 bracket_feature := l_result_tuple.feature_item
4117 end
4118 else
4119 check
4120 constrained_target_type /= Void and then constrained_target_type = constrained_target_type.actual_type
4121 end
4122 -- Check if target is not of type NONE
4123 if constrained_target_type.is_none then
4124 create vuex.make_for_none (bracket_str)
4125 context.init_error (vuex)
4126 vuex.set_location (l_as.left_bracket_location)
4127 error_handler.insert_error (vuex)
4128 error_handler.raise_error
4129 end
4130
4131 -- Check if bracket feature exists
4132 target_class := constrained_target_type.associated_class
4133 bracket_feature := target_class.feature_table.alias_item (bracket_str)
4134 end
4135 if bracket_feature = Void then
4136 -- Feature with bracket alias is not found
4137 create {VWBR1} vwbr
4138 context.init_error (vwbr)
4139 vwbr.set_location (l_as.left_bracket_location)
4140 if l_is_multi_constraint then
4141 check type_set_not_loose: not l_type_set.is_loose end
4142 vwbr.set_target_type (l_type_set)
4143 else
4144 vwbr.set_target_type (constrained_target_type)
4145 end
4146
4147 error_handler.insert_error (vwbr)
4148 error_handler.raise_error
4149 end
4150 if not is_inherited then
4151 l_last_class_id := target_class.class_id
4152 l_as.set_class_id (l_last_class_id)
4153 l_as.set_routine_ids (bracket_feature.rout_id_set)
4154 else
4155 l_last_class_id := l_as.class_id
4156 end
4157
4158 -- Process arguments
4159 create id_feature_name.initialize_from_id (bracket_feature.feature_name_id)
4160 location := l_as.left_bracket_location
4161 id_feature_name.set_position (location.line, location.column, location.position, location.location_count)
4162 -- Restore assigner call flag
4163 is_assigner_call := was_assigner_call
4164 last_calls_target_type := constrained_target_type
4165 -- Process call to bracket feature
4166 l_is_qualified_call := is_qualified_call
4167 is_qualified_call := True
4168 process_call (last_type, Void, id_feature_name, bracket_feature, l_as.operands, False, False, True, False)
4169 last_type := bracket_feature.type.instantiation_in (target_type, l_last_class_id).actual_type
4170 is_qualified_call := l_is_qualified_call
4171 error_handler.checksum
4172
4173 if is_byte_node_enabled then
4174 create nested_b
4175 create target_access
4176 target_access.set_expr (target_expr)
4177 target_access.set_parent (nested_b)
4178 if l_is_multi_constraint then
4179 l_access_b ?= last_byte_node
4180 -- Last generated bytenode is from `process_call'.
4181 check is_access_b: l_access_b /= Void end
4182 l_access_b.set_multi_constraint_static (constrained_target_type.type_i)
4183 call_b := l_access_b
4184 else
4185 call_b ?= last_byte_node
4186 end
4187
4188 check
4189 call_b_not_void: call_b /= Void
4190 end
4191 call_b.set_parent (nested_b)
4192 nested_b.set_message (call_b)
4193 nested_b.set_target (target_access)
4194 last_byte_node := nested_b
4195 end
4196 end
4197
4198 process_external_lang_as (l_as: EXTERNAL_LANG_AS) is
4199 do
4200 -- Nothing to be done
4201 end
4202
4203 process_feature_as (l_as: FEATURE_AS) is
4204 local
4205 l_byte_code: BYTE_CODE
4206 l_list: BYTE_LIST [BYTE_NODE]
4207 l_property_name: STRING
4208 l_custom_attributes: EIFFEL_LIST [CUSTOM_ATTRIBUTE_AS]
4209 do
4210 context.inline_agent_counter.reset
4211 last_byte_node := Void
4212 reset_for_unqualified_call_checking
4213 l_as.body.process (Current)
4214 if is_byte_node_enabled then
4215 l_byte_code ?= last_byte_node
4216 if l_byte_code = Void then
4217 create {ATTRIBUTE_BYTE_CODE} l_byte_code
4218 context.init_byte_code (l_byte_code)
4219 l_byte_code.set_end_location (l_as.end_location)
4220 end
4221 l_byte_code.set_start_line_number (l_as.start_location.line)
4222 l_byte_code.set_has_loop (has_loop)
4223 end
4224 -- For the moment, there is no point in checking custom attributes in non-dotnet mode.
4225 -- This fixes eweasel test#incr207.
4226 if system.il_generation then
4227 l_custom_attributes := l_as.custom_attributes
4228 if l_custom_attributes /= Void then
4229 l_custom_attributes.process (Current)
4230 if is_byte_node_enabled then
4231 l_list ?= last_byte_node
4232 l_byte_code.set_custom_attributes (l_list)
4233 end
4234 end
4235 l_custom_attributes := l_as.class_custom_attributes
4236 if l_custom_attributes /= Void then
4237 l_custom_attributes.process (Current)
4238 if is_byte_node_enabled then
4239 l_list ?= last_byte_node
4240 l_byte_code.set_class_custom_attributes (l_list)
4241 end
4242 end
4243 l_custom_attributes := l_as.interface_custom_attributes
4244 if l_custom_attributes /= Void then
4245 l_custom_attributes.process (Current)
4246 if is_byte_node_enabled then
4247 l_list ?= last_byte_node
4248 l_byte_code.set_interface_custom_attributes (l_list)
4249 end
4250 end
4251 end
4252 l_property_name := l_as.property_name
4253 if l_property_name /= Void then
4254 if is_byte_node_enabled then
4255 l_byte_code.set_property_name (l_property_name)
4256 end
4257 l_custom_attributes := l_as.property_custom_attributes
4258 -- See above comments for why it is only done in .NET mode.
4259 if l_custom_attributes /= Void and system.il_generation then
4260 l_custom_attributes.process (Current)
4261 if is_byte_node_enabled then
4262 l_list ?= last_byte_node
4263 l_byte_code.set_property_custom_attributes (l_list)
4264 end
4265 end
4266 end
4267 if is_byte_node_enabled then
4268 last_byte_node := l_byte_code
4269 end
4270 end
4271
4272 process_infix_prefix_as (l_as: INFIX_PREFIX_AS) is
4273 do
4274 -- Nothing to be done
4275 end
4276
4277 process_feat_name_id_as (l_as: FEAT_NAME_ID_AS) is
4278 do
4279 -- Nothing to be done
4280 end
4281
4282 process_feature_name_alias_as (l_as: FEATURE_NAME_ALIAS_AS) is
4283 do
4284 -- Nothing to be done.
4285 end
4286
4287 process_feature_list_as (l_as: FEATURE_LIST_AS) is
4288 do
4289 -- Nothing to be done
4290 end
4291
4292 process_all_as (l_as: ALL_AS) is
4293 do
4294 -- Nothing to be done
4295 end
4296
4297 process_assign_as (l_as: ASSIGN_AS) is
4298 local
4299 l_target_node: ACCESS_B
4300 l_source_expr: EXPR_B
4301 l_assign: ASSIGN_B
4302 l_ve03: VE03
4303 l_source_type, l_target_type: TYPE_A
4304 l_vjar: VJAR
4305 l_vncb: VNCB
4306 do
4307 break_point_slot_count := break_point_slot_count + 1
4308
4309 -- Init type stack
4310 reset_for_unqualified_call_checking
4311
4312 -- Type check the target
4313 set_is_in_assignment (True)
4314 last_access_writable := False
4315 l_as.target.process (Current)
4316 set_is_in_assignment (False)
4317 l_target_type := last_type
4318 current_target_type := l_target_type
4319
4320 -- Check if the target is not read-only mode.
4321 if not last_access_writable then
4322 -- Read-only entity
4323 create l_ve03
4324 context.init_error (l_ve03)
4325 l_ve03.set_target (l_as.target)
4326 l_ve03.set_location (l_as.target.end_location)
4327 error_handler.insert_error (l_ve03)
4328 end
4329
4330 if is_byte_node_enabled then
4331 l_target_node ?= last_byte_node
4332 end
4333
4334 -- Type check the source
4335 l_as.source.process (Current)
4336 l_source_type := last_type
4337
4338 -- Type checking
4339 process_type_compatibility (l_target_type)
4340 if not is_type_compatible then
4341 if l_source_type.is_bits then
4342 create l_vncb
4343 context.init_error (l_vncb)
4344 l_vncb.set_target_name (l_as.target.access_name)
4345 l_vncb.set_source_type (l_source_type)
4346 l_vncb.set_target_type (l_target_type)
4347 l_vncb.set_location (l_as.start_location)
4348 error_handler.insert_error (l_vncb)
4349 else
4350 create l_vjar
4351 context.init_error (l_vjar)
4352 l_vjar.set_source_type (l_source_type)
4353 l_vjar.set_target_type (l_target_type)
4354 l_vjar.set_target_name (l_as.target.access_name)
4355 l_vjar.set_location (l_as.start_location)
4356 error_handler.insert_error (l_vjar)
4357 end
4358 end
4359
4360 if is_byte_node_enabled then
4361 create l_assign
4362 l_assign.set_target (l_target_node)
4363 l_assign.set_line_number (l_as.target.start_location.line)
4364 l_source_expr ?= last_byte_node
4365 l_assign.set_source (l_source_expr)
4366 l_assign.set_line_pragma (l_as.line_pragma)
4367 last_byte_node := l_assign
4368 end
4369 end
4370
4371 process_assigner_call_as (l_as: ASSIGNER_CALL_AS) is
4372 local
4373 target_byte_node: like last_byte_node
4374 target_type: like last_type
4375 target_assigner: like last_assigner_command
4376 source_byte_node: EXPR_B
4377 source_type: like last_type
4378 vbac1: VBAC1
4379 vbac2: VBAC2
4380 outer_nested_b: NESTED_B
4381 inner_nested_b: NESTED_B
4382 access_b: ACCESS_B
4383 binary_b: BINARY_B
4384 unary_b: UNARY_B
4385 call_b: CALL_B
4386 external_b: EXTERNAL_B
4387 arguments: BYTE_LIST [PARAMETER_B]
4388 argument: PARAMETER_B
4389 assigner_arguments: BYTE_LIST [PARAMETER_B]
4390 l_instr: INSTR_CALL_B
4391 l_tuple_access: TUPLE_ACCESS_B
4392 l_is_tuple_access: BOOLEAN
4393 l_multi_constraint_static: TYPE_I
4394 do
4395 break_point_slot_count := break_point_slot_count + 1
4396
4397 -- Set assigner call flag for target expression
4398 is_assigner_call := True
4399 l_as.target.process (Current)
4400 l_is_tuple_access := is_last_access_tuple_access
4401 is_last_access_tuple_access := False
4402 check
4403 assigner_command_computed: not is_assigner_call
4404 end
4405 target_byte_node := last_byte_node
4406 target_type := last_type
4407 target_assigner := last_assigner_command
4408 l_as.source.process (Current)
4409 process_type_compatibility (target_type)
4410 source_type := last_type
4411 if not is_type_compatible then
4412 create vbac1
4413 context.init_error (vbac1)
4414 vbac1.set_source_type (source_type)
4415 vbac1.set_target_type (target_type)
4416 vbac1.set_location (l_as.start_location)
4417 error_handler.insert_error (vbac1)
4418 elseif target_assigner = Void and then not l_is_tuple_access then
4419 -- If we have no `target_assigner' and the last access is not a tuple access
4420 -- then we have an error.
4421 create vbac2
4422 context.init_error (vbac2)
4423 vbac2.set_location (l_as.start_location)
4424 error_handler.insert_error (vbac2)
4425 end
4426 if is_byte_node_enabled then
4427 -- Make sure all byte node is correct
4428 error_handler.checksum
4429 -- Preserve source byte node
4430 source_byte_node ?= last_byte_node
4431
4432 -- Discriminate over expression kind:
4433 -- it should be either a qualified call,
4434 -- a binary or an unary
4435 outer_nested_b ?= target_byte_node
4436 binary_b ?= target_byte_node
4437 unary_b ?= target_byte_node
4438 external_b ?= target_byte_node
4439 if external_b /= Void then
4440 --| Do nothing (for external static calls)
4441 elseif outer_nested_b /= Void then
4442 call_b := outer_nested_b
4443 -- Find end of call chain
4444 from
4445 inner_nested_b ?= outer_nested_b.message
4446 until
4447 inner_nested_b = Void
4448 loop
4449 outer_nested_b := inner_nested_b
4450 inner_nested_b ?= outer_nested_b.message
4451 end
4452 -- Evaluate assigner command arguments
4453 access_b ?= outer_nested_b.message
4454 check
4455 access_b_not_void: access_b /= Void
4456 end
4457 -- Get the multi_constrait_static if one exists
4458 l_multi_constraint_static := access_b.multi_constraint_static
4459 arguments := access_b.parameters
4460 elseif binary_b /= Void then
4461 -- Create call chain
4462 outer_nested_b := binary_b.nested_b
4463 call_b := outer_nested_b
4464 -- Evaluate assigner command arguments
4465 create arguments.make (1)
4466 create argument
4467 argument.set_expression (binary_b.right)
4468 argument.set_attachment_type (binary_b.attachment)
4469 if not system.il_generation then
4470 argument.set_is_formal (system.seed_of_routine_id (target_assigner.rout_id_set.first).arguments.i_th (1).type_i.is_formal)
4471 end
4472 arguments.extend (argument)
4473 else
4474 check
4475 unary_b_not_void: unary_b /= Void
4476 end
4477 -- Create call chain
4478 outer_nested_b := unary_b.nested_b
4479 call_b := outer_nested_b
4480 -- There are no arguments in unary expression
4481 end
4482
4483 if l_is_tuple_access then
4484 -- When assigning to a tuple, we simply transform the tuple
4485 -- access by giving a source.
4486 l_tuple_access ?= access_b
4487 check l_tuple_access_not_void: l_tuple_access /= Void end
4488 l_tuple_access.set_line_number (l_as.start_location.line)
4489 l_tuple_access.set_source (source_byte_node)
4490 last_byte_node := target_byte_node
4491 else
4492 -- Evaluate assigner command arguments:
4493 -- first is a source of an assigner command
4494 -- next are those from target call
4495 if arguments = Void then
4496 create assigner_arguments.make (1)
4497 else
4498 create assigner_arguments.make (arguments.count + 1)
4499 end
4500 create argument
4501 argument.set_expression (source_byte_node)
4502 argument.set_attachment_type (target_type.type_i)
4503 if not system.il_generation then
4504 argument.set_is_formal (system.seed_of_routine_id (target_assigner.rout_id_set.first).arguments.i_th (1).type_i.is_formal)
4505 end
4506 assigner_arguments.extend (argument)
4507 if arguments /= Void then
4508 assigner_arguments.append (arguments)
4509 end
4510 -- Evaluate assigner command byte node
4511 access_b := target_assigner.access (void_type.type_i, True)
4512 access_b.set_parameters (assigner_arguments)
4513
4514 if l_multi_constraint_static /= Void then
4515 -- We are in the multi constraint case, set the multi constraint static
4516 access_b.set_multi_constraint_static (l_multi_constraint_static)
4517 end
4518
4519 if external_b = Void then
4520 -- Replace end of call chain with an assigner command
4521 access_b.set_parent (outer_nested_b)
4522 outer_nested_b.set_message (access_b)
4523 else
4524 -- Set external static assigner
4525 check call_b_unattached: call_b = Void end
4526 call_b := access_b
4527 end
4528 create l_instr.make (call_b, l_as.start_location.line)
4529 l_instr.set_line_pragma (l_as.line_pragma)
4530 last_byte_node := l_instr
4531 end
4532 end
4533 end
4534
4535 process_reverse_as (l_as: REVERSE_AS) is
4536 local
4537 l_target_node: ACCESS_B
4538 l_source_expr: EXPR_B
4539 l_reverse: REVERSE_B
4540 l_ve03: VE03
4541 l_source_type, l_target_type: TYPE_A
4542 l_conv_info: CONVERSION_INFO
4543 l_formal: FORMAL_A
4544 l_vjrv1: VJRV1
4545 l_vjrv2: VJRV2
4546 l_attribute: ATTRIBUTE_B
4547 l_create_info: CREATE_INFO
4548 do
4549 break_point_slot_count := break_point_slot_count + 1
4550
4551 -- Init type stack
4552 reset_for_unqualified_call_checking
4553
4554 -- Type check the target
4555 set_is_in_assignment (True)
4556 last_access_writable := False
4557 l_as.target.process (Current)
4558 set_is_in_assignment (False)
4559 l_target_type := last_type
4560 current_target_type := l_target_type
4561
4562 -- Check if the target is not read-only mode.
4563 if not last_access_writable then
4564 -- Read-only entity
4565 create l_ve03
4566 context.init_error (l_ve03)
4567 l_ve03.set_target (l_as.target)
4568 l_ve03.set_location (l_as.target.end_location)
4569 error_handler.insert_error (l_ve03)
4570 end
4571
4572 if is_byte_node_enabled then
4573 l_target_node ?= last_byte_node
4574 end
4575
4576 -- Type check the source
4577 l_as.source.process (Current)
4578 l_source_type := last_type
4579 if is_byte_node_enabled then
4580 l_source_expr ?= last_byte_node
4581 create l_reverse
4582 l_reverse.set_target (l_target_node)
4583 l_reverse.set_line_number (l_as.target.start_location.line)
4584 l_reverse.set_line_pragma (l_as.line_pragma)
4585 end
4586
4587 -- Type checking
4588 if l_target_type.is_expanded then
4589 if not is_inherited and context.current_class.is_warning_enabled (w_vjrv) then
4590 create l_vjrv1
4591 context.init_error (l_vjrv1)
4592 l_vjrv1.set_target_name (l_as.target.access_name)
4593 l_vjrv1.set_target_type (l_target_type)
4594 l_vjrv1.set_location (l_as.target.end_location)
4595 error_handler.insert_warning (l_vjrv1)
4596 end
4597 elseif l_target_type.is_formal then
4598 l_formal ?= l_target_type
4599 check
4600 l_formal_not_void: l_formal /= Void
4601 end
4602 if
4603 not l_formal.is_reference and
4604 (not is_inherited and context.current_class.is_warning_enabled (w_vjrv))
4605 then
4606 create l_vjrv2
4607 context.init_error (l_vjrv2)
4608 l_vjrv2.set_target_name (l_as.target.access_name)
4609 l_vjrv2.set_target_type (l_target_type)
4610 l_vjrv2.set_location (l_as.target.end_location)
4611 error_handler.insert_warning (l_vjrv2)
4612 end
4613 else
4614 -- Target is a reference, but source is not.
4615 if l_source_type.is_expanded then
4616 -- Special case `ref ?= exp' where we convert
4617 -- `exp' to its associated reference before
4618 -- doing the assignment.
4619 if l_source_type.convert_to (context.current_class, l_target_type) then
4620 l_conv_info := context.last_conversion_info
4621 if l_conv_info.has_depend_unit then
4622 context.supplier_ids.extend (l_conv_info.depend_unit)
4623 end
4624 if is_byte_node_enabled then
4625 l_source_expr := l_conv_info.byte_node (l_source_expr)
4626 end
4627 end
4628 end
4629 end
4630
4631 if is_byte_node_enabled then
4632 l_reverse.set_source (l_source_expr)
4633 if l_target_node.is_attribute then
4634 l_attribute ?= l_target_node
4635 create {CREATE_FEAT} l_create_info.make (l_attribute.attribute_id,
4636 l_attribute.routine_id, context.current_class)
4637 else
4638 l_create_info := l_target_type.create_info
4639 end
4640
4641 l_reverse.set_info (l_create_info)
4642 last_byte_node := l_reverse
4643 end
4644 end
4645
4646 process_check_as (l_as: CHECK_AS) is
4647 local
4648 l_check: CHECK_B
4649 l_list: BYTE_LIST [BYTE_NODE]
4650 do
4651 if l_as.check_list /= Void then
4652 set_is_checking_check (True)
4653 l_as.check_list.process (Current)
4654 set_is_checking_check (False)
4655
4656 if is_byte_node_enabled then
4657 l_list ?= last_byte_node
4658 create l_check
4659 l_check.set_check_list (l_list)
4660 l_check.set_line_number (l_as.check_list.start_location.line)
4661 l_check.set_end_location (l_as.end_keyword)
4662 l_check.set_line_pragma (l_as.line_pragma)
4663 last_byte_node := l_check
4664 end
4665 elseif is_byte_node_enabled then
4666 create l_check
4667 l_check.set_end_location (l_as.end_keyword)
4668 l_check.set_line_pragma (l_as.line_pragma)
4669 last_byte_node := l_check
4670 end
4671 end
4672
4673 process_abstract_creation (a_creation_type: TYPE_A; a_call: ACCESS_INV_AS; a_name: STRING; a_location: LOCATION_AS) is
4674 require
4675 a_creation_type_not_void: a_creation_type /= Void
4676 a_location_not_void: a_location /= Void
4677 local
4678 l_call_access: CALL_ACCESS_B
4679 l_formal_type: FORMAL_A
4680 l_generic_type: GEN_TYPE_A
4681 l_formal_dec: FORMAL_CONSTRAINT_AS
4682 l_creation_class: CLASS_C
4683 l_creation_type: TYPE_A
4684 l_renamed_creation_type: RENAMED_TYPE_A [TYPE_A]
4685 l_is_formal_creation, l_is_default_creation: BOOLEAN
4686 l_feature, l_feature_item: FEATURE_I
4687 l_orig_call, l_call: ACCESS_INV_AS
4688 l_vgcc1: VGCC1
4689 l_vgcc11: VGCC11
4690 l_vgcc2: VGCC2
4691 l_vgcc4: VGCC4
4692 l_vgcc5: VGCC5
4693 l_creators: HASH_TABLE [EXPORT_I, STRING]
4694 l_needs_byte_node: BOOLEAN
4695 l_actual_creation_type: TYPE_A
4696 l_type_set: TYPE_SET_A
4697 l_constraint_type: TYPE_A
4698 l_deferred_classes: LINKED_LIST[CLASS_C]
4699 l_is_multi_constraint_case: BOOLEAN
4700 l_is_deferred: BOOLEAN
4701 l_constraint_creation_list: LIST [TUPLE [type_item: RENAMED_TYPE_A [TYPE_A]; feature_item: FEATURE_I]]
4702 l_ccl_item: TUPLE [type_item: RENAMED_TYPE_A [TYPE_A]; feature_item: FEATURE_I]
4703 l_mc_feature_info: MC_FEATURE_INFO
4704 l_result: LIST [TUPLE [feature_i: FEATURE_I; cl_type: RENAMED_TYPE_A [TYPE_A]]]
4705 l_result_item: TUPLE [feature_i: FEATURE_I; cl_type: RENAMED_TYPE_A [TYPE_A]]
4706 l_original_default_create_name_id: INTEGER
4707 l_context_current_class: CLASS_C
4708 do
4709 l_needs_byte_node := is_byte_node_enabled
4710 l_orig_call := a_call
4711 l_actual_creation_type := a_creation_type.actual_type
4712 l_context_current_class := context.current_class
4713
4714 l_generic_type ?= l_actual_creation_type
4715
4716 if l_actual_creation_type.is_formal then
4717 -- Cannot be Void
4718 l_formal_type ?= l_actual_creation_type
4719
4720 if l_formal_type.is_single_constraint_without_renaming (l_context_current_class) then
4721 l_constraint_type := l_formal_type.constrained_type (l_context_current_class)
4722 l_creation_type := l_constraint_type
4723 l_creation_class := l_constraint_type.associated_class
4724 l_is_deferred := l_creation_class.is_deferred
4725 else
4726 l_is_multi_constraint_case := True
4727 l_type_set := l_formal_type.constrained_types (l_context_current_class)
4728 l_is_deferred := l_type_set.has_deferred
4729 end
4730 -- Get the corresponding constraint type of the current class
4731 l_formal_dec ?= l_context_current_class.generics.i_th (l_formal_type.position)
4732 check l_formal_dec_not_void: l_formal_dec /= Void end
4733 if
4734 l_formal_dec.has_constraint and then
4735 l_formal_dec.has_creation_constraint
4736 then
4737 l_is_formal_creation := True
4738 -- Ensure to update `has_default_create' from `l_formal_dec'
4739 l_formal_dec.constraint_creation_list (l_context_current_class).do_nothing
4740 else
4741 -- An entity of type a formal generic parameter cannot be
4742 -- created here because there is no creation routine constraints
4743 create l_vgcc1
4744 context.init_error (l_vgcc1)
4745 l_vgcc1.set_target_name (a_name)
4746 l_vgcc1.set_location (a_location)
4747 error_handler.insert_error (l_vgcc1);
4748 end
4749 else
4750 if l_generic_type /= Void then
4751 l_generic_type.check_constraints (l_context_current_class , context.current_feature, True)
4752 l_generic_type.generate_error_from_creation_constraint_list (l_context_current_class , context.current_feature, a_location)
4753 end
4754 l_constraint_type := l_actual_creation_type
4755 l_creation_type := l_constraint_type
4756 l_creation_class := l_constraint_type.associated_class
4757 l_is_deferred := l_creation_class.is_deferred
4758 end
4759
4760 error_handler.checksum
4761
4762 if l_is_deferred and then not l_is_formal_creation then
4763 -- Associated class cannot be deferred
4764 create l_deferred_classes.make
4765 if l_is_multi_constraint_case then
4766 -- We generate a list of all the deferred classes in the type set
4767 l_type_set.do_all (
4768 agent (a_deferred_classes: LIST[CLASS_C]; a_type: RENAMED_TYPE_A [TYPE_A])
4769 do
4770 if a_type.associated_class.is_deferred then
4771 a_deferred_classes.extend (a_type.associated_class)
4772 end
4773 end
4774 (l_deferred_classes,?))
4775 else
4776 -- There's only one class and it is deferred
4777 l_deferred_classes.extend (l_creation_class)
4778 end
4779
4780 create l_vgcc2
4781 context.init_error (l_vgcc2)
4782 l_vgcc2.set_type (a_creation_type)
4783 l_vgcc2.set_deferred_classes (l_deferred_classes)
4784 l_vgcc2.set_target_name (a_name)
4785 l_vgcc2.set_location (a_location)
4786 error_handler.insert_error (l_vgcc2)
4787 error_handler.raise_error
4788 end
4789
4790 if
4791 l_orig_call = Void and then
4792 ((l_creation_class /= Void and then l_creation_class.allows_default_creation) or else
4793 (l_is_formal_creation and then l_formal_dec.has_default_create))
4794 then
4795 if l_creation_class /= Void then
4796 check not_is_multi_constraint_case: not l_is_multi_constraint_case end
4797 l_feature := l_creation_class.default_create_feature
4798 l_creation_type := l_creation_class.actual_type
4799 l_original_default_create_name_id := l_feature.feature_name_id
4800 else
4801 check
4802 is_multi_constrainet_case: l_is_multi_constraint_case
4803 l_formal_type_not_void: l_formal_type /= Void
4804 l_formal_dec_not_void: l_formal_dec /= Void
4805 l_creation_class_is_void: l_creation_class = Void
4806 second_part_of_if_is_true: l_is_formal_creation and then l_formal_dec.has_default_create
4807 end
4808 -- What we want to do is the following:
4809 -- We go through the list of creation constraints and have a look at each feature.
4810 -- If a feature is a version of `default_create' from `ANY' we record it.
4811 -- We should find exactly one feature as otherwise l_formal_dec.has_default_create should not have been true.
4812 l_constraint_creation_list := l_formal_dec.constraint_creation_list (l_context_current_class)
4813 from
4814 l_constraint_creation_list.start
4815 until
4816 l_constraint_creation_list.after or l_creation_class /= Void
4817 loop
4818 l_ccl_item := l_constraint_creation_list.item
4819 l_feature_item := l_ccl_item.feature_item
4820 if l_feature_item.rout_id_set.first = system.default_create_id then
4821 l_feature := l_feature_item
4822 l_renamed_creation_type := l_ccl_item.type_item
4823 if l_renamed_creation_type.has_renaming then
4824 l_original_default_create_name_id := l_renamed_creation_type.renaming.new_name (l_feature.feature_name_id)
4825 else
4826 l_original_default_create_name_id := l_feature.feature_name_id
4827 end
4828 l_creation_type := l_renamed_creation_type.type
4829 l_creation_class := l_creation_type.associated_class
4830 last_type := l_creation_type
4831 end
4832 l_constraint_creation_list.forth
4833 end
4834
4835 check
4836 found_item_was_the_only_one:
4837 (agent (a_constraint_creation_list: LIST [TUPLE [type_item: RENAMED_TYPE_A [TYPE_A]; feature_item: FEATURE_I]]): BOOLEAN
4838 -- Check that there is no more version of default create.
4839 --| Otherwise we should never get in here as `l_formal_dec.has_default_create'
4840 --| should have returned false and prevented this from happening.
4841 do
4842 Result := True
4843 from do_nothing
4844 until
4845 a_constraint_creation_list.after
4846 loop
4847 if a_constraint_creation_list.item.feature_item.rout_id_set.first = system.default_create_id then
4848 Result := False
4849 end
4850 a_constraint_creation_list.forth
4851 end
4852 end).item ([l_constraint_creation_list])
4853 end
4854 end
4855
4856 check l_feature /= Void end
4857 check l_creation_class /= Void end
4858
4859 -- Use default_create
4860 create {ACCESS_INV_AS} l_call.make (
4861 create {ID_AS}.initialize_from_id (l_original_default_create_name_id), Void, Void)
4862 -- For better error reporting as we insert a dummy call for type checking.
4863 l_call.feature_name.set_position (a_location.line, a_location.column,
4864 a_location.position, a_location.location_count)
4865 if l_is_formal_creation or else not l_feature.is_empty then
4866 -- We want to generate a call only when needed:
4867 -- 1 - In a formal generic creation call
4868 -- 2 - When body of `default_create' is not empty
4869 l_orig_call := l_call
4870 end
4871 l_call.set_routine_ids (l_feature.rout_id_set)
4872 l_is_default_creation := True
4873 else
4874 l_call := l_orig_call
4875 end
4876
4877 if l_creation_class /= Void then
4878 l_creators := l_creation_class.creators
4879 end
4880
4881 if l_call /= Void then
4882 if is_inherited then
4883 if l_is_multi_constraint_case then
4884 -- We need to iterate through the type set to find the routine of ID
4885 check
4886 -- It should work as we are in the multi constraint case
4887 l_formal_type_not_void: l_formal_type /= Void
4888 end
4889 l_result := l_type_set.feature_i_list_by_rout_id (l_call.routine_ids.first)
4890 check at_least_one_feature_found: l_result.count > 0 end
4891 from
4892 l_result.start
4893 until
4894 l_result.after
4895 loop
4896 l_result_item := l_result.item
4897 l_feature := l_result_item.feature_i
4898 l_creation_type := l_result_item.cl_type.type
4899 l_creation_class := l_creation_type.associated_class
4900 last_calls_target_type := l_creation_type
4901 -- Type check the call
4902 process_call (last_type, Void, l_call.feature_name, l_feature, l_call.parameters, False, False, False, False)
4903 -- Even though this code is very similar to the one in `process_access_feat_as' we do not
4904 -- need to adapt last_type as this is a creation procedure without a result.
4905 end
4906 -- Martins 3/29/2007
4907 -- After the loop we simply continue with whatever feature was last found.
4908 -- Is this a good idea? Well, it depends:
4909 -- We have done all checks, so whatever it might be, we're fine.
4910 -- But if we would have to generate new code (replication?) it is not decideable what to do
4911 -- because the selection of the static type of the call has an influence to the dynamic binding.
4912 -- And we have possibly more than one possibility to chose from and they are equally acceptable.
4913 fixme ("Possibly a multi constraint issue (in the future) regarding dynamic binding.")
4914 else
4915 check l_creation_class_not_void: l_creation_class /= Void end
4916 l_feature := l_creation_class.feature_of_rout_id (l_call.routine_ids.first)
4917 check l_creation_type_not_void_if_l_feature_is_available: l_feature /= Void implies l_creation_type /= Void end
4918 -- We set `last_calls_target_type' in order to be able to use the same code as we use in the multiconstrained case.
4919 last_calls_target_type := l_creation_type
4920 -- Type check the call
4921 process_call (last_type, Void, l_call.feature_name, l_feature, l_call.parameters, False, False, False, False)
4922 end
4923 else
4924 -- Type check the call
4925 check l_creation_type_not_void_if_l_feature_is_available: l_feature /= Void implies l_creation_type /= Void end
4926 -- We set last_calls_target_type in case we have a multi constrained formal.
4927 last_calls_target_type := l_creation_type
4928 process_call (last_type, Void, l_call.feature_name, l_feature, l_call.parameters, False, False, False, False)
4929 end
4930
4931 check l_creation_class /= Void implies last_calls_target_type.associated_class.conform_to (l_creation_class) end
4932 if not is_inherited then
4933 -- Set some type informations
4934 if l_is_multi_constraint_case then
4935 l_call.set_class_id (last_calls_target_type.associated_class.class_id)
4936 else
4937 l_call.set_class_id (l_creation_class.class_id)
4938 end
4939 -- Note that `last_routine_id_set' could be Void in case it is
4940 -- a named tuple access.
4941 if last_routine_id_set /= Void then
4942 l_call.set_routine_ids (last_routine_id_set)
4943 end
4944 end
4945
4946 -- We need to reset `last_type' as it now `VOID_A' after checking the call
4947 -- which a procedure.
4948 last_type := a_creation_type
4949 if l_needs_byte_node and then l_orig_call /= Void then
4950 l_call_access ?= last_byte_node
4951 if l_is_multi_constraint_case and then l_is_default_creation then
4952 check
4953 no_static_set: not l_call_access.has_multi_constraint_static
4954 end
4955 l_call_access.set_multi_constraint_static (l_creation_type.type_i)
4956 end
4957 end
4958
4959 if not l_is_formal_creation then
4960 -- Check if creation routine is non-once procedure
4961 if
4962 not l_creation_class.valid_creation_procedure (last_feature_name)
4963 then
4964 create l_vgcc5
4965 context.init_error (l_vgcc5)
4966 l_vgcc5.set_target_name (a_name)
4967 l_vgcc5.set_type (a_creation_type)
4968 l_vgcc5.set_creation_feature (l_creation_class.feature_table.item (last_feature_name))
4969 l_vgcc5.set_location (l_call.feature_name)
4970 error_handler.insert_error (l_vgcc5)
4971 elseif l_creators /= Void then
4972 if not l_creators.item (last_feature_name).valid_for (l_context_current_class) then
4973 -- Creation procedure is not exported
4974 create l_vgcc5
4975 context.init_error (l_vgcc5)
4976 l_vgcc5.set_target_name (a_name)
4977 l_vgcc5.set_type (a_creation_type)
4978 l_vgcc5.set_creation_feature (
4979 l_creation_class.feature_table.item_id (last_feature_name_id))
4980 l_vgcc5.set_location (l_call.feature_name)
4981 error_handler.insert_error (l_vgcc5)
4982 end
4983 end
4984 else
4985 -- Check that the creation feature used for creating the generic
4986 -- parameter has been listed in the constraint for the generic
4987 -- parameter.
4988 if not l_formal_dec.has_creation_feature_name_id (last_actual_feature_name_id) then
4989 create l_vgcc11
4990 context.init_error (l_vgcc11)
4991 l_vgcc11.set_target_name (a_name)
4992 if l_is_multi_constraint_case then
4993 l_mc_feature_info := l_type_set.info_about_feature_by_name_id (last_original_feature_name_id, l_formal_type.position, l_context_current_class)
4994 if not l_mc_feature_info.is_empty then
4995 l_vgcc11.set_creation_feature (l_mc_feature_info.first.feature_i)
4996 end
4997 else
4998 check l_creation_class /= Void end
4999 l_vgcc11.set_creation_feature (l_creation_class.feature_table.item (last_feature_name))
5000 end
5001
5002 l_vgcc11.set_location (l_call.feature_name)
5003 error_handler.insert_error (l_vgcc11)
5004 end
5005 end
5006 else
5007 if not l_is_formal_creation then
5008 if (l_creators = Void) or l_is_default_creation then
5009 elseif l_creators.is_empty then
5010 create l_vgcc5
5011 context.init_error (l_vgcc5)
5012 l_vgcc5.set_target_name (a_name)
5013 l_vgcc5.set_type (a_creation_type)
5014 l_vgcc5.set_creation_feature (Void)
5015 l_vgcc5.set_location (a_location)
5016 error_handler.insert_error (l_vgcc5)
5017 else
5018 create l_vgcc4
5019 context.init_error (l_vgcc4)
5020 l_vgcc4.set_target_name (a_name)
5021 l_vgcc4.set_type (a_creation_type)
5022 l_vgcc4.set_location (a_location)
5023 error_handler.insert_error (l_vgcc4)
5024 end
5025 else
5026 -- An entity of type a formal generic parameter cannot be
5027 -- created here because we need a creation routine call
5028 create l_vgcc1
5029 context.init_error (l_vgcc1)
5030 l_vgcc1.set_target_name (a_name)
5031 l_vgcc1.set_location (a_location)
5032 error_handler.insert_error (l_vgcc1)
5033 end
5034 end
5035 error_handler.checksum
5036 if l_needs_byte_node then
5037 last_byte_node := l_call_access
5038 end
5039 end
5040
5041 process_creation_as (l_as: CREATION_AS) is
5042 local
5043 l_access: ACCESS_B
5044 l_call_access: CALL_ACCESS_B
5045 l_creation_expr: CREATION_EXPR_B
5046 l_assign: ASSIGN_B
5047 l_attribute: ATTRIBUTE_B
5048 l_target_type, l_explicit_type, l_creation_type: TYPE_A
5049 l_create_info: CREATE_INFO
5050 l_vgcc3: VGCC3
5051 l_vgcc31: VGCC31
5052 l_vgcc7: VGCC7
5053 l_needs_byte_node: BOOLEAN
5054 do
5055 break_point_slot_count := break_point_slot_count + 1
5056
5057 l_needs_byte_node := is_byte_node_enabled
5058 reset_for_unqualified_call_checking
5059
5060 -- Set flag so that depend_unit knows it is used as a creation routine
5061 -- not just a normal feature call. It is reset as soon as it is processed.
5062 is_target_of_creation_instruction := True
5063 last_access_writable := False
5064 l_as.target.process (Current)
5065 -- Although it might be already reset when `target' is indeed
5066 -- a feature of the current class, it is not reset when it is a local,
5067 -- that's why we reset it.
5068 is_target_of_creation_instruction := False
5069 l_target_type := last_type
5070 if l_needs_byte_node then
5071 l_access ?= last_byte_node
5072 end
5073
5074 if not last_access_writable then
5075 create l_vgcc7
5076 context.init_error (l_vgcc7)
5077 l_vgcc7.set_target_name (l_as.target.access_name)
5078 l_vgcc7.set_type (l_target_type)
5079 l_vgcc7.set_location (l_as.target.start_location)
5080 error_handler.insert_error (l_vgcc7)
5081 else
5082 if l_as.type /= Void then
5083 l_as.type.process (Current)
5084 l_explicit_type := last_type
5085 end
5086
5087 -- Check validity of creation type.
5088 if
5089 l_target_type.is_none or else (l_explicit_type /= Void and then
5090 (l_explicit_type.is_none or else
5091 (l_target_type.is_expanded and then l_explicit_type.is_expanded and then
5092 not l_explicit_type.same_as (l_target_type))))
5093 then
5094 -- Cannot create instance of NONE.
5095 -- Cannot create an expanded type which is different from
5096 -- the declared type of `l_as.target'.
5097 create l_vgcc3
5098 context.init_error (l_vgcc3)
5099 l_vgcc3.set_type (l_explicit_type)
5100 l_vgcc3.set_target_name (l_as.target.access_name)
5101 l_vgcc3.set_location (l_as.target.start_location)
5102 error_handler.insert_error (l_vgcc3)
5103 error_handler.raise_error
5104 end
5105
5106 if
5107 l_explicit_type /= Void and then
5108 not l_explicit_type.conform_to (l_target_type)
5109 then
5110 -- Specified creation type must conform to
5111 -- the entity type
5112 create l_vgcc31
5113 context.init_error (l_vgcc31)
5114 l_vgcc31.set_target_name (l_as.target.access_name)
5115 l_vgcc31.set_type (l_explicit_type)
5116 l_vgcc31.set_location (l_as.type.start_location)