/[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 69868 - (show annotations)
Fri Aug 3 22:28:26 2007 UTC (12 years, 4 months ago) by martins
File size: 266761 byte(s)
enabled more types to store monomorph information
<
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_unadapted_formal_arg_type, 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_unadapted_formal_arg_type := l_feature.arguments.i_th (i)
1439 -- Take care of anchoring to argument
1440 if l_unadapted_formal_arg_type.is_like_argument then
1441 l_like_arg_type := l_unadapted_formal_arg_type.actual_argument_type (l_arg_types)
1442 l_like_arg_type :=
1443 l_like_arg_type.instantiation_in (l_last_type, l_last_id).actual_type
1444 -- Check that `l_arg_type' is compatible to its `like argument'.
1445 -- Once this is done, then type checking is done on the real
1446 -- type of the routine, not the anchor.
1447 if
1448 not l_arg_type.conform_to (l_like_arg_type) and then
1449 not l_arg_type.convert_to (context.current_class, l_like_arg_type)
1450 then
1451 insert_vuar2_error (l_feature, l_parameters, l_last_id, i, l_arg_type,
1452 l_like_arg_type)
1453 end
1454 end
1455
1456 -- Adapted type in case it is a formal generic parameter or a like.
1457 l_formal_arg_type := adapted_type (l_unadapted_formal_arg_type, l_last_type, l_last_constrained)
1458 -- Actual type of feature argument
1459 l_formal_arg_type := l_formal_arg_type.instantiation_in (l_last_type, l_last_id).actual_type
1460
1461 -- Variance check: First, check if argument is a formal.
1462 l_formal ?= l_formal_arg_type.conformance_type
1463 if l_formal /= Void then
1464 -- The actual generic parameter is a formal. If the actual generic parameter
1465 -- is marked as 'variant' we insert an error
1466 l_gen_type ?= l_last_constrained.conformance_type
1467 check
1468 -- l_gen_type can be Void only in one case:
1469 -- * If a call is made on a formal generic which has the argument `like Current':
1470 -- e.g. v: G; v.is_equal (v). Then the argument is formal but the target type is not a gen-type
1471 -- Otherwise, if the argument is a formal, the target is a gen type
1472 l_feature.arguments.i_th (i).is_like_current or else l_gen_type /= Void
1473 end
1474 if l_gen_type /= Void and then l_gen_type.is_covariant (l_formal.position) then
1475 insert_vuar3_error (l_feature, l_parameters, l_last_id, i, l_arg_type,
1476 l_formal)
1477 end
1478 end
1479
1480 -- `like Current' check: First, check if argument is a `like Current' somwhere in the chain of likes.
1481 if l_unadapted_formal_arg_type.is_referencing_current then
1482 -- The call is only allowed in one case:
1483 -- * It is called on a monomorphic type
1484 -- Note: This includes `Current' and therefore `like Current' also
1485 -- formals marked as frozen are ok
1486
1487 if not l_last_constrained.conformance_type.is_monomorph and then not l_last_constrained.is_referencing_current then
1488 insert_vuar4_error (l_feature, l_parameters, l_last_id, i, l_last_constrained, l_arg_type, l_formal_arg_type)
1489 end
1490 end
1491 -- Conformance: take care of constrained genericity
1492 -- We must generate an error when `l_formal_arg_type' becomes
1493 -- an OPEN_TYPE_A, for example "~equal (?, b)" will
1494 -- check that the type of `b' conforms to type of `?'
1495 -- since `equal' is defined as `equal (a: ANY; b: like a)'.
1496 -- However `conform_to' does not work when parameter
1497 -- is an OPEN_TYPE_A type. Since this checks can only
1498 -- happens in type checking of an agent, we can do it
1499 -- at only one place, ie here.
1500 l_open_type ?= l_formal_arg_type
1501 if l_open_type /= Void or else not l_arg_type.conform_to (l_formal_arg_type) then
1502 if
1503 l_open_type = Void and
1504 l_arg_type.convert_to (context.current_class, l_formal_arg_type)
1505 then
1506 l_conv_info := context.last_conversion_info
1507 if l_conv_info.has_depend_unit then
1508 context.supplier_ids.extend (l_conv_info.depend_unit)
1509 end
1510
1511 -- Store conversion info for catcall check later on
1512 if l_conformance_arg_types = Void then
1513 l_conformance_arg_types := l_arg_types.twin
1514 end
1515 l_conformance_arg_types [i] := l_formal_arg_type
1516
1517 -- Generate conversion byte node only if we are not checking
1518 -- a custom attribute. Indeed in that case, we do not want those
1519 -- conversion routines, we will use the attachment type to figure
1520 -- out how the custom attribute will be generated.
1521 if l_needs_byte_node and not is_checking_cas then
1522 l_expr ?= l_arg_nodes.i_th (i)
1523 l_arg_nodes.put_i_th (l_conv_info.byte_node (l_expr), i)
1524 end
1525 elseif
1526 l_arg_type.is_expanded and then l_formal_arg_type.is_external and then
1527 l_arg_type.is_conformant_to (l_formal_arg_type)
1528 then
1529 -- No need for conversion, this is currently done at the code
1530 -- generation level to properly handle the generic case.
1531 -- If not done at the code generation, we would need the
1532 -- following lines.
1533 -- l_expr ?= l_arg_nodes.i_th (i)
1534 -- l_arg_nodes.put_i_th ((create {BOX_CONVERSION_INFO}.make (l_arg_type)).
1535 -- byte_node (l_expr), i)
1536 else
1537 insert_vuar2_error (l_feature, l_parameters, l_last_id, i, l_arg_type,
1538 l_formal_arg_type)
1539 end
1540 end
1541 if l_needs_byte_node then
1542 create l_parameter
1543 l_expr ?= l_arg_nodes.i_th (i)
1544 l_parameter.set_expression (l_expr)
1545 -- Partial solution to the case of using Precursor in an expanded
1546 -- class where some of the arguments are not expanded in the parent
1547 -- class but are now in the current class (a typical example is
1548 -- `prefix "not": like Current' defined in BOOLEAN_REF which is kept
1549 -- as is in BOOLEAN). We need to remember that the original type
1550 -- were not expanded otherwise we do not perform a proper code
1551 -- generation.
1552 -- This fix is incomplete since it does not take care of types
1553 -- that are redefined as expanded.
1554 if a_precursor_type /= Void and l_last_class.is_expanded then
1555 l_parameter.set_attachment_type (l_formal_arg_type.instantiation_in (a_precursor_type, a_precursor_type.associated_class.class_id).type_i)
1556 else
1557 l_parameter.set_attachment_type (l_formal_arg_type.type_i)
1558 if not system.il_generation then
1559 l_parameter.set_is_formal (l_seed.arguments.i_th (i).type_i.is_formal)
1560 end
1561 end
1562 l_parameter_list.extend (l_parameter)
1563
1564 if is_checking_cas then
1565 fixme ("[
1566 Validity checking should not be done when byte code generation
1567 is required. But unfortunately we need the compiled version to get
1568 information about the parameters.
1569 ]")
1570 if not l_expr.is_constant_expression then
1571 create l_vica2.make (context.current_class, current_feature)
1572 l_vica2.set_location (l_parameters.i_th (i).start_location)
1573 error_handler.insert_error (l_vica2)
1574 end
1575 end
1576 end
1577 i := i + 1
1578 end
1579 end
1580
1581 -- Reset original name because it was polluted by the argument checking
1582 last_original_feature_name_id := l_last_original_feature_name_id
1583 check
1584 last_original_feature_name_correct: a_name /= Void implies (last_original_feature_name = a_name.name)
1585 end
1586
1587 -- Get the type of Current feature.
1588 l_result_type := l_feature.type
1589 -- Adapted type in case it is a formal generic parameter or a like.
1590 l_result_type := adapted_type (l_result_type, l_last_type, l_last_constrained)
1591 if l_arg_types /= Void then
1592 l_pure_result_type := l_result_type
1593 l_result_type := l_result_type.actual_argument_type (l_arg_types)
1594 l_open_type ?= l_result_type
1595 if l_open_type /= Void then
1596 -- It means that the result type is a like argument. In that case,
1597 -- we take the static signature of the feature to evaluate `l_result_type'.
1598 -- This fix eweasel test#term141.
1599 l_result_type := l_pure_result_type.actual_argument_type (l_feature.arguments)
1600 end
1601 end
1602 l_result_type := l_result_type.instantiation_in (l_last_type, l_last_id).actual_type
1603 if l_arg_types /= Void and then l_pure_result_type.is_like_argument and then is_byte_node_enabled then
1604 -- Ensure the expandedness status of the result type matches
1605 -- the expandedness status of the argument it is anchored to (if any).
1606 l_like_argument ?= l_pure_result_type
1607 check
1608 l_like_argument_attached: l_like_argument /= Void
1609 end
1610 i := l_like_argument.position
1611 if l_feature.arguments.i_th (i).actual_type.is_reference and then l_result_type.is_expanded then
1612 l_cl_type_a ?= l_result_type
1613 if l_cl_type_a /= Void then
1614 l_generated_result_type := l_cl_type_a.reference_type
1615 end
1616 end
1617 end
1618 -- Export validity
1619 if
1620 not context.is_ignoring_export and is_qualified and
1621 not l_feature.is_exported_for (context.current_class)
1622 then
1623 create l_vuex
1624 context.init_error (l_vuex)
1625 l_vuex.set_static_class (l_last_class)
1626 l_vuex.set_exported_feature (l_feature)
1627 l_vuex.set_location (l_feature_name)
1628 error_handler.insert_error (l_vuex)
1629 end
1630 if
1631 l_feature.is_obsolete
1632 -- If the obsolete call is in an obsolete class,
1633 -- no message is displayed
1634 and then not context.current_class.is_obsolete
1635 -- The current feature is whether the invariant or
1636 -- a non obsolete feature
1637 and then (current_feature = Void or else
1638 not current_feature.is_obsolete)
1639 -- Inherited code is checked in parent class.
1640 and then not is_inherited
1641 -- Warning not disabled
1642 and then context.current_class.is_warning_enabled (w_obsolete_feature)
1643 then
1644 create l_obs_warn
1645 l_obs_warn.set_class (context.current_class)
1646 l_obs_warn.set_obsolete_class (l_last_constrained.associated_class)
1647 l_obs_warn.set_obsolete_feature (l_feature)
1648 l_obs_warn.set_feature (current_feature)
1649 error_handler.insert_warning (l_obs_warn)
1650 end
1651 if
1652 not System.do_not_check_vape and then is_checking_precondition and then
1653 not l_is_in_creation_expression and then
1654 not current_feature.export_status.is_subset (l_feature.export_status)
1655 then
1656 -- In precondition and checking for vape
1657 create l_vape
1658 context.init_error (l_vape)
1659 l_vape.set_exported_feature (l_feature)
1660 l_vape.set_location (l_feature_name)
1661 error_handler.insert_error (l_vape)
1662 error_handler.raise_error
1663 end
1664
1665 -- Supplier dependances update
1666 if not l_feature.is_inline_agent then
1667 if l_is_target_of_creation_instruction then
1668 create l_depend_unit.make_with_level (l_last_id, l_feature,
1669 {DEPEND_UNIT}.is_in_creation_flag | depend_unit_level)
1670 else
1671 if is_precursor then
1672 create l_depend_unit.make_with_level (a_precursor_type.associated_class.class_id, l_feature,
1673 depend_unit_level)
1674 context.supplier_ids.extend (l_depend_unit)
1675 end
1676 create l_depend_unit.make_with_level (l_last_id, l_feature, depend_unit_level)
1677 end
1678 context.supplier_ids.extend (l_depend_unit)
1679 end
1680
1681 if l_is_assigner_call then
1682 process_assigner_command (l_last_id, l_feature)
1683 end
1684
1685 if l_needs_byte_node then
1686 if l_generated_result_type = Void then
1687 l_generated_result_type := l_result_type
1688 end
1689 if not is_static then
1690 if is_precursor then
1691 l_cl_type_i ?= a_precursor_type.type_i
1692 l_access := l_feature.access_for_feature (l_generated_result_type.type_i, l_cl_type_i, False)
1693 -- Strange situation where Precursor is an external, then we do as if
1694 -- it was a static call.
1695 l_ext ?= l_access
1696 if l_ext /= Void then
1697 l_ext.enable_static_call
1698 end
1699 else
1700 if l_is_multiple_constraint_case then
1701 check not l_last_constrained.type_i.is_formal end
1702 l_access := l_feature.access_for_multi_constraint (l_generated_result_type.type_i, l_last_constrained.type_i, is_qualified)
1703 else
1704 l_access := l_feature.access (l_generated_result_type.type_i, is_qualified)
1705 end
1706 end
1707 else
1708 l_access := l_feature.access_for_feature (l_generated_result_type.type_i, a_type.type_i, is_qualified)
1709 if l_is_multiple_constraint_case then
1710 check not l_last_constrained.type_i.is_formal end
1711 l_access.set_multi_constraint_static (l_last_constrained.type_i)
1712 end
1713 l_ext ?= l_access
1714 if l_ext /= Void then
1715 l_ext.enable_static_call
1716 end
1717 end
1718 l_access.set_parameters (l_parameter_list)
1719 last_byte_node := l_access
1720 end
1721
1722 -- Check if cat-call detection is enabled for current context class
1723 if context.current_class.is_cat_call_detection then
1724 -- An error is added if all of the following conditions apply:
1725 -- * Qualified call:
1726 -- Unqualified calls don't need to be checked as their target, `Current', is monomorph
1727 -- * The feature is marked as manualy covariant (not "generic" or "like Current" covariance
1728 -- this has been handled before):
1729 -- features which are not marked covariant don't need to be checked
1730 -- * `l_last_type' is not monomorph or formal:
1731 -- Calls on monomorph types don't need to be checked. Formals are an exception as they
1732 -- can be derived with any type which fits their constraint, so even monomorph formals
1733 -- need to be checked
1734 -- * Not inline agent, static calls or frozen calls:
1735 -- There are no descendant features which could overwrite the arguments covariantly
1736 -- Note: The static and inline agent check is probably not necessary, as these features
1737 -- are not marked as covariant anyway. This is also true for frozen features:
1738 -- They can never be redefined covariantly.
1739 if
1740 is_qualified and then
1741 system.covariant_argument_index.is_covariantly_redefined (l_feature.rout_id_set.first, l_last_constrained.associated_class) and then
1742 (not l_last_type.is_monomorph or else l_last_type.is_formal)
1743 then
1744 check
1745 not_a_call_to_a_inline_agent: not l_feature.is_inline_agent
1746 not_a_static_call: not is_static
1747 not_a_frozen_feature: not l_feature.is_frozen
1748 end
1749
1750 -- Report an error
1751 create l_cat_call_warning.make (context.current_class, context.current_feature, l_feature_name)
1752 l_cat_call_warning.set_called_feature (l_feature)
1753 error_handler.insert_warning (l_cat_call_warning)
1754 end
1755 -- Statistics
1756 system.statistics.feature_calls := system.statistics.feature_calls + 1
1757 if l_feature.argument_count > 0 then
1758 system.statistics.feature_arguments := system.statistics.feature_arguments + 1
1759 end
1760 end
1761
1762 last_type := l_result_type
1763 last_calls_target_type := l_last_constrained
1764 last_access_writable := l_feature.is_attribute
1765 last_feature_name_id := l_feature.feature_name_id
1766 check
1767 last_feature_name_correct: last_feature_name = l_feature.feature_name
1768 end
1769 last_routine_id_set := l_feature.rout_id_set
1770 else
1771 -- `l_feature' was not valid for current, report
1772 -- corresponding error.
1773 if l_feature = Void then
1774 -- Not a valid feature name.
1775 -- In case of a multi constraint we throw a VTMC1 error instead of a VEEN.
1776 if l_is_multiple_constraint_case then
1777 create l_vtmc1
1778 context.init_error (l_vtmc1)
1779 l_vtmc1.set_feature_call_name (l_feature_name.name)
1780 l_vtmc1.set_location (l_feature_name)
1781 l_vtmc1.set_type_set (l_last_type_set)
1782 l_vtmc1.set_location (l_feature_name)
1783 error_handler.insert_error (l_vtmc1)
1784 error_handler.raise_error
1785 else
1786 create l_veen
1787 context.init_error (l_veen)
1788 l_veen.set_identifier (l_feature_name.name)
1789 l_veen.set_parameter_count (l_actual_count)
1790 l_veen.set_location (l_feature_name)
1791 error_handler.insert_error (l_veen)
1792 error_handler.raise_error
1793 end
1794 elseif is_static then
1795 -- Not a valid feature for static access.
1796 create l_vsta2
1797 context.init_error (l_vsta2)
1798 l_vsta2.set_non_static_feature (l_feature)
1799 l_vsta2.set_location (l_feature_name)
1800 error_handler.insert_error (l_vsta2)
1801 error_handler.raise_error
1802 end
1803 end
1804 end
1805 -- Finally update current to reflect if current call is a tuple
1806 -- access or not.
1807 is_last_access_tuple_access := l_is_last_access_tuple_access
1808 if l_is_last_access_tuple_access then
1809 -- Properly update current to show we have just accessed a tuple.
1810 last_access_writable := True
1811 last_routine_id_set := Void
1812 end
1813 ensure
1814 last_calls_target_type_proper_set: not (error_handler.has_error or is_last_access_tuple_access) implies last_calls_target_type /= Void
1815 end
1816
1817 process_feature_clause_as (l_as: FEATURE_CLAUSE_AS) is
1818 do
1819 -- Nothing to be done
1820 end
1821
1822 process_unique_as (l_as: UNIQUE_AS) is
1823 do
1824 -- Nothing to be done
1825 end
1826
1827 process_tuple_as (l_as: TUPLE_AS) is
1828 local
1829 l_tuple_type: TUPLE_TYPE_A
1830 l_list: BYTE_LIST [EXPR_B]
1831 do
1832 reset_for_unqualified_call_checking
1833
1834 -- Type check expression list
1835 process_expressions_list_for_tuple (l_as.expressions)
1836
1837 -- Update type stack
1838 create l_tuple_type.make (system.tuple_id, last_expressions_type)
1839 instantiator.dispatch (l_tuple_type, context.current_class)
1840 last_tuple_type := l_tuple_type
1841 last_type := l_tuple_type
1842
1843 if is_byte_node_enabled then
1844 l_list ?= last_byte_node
1845 create {TUPLE_CONST_B} last_byte_node.make (l_list, l_tuple_type.type_i)
1846 end
1847 ensure then
1848 last_tuple_type_set: last_tuple_type /= Void
1849 end
1850
1851 process_real_as (l_as: REAL_AS) is
1852 do
1853 if l_as.constant_type = Void then
1854 last_type := Real_64_type
1855 else
1856 fixme ("We should check that `constant_type' matches the real `value' and%
1857 %possibly remove `constant_type' from REAL_AS.")
1858 check_type (l_as.constant_type)
1859 end
1860 if is_byte_node_enabled then
1861 create {REAL_CONST_B} last_byte_node.make (l_as.value, last_type)
1862 end
1863 end
1864
1865 process_bool_as (l_as: BOOL_AS) is
1866 do
1867 last_type := Boolean_type
1868 if is_byte_node_enabled then
1869 create {BOOL_CONST_B} last_byte_node.make (l_as.value)
1870 end
1871 end
1872
1873 process_bit_const_as (l_as: BIT_CONST_AS) is
1874 do
1875 create {BITS_A} last_type.make (l_as.value.name.count)
1876 if is_byte_node_enabled then
1877 create {BIT_CONST_B} last_byte_node.make (l_as.value.name)
1878 end
1879 end
1880
1881 process_array_as (l_as: ARRAY_AS) is
1882 local
1883 i, nb: INTEGER
1884 l_array_type: GEN_TYPE_A
1885 l_generics: ARRAY [TYPE_A]
1886 l_type_a, l_element_type: TYPE_A
1887 l_list: BYTE_LIST [EXPR_B]
1888 l_gen_type: GEN_TYPE_A
1889 l_last_types: like last_expressions_type
1890 l_has_error: BOOLEAN
1891 l_has_array_target: BOOLEAN
1892 do
1893 reset_for_unqualified_call_checking
1894 -- Get target for manifest array creation (either through assignment or
1895 -- argument passing).
1896 l_gen_type ?= current_target_type
1897 -- Let's try to find the type of the manifest array.
1898 if l_gen_type /= Void then
1899 -- Check that it is either an ARRAY, or a NATIVE_ARRAY when used
1900 -- in a custom attribute.
1901 if
1902 l_gen_type.class_id = system.array_id or
1903 (is_checking_cas and then l_gen_type.class_id = system.native_array_id)
1904 then
1905 l_has_array_target := True
1906 -- Check that expressions' type matches element's type of `l_gen_type' array.
1907 l_element_type := l_gen_type.generics.item (1).actual_type
1908 end
1909 end
1910
1911 -- Type check expression list
1912 -- If there is a manifest array within a manifest array, we consider there is
1913 -- no target type specified.
1914 nb := l_as.expressions.count
1915 current_target_type := l_element_type
1916 process_expressions_list (l_as.expressions)
1917 l_last_types := last_expressions_type
1918
1919 if is_byte_node_enabled then
1920 l_list ?= last_byte_node
1921 end
1922
1923 -- Let's try to find the type of the manifest array.
1924 if l_has_array_target then
1925 -- Check that expressions' type matches element's type of `l_gen_type' array.
1926 l_type_a := l_element_type
1927 if nb > 0 then
1928 from
1929 i := 1
1930 until
1931 i > nb
1932 loop
1933 l_element_type := l_last_types.item (i)
1934 if not l_element_type.conform_to (l_type_a) then
1935 if l_element_type.convert_to (context.current_class, l_type_a) then
1936 if is_byte_node_enabled and not is_checking_cas then
1937 l_list.put_i_th (context.last_conversion_info.byte_node (
1938 l_list.i_th (i)), i)
1939 end
1940 else
1941 l_has_error := True
1942 i := nb + 1 -- Exit the loop
1943 end
1944 end
1945 i := i + 1
1946 end
1947 end
1948 if not l_has_error then
1949 -- We could keep `l_gen_type' for `l_array_type', but unfortunately it
1950 -- causes the eweasel test `term131' to fail because if it contains an
1951 -- anchor then it is not marked as used for dead code removal (because
1952 -- anchor appears in signature and signatures are not solved for dependances
1953 -- at degree 4) and we would crash while generating the table at the very
1954 -- end of finalization.
1955 -- For now we use `l_type_a.deep_actual_type' (which removes any usage of
1956 -- the anchor) to solve the problem.
1957 create l_generics.make (1, 1)
1958 l_generics.put (l_type_a.deep_actual_type, 1)
1959 if is_checking_cas then
1960 check l_gen_type.class_id = system.native_array_id end
1961 create {NATIVE_ARRAY_TYPE_A} l_array_type.make (system.native_array_id, l_generics)
1962 else
1963 create l_array_type.make (system.array_id, l_generics)
1964 end
1965 instantiator.dispatch (l_array_type, context.current_class)
1966 end
1967 end
1968 if l_array_type = Void then
1969 if nb > 0 then
1970 if is_checking_cas then
1971 -- `l_gen_type' is not an array type, so for now we compute as if
1972 -- there was no context the type of the manifest array by taking the lowest
1973 -- common type.
1974 from
1975 l_has_error := False
1976 -- Take first element in manifest array and let's suppose
1977 -- it is the lowest type.
1978 l_type_a := l_last_types.item (1)
1979 i := 2
1980 until
1981 i > nb
1982 loop
1983 l_element_type := l_last_types.item (i)
1984 -- Let's try to find the type to which everyone conforms to.
1985 -- If not found it will be ANY.
1986 if
1987 l_element_type.conform_to (l_type_a) or
1988 l_element_type.convert_to (context.current_class, l_type_a)
1989 then
1990 -- Nothing to be done
1991 elseif
1992 l_type_a.conform_to (l_element_type) or
1993 l_type_a.convert_to (context.current_class, l_element_type)
1994 then
1995 -- Found a lowest type.
1996 l_type_a := l_element_type
1997 else
1998 -- Cannot find a common type
1999 l_has_error := True
2000 i := nb + 1 -- Exit the loop
2001 end
2002 i := i + 1
2003 end
2004 else
2005 -- `l_gen_type' is not an array type, so for now we compute as if
2006 -- there was no context the type of the manifest array by taking the lowest
2007 -- common type.
2008 from
2009 l_has_error := False
2010 -- Take first element in manifest array and let's suppose
2011 -- it is the lowest type.
2012 l_type_a := l_last_types.item (1)
2013 i := 2
2014 until
2015 i > nb
2016 loop
2017 l_element_type := l_last_types.item (i)
2018 -- Let's try to find the type to which everyone conforms to.
2019 -- If not found it will be ANY.
2020 if l_element_type.conform_to (l_type_a) then
2021 -- Nothing to be done
2022 elseif l_type_a.conform_to (l_element_type) then
2023 -- Found a lowest type.
2024 l_type_a := l_element_type
2025 else
2026 -- Cannot find a common type
2027 l_has_error := True
2028 i := nb + 1 -- Exit the loop
2029 end
2030 i := i + 1
2031 end
2032 end
2033 if l_has_error then
2034 -- We could not find a common type, so let's iterate again to ensure that
2035 -- elements conform or convert to ANY.
2036 from
2037 i := 1
2038 l_has_error := False
2039 create {CL_TYPE_A} l_type_a.make (system.any_id)
2040 until
2041 i > nb
2042 loop
2043 l_element_type := l_last_types.item (i)
2044 if not l_element_type.conform_to (l_type_a) then
2045 if l_element_type.convert_to (context.current_class, l_type_a) then
2046 if is_byte_node_enabled and not is_checking_cas then
2047 l_list.put_i_th (context.last_conversion_info.byte_node (
2048 l_list.i_th (i)), i)
2049 end
2050 else
2051 l_has_error := True
2052 i := nb + 1 -- Exit the loop
2053 end
2054 end
2055 i := i + 1
2056 end
2057 end
2058 if not l_has_error then
2059 create l_generics.make (1, 1)
2060 l_generics.put (l_type_a, 1)
2061 create l_array_type.make (system.array_id, l_generics)
2062 instantiator.dispatch (l_array_type, context.current_class)
2063 end
2064 else
2065 -- Empty manifest array
2066 create l_generics.make (1, 1)
2067 l_generics.put (create {CL_TYPE_A}.make (system.any_id), 1)
2068 create l_array_type.make (system.array_id, l_generics)
2069 instantiator.dispatch (l_array_type, context.current_class)
2070 end
2071 end
2072
2073 if not l_has_error then
2074 -- Update type stack
2075 last_type := l_array_type
2076 l_as.set_array_type (last_type)
2077 if is_byte_node_enabled then
2078 create {ARRAY_CONST_B} last_byte_node.make (l_list,
2079 l_array_type.type_i, l_array_type.create_info)
2080 end
2081 else
2082 fixme ("Insert new validity error saying that manifest array is not valid")
2083 end
2084 end
2085
2086 process_char_as (l_as: CHAR_AS) is
2087 do
2088 if l_as.type = Void then
2089 if l_as.value.is_character_8 then
2090 last_type := character_type
2091 else
2092 last_type := Wide_char_type
2093 end
2094 else
2095 check_type (l_as.type)
2096 end
2097 if is_byte_node_enabled then
2098 create {CHAR_CONST_B} last_byte_node.make (l_as.value, last_type)
2099 end
2100 end
2101
2102 process_string_as (l_as: STRING_AS) is
2103 do
2104 last_type := string_type
2105 if is_byte_node_enabled then
2106 if l_as.is_once_string then
2107 once_manifest_string_index := once_manifest_string_index + 1
2108 create {ONCE_STRING_B} last_byte_node.make (l_as.value, once_manifest_string_index)
2109 else
2110 create {STRING_B} last_byte_node.make (l_as.value)
2111 end
2112 end
2113 end
2114
2115 process_verbatim_string_as (l_as: VERBATIM_STRING_AS) is
2116 do
2117 process_string_as (l_as)
2118 end
2119
2120 process_body_as (l_as: BODY_AS) is
2121 do
2122 safe_process (l_as.content)
2123 end
2124
2125 process_built_in_as (l_as: BUILT_IN_AS) is
2126 -- Process `l_as'.
2127 local
2128 l_external: EXTERNAL_I
2129 l_built_in_processor: BUILT_IN_PROCESSOR
2130 l_feature_as: FEATURE_AS
2131 l_feature_checker: AST_FEATURE_CHECKER_GENERATOR
2132 do
2133 if is_byte_node_enabled then
2134 l_external ?= current_feature
2135 -- If associated feature is not an external anymore, it means that it was interpreted
2136 -- by our compiler as a real `built_in'.
2137 if l_external = Void then
2138 create l_built_in_processor.make (context.current_class, current_feature.feature_name, system.il_generation)
2139 l_feature_as := l_built_in_processor.ast_node
2140 if l_feature_as /= Void and then l_feature_as.body.content /= Void then
2141 -- Only interprets the `built_in' implementation if this is not an attribute.
2142 create l_feature_checker
2143 l_feature_checker.init (context)
2144 l_feature_checker.check_body (current_feature,
2145 l_feature_as.body, True, False, False)
2146 last_byte_node := l_feature_checker.last_byte_node
2147 l_as.set_body (l_feature_as)
2148 else
2149 -- No implementation is provided, let's assume empty body.
2150 create {STD_BYTE_CODE} last_byte_node
2151 end
2152 else
2153 create {EXT_BYTE_CODE} last_byte_node.make (l_external.external_name_id)
2154 end
2155 end
2156 end
2157
2158 process_result_as (l_as: RESULT_AS) is
2159 local
2160 l_feat_type: TYPE_A
2161 l_vrle3: VRLE3
2162 l_has_error: BOOLEAN
2163 l_veen2a: VEEN2A
2164 do
2165 -- Error if in procedure or invariant
2166 l_has_error := is_checking_invariant
2167 if not l_has_error then
2168 l_feat_type := current_feature.type
2169 l_has_error := l_feat_type.actual_type.conform_to (Void_type)
2170 end
2171
2172 if l_has_error then
2173 create l_vrle3
2174 context.init_error (l_vrle3)
2175 l_vrle3.set_location (l_as.start_location)
2176 error_handler.insert_error (l_vrle3)
2177 -- Cannot go on here
2178 error_handler.raise_error
2179 else
2180 if is_checking_precondition then
2181 -- Result entity in precondition
2182 create l_veen2a
2183 context.init_error (l_veen2a)
2184 l_veen2a.set_location (l_as.start_location)
2185 error_handler.insert_error (l_veen2a)
2186 end
2187
2188 -- Update the type stack
2189 last_type := l_feat_type
2190 last_access_writable := True
2191 if is_byte_node_enabled then
2192 create {RESULT_B} last_byte_node
2193 end
2194 end
2195 end
2196
2197 process_current_as (l_as: CURRENT_AS) is
2198 do
2199 last_type := context.current_class_type
2200 if is_byte_node_enabled then
2201 create {CURRENT_B} last_byte_node
2202 end
2203 end
2204
2205 process_access_feat_as (l_as: ACCESS_FEAT_AS) is
2206 local
2207 l_type_a, l_last_type, l_last_constrained, l_feature_type, l_last_feature_type: TYPE_A
2208 l_last_class_id: INTEGER
2209 l_formal: FORMAL_A
2210 l_feature: FEATURE_I
2211 l_result: LIST [TUPLE [feature_i: FEATURE_I; cl_type: RENAMED_TYPE_A [TYPE_A]]]
2212 l_result_item: TUPLE [feature_i: FEATURE_I; cl_type: RENAMED_TYPE_A [TYPE_A]]
2213 l_type_a_is_multi_constrained: BOOLEAN
2214 l_type_set: TYPE_SET_A
2215 l_vtmc4: VTMC4
2216 do
2217 l_type_a := last_type.actual_type
2218 if l_type_a.is_formal then
2219 l_formal ?= l_type_a
2220 if l_formal.is_multi_constrained (context.current_class) then
2221 l_type_a_is_multi_constrained := True
2222 else
2223 l_type_a := l_formal.constrained_type (context.current_class)
2224 end
2225 end
2226
2227 if not l_type_a_is_multi_constrained then
2228 if not l_type_a.is_none and not l_type_a.is_void then
2229 if is_inherited and not l_as.is_tuple_access then
2230 -- Reuse the feature when it is really one, otherwise when it is a tuple
2231 -- access the call to `process_call' will do the right thing for inherited code.
2232 l_feature := l_type_a.associated_class.feature_of_rout_id (l_as.routine_ids.first)
2233 end
2234 end
2235 -- Type check the call
2236 process_call (last_type, Void, l_as.feature_name, l_feature, l_as.parameters,
2237 False, False, True, False)
2238 else
2239 -- Multi constraint case
2240 if is_inherited then
2241 -- This code here is very similar to some parts of `process_abstract_creation'.
2242 -- It has the very same issues as described there.
2243 fixme ("Related to fix me in `process_abstract_creation'")
2244
2245 -- Note: We do not need to protect against TUPLE access here since
2246 -- named tuples are not allowed in multiple-constraint.
2247
2248 -- We need to iterate through the type set to find the routine of ID
2249 l_formal ?= l_type_a
2250 check
2251 -- It should work as we are in the multi constraint case
2252 l_formal_not_void: l_formal /= Void
2253 end
2254 l_type_set := context.current_class.constraints (l_formal.position)
2255 l_type_set := l_type_set.constraining_types (context.current_class)
2256 l_result := l_type_set.feature_i_list_by_rout_id (l_as.routine_ids.first)
2257 check at_least_one_feature_found: l_result.count > 0 end
2258 -- As we inherited this feature there's the possiblity that now,
2259 from
2260 l_result.start
2261 l_last_type :=last_type
2262 until
2263 l_result.after or l_vtmc4 /= Void
2264 loop
2265 l_result_item := l_result.item
2266 l_feature := l_result_item.feature_i
2267 l_last_class_id := l_result_item.cl_type.associated_class.class_id
2268 l_last_constrained := l_result_item.cl_type.type
2269 -- Restore last_type
2270 last_calls_target_type := l_last_constrained
2271 -- Type check the call
2272 process_call (l_last_type, Void, l_as.feature_name, l_feature, l_as.parameters,
2273 False, False, True, False)
2274 l_result.forth
2275 -- We inherited this feature. Adapt it's type. DELETEME and the commented code below
2276 l_feature_type := last_type -- l_feature.type.instantiation_in (l_last_type, l_last_class_id).actual_type
2277 if l_last_feature_type /= Void and then l_last_feature_type.same_as (l_feature_type) then
2278 -- Ok, the two features have still the same return type.
2279 else
2280 -- The two features have redefined their return type differently.
2281 -- We don't allow this: Add an error, but continue checking as this only an additional
2282 -- check and does not break anything else.
2283 -- Note: If `like Current' is the type of the feature this is ok, as the type is adapted to the formal.
2284 create l_vtmc4
2285 l_vtmc4.set_class (context.current_class)
2286 l_vtmc4.set_written_class (system.class_of_id (l_as.class_id))
2287 l_vtmc4.set_feature (context.current_feature)
2288 l_vtmc4.set_location (l_as.start_location)
2289 l_vtmc4.set_feature_info (l_result)
2290 error_handler.insert_error (l_vtmc4)
2291 end
2292 end
2293 -- We inherited this feature. Adapt it's type.
2294 last_type := l_feature_type
2295
2296 else
2297 -- Type check the call
2298 process_call (last_type, Void, l_as.feature_name, l_feature, l_as.parameters,
2299 False, False, True, False)
2300 end
2301 end
2302
2303 error_handler.checksum
2304
2305 if not is_inherited then
2306 -- set some type attributes of the node
2307 if last_calls_target_type /= Void then
2308 l_as.set_class_id (last_calls_target_type.associated_class.class_id)
2309 else
2310 l_as.set_class_id (-1)
2311 end
2312 if last_routine_id_set /= Void then
2313 check
2314 not_is_tuple_access: not is_last_access_tuple_access
2315 end
2316 l_as.set_routine_ids (last_routine_id_set)
2317 else
2318 check
2319 is_tuple_access: is_last_access_tuple_access
2320 end
2321 l_as.enable_tuple_access
2322 end
2323 end
2324 end
2325
2326 process_access_inv_as (l_as: ACCESS_INV_AS) is
2327 local
2328 l_class_id: INTEGER
2329 l_type_a: TYPE_A
2330 l_feature: FEATURE_I
2331 do
2332 l_type_a := last_type.actual_type
2333 check
2334 not_formal: not l_type_a.is_formal
2335 end
2336 l_class_id := l_type_a.associated_class.class_id
2337 if is_inherited then
2338 l_feature := l_type_a.associated_class.feature_of_rout_id (l_as.routine_ids.first)
2339 end
2340 process_call (last_type, Void, l_as.feature_name, l_feature, l_as.parameters, False, False, False, False)
2341 error_handler.checksum
2342
2343 if not is_inherited then
2344 -- set some type attributes of the node
2345 l_as.set_class_id (l_class_id)
2346 l_as.set_routine_ids (last_routine_id_set)
2347 end
2348 end
2349
2350 process_access_id_as (l_as: ACCESS_ID_AS) is
2351 local
2352 l_arg_pos: INTEGER
2353 l_last_id: INTEGER
2354 l_local: LOCAL_B
2355 l_argument: ARGUMENT_B
2356 l_local_info: LOCAL_INFO
2357 l_feature: FEATURE_I
2358 l_has_vuar_error: BOOLEAN
2359 l_vuar1: VUAR1
2360 l_veen2b: VEEN2B
2361 l_needs_byte_node: BOOLEAN
2362 l_type: TYPE_A
2363 l_context_current_class: CLASS_C
2364 do
2365 l_context_current_class := context.current_class
2366 l_needs_byte_node := is_byte_node_enabled
2367 -- No need for `last_type.actual_type' as here `last_type' is equal to
2368 -- `context.current_class_type' since we start a feature call.
2369 check not_is_formal: not last_type.is_formal end
2370 l_last_id := last_type.associated_class.class_id
2371 check equivalent_ids: l_last_id = last_type.conformance_type.associated_class.class_id end
2372
2373 l_feature := current_feature
2374 -- Look for an argument
2375 if l_feature /= Void then
2376 if is_inherited then
2377 if l_as.is_argument then
2378 l_arg_pos := l_as.argument_position
2379 end
2380 else
2381 l_arg_pos := l_feature.argument_position (l_as.feature_name.name_id)
2382 end
2383 end
2384 if l_arg_pos /= 0 then
2385 -- Found argument
2386 l_type := l_feature.arguments.i_th (l_arg_pos)
2387 l_type := l_type.actual_type.instantiation_in (last_type, l_last_id)
2388 l_has_vuar_error := l_as.parameters /= Void
2389 if l_needs_byte_node then
2390 create l_argument
2391 l_argument.set_position (l_arg_pos)
2392 last_byte_node := l_argument
2393 end
2394 -- set some type attributes of the node
2395 if not is_inherited then
2396 l_as.enable_argument
2397 l_as.set_argument_position (l_arg_pos)
2398 l_as.set_class_id (class_id_of (l_type))
2399 end
2400 else
2401 -- Look for a local if not in a pre- or postcondition
2402 if not is_inherited or else l_as.is_local then
2403 l_local_info := context.locals.item (l_as.feature_name.name_id)
2404 end
2405 if l_local_info /= Void then
2406 -- Local found
2407 l_local_info.set_is_used (True)
2408 last_access_writable := True
2409 l_has_vuar_error := l_as.parameters /= Void
2410 l_type := l_local_info.type
2411 l_type := l_type.instantiation_in (last_type, l_last_id)
2412 if l_needs_byte_node then
2413 create l_local
2414 l_local.set_position (l_local_info.position)
2415 last_byte_node := l_local
2416 end
2417
2418 if is_checking_postcondition or else is_checking_precondition then
2419 -- Local in post- or precondition
2420 --|Note: this should not happen since
2421 --|in the context of assertions we would have
2422 --|ACCESS_ASSERT_AS and not ACCESS_ID_AS objects.
2423 --|(Fred)
2424 create l_veen2b
2425 context.init_error (l_veen2b)
2426 l_veen2b.set_identifier (l_as.feature_name.name)
2427 l_veen2b.set_location (l_as.feature_name)
2428 error_handler.insert_error (l_veen2b)
2429 end
2430 if not is_inherited then
2431 -- set some type attributes of the node
2432 l_as.enable_local
2433 l_as.set_class_id (class_id_of (l_type))
2434 end
2435 else
2436 -- Look for a feature
2437 l_feature := Void
2438 if is_inherited then
2439 check system.class_of_id (l_last_id) = last_type.associated_class end
2440 l_feature := system.class_of_id (l_last_id).feature_of_rout_id (l_as.routine_ids.first)
2441 end
2442 process_call (last_type, Void, l_as.feature_name, l_feature, l_as.parameters, False, False, False, False)
2443 l_type := last_type
2444 if not is_inherited then
2445 -- set some type attributes of the node
2446 l_as.set_class_id (l_last_id)
2447 l_as.set_routine_ids (last_routine_id_set)
2448 end
2449 end
2450 end
2451 if l_has_vuar_error then
2452 create l_vuar1
2453 if l_arg_pos /= 0 then
2454 l_vuar1.set_arg_name (l_as.feature_name.name)
2455 else
2456 l_vuar1.set_local_name (l_as.feature_name.name)
2457 end
2458 context.init_error (l_vuar1)
2459 l_vuar1.set_location (l_as.feature_name)
2460 error_handler.insert_error (l_vuar1)
2461 else
2462 last_type := l_type
2463 end
2464 error_handler.checksum
2465 end
2466
2467 process_access_assert_as (l_as: ACCESS_ASSERT_AS) is
2468 local
2469 l_arg_pos: INTEGER
2470 l_local_info: LOCAL_INFO
2471 l_argument: ARGUMENT_B
2472 l_arg_type: TYPE_A
2473 l_feature: FEATURE_I
2474 l_vuar1: VUAR1
2475 l_veen2b: VEEN2B
2476 l_last_id: INTEGER
2477 do
2478 -- No need for `last_type.actual_type' as here `last_type' is equal to
2479 -- `context.current_class_type' since we start a feature call.
2480 check not_is_formal: not last_type.is_formal end
2481 l_last_id := last_type.associated_class.class_id
2482 check equivalent_ids: l_last_id = last_type.associated_class.class_id end
2483
2484 l_feature := current_feature
2485 -- Look for an argument
2486 if is_inherited then
2487 l_arg_pos := l_as.argument_position
2488 else
2489 l_arg_pos := l_feature.argument_position (l_as.feature_name.name_id)
2490 end
2491 if l_arg_pos /= 0 then
2492 -- Found argument
2493 l_arg_type := l_feature.arguments.i_th (l_arg_pos)
2494
2495 last_type := l_arg_type.actual_type.instantiation_in (last_type, l_last_id)
2496 if l_as.parameters /= Void then
2497 create l_vuar1
2498 context.init_error (l_vuar1)
2499 l_vuar1.set_arg_name (l_as.feature_name.name)
2500 l_vuar1.set_location (l_as.feature_name)
2501 error_handler.insert_error (l_vuar1)
2502 end
2503 if is_byte_node_enabled then
2504 create l_argument
2505 l_argument.set_position (l_arg_pos)
2506 last_byte_node := l_argument
2507 end
2508 if not is_inherited then
2509 -- set some type attributes of the node
2510 l_as.enable_argument
2511 l_as.set_argument_position (l_arg_pos)
2512 l_as.set_class_id (class_id_of (last_type))
2513 end
2514 else
2515 -- Look for a local if in a pre- or postcondition
2516 if not is_inherited then
2517 l_local_info := context.locals.item (l_as.feature_name.name_id)
2518 end
2519 if l_local_info /= Void then
2520 -- Local found
2521 create l_veen2b
2522 context.init_error (l_veen2b)
2523 l_veen2b.set_identifier (l_as.feature_name.name)
2524 l_veen2b.set_location (l_as.feature_name)
2525 error_handler.insert_error (l_veen2b)
2526 else
2527 -- Look for a feature
2528 l_feature := Void
2529 if is_inherited then
2530 l_feature := system.class_of_id (l_last_id).feature_of_rout_id (l_as.routine_ids.first)
2531 end
2532 process_call (last_type, Void, l_as.feature_name, l_feature, l_as.parameters, False, False, False, False)
2533 if not is_inherited then
2534 -- set some type attributes of the node
2535 l_as.set_routine_ids (last_routine_id_set)
2536 l_as.set_class_id (l_last_id) -- last_type_of_call.associated_class.class_id -- seems to be wrong...
2537 end
2538 end
2539 end
2540 error_handler.checksum
2541 end
2542
2543 process_precursor_as (l_as: PRECURSOR_AS) is
2544 local
2545 l_vupr1: VUPR1
2546 l_vupr2: VUPR2
2547 l_vupr3: VUPR3
2548 l_pre_table: LINKED_LIST [PAIR[CL_TYPE_A, INTEGER]]
2549 l_feature_i: FEATURE_I
2550 l_parent_type: CL_TYPE_A
2551 l_parent_class: CLASS_C
2552 l_feat_ast: FEATURE_AS
2553 l_precursor_id: ID_AS
2554 l_instatiation_type: LIKE_CURRENT
2555 do
2556 if not is_inherited then
2557 if current_feature.is_invariant or else current_feature.is_inline_agent then
2558 create l_vupr1
2559 context.init_error (l_vupr1)
2560 error_handler.insert_error (l_vupr1)
2561 -- Cannot go on here.
2562 error_handler.raise_error
2563 else
2564 l_feat_ast := context.current_class.feature_with_name (current_feature.feature_name).ast
2565
2566 -- Check that feature has a unique name (vupr1)
2567 -- Check that we're in the body of a routine (l_vupr1).
2568 if
2569 l_feat_ast.feature_names.count > 1 or
2570 is_checking_precondition or is_checking_postcondition or is_checking_invariant
2571 then
2572 create l_vupr1
2573 context.init_error (l_vupr1)
2574 error_handler.insert_error (l_vupr1)
2575 -- Cannot go on here.
2576 error_handler.raise_error
2577 end
2578
2579 -- Create table of routine ids of all parents which have
2580 -- an effective precursor of the current feature.
2581 l_pre_table := precursor_table (l_as)
2582
2583 -- Check that current feature is a redefinition.
2584 if l_pre_table.count = 0 then
2585 if l_as.parent_base_class /= Void then
2586 -- The specified parent does not have
2587 -- an effective precursor.
2588 create l_vupr2
2589 context.init_error (l_vupr2)
2590 error_handler.insert_error (l_vupr2)
2591 -- Cannot go on here.
2592 error_handler.raise_error
2593 else
2594 -- No parent has an effective precursor
2595 -- (not a redefinition)
2596 create l_vupr3
2597 context.init_error (l_vupr3)
2598 error_handler.insert_error (l_vupr3)
2599 -- Cannot go on here.
2600 error_handler.raise_error
2601 end
2602 end
2603
2604 -- Check that an unqualified precursor construct
2605 -- is not ambiguous.
2606 if l_pre_table.count > 1 then
2607 -- Ambiguous construct
2608 create l_vupr3
2609 context.init_error (l_vupr3)
2610 error_handler.insert_error (l_vupr3)
2611 -- Cannot go on here.
2612 error_handler.raise_error
2613 end
2614
2615 -- Table has exactly one entry.
2616 l_pre_table.start
2617 l_parent_type := l_pre_table.item.first
2618 l_parent_class := l_parent_type.associated_class
2619 l_feature_i := l_parent_class.feature_table.feature_of_rout_id (l_pre_table.item.second)
2620 l_as.set_class_id (l_parent_class.class_id)
2621 l_as.set_routine_ids (l_feature_i.rout_id_set)
2622 end
2623 else
2624 l_parent_class := system.class_of_id (l_as.class_id)
2625 l_parent_type := l_parent_class.actual_type
2626 l_parent_type ?= l_parent_type.instantiation_in (
2627 context.current_class.actual_type, l_as.class_id)
2628 l_feature_i := l_parent_class.feature_of_rout_id (l_as.routine_ids.first)
2629 end
2630
2631 -- Update signature of parent `l_feature_i' in context of its instantiation
2632 -- in current class.
2633 l_feature_i := l_feature_i.duplicate
2634 -- Adapt `l_feature_i' to context of current class (e.g. if `l_parent_type' is
2635 -- generic then we need to resolve formals used in `l_feature_i' but the one from
2636 -- the instantiation `l_parent_type'.
2637 create l_instatiation_type
2638 l_instatiation_type.set_actual_type (l_parent_type)
2639 l_feature_i.instantiate (l_instatiation_type)
2640 -- Now that we have the fully instantiated type, we need to adapt it to
2641 -- the current class type (e.g. like Current).
2642 l_feature_i.instantiate (context.current_class_type)
2643
2644 create l_precursor_id.initialize_from_id (precursor_name_id)
2645 l_precursor_id.set_position (l_as.precursor_keyword.line, l_as.precursor_keyword.column,
2646 l_as.precursor_keyword.position, l_as.precursor_keyword.location_count)
2647 process_call (context.current_class_type, l_parent_type, l_precursor_id, l_feature_i,
2648 l_as.parameters, False, False, False, True)
2649 end
2650
2651 process_nested_expr_as (l_as: NESTED_EXPR_AS) is
2652 local
2653 l_target_type: TYPE_A
2654 l_target_expr: EXPR_B
2655 l_access_expr: ACCESS_EXPR_B
2656 l_call: CALL_B
2657 l_nested: NESTED_B
2658 l_is_qualified_call: BOOLEAN
2659 do
2660 -- Type check the target
2661 l_as.target.process (Current)
2662 l_target_type := last_type
2663 if is_byte_node_enabled then
2664 l_target_expr ?= last_byte_node
2665 create l_access_expr
2666 l_access_expr.set_expr (l_target_expr)
2667 end
2668
2669 -- Type check the message
2670 l_is_qualified_call := is_qualified_call
2671 is_qualified_call := True
2672 l_as.message.process (Current)
2673 is_qualified_call := l_is_qualified_call
2674 if is_byte_node_enabled then
2675 l_call ?= last_byte_node
2676 check
2677 l_call_not_void: l_call /= Void
2678 end
2679 create l_nested
2680 l_nested.set_target (l_access_expr)
2681 fixme ("Should we set `parent' on `l_access_expr' as we do for a NESTED_AS")
2682 l_nested.set_message (l_call)
2683 l_call.set_parent (l_nested)
2684 last_byte_node := l_nested
2685 end
2686 end
2687
2688 process_nested_as (l_as: NESTED_AS) is
2689 local
2690 l_target_access: ACCESS_B
2691 l_call: CALL_B
2692 l_nested: NESTED_B
2693 l_is_assigner_call: BOOLEAN
2694 l_is_qualified_call: BOOLEAN
2695 do
2696 -- Mask out assigner call flag for target of the call
2697 l_is_assigner_call := is_assigner_call
2698 is_assigner_call := False
2699 -- Type check the target
2700 l_as.target.process (Current)
2701 -- Restore assigner call flag for nested call
2702 is_assigner_call := l_is_assigner_call
2703 l_is_qualified_call := is_qualified_call
2704 is_qualified_call := True
2705 if not is_byte_node_enabled then
2706 -- Type check the message
2707 l_as.message.process (Current)
2708 else
2709 l_target_access ?= last_byte_node
2710
2711 -- Type check the message
2712 l_as.message.process (Current)
2713
2714 -- Create byte node.
2715 l_call ?= last_byte_node
2716 check
2717 l_call_not_void: l_call /= Void
2718 end
2719 create l_nested
2720 l_nested.set_target (l_target_access)
2721 l_nested.set_message (l_call)
2722
2723 l_target_access.set_parent (l_nested)
2724 l_call.set_parent (l_nested)
2725
2726 last_byte_node := l_nested
2727 end
2728 is_qualified_call := l_is_qualified_call
2729 end
2730
2731 process_routine_as (l_as: ROUTINE_AS) is
2732 local
2733 l_vxrc: VXRC
2734 l_byte_code: BYTE_CODE
2735 l_list: BYTE_LIST [BYTE_NODE]
2736 l_needs_byte_node: BOOLEAN
2737 do
2738 l_needs_byte_node := is_byte_node_enabled
2739
2740 -- Check local variables
2741 if l_as.locals /= Void then
2742 check_locals (l_as)
2743 end
2744 -- Check preconditions
2745 if l_as.precondition /= Void then
2746 -- Set Result access analysis level to `is_checking_precondition': locals
2747 -- and Result cannot be found in preconditions
2748 set_is_checking_precondition (True)
2749 l_as.precondition.process (Current)
2750 if l_needs_byte_node then
2751 l_list ?= last_byte_node
2752 end
2753 -- Reset the levels to default values
2754 set_is_checking_precondition (False)
2755 end
2756
2757 -- Check body
2758 l_as.routine_body.process (Current)
2759 if l_needs_byte_node then
2760 l_byte_code ?= last_byte_node
2761 context.init_byte_code (l_byte_code)
2762 l_byte_code.set_precondition (l_list)
2763 end
2764
2765 -- Check postconditions
2766 if l_as.postcondition /= Void then
2767 -- Set access id level analysis to `is_checking_postcondition': locals
2768 -- are not taken into account
2769 set_is_checking_postcondition (True)
2770 l_as.postcondition.process (Current)
2771 if l_needs_byte_node then
2772 l_list ?= last_byte_node
2773 l_byte_code.set_postcondition (l_list)
2774 end
2775 -- Reset the level
2776 set_is_checking_postcondition (False)
2777 end
2778
2779 -- Check rescue-clause
2780 if l_as.rescue_clause /= Void then
2781 -- A deferred or external feature cannot have a rescue
2782 -- clause
2783 if l_as.routine_body.is_deferred or else l_as.routine_body.is_external then
2784 create l_vxrc
2785 context.init_error (l_vxrc)
2786 l_vxrc.set_deferred (l_as.routine_body.is_deferred)
2787 l_vxrc.set_location (l_as.rescue_clause.start_location)
2788 error_handler.insert_error (l_vxrc)
2789 else
2790 -- Set mark of context
2791 is_in_rescue := True
2792 l_as.rescue_clause.process (Current)
2793 if l_needs_byte_node then
2794 l_list ?= last_byte_node
2795 l_byte_code.set_rescue_clause (l_list)
2796 end
2797 is_in_rescue := False
2798 end
2799 end
2800
2801 if l_as.locals /= Void and then context.current_class.is_warning_enabled (w_unused_local) then
2802 check_unused_locals (context.locals)
2803 end
2804
2805 if l_needs_byte_node then
2806 if old_expressions /= Void and then not old_expressions.is_empty then
2807 l_byte_code.set_old_expressions (old_expressions)
2808 end
2809 l_byte_code.set_end_location (l_as.end_location)
2810 l_byte_code.set_once_manifest_string_count (l_as.once_manifest_string_count)
2811 last_byte_node := l_byte_code
2812 end
2813 l_as.set_number_of_breakpoint_slots (break_point_slot_count)
2814 end
2815
2816 process_constant_as (l_as: CONSTANT_AS) is
2817 do
2818 -- Nothing to be done
2819 end
2820
2821 process_eiffel_list (l_as: EIFFEL_LIST [AST_EIFFEL]) is
2822 local
2823 l_cursor: INTEGER
2824 l_list: BYTE_LIST [BYTE_NODE]
2825 do
2826 l_cursor := l_as.index
2827 l_as.start
2828
2829 if is_byte_node_enabled then
2830 from
2831 create l_list.make (l_as.count)
2832 until
2833 l_as.after
2834 loop
2835 l_as.item.process (Current)
2836 l_list.extend (last_byte_node)
2837 l_as.forth
2838 end
2839 last_byte_node := l_list
2840 else
2841 from
2842 until
2843 l_as.after
2844 loop
2845 l_as.item.process (Current)
2846 l_as.forth
2847 end
2848 end
2849 l_as.go_i_th (l_cursor)
2850 end
2851
2852 process_indexing_clause_as (l_as: INDEXING_CLAUSE_AS) is
2853 do
2854 -- Nothing to be done
2855 end
2856
2857 process_operand_as (l_as: OPERAND_AS) is
2858 local
2859 l_class_type: TYPE_A
2860 do
2861 if l_as.target /= Void then
2862 l_as.target.process (Current)
2863 elseif l_as.expression /= Void then
2864 reset_for_unqualified_call_checking
2865 l_as.expression.process (Current)
2866 elseif l_as.class_type /= Void then
2867 l_as.class_type.process (Current)
2868 l_class_type := last_type
2869 instantiator.dispatch (l_class_type, context.current_class)
2870 if is_byte_node_enabled then
2871 create {OPERAND_B} last_byte_node
2872 end
2873 else
2874 create {OPEN_TYPE_A} last_type
2875 if is_byte_node_enabled then
2876 create {OPERAND_B} last_byte_node
2877 end
2878 end
2879 end
2880
2881 process_tagged_as (l_as: TAGGED_AS) is
2882 local
2883 l_vwbe3: VWBE3
2884 l_assert: ASSERT_B
2885 l_expr: EXPR_B
2886 do
2887 break_point_slot_count := break_point_slot_count + 1
2888
2889 reset_for_unqualified_call_checking
2890
2891 l_as.expr.process (Current)
2892
2893 -- Check if the type of the expression is boolean
2894 if not last_type.actual_type.is_boolean then
2895 create l_vwbe3
2896 context.init_error (l_vwbe3)
2897 l_vwbe3.set_type (last_type)
2898 l_vwbe3.set_location (l_as.expr.end_location)
2899 error_handler.insert_error (l_vwbe3)
2900 end
2901
2902 if is_byte_node_enabled then
2903 l_expr ?= last_byte_node
2904 check
2905 l_expr_not_void: l_expr /= Void
2906 end
2907 create l_assert
2908 if l_as.tag /= Void then
2909 l_assert.set_tag (l_as.tag.name)
2910 else
2911 l_assert.set_tag (Void)
2912 end
2913 l_assert.set_expr (l_expr)
2914 l_assert.set_line_number (l_as.expr.start_location.line)
2915 last_byte_node := l_assert
2916 end
2917 end
2918
2919 process_variant_as (l_as: VARIANT_AS) is
2920 local
2921 l_vave: VAVE
2922 l_assert: VARIANT_B
2923 l_expr: EXPR_B
2924 do
2925 reset_for_unqualified_call_checking
2926 l_as.expr.process (Current)
2927
2928 -- Check if the type of the expression is integer
2929 if not last_type.is_integer then
2930 create l_vave
2931 context.init_error (l_vave)
2932 l_vave.set_type (last_type)
2933 l_vave.set_location (l_as.expr.end_location)
2934 error_handler.insert_error (l_vave)
2935 end
2936
2937 if is_byte_node_enabled then
2938 l_expr ?= last_byte_node
2939 check
2940 l_expr_not_void: l_expr /= Void
2941 end
2942 create l_assert
2943 if l_as.tag /= Void then
2944 l_assert.set_tag (l_as.tag.name)
2945 else
2946 l_assert.set_tag (Void)
2947 end
2948 l_assert.set_expr (l_expr)
2949 l_assert.set_line_number (l_as.expr.start_location.line)
2950 last_byte_node := l_assert
2951 end
2952 end
2953
2954 process_un_strip_as (l_as: UN_STRIP_AS) is
2955 local
2956 l_id: INTEGER
2957 l_index: INTEGER
2958 l_feat_tbl: FEATURE_TABLE
2959 l_attribute_i: ATTRIBUTE_I
2960 l_depend_unit: DEPEND_UNIT
2961 l_vwst1: VWST1
2962 l_vwst2: VWST2
2963 l_strip: STRIP_B
2964 l_needs_byte_node: BOOLEAN
2965 do
2966 l_needs_byte_node := is_byte_node_enabled
2967 from
2968 if l_needs_byte_node then
2969 create l_strip.make
2970 end
2971 l_feat_tbl := context.current_class.feature_table
2972 l_as.id_list.start
2973 until
2974 l_as.id_list.after
2975 loop
2976 l_id := l_as.id_list.item
2977 l_index := l_as.id_list.index
2978 l_as.id_list.forth
2979 l_as.id_list.search (l_id)
2980 if not l_as.id_list.after then
2981 -- Id appears more than once in attribute list
2982 create l_vwst2
2983 context.init_error (l_vwst2)
2984 l_vwst2.set_attribute_name (Names_heap.item (l_id))
2985 l_vwst2.set_location (l_as.start_location)
2986 error_handler.insert_error (l_vwst2)
2987 else
2988 l_attribute_i ?= l_feat_tbl.item_id (l_id)
2989 if l_attribute_i = Void then
2990 create l_vwst1
2991 context.init_error (l_vwst1)
2992 l_vwst1.set_attribute_name (Names_heap.item (l_id))
2993 l_vwst1.set_location (l_as.start_location)
2994 error_handler.insert_error (l_vwst1)
2995 else
2996 create l_depend_unit.make (context.current_class.class_id,
2997 l_attribute_i)
2998 context.supplier_ids.extend (l_depend_unit)
2999 if l_needs_byte_node then
3000 l_strip.feature_ids.put (l_attribute_i.feature_id)
3001 end
3002 end
3003 end
3004 l_as.id_list.go_i_th (l_index)
3005 l_as.id_list.forth
3006 end
3007 last_type := strip_type
3008 if l_needs_byte_node then
3009 last_byte_node := l_strip
3010 end
3011 end
3012
3013 process_paran_as (l_as: PARAN_AS) is
3014 local
3015 l_expr: EXPR_B
3016 do
3017 l_as.expr.process (Current)
3018 if is_byte_node_enabled then
3019 l_expr ?= last_byte_node
3020 create {PARAN_B} last_byte_node.make (l_expr)
3021 end
3022 end
3023
3024 process_expr_call_as (l_as: EXPR_CALL_AS) is
3025 local
3026 l_vkcn3: VKCN3
3027 do
3028 reset_for_unqualified_call_checking
3029 l_as.call.process (Current)
3030 if last_type.is_void then
3031 create l_vkcn3
3032 context.init_error (l_vkcn3)
3033 l_vkcn3.set_location (l_as.call.end_location)
3034 error_handler.insert_error (l_vkcn3)
3035 error_handler.raise_error
3036 end
3037
3038 -- Nothing to be done for `last_byte_node' as it was computed in previous call
3039 -- `l_as.call.process'.
3040 end
3041
3042 process_expr_address_as (l_as: EXPR_ADDRESS_AS) is
3043 local
3044 l_expr: EXPR_B
3045 do
3046 l_as.expr.process (Current)
3047 last_type := pointer_type
3048 if is_byte_node_enabled then
3049 l_expr ?= last_byte_node
3050 create {EXPR_ADDRESS_B} last_byte_node.make (l_expr)
3051 end
3052 end
3053
3054 process_address_result_as (l_as: ADDRESS_RESULT_AS) is
3055 local
3056 l_vrle3: VRLE3
3057 l_veen2a: VEEN2A
3058 l_type: TYPE_A
3059 do
3060 if
3061 is_checking_invariant or else not current_feature.has_return_value
3062 then
3063 -- It means that we are in a location where `Result' is not
3064 -- acceptable (e.g. an invariant, or within the body of a procedure).
3065 create l_vrle3
3066 context.init_error (l_vrle3)
3067 l_vrle3.set_location (l_as.start_location)
3068 error_handler.insert_error (l_vrle3)
3069 -- Cannot go on here
3070 error_handler.raise_error
3071 elseif is_checking_precondition then
3072 -- Result entity in precondition
3073 create l_veen2a
3074 context.init_error (l_veen2a)
3075 l_veen2a.set_location (l_as.start_location)
3076 error_handler.insert_error (l_veen2a)
3077 end
3078 l_type := current_feature.type
3079 create {TYPED_POINTER_A} last_type.make_typed (l_type)
3080 if is_byte_node_enabled then
3081 create {HECTOR_B} last_byte_node.make (create {RESULT_B})
3082 end
3083 end
3084
3085 process_address_current_as (l_as: ADDRESS_CURRENT_AS) is
3086 local
3087 l_like_current: LIKE_CURRENT
3088 do
3089 l_like_current := context.current_class_type
3090 create {TYPED_POINTER_A} last_type.make_typed (l_like_current)
3091 if is_byte_node_enabled then
3092 create {HECTOR_B} last_byte_node.make (create {CURRENT_B})
3093 end
3094 end
3095
3096 process_address_as (l_as: ADDRESS_AS) is
3097 local
3098 l_access: ACCESS_B
3099 l_argument: ARGUMENT_B
3100 l_local: LOCAL_B
3101 l_local_info: LOCAL_INFO
3102 l_unsupported: NOT_SUPPORTED
3103 l_feature: FEATURE_I
3104 l_vzaa1: VZAA1
3105 l_veen: VEEN
3106 l_veen2b: VEEN2B
3107 l_arg_pos: INTEGER
3108 l_last_id: INTEGER
3109 l_type: TYPE_A
3110 l_depend_unit: DEPEND_UNIT
3111 l_needs_byte_node: BOOLEAN
3112 do
3113 l_needs_byte_node := is_byte_node_enabled
3114
3115 -- Initialization of the type stack
3116 reset_for_unqualified_call_checking
3117
3118 l_last_id := context.current_class.class_id
3119 if not is_inherited then
3120 l_as.set_class_id (l_last_id)
3121 end
3122
3123 l_feature := current_feature
3124 -- Look for an argument
3125 if l_feature /= Void then
3126 if is_inherited then
3127 if l_as.is_argument then
3128 l_arg_pos := l_as.argument_position
3129 end
3130 else
3131 l_arg_pos := l_feature.argument_position (l_as.feature_name.internal_name.name_id)
3132 end
3133 end
3134 if l_arg_pos /= 0 then
3135 -- Found argument
3136 l_type := l_feature.arguments.i_th (l_arg_pos)
3137 l_type := l_type.actual_type.instantiation_in (last_type, l_last_id)
3138 create {TYPED_POINTER_A} last_type.make_typed (l_type)
3139 if l_needs_byte_node then
3140 create l_argument
3141 l_argument.set_position (l_arg_pos)
3142 create {HECTOR_B} last_byte_node.make_with_type (l_argument, last_type.type_i)
3143 end
3144 if not is_inherited then
3145 l_as.enable_argument
3146 l_as.set_argument_position (l_arg_pos)
3147 end
3148 else
3149 -- Look for a local if not in a pre- or postcondition
3150 if not is_inherited or else l_as.is_local then
3151 l_local_info := context.locals.item (l_as.feature_name.internal_name.name_id)
3152 end
3153 if l_local_info /= Void then
3154 -- Local found
3155 l_local_info.set_is_used (True)
3156 l_type := l_local_info.type
3157 l_type := l_type.instantiation_in (last_type, l_last_id)
3158 create {TYPED_POINTER_A} last_type.make_typed (l_type)
3159 if l_needs_byte_node then
3160 create l_local
3161 l_local.set_position (l_local_info.position)
3162 create {HECTOR_B} last_byte_node.make_with_type (l_local, last_type.type_i)
3163 end
3164
3165 if is_checking_postcondition or else is_checking_precondition then
3166 -- Local in post- or precondition
3167 --|Note: this should not happen since
3168 --|in the context of assertions we would have
3169 --|ACCESS_ASSERT_AS and not ACCESS_ID_AS objects.
3170 --|(Fred)
3171 create l_veen2b
3172 context.init_error (l_veen2b)
3173 l_veen2b.set_identifier (l_as.feature_name.internal_name.name)
3174 l_veen2b.set_location (l_as.feature_name.start_location)
3175 error_handler.insert_error (l_veen2b)
3176 end
3177
3178 if not is_inherited then
3179 l_as.enable_local
3180 end
3181 else
3182 if is_inherited then
3183 l_feature := context.current_class.feature_of_rout_id (l_as.routine_ids.first)
3184 else
3185 l_feature := context.current_class.feature_table.item_id (l_as.feature_name.internal_name.name_id)
3186 end
3187 if l_feature = Void then
3188 create l_veen
3189 context.init_error (l_veen)
3190 l_veen.set_identifier (l_as.feature_name.internal_name.name)
3191 l_veen.set_location (l_as.feature_name.start_location)
3192 error_handler.insert_error (l_veen)
3193 else
3194 if l_feature.is_constant then
3195 create l_vzaa1
3196 context.init_error (l_vzaa1)
3197 l_vzaa1.set_address_name (l_as.feature_name.internal_name.name)
3198 l_vzaa1.set_location (l_as.feature_name.start_location)
3199 error_handler.insert_error (l_vzaa1)
3200 elseif l_feature.is_external then
3201 create l_unsupported
3202 context.init_error (l_unsupported)
3203 l_unsupported.set_message ("The $ operator is not supported on externals.")
3204 l_unsupported.set_location (l_as.feature_name.start_location)
3205 error_handler.insert_error (l_unsupported)
3206 elseif l_feature.is_attribute then
3207 l_type := l_feature.type.actual_type
3208 create {TYPED_POINTER_A} last_type.make_typed (l_type)
3209 else
3210 last_type := Pointer_type
3211 end
3212
3213 -- Dependance
3214 create l_depend_unit.make_with_level (l_last_id, l_feature, depend_unit_level)
3215 context.supplier_ids.extend (l_depend_unit)
3216
3217 if l_needs_byte_node then
3218 if l_feature.is_attribute then
3219 l_access := l_feature.access (l_type.type_i, False)
3220 create {HECTOR_B} last_byte_node.make_with_type (l_access, last_type.type_i)
3221 else
3222 create {ADDRESS_B} last_byte_node.make (context.current_class.class_id, l_feature)
3223 end
3224 end
3225 if not is_inherited then
3226 l_as.set_routine_ids (l_feature.rout_id_set)
3227 end
3228 end
3229 end
3230 end
3231 instantiator.dispatch (last_type, context.current_class)
3232 error_handler.checksum
3233 end
3234
3235 process_type_expr_as (l_as: TYPE_EXPR_AS) is
3236 local
3237 l_type: TYPE_A
3238 l_type_type: GEN_TYPE_A
3239 do
3240 l_as.type.process (Current)
3241 l_type := last_type
3242
3243 create l_type_type.make (system.type_class.compiled_class.class_id, << l_type >>)
3244 instantiator.dispatch (l_type_type, context.current_class)
3245 last_type := l_type_type
3246 if is_byte_node_enabled then
3247 create {TYPE_EXPR_B} last_byte_node.make (l_type_type.type_i)
3248 end
3249 end
3250
3251 process_routine_creation_as_ext (l_as: ROUTINE_CREATION_AS; a_feature: FEATURE_I) is
3252 local
3253 l_class: CLASS_C
3254 l_feature: FEATURE_I
3255 l_table: FEATURE_TABLE
3256 l_unsupported: NOT_SUPPORTED
3257 l_target_type: TYPE_A
3258 l_target_node: BYTE_NODE
3259 l_needs_byte_node: BOOLEAN
3260 l_feature_name: ID_AS
3261 l_access: ACCESS_B
3262 l_open: OPEN_TYPE_A
3263 l_named_tuple: NAMED_TUPLE_TYPE_A
3264 l_label_pos: INTEGER
3265 l_is_named_tuple: BOOLEAN
3266 do
3267 l_needs_byte_node := is_byte_node_enabled
3268
3269 -- Type check the target
3270 reset_for_unqualified_call_checking
3271
3272 if l_as.target = Void then
3273 -- Target is the closed operand `Current'.
3274 l_target_type := context.current_class_type
3275 if l_needs_byte_node then
3276 create {CURRENT_B} l_target_node
3277 end
3278 else
3279 l_as.target.process (Current)
3280 l_target_type := last_type
3281 l_open ?= l_target_type
3282 if l_open /= Void then
3283 -- Target is the open operand, but we artificially make its type
3284 -- to be the current type.
3285 l_target_type := context.current_class_type
3286 end
3287 if l_needs_byte_node then
3288 l_target_node := last_byte_node
3289 end
3290 end
3291
3292 l_feature_name := l_as.feature_name
3293
3294 if l_target_type.conformance_type.is_formal or l_target_type.conformance_type.is_basic then
3295 -- Not supported. May change in the future - M.S.
3296 -- Reason: We cannot call a feature with basic call target!
3297 create l_unsupported
3298 context.init_error (l_unsupported)
3299 l_unsupported.set_message ("Type of target in a agent call may not be a basic type or a formal.")
3300 if l_as.target /= Void then
3301 l_unsupported.set_location (l_as.target.start_location)
3302 else
3303 l_unsupported.set_location (l_feature_name)
3304 end
3305 error_handler.insert_error (l_unsupported)
3306 error_handler.raise_error
3307 end
3308
3309 if l_target_type.has_associated_class then
3310 l_class := l_target_type.associated_class
3311 l_table := l_class.feature_table
3312
3313 if is_inherited then
3314 if a_feature = Void then
3315 l_feature := l_class.feature_of_rout_id (l_as.routine_ids.first)
3316 else
3317 l_feature := a_feature
3318 end
3319 else
3320 if a_feature = Void then
3321 -- Note that the following can yield `Void' in case it is not a valid feature name or
3322 -- if it is a named tuple access. That's ok, since it is going to be properly
3323 -- handled by `process_call'.
3324 l_feature := l_table.item_id (l_feature_name.name_id)
3325 else
3326 l_feature := a_feature
3327 end
3328 end
3329 else
3330 l_feature := a_feature
3331 end
3332
3333 -- Type check the call
3334 process_call (l_target_type, Void, l_feature_name, l_feature, l_as.operands, False, True, l_as.has_target, False)
3335
3336 if l_feature = Void then
3337 l_named_tuple ?= l_target_type
3338 if l_named_tuple /= Void then
3339 l_label_pos := l_named_tuple.label_position (l_feature_name.name)
3340 if l_label_pos > 0 then
3341 l_is_named_tuple := True
3342 end
3343 end
3344 end
3345
3346 if l_feature = Void and then not l_is_named_tuple then
3347 create l_unsupported
3348 context.init_error (l_unsupported)
3349 l_unsupported.set_message ("Agent creation on `" + l_feature_name.name + "' is%
3350 % not supported because it is either an attribute, a constant or%
3351 % an external feature")
3352 l_unsupported.set_location (l_feature_name)
3353 error_handler.insert_error (l_unsupported)
3354 else
3355 if not is_inherited then
3356 l_as.set_class_id (l_class.class_id)
3357 if l_feature /= Void then
3358 l_as.set_routine_ids (l_feature.rout_id_set)
3359 end
3360 end
3361 l_access ?= last_byte_node
3362 if l_is_named_tuple or else l_feature.is_attribute or else l_feature.is_constant then
3363 is_byte_node_enabled := False
3364
3365 compute_routine (l_table, l_feature, True, False, l_class.class_id, l_target_type, last_type,
3366 l_as, l_access, l_target_node)
3367
3368 if l_needs_byte_node then
3369 is_byte_node_enabled := True
3370 if l_is_named_tuple then
3371 compute_named_tuple_fake_inline_agent (
3372 l_as, l_named_tuple, l_label_pos, l_target_node, l_target_type, last_type)
3373 else
3374 compute_feature_fake_inline_agent (
3375 l_as, l_feature, l_target_node, l_target_type, last_type)
3376 end
3377 end
3378 else
3379 compute_routine (l_table, l_feature, not l_feature.type.is_void,l_feature.has_arguments,
3380 l_class.class_id, l_target_type, last_type, l_as, l_access, l_target_node)
3381 end
3382 System.instantiator.dispatch (last_type, context.current_class)
3383 end
3384 error_handler.checksum
3385 end
3386
3387 process_routine_creation_as (l_as: ROUTINE_CREATION_AS) is
3388 do
3389 process_routine_creation_as_ext (l_as, Void)
3390 end
3391
3392 process_unary_as (l_as: UNARY_AS) is
3393 require
3394 l_as_not_void: l_as /= Void
3395 local
3396 l_prefix_feature: FEATURE_I
3397 l_prefix_feature_type, l_last_constrained: TYPE_A
3398 l_last_class: CLASS_C
3399 l_depend_unit: DEPEND_UNIT
3400 l_vwoe: VWOE
3401 l_vuex: VUEX
3402 l_vape: VAPE
3403 l_manifest: MANIFEST_INTEGER_A
3404 l_value: ATOMIC_AS
3405 l_needs_byte_node: BOOLEAN
3406 l_expr: EXPR_B
3407 l_access: ACCESS_B
3408 l_unary: UNARY_B
3409 l_is_assigner_call: BOOLEAN
3410 l_formal: FORMAL_A
3411 l_is_multi_constrained: BOOLEAN
3412 l_type_set: TYPE_SET_A
3413 l_result_tuple: TUPLE[feature_item: FEATURE_I; class_type_of_feature: CL_TYPE_A; features_found_count: INTEGER]
3414 l_context_current_class: CLASS_C
3415 do
3416 l_needs_byte_node := is_byte_node_enabled
3417
3418 -- Reset assigner call flag
3419 l_is_assigner_call := is_assigner_call
3420 is_assigner_call := False
3421 l_context_current_class := context.current_class
3422 -- Check operand
3423 l_as.expr.process (Current)
3424
3425 if l_needs_byte_node then
3426 l_expr ?= last_byte_node
3427 end
3428 last_type := last_type.actual_type
3429 l_formal ?= last_type
3430 if l_formal /= Void then
3431 if not l_formal.is_single_constraint_without_renaming (l_context_current_class) then
3432 l_is_multi_constrained := True
3433 else
3434 l_last_constrained := l_formal.constrained_type (context.current_class)
3435 end
3436 else
3437 l_last_constrained := last_type
3438 end
3439
3440 if l_is_multi_constrained then
3441 l_type_set := last_type.actual_type.to_type_set.constraining_types (l_context_current_class)
3442 l_result_tuple := l_type_set.feature_i_state_by_alias_name (l_as.prefix_feature_name)
3443 if l_result_tuple.features_found_count > 1 then
3444 raise_vtmc_error (create {ID_AS}.initialize (l_as.prefix_feature_name), l_formal.position, l_context_current_class)
3445 elseif l_result_tuple.features_found_count = 1 then
3446 l_last_class := l_result_tuple.class_type_of_feature.associated_class
3447 l_last_constrained := l_last_class.actual_type
3448 last_calls_target_type := l_last_constrained
3449 l_prefix_feature := l_result_tuple.feature_item
3450 end
3451 else
3452 check l_last_constrained /= Void end
3453 if l_last_constrained.is_none then
3454 -- If we have a formal constrained to NONE it should already be checked earlier.
3455 create l_vuex.make_for_none (l_as.prefix_feature_name)
3456 context.init_error (l_vuex)
3457 l_vuex.set_location (l_as.expr.end_location)
3458 error_handler.insert_error (l_vuex)
3459 -- Cannot go on here
3460 error_handler.raise_error
3461 end
3462
3463 l_last_class := l_last_constrained.associated_class
3464 l_prefix_feature := l_last_class.feature_table.alias_item (l_as.prefix_feature_name)
3465 end
3466
3467 if l_prefix_feature = Void then
3468 -- Error: not prefixed function found
3469 create l_vwoe
3470 context.init_error (l_vwoe)
3471 l_vwoe.set_other_class (l_last_class)
3472 l_vwoe.set_op_name (l_as.prefix_feature_name)
3473 l_vwoe.set_location (l_as.operator_location)
3474 error_handler.insert_error (l_vwoe)
3475 -- Cannot go on here.
3476 error_handler.raise_error
3477 end
3478 if not is_inherited then
3479 l_as.set_class_id (l_last_class.class_id)
3480 l_as.set_routine_ids (l_prefix_feature.rout_id_set)
3481 end
3482
3483 -- Export validity
3484 if
3485 not (context.is_ignoring_export or l_prefix_feature.is_exported_for (l_last_class))
3486 then
3487 create l_vuex
3488 context.init_error (l_vuex)
3489 l_vuex.set_static_class (l_last_class)
3490 l_vuex.set_exported_feature (l_prefix_feature)
3491 l_vuex.set_location (l_as.operator_location)
3492 error_handler.insert_error (l_vuex)
3493 error_handler.raise_error
3494 end
3495
3496 if
3497 not System.do_not_check_vape and then is_checking_precondition and then
3498 not current_feature.export_status.is_subset (l_prefix_feature.export_status)
3499 then
3500 -- In precondition and checking for vape
3501 create l_vape
3502 context.init_error (l_vape)
3503 l_vape.set_exported_feature (current_feature)
3504 l_vape.set_location (l_as.operator_location)
3505 error_handler.insert_error (l_vape)
3506 error_handler.raise_error
3507 end
3508
3509 -- Suppliers update
3510 create l_depend_unit.make_with_level (l_last_class.class_id, l_prefix_feature, depend_unit_level)
3511 context.supplier_ids.extend (l_depend_unit)
3512
3513 -- Assumes here that a prefix feature has no argument
3514 -- Update the type stack; instantiate the result of the
3515 -- refixed feature
3516 l_prefix_feature_type := l_prefix_feature.type
3517 if l_last_constrained.is_bits and then l_prefix_feature_type.is_like_current then
3518 -- For feature prefix "not" of symbolic class BIT_REF.
3519 l_prefix_feature_type := l_last_constrained
3520 else
3521 if l_as.is_minus then
3522 -- Let's say if it is a special case the negation of a positive
3523 -- value in which case we maintain the type of the expression.
3524 -- E.g. -127 is of type INTEGER_8, not of type INTEGER
3525 -- -128 is of type INTEGER_16, since 128 is an INTEGER_16
3526 -- -511 is of type INTEGER_16, not of type INTEGER
3527 --
3528 -- FIXME: Manu 02/06/2004: we do not attempt here to ensure
3529 -- that `-128' is of type INTEGER_8. We will have to wait for ETL3
3530 -- to tell us what we need to do. The current behavior preserve
3531 -- compatibility with older version of Eiffel (5.4 and earlier).
3532 l_manifest ?= l_last_constrained
3533 l_value ?= l_as.expr
3534 if l_value /= Void and l_manifest /= Void then
3535 l_prefix_feature_type := l_last_constrained
3536 else
3537 -- Usual case
3538 l_prefix_feature_type := l_prefix_feature_type.instantiation_in
3539 (last_type, l_last_class.class_id).actual_type
3540 end
3541 else
3542 -- Usual case
3543 l_prefix_feature_type := l_prefix_feature_type.instantiation_in
3544 (last_type, l_last_class.class_id).actual_type
3545 end
3546 end
3547 if l_is_assigner_call then
3548 process_assigner_command (l_last_class.class_id, l_prefix_feature)
3549 end
3550
3551 if l_needs_byte_node then
3552 l_access := l_prefix_feature.access (l_prefix_feature_type.type_i, True)
3553 -- If we have something like `a.f' where `a' is predefined
3554 -- and `f' is a constant then we simply generate a byte
3555 -- node that will be the constant only. Otherwise if `a' is
3556 -- not predefined and `f' is a constant, we generate the
3557 -- complete evaluation `a.f'. However during generation,
3558 -- we will do an optimization by hardwiring value of constant.
3559 if l_is_multi_constrained then
3560 l_access.set_multi_constraint_static (last_calls_target_type.type_i)
3561 end
3562 if not (l_access.is_constant and l_expr.is_predefined) then
3563 l_unary := byte_anchor.unary_node (l_as)
3564 l_unary.set_expr (l_expr)
3565 l_unary.init (l_access)
3566 last_byte_node := l_unary
3567 else
3568 last_byte_node := l_access
3569 end
3570 end
3571
3572 last_type := l_prefix_feature_type
3573 end
3574
3575 process_un_free_as (l_as: UN_FREE_AS) is
3576 do
3577 process_unary_as (l_as)
3578 end
3579
3580 process_un_minus_as (l_as: UN_MINUS_AS) is
3581 do
3582 process_unary_as (l_as)
3583 end
3584
3585 process_un_not_as (l_as: UN_NOT_AS) is
3586 do
3587 process_unary_as (l_as)
3588 end
3589
3590 process_un_old_as (l_as: UN_OLD_AS) is
3591 local
3592 l_vaol1: VAOL1
3593 l_vaol2: VAOL2
3594 l_saved_vaol_check: BOOLEAN
3595 l_expr: EXPR_B
3596 l_un_old: UN_OLD_B
3597 do
3598 if not is_checking_postcondition then
3599 -- Old expression found somewhere else that in a
3600 -- postcondition
3601 create l_vaol1
3602 context.init_error (l_vaol1)
3603 l_vaol1.set_location (l_as.expr.start_location)
3604 error_handler.insert_error (l_vaol1)
3605 error_handler.raise_error
3606 end
3607
3608 l_saved_vaol_check := check_for_vaol
3609 if not l_saved_vaol_check then
3610 -- Set flag for vaol check.
3611 -- Check for an old expression within
3612 -- an old expression.
3613 check_for_vaol := True
3614 end
3615 -- Expression type check
3616 l_as.expr.process (Current)
3617 if not l_saved_vaol_check then
3618 -- Reset flag for vaol check
3619 check_for_vaol := False
3620 end
3621
3622 if last_type.conform_to (Void_type) or else check_for_vaol then
3623 -- Not an expression
3624 create l_vaol2
3625 context.init_error (l_vaol2)
3626 l_vaol2.set_location (l_as.expr.end_location)
3627 error_handler.insert_error (l_vaol2)
3628 elseif is_byte_node_enabled then
3629 l_expr ?= last_byte_node
3630 create l_un_old
3631 l_un_old.set_expr (l_expr)
3632 if old_expressions = Void then
3633 create old_expressions.make
3634 end
3635 old_expressions.put_front (l_un_old)
3636 last_byte_node := l_un_old
3637 end
3638 if not is_inherited then
3639 l_as.set_class_id (class_id_of (last_type.actual_type))
3640 end
3641
3642 if not l_saved_vaol_check then
3643 -- Reset flag for vaol check
3644 check_for_vaol := False
3645 end
3646 end
3647
3648 process_un_plus_as (l_as: UN_PLUS_AS) is
3649 do
3650 process_unary_as (l_as)
3651 end
3652
3653 process_binary_as (l_as: BINARY_AS) is
3654 require
3655 l_as_not_void: l_as /= Void
3656 local
3657 l_infix_type: TYPE_A
3658 l_left_type, l_right_type: TYPE_A
3659 l_right_constrained, l_left_constrained: TYPE_A
3660 l_target_type: TYPE_A
3661 l_formal: FORMAL_A
3662 l_left_id: INTEGER
3663 l_depend_unit: DEPEND_UNIT
3664 l_vuex: VUEX
3665 l_error: ERROR
3666 l_target_conv_info: CONVERSION_INFO
3667 l_left_expr, l_right_expr: EXPR_B
3668 l_needs_byte_node: BOOLEAN
3669 l_binary: BINARY_B
3670 l_call_access: CALL_ACCESS_B
3671 l_is_assigner_call: BOOLEAN
3672 l_is_left_multi_constrained, l_is_right_multi_constrained: BOOLEAN
3673 l_class: CLASS_C
3674 l_context_current_class: CLASS_C
3675 do
3676 l_needs_byte_node := is_byte_node_enabled
3677 l_context_current_class := context.current_class
3678
3679 -- Reset assigner call
3680 l_is_assigner_call := is_assigner_call
3681 is_assigner_call := False
3682
3683 -- First type check the left operand
3684 l_as.left.process (Current)
3685 l_left_type := last_type.actual_type
3686 if l_left_type.is_formal then
3687 l_formal ?= l_left_type
3688 if l_formal.is_multi_constrained (l_context_current_class) then
3689 l_is_left_multi_constrained := True
3690 else
3691 l_left_constrained := l_formal.constrained_type (l_context_current_class)
3692 end
3693 else
3694 l_left_constrained := l_left_type
3695 end
3696
3697 if l_needs_byte_node then
3698 l_left_expr ?= last_byte_node
3699 end
3700
3701 if not l_is_left_multi_constrained then
3702 check l_left_constrained_attached: l_left_constrained /= Void end
3703 -- Check if target is not of type NONE
3704 if l_left_constrained.is_none then
3705 create l_vuex.make_for_none (l_as.infix_function_name)
3706 context.init_error (l_vuex)
3707 l_vuex.set_location (l_as.operator_location)
3708 error_handler.insert_error (l_vuex)
3709 error_handler.raise_error
3710 end
3711 end
3712
3713 -- Then type check the right operand
3714 l_as.right.process (Current)
3715 l_right_type := last_type.actual_type
3716 if l_right_type.is_formal then
3717 l_formal ?= l_right_type
3718 if l_formal.is_multi_constrained (l_context_current_class) then
3719 l_is_right_multi_constrained := True
3720 else
3721 l_right_constrained := l_formal.constrained_type (l_context_current_class)
3722 end
3723 else
3724 l_right_constrained := l_right_type
3725 end
3726
3727 if l_needs_byte_node then
3728 l_right_expr ?= last_byte_node
3729 end
3730
3731 -- Conformance: take care of constrained genericity and
3732 -- of the balancing rule for the simple numeric types
3733 if is_inherited then
3734 l_class := system.class_of_id (l_as.class_id)
3735 last_infix_feature := l_class.feature_of_rout_id (l_as.routine_ids.first)
3736 l_left_constrained := l_class.actual_type
3737 else
3738 if is_infix_valid (l_left_type, l_right_type, l_as.infix_function_name) then
3739 check last_calls_target_type /= Void end
3740 if l_left_constrained = Void then
3741 l_left_constrained := last_calls_target_type
3742 end
3743
3744 else
3745 l_error := last_infix_error
3746 if l_left_type.convert_to (context.current_class, l_right_type) then
3747 l_target_conv_info := context.last_conversion_info
3748 if is_infix_valid (l_right_type, l_right_type, l_as.infix_function_name) then
3749 l_right_constrained := last_calls_target_type
3750 l_left_constrained := l_right_constrained
3751 l_as.set_left_type_converted (True)
3752 else
3753 l_target_conv_info := Void
3754 end
3755 end
3756 end
3757 end
3758
3759 if last_infix_feature = Void then
3760 -- Raise error here
3761 l_error.set_location (l_as.operator_location)
3762 error_handler.insert_error (l_error)
3763 error_handler.raise_error
3764 else
3765 -- Process conversion if any.
3766 if l_target_conv_info /= Void then
3767 check
3768 no_conversion_if_right_type_is_formal: not l_right_type.is_formal
3769 therefore_l_right_constrained_not_void: l_right_constrained /= Void
3770 end
3771 l_left_id := l_right_constrained.associated_class.class_id
3772 if l_target_conv_info.has_depend_unit then
3773 context.supplier_ids.extend (l_target_conv_info.depend_unit)
3774 end
3775 l_target_type := l_target_conv_info.target_type
3776 if l_needs_byte_node then
3777 l_left_expr := l_target_conv_info.byte_node (l_left_expr)
3778 end
3779 else
3780 l_left_id := l_left_constrained.associated_class.class_id
3781 l_target_type := l_left_type
3782 end
3783
3784 if not is_inherited then
3785 -- Set type informations
3786 l_as.set_routine_ids (last_infix_feature.rout_id_set)
3787 l_as.set_class_id (l_left_id)
3788 end
3789
3790 if last_infix_argument_conversion_info /= Void then
3791 if last_infix_argument_conversion_info.has_depend_unit then
3792 context.supplier_ids.extend (last_infix_argument_conversion_info.depend_unit)
3793 end
3794 if l_needs_byte_node then
3795 l_right_expr ?= last_infix_argument_conversion_info.byte_node (l_right_expr)
3796 end
3797 end
3798
3799 -- Suppliers update
3800 create l_depend_unit.make_with_level (l_left_id, last_infix_feature, depend_unit_level)
3801 context.supplier_ids.extend (l_depend_unit)
3802
3803 -- Update the type stack: instantiate result type of the
3804 -- infixed feature
3805 l_infix_type := last_infix_feature.type
3806 if
3807 l_target_type.is_bits and then l_right_constrained.is_bits and then
3808 l_infix_type.is_like_current
3809 then
3810 -- For non-balanced features of symbolic class BIT_REF
3811 -- like infix "^" or infix "#"
3812 l_infix_type := l_target_type
3813 else
3814 -- Usual case
3815 l_infix_type := adapted_type (l_infix_type, l_left_type.actual_type, l_left_constrained)
3816 l_infix_type := l_infix_type.instantiation_in (l_target_type, l_left_id).actual_type
3817 end
3818
3819 if l_is_assigner_call then
3820 process_assigner_command (l_left_id, last_infix_feature)
3821 end
3822
3823 if l_needs_byte_node then
3824 l_binary := byte_anchor.binary_node (l_as)
3825 l_binary.set_left (l_left_expr)
3826 l_binary.set_right (l_right_expr)
3827
3828 l_call_access ?= last_infix_feature.access (l_infix_type.type_i, True)
3829 -- If we have a multi constrained formal we need to set the selected constrained type on which the call is done.
3830 if l_is_left_multi_constrained then
3831 l_call_access.set_multi_constraint_static (l_left_constrained.conformance_type.type_i)
3832 end
3833 l_binary.init (l_call_access)
3834 -- Add type to `parameters' in case we will need it later.
3835 l_binary.set_attachment (last_infix_arg_type.type_i)
3836 last_byte_node := l_binary
3837 end
3838 last_type := l_infix_type
3839 end
3840 last_infix_error := Void
3841 last_infix_feature := Void
3842 last_infix_arg_type := Void
3843 last_infix_argument_conversion_info := Void
3844 end
3845
3846 process_bin_and_then_as (l_as: BIN_AND_THEN_AS) is
3847 do
3848 process_binary_as (l_as)
3849 end
3850
3851 process_bin_free_as (l_as: BIN_FREE_AS) is
3852 do
3853 process_binary_as (l_as)
3854 end
3855
3856 process_bin_implies_as (l_as: BIN_IMPLIES_AS) is
3857 local
3858 l_implies: B_IMPLIES_B
3859 l_bool_val: VALUE_I
3860 l_old_expr: like old_expressions
3861 do
3862 l_old_expr := old_expressions
3863 old_expressions := Void
3864 process_binary_as (l_as)
3865 if is_byte_node_enabled then
3866 -- Special optimization, if the left-hand side is False, then
3867 -- expression is evaluated to True and we discard any new UN_OLD_AS
3868 -- expressions as they are not needed.
3869 l_implies ?= last_byte_node
3870 check
3871 l_implies_not_void: l_implies /= Void
3872 end
3873 l_bool_val := l_implies.left.evaluate
3874 if l_bool_val.is_boolean and then not l_bool_val.boolean_value then
3875 -- Expression can be simplified into a Boolean constant
3876 create {BOOL_CONST_B} last_byte_node.make (True)
3877 old_expressions := l_old_expr
3878 else
3879 -- Add any new UN_OLD_AS expression we found during type checking.
3880 if old_expressions = Void then
3881 old_expressions := l_old_expr
3882 elseif l_old_expr /= Void and old_expressions /= Void then
3883 old_expressions.append (l_old_expr)
3884 end
3885 end
3886 end
3887 end
3888
3889 process_bin_or_as (l_as: BIN_OR_AS) is
3890 do
3891 process_binary_as (l_as)
3892 end
3893
3894 process_bin_or_else_as (l_as: BIN_OR_ELSE_AS) is
3895 do
3896 process_binary_as (l_as)
3897 end
3898
3899 process_bin_xor_as (l_as: BIN_XOR_AS) is
3900 do
3901 process_binary_as (l_as)
3902 end
3903
3904 process_bin_ge_as (l_as: BIN_GE_AS) is
3905 do
3906 process_binary_as (l_as)
3907 end
3908
3909 process_bin_gt_as (l_as: BIN_GT_AS) is
3910 do
3911 process_binary_as (l_as)
3912 end
3913
3914 process_bin_le_as (l_as: BIN_LE_AS) is
3915 do
3916 process_binary_as (l_as)
3917 end
3918
3919 process_bin_lt_as (l_as: BIN_LT_AS) is
3920 do
3921 process_binary_as (l_as)
3922 end
3923
3924 process_bin_div_as (l_as: BIN_DIV_AS) is
3925 do
3926 process_binary_as (l_as)
3927 end
3928
3929 process_bin_minus_as (l_as: BIN_MINUS_AS) is
3930 do
3931 process_binary_as (l_as)
3932 end
3933
3934 process_bin_mod_as (l_as: BIN_MOD_AS) is
3935 do
3936 process_binary_as (l_as)
3937 end
3938
3939 process_bin_plus_as (l_as: BIN_PLUS_AS) is
3940 do
3941 process_binary_as (l_as)
3942 end
3943
3944 process_bin_power_as (l_as: BIN_POWER_AS) is
3945 do
3946 process_binary_as (l_as)
3947 end
3948
3949 process_bin_slash_as (l_as: BIN_SLASH_AS) is
3950 do
3951 process_binary_as (l_as)
3952 end
3953
3954 process_bin_star_as (l_as: BIN_STAR_AS) is
3955 do
3956 process_binary_as (l_as)
3957 end
3958
3959 process_bin_and_as (l_as: BIN_AND_AS) is
3960 do
3961 process_binary_as (l_as)
3962 end
3963
3964 process_bin_eq_as (l_as: BIN_EQ_AS) is
3965 local
3966 l_left_type, l_right_type: TYPE_A
3967 l_left_expr, l_right_expr: EXPR_B
3968 l_conv_info: CONVERSION_INFO
3969 l_binary: BINARY_B
3970 l_vweq: VWEQ
3971 l_needs_byte_node: BOOLEAN
3972 l_is_byte_node_simplified: BOOLEAN
3973 l_ne_as: BIN_NE_AS
3974 do
3975 l_needs_byte_node := is_byte_node_enabled
3976
3977 -- First type check the left member
3978 l_as.left.process (Current)
3979 l_left_type := last_type
3980 if l_needs_byte_node then
3981 l_left_expr ?= last_byte_node
3982 end
3983
3984 if not is_inherited then
3985 l_as.set_class_id (class_id_of (l_left_type))
3986 end
3987
3988 -- Then type check the right member
3989 l_as.right.process (Current)
3990 l_right_type := last_type
3991 if l_needs_byte_node then
3992 l_right_expr ?= last_byte_node
3993 end
3994
3995 -- Check if `l_left_type' conforms to `l_right_type' or if
3996 -- `l_right_type' conforms to `l_left_type'.
3997 if
3998 not (l_left_type.silent_conform_to (l_right_type.actual_type) or else
3999 l_right_type.silent_conform_to (l_left_type.actual_type))
4000 then
4001 if l_right_type.convert_to (context.current_class, l_left_type.actual_type) then
4002 l_conv_info := context.last_conversion_info
4003 if l_conv_info.has_depend_unit then
4004 context.supplier_ids.extend (l_conv_info.depend_unit)
4005 end
4006 if l_needs_byte_node then
4007 l_right_expr := l_conv_info.byte_node (l_right_expr)
4008 end
4009 else
4010 if l_left_type.convert_to (context.current_class, l_right_type.actual_type) then
4011 l_conv_info := context.last_conversion_info
4012 if l_conv_info.has_depend_unit then
4013 context.supplier_ids.extend (l_conv_info.depend_unit)
4014 end
4015 if l_needs_byte_node then
4016 l_left_expr := l_conv_info.byte_node (l_left_expr)
4017 end
4018 elseif not is_inherited then
4019 if context.current_class.is_warning_enabled (w_vweq) then
4020 create l_vweq
4021 context.init_error (l_vweq)
4022 l_vweq.set_left_type (l_left_type)
4023 l_vweq.set_right_type (l_right_type)
4024 l_vweq.set_location (l_as.operator_location)
4025 error_handler.insert_warning (l_vweq)
4026 end
4027 if l_left_type.is_basic and l_right_type.is_basic then
4028 -- Non-compatible basic type always implies a False/true comparison.
4029 l_is_byte_node_simplified := True
4030 end
4031 end
4032 end
4033 end
4034
4035 if l_needs_byte_node then
4036 if l_is_byte_node_simplified then
4037 l_ne_as ?= l_as
4038 if l_ne_as /= Void then
4039 create {BOOL_CONST_B} last_byte_node.make (True)
4040 else
4041 create {BOOL_CONST_B} last_byte_node.make (False)
4042 end
4043 else
4044 l_binary := byte_anchor.binary_node (l_as)
4045 l_binary.set_left (l_left_expr)
4046 l_binary.set_right (l_right_expr)
4047 last_byte_node := l_binary
4048 end
4049 end
4050
4051 last_type := boolean_type
4052 end
4053
4054 process_bin_ne_as (l_as: BIN_NE_AS) is
4055 do
4056 process_bin_eq_as (l_as)
4057 end
4058
4059 process_bracket_as (l_as: BRACKET_AS) is
4060 local
4061 was_assigner_call: BOOLEAN
4062 target_type: TYPE_A
4063 constrained_target_type: TYPE_A
4064 target_expr: EXPR_B
4065 target_access: ACCESS_EXPR_B
4066 target_class: CLASS_C
4067 bracket_feature: FEATURE_I
4068 id_feature_name: ID_AS
4069 location: LOCATION_AS
4070 call_b: CALL_B
4071 nested_b: NESTED_B
4072 vuex: VUEX
4073 vwbr: VWBR
4074 l_formal: FORMAL_A
4075 l_is_multi_constraint: BOOLEAN
4076 l_type_set: TYPE_SET_A
4077 l_result_tuple: TUPLE[feature_item: FEATURE_I; class_type_of_feature: CL_TYPE_A; features_found_count: INTEGER]
4078 l_context_current_class: CLASS_C
4079 l_last_class_id: INTEGER
4080 l_access_b: ACCESS_B
4081 l_is_qualified_call: BOOLEAN
4082 do
4083 -- Clean assigner call flag for bracket target
4084 was_assigner_call := is_assigner_call
4085 is_assigner_call := False
4086 l_context_current_class := context.current_class
4087 -- Check target
4088 l_as.target.process (Current)
4089 target_type := last_type.actual_type
4090 if is_byte_node_enabled then
4091 target_expr ?= last_byte_node
4092 end
4093
4094 check actual_type_called: target_type = target_type.actual_type end
4095 l_formal ?= target_type
4096 if l_formal /= Void then
4097 if l_formal.is_single_constraint_without_renaming (l_context_current_class) then
4098 constrained_target_type := l_formal.constrained_type (context.current_class)
4099 else
4100 l_is_multi_constraint := True
4101 end
4102 else
4103 check actual_type_called: target_type = target_type.actual_type end
4104 constrained_target_type := target_type
4105 end
4106
4107 if l_is_multi_constraint then
4108 l_type_set := l_formal.constrained_types (l_context_current_class)
4109 l_result_tuple := l_type_set.feature_i_state_by_alias_name (bracket_str)
4110 if l_result_tuple.features_found_count > 1 then
4111 raise_vtmc_error (create {ID_AS}.initialize (bracket_str), l_formal.position, l_context_current_class)
4112 elseif l_result_tuple.features_found_count = 1 then
4113 constrained_target_type := l_result_tuple.class_type_of_feature
4114 target_class := constrained_target_type.associated_class
4115 bracket_feature := l_result_tuple.feature_item
4116 end
4117 else
4118 check
4119 constrained_target_type /= Void and then constrained_target_type = constrained_target_type.actual_type
4120 end
4121 -- Check if target is not of type NONE
4122 if constrained_target_type.is_none then
4123 create vuex.make_for_none (bracket_str)
4124 context.init_error (vuex)
4125 vuex.set_location (l_as.left_bracket_location)
4126 error_handler.insert_error (vuex)
4127 error_handler.raise_error
4128 end
4129
4130 -- Check if bracket feature exists
4131 target_class := constrained_target_type.associated_class
4132 bracket_feature := target_class.feature_table.alias_item (bracket_str)
4133 end
4134 if bracket_feature = Void then
4135 -- Feature with bracket alias is not found
4136 create {VWBR1} vwbr
4137 context.init_error (vwbr)
4138 vwbr.set_location (l_as.left_bracket_location)
4139 if l_is_multi_constraint then
4140 check type_set_not_loose: not l_type_set.is_loose end
4141 vwbr.set_target_type (l_type_set)
4142 else
4143 vwbr.set_target_type (constrained_target_type)
4144 end
4145
4146 error_handler.insert_error (vwbr)
4147 error_handler.raise_error
4148 end
4149 if not is_inherited then
4150 l_last_class_id := target_class.class_id
4151 l_as.set_class_id (l_last_class_id)
4152 l_as.set_routine_ids (bracket_feature.rout_id_set)
4153 else
4154 l_last_class_id := l_as.class_id
4155 end
4156
4157 -- Process arguments
4158 create id_feature_name.initialize_from_id (bracket_feature.feature_name_id)
4159 location := l_as.left_bracket_location
4160 id_feature_name.set_position (location.line, location.column, location.position, location.location_count)
4161 -- Restore assigner call flag
4162 is_assigner_call := was_assigner_call
4163 last_calls_target_type := constrained_target_type
4164 -- Process call to bracket feature
4165 l_is_qualified_call := is_qualified_call
4166 is_qualified_call := True
4167 process_call (last_type, Void, id_feature_name, bracket_feature, l_as.operands, False, False, True, False)
4168 last_type := bracket_feature.type.instantiation_in (target_type, l_last_class_id).actual_type
4169 is_qualified_call := l_is_qualified_call
4170 error_handler.checksum
4171
4172 if is_byte_node_enabled then
4173 create nested_b
4174 create target_access
4175 target_access.set_expr (target_expr)
4176 target_access.set_parent (nested_b)
4177 if l_is_multi_constraint then
4178 l_access_b ?= last_byte_node
4179 -- Last generated bytenode is from `process_call'.
4180 check is_access_b: l_access_b /= Void end
4181 l_access_b.set_multi_constraint_static (constrained_target_type.type_i)
4182 call_b := l_access_b
4183 else
4184 call_b ?= last_byte_node
4185 end
4186
4187 check
4188 call_b_not_void: call_b /= Void
4189 end
4190 call_b.set_parent (nested_b)
4191 nested_b.set_message (call_b)
4192 nested_b.set_target (target_access)
4193 last_byte_node := nested_b
4194 end
4195 end
4196
4197 process_external_lang_as (l_as: EXTERNAL_LANG_AS) is
4198 do
4199 -- Nothing to be done
4200 end
4201
4202 process_feature_as (l_as: FEATURE_AS) is
4203 local
4204 l_byte_code: BYTE_CODE
4205 l_list: BYTE_LIST [BYTE_NODE]
4206 l_property_name: STRING
4207 l_custom_attributes: EIFFEL_LIST [CUSTOM_ATTRIBUTE_AS]
4208 do
4209 context.inline_agent_counter.reset
4210 last_byte_node := Void
4211 reset_for_unqualified_call_checking
4212 l_as.body.process (Current)
4213 if is_byte_node_enabled then
4214 l_byte_code ?= last_byte_node
4215 if l_byte_code = Void then
4216 create {ATTRIBUTE_BYTE_CODE} l_byte_code
4217 context.init_byte_code (l_byte_code)
4218 l_byte_code.set_end_location (l_as.end_location)
4219 end
4220 l_byte_code.set_start_line_number (l_as.start_location.line)
4221 l_byte_code.set_has_loop (has_loop)
4222 end
4223 -- For the moment, there is no point in checking custom attributes in non-dotnet mode.
4224 -- This fixes eweasel test#incr207.
4225 if system.il_generation then
4226 l_custom_attributes := l_as.custom_attributes
4227 if l_custom_attributes /= Void then
4228 l_custom_attributes.process (Current)
4229 if is_byte_node_enabled then
4230 l_list ?= last_byte_node
4231 l_byte_code.set_custom_attributes (l_list)
4232 end
4233 end
4234 l_custom_attributes := l_as.class_custom_attributes
4235 if l_custom_attributes /= Void then
4236 l_custom_attributes.process (Current)
4237 if is_byte_node_enabled then
4238 l_list ?= last_byte_node
4239 l_byte_code.set_class_custom_attributes (l_list)
4240 end
4241 end
4242 l_custom_attributes := l_as.interface_custom_attributes
4243 if l_custom_attributes /= Void then
4244 l_custom_attributes.process (Current)
4245 if is_byte_node_enabled then
4246 l_list ?= last_byte_node
4247 l_byte_code.set_interface_custom_attributes (l_list)
4248 end
4249 end
4250 end
4251 l_property_name := l_as.property_name
4252 if l_property_name /= Void then
4253 if is_byte_node_enabled then
4254 l_byte_code.set_property_name (l_property_name)
4255 end
4256 l_custom_attributes := l_as.property_custom_attributes
4257 -- See above comments for why it is only done in .NET mode.
4258 if l_custom_attributes /= Void and system.il_generation then
4259 l_custom_attributes.process (Current)
4260 if is_byte_node_enabled then
4261 l_list ?= last_byte_node
4262 l_byte_code.set_property_custom_attributes (l_list)
4263 end
4264 end
4265 end
4266 if is_byte_node_enabled then
4267 last_byte_node := l_byte_code
4268 end
4269 end
4270
4271 process_infix_prefix_as (l_as: INFIX_PREFIX_AS) is
4272 do
4273 -- Nothing to be done
4274 end
4275
4276 process_feat_name_id_as (l_as: FEAT_NAME_ID_AS) is
4277 do
4278 -- Nothing to be done
4279 end
4280
4281 process_feature_name_alias_as (l_as: FEATURE_NAME_ALIAS_AS) is
4282 do
4283 -- Nothing to be done.
4284 end
4285
4286 process_feature_list_as (l_as: FEATURE_LIST_AS) is
4287 do
4288 -- Nothing to be done
4289 end
4290
4291 process_all_as (l_as: ALL_AS) is
4292 do
4293 -- Nothing to be done
4294 end
4295
4296 process_assign_as (l_as: ASSIGN_AS) is
4297 local
4298 l_target_node: ACCESS_B
4299 l_source_expr: EXPR_B
4300 l_assign: ASSIGN_B
4301 l_ve03: VE03
4302 l_source_type, l_target_type: TYPE_A
4303 l_vjar: VJAR
4304 l_vncb: VNCB
4305 do
4306 break_point_slot_count := break_point_slot_count + 1
4307
4308 -- Init type stack
4309 reset_for_unqualified_call_checking
4310
4311 -- Type check the target
4312 set_is_in_assignment (True)
4313 last_access_writable := False
4314 l_as.target.process (Current)
4315 set_is_in_assignment (False)
4316 l_target_type := last_type
4317 current_target_type := l_target_type
4318
4319 -- Check if the target is not read-only mode.
4320 if not last_access_writable then
4321 -- Read-only entity
4322 create l_ve03
4323 context.init_error (l_ve03)
4324 l_ve03.set_target (l_as.target)
4325 l_ve03.set_location (l_as.target.end_location)
4326 error_handler.insert_error (l_ve03)
4327 end
4328
4329 if is_byte_node_enabled then
4330 l_target_node ?= last_byte_node
4331 end
4332
4333 -- Type check the source
4334 l_as.source.process (Current)
4335 l_source_type := last_type
4336
4337 -- Type checking
4338 process_type_compatibility (l_target_type)
4339 if not is_type_compatible then
4340 if l_source_type.is_bits then
4341 create l_vncb
4342 context.init_error (l_vncb)
4343 l_vncb.set_target_name (l_as.target.access_name)
4344 l_vncb.set_source_type (l_source_type)
4345 l_vncb.set_target_type (l_target_type)
4346 l_vncb.set_location (l_as.start_location)
4347 error_handler.insert_error (l_vncb)
4348 else
4349 create l_vjar
4350 context.init_error (l_vjar)
4351 l_vjar.set_source_type (l_source_type)
4352 l_vjar.set_target_type (l_target_type)
4353 l_vjar.set_target_name (l_as.target.access_name)
4354 l_vjar.set_location (l_as.start_location)
4355 error_handler.insert_error (l_vjar)
4356 end
4357 end
4358
4359 if is_byte_node_enabled then
4360 create l_assign
4361 l_assign.set_target (l_target_node)
4362 l_assign.set_line_number (l_as.target.start_location.line)
4363 l_source_expr ?= last_byte_node
4364 l_assign.set_source (l_source_expr)
4365 l_assign.set_line_pragma (l_as.line_pragma)
4366 last_byte_node := l_assign
4367 end
4368 end
4369
4370 process_assigner_call_as (l_as: ASSIGNER_CALL_AS) is
4371 local
4372 target_byte_node: like last_byte_node
4373 target_type: like last_type
4374 target_assigner: like last_assigner_command
4375 source_byte_node: EXPR_B
4376 source_type: like last_type
4377 vbac1: VBAC1
4378 vbac2: VBAC2
4379 outer_nested_b: NESTED_B
4380 inner_nested_b: NESTED_B
4381 access_b: ACCESS_B
4382 binary_b: BINARY_B
4383 unary_b: UNARY_B
4384 call_b: CALL_B
4385 external_b: EXTERNAL_B
4386 arguments: BYTE_LIST [PARAMETER_B]
4387 argument: PARAMETER_B
4388 assigner_arguments: BYTE_LIST [PARAMETER_B]
4389 l_instr: INSTR_CALL_B
4390 l_tuple_access: TUPLE_ACCESS_B
4391 l_is_tuple_access: BOOLEAN
4392 l_multi_constraint_static: TYPE_I
4393 do
4394 break_point_slot_count := break_point_slot_count + 1
4395
4396 -- Set assigner call flag for target expression
4397 is_assigner_call := True
4398 l_as.target.process (Current)
4399 l_is_tuple_access := is_last_access_tuple_access
4400 is_last_access_tuple_access := False
4401 check
4402 assigner_command_computed: not is_assigner_call
4403 end
4404 target_byte_node := last_byte_node
4405 target_type := last_type
4406 target_assigner := last_assigner_command
4407 l_as.source.process (Current)
4408 process_type_compatibility (target_type)
4409 source_type := last_type
4410 if not is_type_compatible then
4411 create vbac1
4412 context.init_error (vbac1)
4413 vbac1.set_source_type (source_type)
4414 vbac1.set_target_type (target_type)
4415 vbac1.set_location (l_as.start_location)
4416 error_handler.insert_error (vbac1)
4417 elseif target_assigner = Void and then not l_is_tuple_access then
4418 -- If we have no `target_assigner' and the last access is not a tuple access
4419 -- then we have an error.
4420 create vbac2
4421 context.init_error (vbac2)
4422 vbac2.set_location (l_as.start_location)
4423 error_handler.insert_error (vbac2)
4424 end
4425 if is_byte_node_enabled then
4426 -- Make sure all byte node is correct
4427 error_handler.checksum
4428 -- Preserve source byte node
4429 source_byte_node ?= last_byte_node
4430
4431 -- Discriminate over expression kind:
4432 -- it should be either a qualified call,
4433 -- a binary or an unary
4434 outer_nested_b ?= target_byte_node
4435 binary_b ?= target_byte_node
4436 unary_b ?= target_byte_node
4437 external_b ?= target_byte_node
4438 if external_b /= Void then
4439 --| Do nothing (for external static calls)
4440 elseif outer_nested_b /= Void then
4441 call_b := outer_nested_b
4442 -- Find end of call chain
4443 from
4444 inner_nested_b ?= outer_nested_b.message
4445 until
4446 inner_nested_b = Void
4447 loop
4448 outer_nested_b := inner_nested_b
4449 inner_nested_b ?= outer_nested_b.message
4450 end
4451 -- Evaluate assigner command arguments
4452 access_b ?= outer_nested_b.message
4453 check
4454 access_b_not_void: access_b /= Void
4455 end
4456 -- Get the multi_constrait_static if one exists
4457 l_multi_constraint_static := access_b.multi_constraint_static
4458 arguments := access_b.parameters
4459 elseif binary_b /= Void then
4460 -- Create call chain
4461 outer_nested_b := binary_b.nested_b
4462 call_b := outer_nested_b
4463 -- Evaluate assigner command arguments
4464 create arguments.make (1)
4465 create argument
4466 argument.set_expression (binary_b.right)
4467 argument.set_attachment_type (binary_b.attachment)
4468 if not system.il_generation then
4469 argument.set_is_formal (system.seed_of_routine_id (target_assigner.rout_id_set.first).arguments.i_th (1).type_i.is_formal)
4470 end
4471 arguments.extend (argument)
4472 else
4473 check
4474 unary_b_not_void: unary_b /= Void
4475 end
4476 -- Create call chain
4477 outer_nested_b := unary_b.nested_b
4478 call_b := outer_nested_b
4479 -- There are no arguments in unary expression
4480 end
4481
4482 if l_is_tuple_access then
4483 -- When assigning to a tuple, we simply transform the tuple
4484 -- access by giving a source.
4485 l_tuple_access ?= access_b
4486 check l_tuple_access_not_void: l_tuple_access /= Void end
4487 l_tuple_access.set_line_number (l_as.start_location.line)
4488 l_tuple_access.set_source (source_byte_node)
4489 last_byte_node := target_byte_node
4490 else
4491 -- Evaluate assigner command arguments:
4492 -- first is a source of an assigner command
4493 -- next are those from target call
4494 if arguments = Void then
4495 create assigner_arguments.make (1)
4496 else
4497 create assigner_arguments.make (arguments.count + 1)
4498 end
4499 create argument
4500 argument.set_expression (source_byte_node)
4501 argument.set_attachment_type (target_type.type_i)
4502 if not system.il_generation then
4503 argument.set_is_formal (system.seed_of_routine_id (target_assigner.rout_id_set.first).arguments.i_th (1).type_i.is_formal)
4504 end
4505 assigner_arguments.extend (argument)
4506 if arguments /= Void then
4507 assigner_arguments.append (arguments)
4508 end
4509 -- Evaluate assigner command byte node
4510 access_b := target_assigner.access (void_type.type_i, True)
4511 access_b.set_parameters (assigner_arguments)
4512
4513 if l_multi_constraint_static /= Void then
4514 -- We are in the multi constraint case, set the multi constraint static
4515 access_b.set_multi_constraint_static (l_multi_constraint_static)
4516 end
4517
4518 if external_b = Void then
4519 -- Replace end of call chain with an assigner command
4520 access_b.set_parent (outer_nested_b)
4521 outer_nested_b.set_message (access_b)
4522 else
4523 -- Set external static assigner
4524 check call_b_unattached: call_b = Void end
4525 call_b := access_b
4526 end
4527 create l_instr.make (call_b, l_as.start_location.line)
4528 l_instr.set_line_pragma (l_as.line_pragma)
4529 last_byte_node := l_instr
4530 end
4531 end
4532 end
4533
4534 process_reverse_as (l_as: REVERSE_AS) is
4535 local
4536 l_target_node: ACCESS_B
4537 l_source_expr: EXPR_B
4538 l_reverse: REVERSE_B
4539 l_ve03: VE03
4540 l_source_type, l_target_type: TYPE_A
4541 l_conv_info: CONVERSION_INFO
4542 l_formal: FORMAL_A
4543 l_vjrv1: VJRV1
4544 l_vjrv2: VJRV2
4545 l_attribute: ATTRIBUTE_B
4546 l_create_info: CREATE_INFO
4547 do
4548 break_point_slot_count := break_point_slot_count + 1
4549
4550 -- Init type stack
4551 reset_for_unqualified_call_checking
4552
4553 -- Type check the target
4554 set_is_in_assignment (True)
4555 last_access_writable := False
4556 l_as.target.process (Current)
4557 set_is_in_assignment (False)
4558 l_target_type := last_type
4559 current_target_type := l_target_type
4560
4561 -- Check if the target is not read-only mode.
4562 if not last_access_writable then
4563 -- Read-only entity
4564 create l_ve03
4565 context.init_error (l_ve03)
4566 l_ve03.set_target (l_as.target)
4567 l_ve03.set_location (l_as.target.end_location)
4568 error_handler.insert_error (l_ve03)
4569 end
4570
4571 if is_byte_node_enabled then
4572 l_target_node ?= last_byte_node
4573 end
4574
4575 -- Type check the source
4576 l_as.source.process (Current)
4577 l_source_type := last_type
4578 if is_byte_node_enabled then
4579 l_source_expr ?= last_byte_node
4580 create l_reverse
4581 l_reverse.set_target (l_target_node)
4582 l_reverse.set_line_number (l_as.target.start_location.line)
4583 l_reverse.set_line_pragma (l_as.line_pragma)
4584 end
4585
4586 -- Type checking
4587 if l_target_type.is_expanded then
4588 if not is_inherited and context.current_class.is_warning_enabled (w_vjrv) then
4589 create l_vjrv1
4590 context.init_error (l_vjrv1)
4591 l_vjrv1.set_target_name (l_as.target.access_name)
4592 l_vjrv1.set_target_type (l_target_type)
4593 l_vjrv1.set_location (l_as.target.end_location)
4594 error_handler.insert_warning (l_vjrv1)
4595 end
4596 elseif l_target_type.is_formal then
4597 l_formal ?= l_target_type
4598 check
4599 l_formal_not_void: l_formal /= Void
4600 end
4601 if
4602 not l_formal.is_reference and
4603 (not is_inherited and context.current_class.is_warning_enabled (w_vjrv))
4604 then
4605 create l_vjrv2
4606 context.init_error (l_vjrv2)
4607 l_vjrv2.set_target_name (l_as.target.access_name)
4608 l_vjrv2.set_target_type (l_target_type)
4609 l_vjrv2.set_location (l_as.target.end_location)
4610 error_handler.insert_warning (l_vjrv2)
4611 end
4612 else
4613 -- Target is a reference, but source is not.
4614 if l_source_type.is_expanded then
4615 -- Special case `ref ?= exp' where we convert
4616 -- `exp' to its associated reference before
4617 -- doing the assignment.
4618 if l_source_type.convert_to (context.current_class, l_target_type) then
4619 l_conv_info := context.last_conversion_info
4620 if l_conv_info.has_depend_unit then
4621 context.supplier_ids.extend (l_conv_info.depend_unit)
4622 end
4623 if is_byte_node_enabled then
4624 l_source_expr := l_conv_info.byte_node (l_source_expr)
4625 end
4626 end
4627 end
4628 end
4629
4630 if is_byte_node_enabled then
4631 l_reverse.set_source (l_source_expr)
4632 if l_target_node.is_attribute then
4633 l_attribute ?= l_target_node
4634 create {CREATE_FEAT} l_create_info.make (l_attribute.attribute_id,
4635 l_attribute.routine_id, context.current_class)
4636 else
4637 l_create_info := l_target_type.create_info
4638 end
4639
4640 l_reverse.set_info (l_create_info)
4641 last_byte_node := l_reverse
4642 end
4643 end
4644
4645 process_check_as (l_as: CHECK_AS) is
4646 local
4647 l_check: CHECK_B
4648 l_list: BYTE_LIST [BYTE_NODE]
4649 do
4650 if l_as.check_list /= Void then
4651 set_is_checking_check (True)
4652 l_as.check_list.process (Current)
4653 set_is_checking_check (False)
4654
4655 if is_byte_node_enabled then
4656 l_list ?= last_byte_node
4657 create l_check
4658 l_check.set_check_list (l_list)
4659 l_check.set_line_number (l_as.check_list.start_location.line)
4660 l_check.set_end_location (l_as.end_keyword)
4661 l_check.set_line_pragma (l_as.line_pragma)
4662 last_byte_node := l_check
4663 end
4664 elseif is_byte_node_enabled then
4665 create l_check
4666 l_check.set_end_location (l_as.end_keyword)
4667 l_check.set_line_pragma (l_as.line_pragma)
4668 last_byte_node := l_check
4669 end
4670 end
4671
4672 process_abstract_creation (a_creation_type: TYPE_A; a_call: ACCESS_INV_AS; a_name: STRING; a_location: LOCATION_AS) is
4673 require
4674 a_creation_type_not_void: a_creation_type /= Void
4675 a_location_not_void: a_location /= Void
4676 local
4677 l_call_access: CALL_ACCESS_B
4678 l_formal_type: FORMAL_A
4679 l_generic_type: GEN_TYPE_A
4680 l_formal_dec: FORMAL_CONSTRAINT_AS
4681 l_creation_class: CLASS_C
4682 l_creation_type: TYPE_A
4683 l_renamed_creation_type: RENAMED_TYPE_A [TYPE_A]
4684 l_is_formal_creation, l_is_default_creation: BOOLEAN
4685 l_feature, l_feature_item: FEATURE_I
4686 l_orig_call, l_call: ACCESS_INV_AS
4687 l_vgcc1: VGCC1
4688 l_vgcc11: VGCC11
4689 l_vgcc2: VGCC2
4690 l_vgcc4: VGCC4
4691 l_vgcc5: VGCC5
4692 l_creators: HASH_TABLE [EXPORT_I, STRING]
4693 l_needs_byte_node: BOOLEAN
4694 l_actual_creation_type: TYPE_A
4695 l_type_set: TYPE_SET_A
4696 l_constraint_type: TYPE_A
4697 l_deferred_classes: LINKED_LIST[CLASS_C]
4698 l_is_multi_constraint_case: BOOLEAN
4699 l_is_deferred: BOOLEAN
4700 l_constraint_creation_list: LIST [TUPLE [type_item: RENAMED_TYPE_A [TYPE_A]; feature_item: FEATURE_I]]
4701 l_ccl_item: TUPLE [type_item: RENAMED_TYPE_A [TYPE_A]; feature_item: FEATURE_I]
4702 l_mc_feature_info: MC_FEATURE_INFO
4703 l_result: LIST [TUPLE [feature_i: FEATURE_I; cl_type: RENAMED_TYPE_A [TYPE_A]]]
4704 l_result_item: TUPLE [feature_i: FEATURE_I; cl_type: RENAMED_TYPE_A [TYPE_A]]
4705 l_original_default_create_name_id: INTEGER
4706 l_context_current_class: CLASS_C
4707 do
4708 l_needs_byte_node := is_byte_node_enabled
4709 l_orig_call := a_call
4710 l_actual_creation_type := a_creation_type.actual_type
4711 l_context_current_class := context.current_class
4712
4713 l_generic_type ?= l_actual_creation_type
4714
4715 if l_actual_creation_type.is_formal then
4716 -- Cannot be Void
4717 l_formal_type ?= l_actual_creation_type
4718
4719 if l_formal_type.is_single_constraint_without_renaming (l_context_current_class) then
4720 l_constraint_type := l_formal_type.constrained_type (l_context_current_class)
4721 l_creation_type := l_constraint_type
4722 l_creation_class := l_constraint_type.associated_class
4723 l_is_deferred := l_creation_class.is_deferred
4724 else
4725 l_is_multi_constraint_case := True
4726 l_type_set := l_formal_type.constrained_types (l_context_current_class)
4727 l_is_deferred := l_type_set.has_deferred
4728 end
4729 -- Get the corresponding constraint type of the current class
4730 l_formal_dec ?= l_context_current_class.generics.i_th (l_formal_type.position)
4731 check l_formal_dec_not_void: l_formal_dec /= Void end
4732 if
4733 l_formal_dec.has_constraint and then
4734 l_formal_dec.has_creation_constraint
4735 then
4736 l_is_formal_creation := True
4737 -- Ensure to update `has_default_create' from `l_formal_dec'
4738 l_formal_dec.constraint_creation_list (l_context_current_class).do_nothing
4739 else
4740 -- An entity of type a formal generic parameter cannot be
4741 -- created here because there is no creation routine constraints
4742 create l_vgcc1
4743 context.init_error (l_vgcc1)
4744 l_vgcc1.set_target_name (a_name)
4745 l_vgcc1.set_location (a_location)
4746 error_handler.insert_error (l_vgcc1);
4747 end
4748 else
4749 if l_generic_type /= Void then
4750 l_generic_type.check_constraints (l_context_current_class , context.current_feature, True)
4751 l_generic_type.generate_error_from_creation_constraint_list (l_context_current_class , context.current_feature, a_location)
4752 end
4753 l_constraint_type := l_actual_creation_type
4754 l_creation_type := l_constraint_type
4755 l_creation_class := l_constraint_type.associated_class
4756 l_is_deferred := l_creation_class.is_deferred
4757 end
4758
4759 error_handler.checksum
4760
4761 if l_is_deferred and then not l_is_formal_creation then
4762 -- Associated class cannot be deferred
4763 create l_deferred_classes.make
4764 if l_is_multi_constraint_case then
4765 -- We generate a list of all the deferred classes in the type set
4766 l_type_set.do_all (
4767 agent (a_deferred_classes: LIST[CLASS_C]; a_type: RENAMED_TYPE_A [TYPE_A])
4768 do
4769 if a_type.associated_class.is_deferred then
4770 a_deferred_classes.extend (a_type.associated_class)
4771 end
4772 end
4773 (l_deferred_classes,?))
4774 else
4775 -- There's only one class and it is deferred
4776 l_deferred_classes.extend (l_creation_class)
4777 end
4778
4779 create l_vgcc2
4780 context.init_error (l_vgcc2)
4781 l_vgcc2.set_type (a_creation_type)
4782 l_vgcc2.set_deferred_classes (l_deferred_classes)
4783 l_vgcc2.set_target_name (a_name)
4784 l_vgcc2.set_location (a_location)
4785 error_handler.insert_error (l_vgcc2)
4786 error_handler.raise_error
4787 end
4788
4789 if
4790 l_orig_call = Void and then
4791 ((l_creation_class /= Void and then l_creation_class.allows_default_creation) or else
4792 (l_is_formal_creation and then l_formal_dec.has_default_create))
4793 then
4794 if l_creation_class /= Void then
4795 check not_is_multi_constraint_case: not l_is_multi_constraint_case end
4796 l_feature := l_creation_class.default_create_feature
4797 l_creation_type := l_creation_class.actual_type
4798 l_original_default_create_name_id := l_feature.feature_name_id
4799 else
4800 check
4801 is_multi_constrainet_case: l_is_multi_constraint_case
4802 l_formal_type_not_void: l_formal_type /= Void
4803 l_formal_dec_not_void: l_formal_dec /= Void
4804 l_creation_class_is_void: l_creation_class = Void
4805 second_part_of_if_is_true: l_is_formal_creation and then l_formal_dec.has_default_create
4806 end
4807 -- What we want to do is the following:
4808 -- We go through the list of creation constraints and have a look at each feature.
4809 -- If a feature is a version of `default_create' from `ANY' we record it.
4810 -- We should find exactly one feature as otherwise l_formal_dec.has_default_create should not have been true.
4811 l_constraint_creation_list := l_formal_dec.constraint_creation_list (l_context_current_class)
4812 from
4813 l_constraint_creation_list.start
4814 until
4815 l_constraint_creation_list.after or l_creation_class /= Void
4816 loop
4817 l_ccl_item := l_constraint_creation_list.item
4818 l_feature_item := l_ccl_item.feature_item
4819 if l_feature_item.rout_id_set.first = system.default_create_id then
4820 l_feature := l_feature_item
4821 l_renamed_creation_type := l_ccl_item.type_item
4822 if l_renamed_creation_type.has_renaming then
4823 l_original_default_create_name_id := l_renamed_creation_type.renaming.new_name (l_feature.feature_name_id)
4824 else
4825 l_original_default_create_name_id := l_feature.feature_name_id
4826 end
4827 l_creation_type := l_renamed_creation_type.type
4828 l_creation_class := l_creation_type.associated_class
4829 last_type := l_creation_type
4830 end
4831 l_constraint_creation_list.forth
4832 end
4833
4834 check
4835 found_item_was_the_only_one:
4836 (agent (a_constraint_creation_list: LIST [TUPLE [type_item: RENAMED_TYPE_A [TYPE_A]; feature_item: FEATURE_I]]): BOOLEAN
4837 -- Check that there is no more version of default create.
4838 --| Otherwise we should never get in here as `l_formal_dec.has_default_create'
4839 --| should have returned false and prevented this from happening.
4840 do
4841 Result := True
4842 from do_nothing
4843 until
4844 a_constraint_creation_list.after
4845 loop
4846 if a_constraint_creation_list.item.feature_item.rout_id_set.first = system.default_create_id then
4847 Result := False
4848 end
4849 a_constraint_creation_list.forth
4850 end
4851 end).item ([l_constraint_creation_list])
4852 end
4853 end
4854
4855 check l_feature /= Void end
4856 check l_creation_class /= Void end
4857
4858 -- Use default_create
4859 create {ACCESS_INV_AS} l_call.make (
4860 create {ID_AS}.initialize_from_id (l_original_default_create_name_id), Void, Void)
4861 -- For better error reporting as we insert a dummy call for type checking.
4862 l_call.feature_name.set_position (a_location.line, a_location.column,
4863 a_location.position, a_location.location_count)
4864 if l_is_formal_creation or else not l_feature.is_empty then
4865 -- We want to generate a call only when needed:
4866 -- 1 - In a formal generic creation call
4867 -- 2 - When body of `default_create' is not empty
4868 l_orig_call := l_call
4869 end
4870 l_call.set_routine_ids (l_feature.rout_id_set)
4871 l_is_default_creation := True
4872 else
4873 l_call := l_orig_call
4874 end
4875
4876 if l_creation_class /= Void then
4877 l_creators := l_creation_class.creators
4878 end
4879
4880 if l_call /= Void then
4881 if is_inherited then
4882 if l_is_multi_constraint_case then
4883 -- We need to iterate through the type set to find the routine of ID
4884 check
4885 -- It should work as we are in the multi constraint case
4886 l_formal_type_not_void: l_formal_type /= Void
4887 end
4888 l_result := l_type_set.feature_i_list_by_rout_id (l_call.routine_ids.first)
4889 check at_least_one_feature_found: l_result.count > 0 end
4890 from
4891 l_result.start
4892 until
4893 l_result.after
4894 loop
4895 l_result_item := l_result.item
4896 l_feature := l_result_item.feature_i
4897 l_creation_type := l_result_item.cl_type.type
4898 l_creation_class := l_creation_type.associated_class
4899 last_calls_target_type := l_creation_type
4900 -- Type check the call
4901 process_call (last_type, Void, l_call.feature_name, l_feature, l_call.parameters, False, False, False, False)
4902 -- Even though this code is very similar to the one in `process_access_feat_as' we do not
4903 -- need to adapt last_type as this is a creation procedure without a result.
4904 end
4905 -- Martins 3/29/2007
4906 -- After the loop we simply continue with whatever feature was last found.
4907 -- Is this a good idea? Well, it depends:
4908 -- We have done all checks, so whatever it might be, we're fine.
4909 -- But if we would have to generate new code (replication?) it is not decideable what to do
4910 -- because the selection of the static type of the call has an influence to the dynamic binding.
4911 -- And we have possibly more than one possibility to chose from and they are equally acceptable.
4912 fixme ("Possibly a multi constraint issue (in the future) regarding dynamic binding.")
4913 else
4914 check l_creation_class_not_void: l_creation_class /= Void end
4915 l_feature := l_creation_class.feature_of_rout_id (l_call.routine_ids.first)
4916 check l_creation_type_not_void_if_l_feature_is_available: l_feature /= Void implies l_creation_type /= Void end
4917 -- We set `last_calls_target_type' in order to be able to use the same code as we use in the multiconstrained case.
4918 last_calls_target_type := l_creation_type
4919 -- Type check the call
4920 process_call (last_type, Void, l_call.feature_name, l_feature, l_call.parameters, False, False, False, False)
4921 end
4922 else
4923 -- Type check the call
4924 check l_creation_type_not_void_if_l_feature_is_available: l_feature /= Void implies l_creation_type /= Void end
4925 -- We set last_calls_target_type in case we have a multi constrained formal.
4926 last_calls_target_type := l_creation_type
4927 process_call (last_type, Void, l_call.feature_name, l_feature, l_call.parameters, False, False, False, False)
4928 end
4929
4930 check l_creation_class /= Void implies last_calls_target_type.associated_class.conform_to (l_creation_class) end
4931 if not is_inherited then
4932 -- Set some type informations
4933 if l_is_multi_constraint_case then
4934 l_call.set_class_id (last_calls_target_type.associated_class.class_id)
4935 else
4936 l_call.set_class_id (l_creation_class.class_id)
4937 end
4938 -- Note that `last_routine_id_set' could be Void in case it is
4939 -- a named tuple access.
4940 if last_routine_id_set /= Void then
4941 l_call.set_routine_ids (last_routine_id_set)
4942 end
4943 end
4944
4945 -- We need to reset `last_type' as it now `VOID_A' after checking the call
4946 -- which a procedure.
4947 last_type := a_creation_type
4948 if l_needs_byte_node and then l_orig_call /= Void then
4949 l_call_access ?= last_byte_node
4950 if l_is_multi_constraint_case and then l_is_default_creation then
4951 check
4952 no_static_set: not l_call_access.has_multi_constraint_static
4953 end
4954 l_call_access.set_multi_constraint_static (l_creation_type.type_i)
4955 end
4956 end
4957
4958 if not l_is_formal_creation then
4959 -- Check if creation routine is non-once procedure
4960 if
4961 not l_creation_class.valid_creation_procedure (last_feature_name)
4962 then
4963 create l_vgcc5
4964 context.init_error (l_vgcc5)
4965 l_vgcc5.set_target_name (a_name)
4966 l_vgcc5.set_type (a_creation_type)
4967 l_vgcc5.set_creation_feature (l_creation_class.feature_table.item (last_feature_name))
4968 l_vgcc5.set_location (l_call.feature_name)
4969 error_handler.insert_error (l_vgcc5)
4970 elseif l_creators /= Void then
4971 if not l_creators.item (last_feature_name).valid_for (l_context_current_class) then
4972 -- Creation procedure is not exported
4973 create l_vgcc5
4974 context.init_error (l_vgcc5)
4975 l_vgcc5.set_target_name (a_name)
4976 l_vgcc5.set_type (a_creation_type)
4977 l_vgcc5.set_creation_feature (
4978 l_creation_class.feature_table.item_id (last_feature_name_id))
4979 l_vgcc5.set_location (l_call.feature_name)
4980 error_handler.insert_error (l_vgcc5)
4981 end
4982 end
4983 else
4984 -- Check that the creation feature used for creating the generic
4985 -- parameter has been listed in the constraint for the generic
4986 -- parameter.
4987 if not l_formal_dec.has_creation_feature_name_id (last_actual_feature_name_id) then
4988 create l_vgcc11
4989 context.init_error (l_vgcc11)
4990 l_vgcc11.set_target_name (a_name)
4991 if l_is_multi_constraint_case then
4992 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)
4993 if not l_mc_feature_info.is_empty then
4994 l_vgcc11.set_creation_feature (l_mc_feature_info.first.feature_i)
4995 end
4996 else
4997 check l_creation_class /= Void end
4998 l_vgcc11.set_creation_feature (l_creation_class.feature_table.item (last_feature_name))
4999 end
5000
5001 l_vgcc11.set_location (l_call.feature_name)
5002 error_handler.insert_error (l_vgcc11)
5003 end
5004 end
5005 else
5006 if not l_is_formal_creation then
5007 if (l_creators = Void) or l_is_default_creation then
5008 elseif l_creators.is_empty then
5009 create l_vgcc5
5010 context.init_error (l_vgcc5)
5011 l_vgcc5.set_target_name (a_name)
5012 l_vgcc5.set_type (a_creation_type)
5013 l_vgcc5.set_creation_feature (Void)
5014 l_vgcc5.set_location (a_location)
5015 error_handler.insert_error (l_vgcc5)
5016 else
5017 create l_vgcc4
5018 context.init_error (l_vgcc4)
5019 l_vgcc4.set_target_name (a_name)
5020 l_vgcc4.set_type (a_creation_type)
5021 l_vgcc4.set_location (a_location)
5022 error_handler.insert_error (l_vgcc4)
5023 end
5024 else
5025 -- An entity of type a formal generic parameter cannot be
5026 -- created here because we need a creation routine call
5027 create l_vgcc1
5028 context.init_error (l_vgcc1)
5029 l_vgcc1.set_target_name (a_name)
5030 l_vgcc1.set_location (a_location)
5031 error_handler.insert_error (l_vgcc1)
5032 end
5033 end
5034 error_handler.checksum
5035 if l_needs_byte_node then
5036 last_byte_node := l_call_access
5037 end
5038 end
5039
5040 process_creation_as (l_as: CREATION_AS) is
5041 local
5042 l_access: ACCESS_B
5043 l_call_access: CALL_ACCESS_B
5044 l_creation_expr: CREATION_EXPR_B
5045 l_assign: ASSIGN_B
5046 l_attribute: ATTRIBUTE_B
5047 l_target_type, l_explicit_type, l_creation_type: TYPE_A
5048 l_create_info: CREATE_INFO
5049 l_vgcc3: VGCC3
5050 l_vgcc31: VGCC31
5051 l_vgcc7: VGCC7
5052 l_needs_byte_node: BOOLEAN
5053 do
5054 break_point_slot_count := break_point_slot_count + 1
5055
5056 l_needs_byte_node := is_byte_node_enabled
5057 reset_for_unqualified_call_checking
5058
5059 -- Set flag so that depend_unit knows it is used as a creation routine
5060 -- not just a normal feature call. It is reset as soon as it is processed.
5061 is_target_of_creation_instruction := True
5062 last_access_writable := False
5063 l_as.target.process (Current)
5064 -- Although it might be already reset when `target' is indeed
5065 -- a feature of the current class, it is not reset when it is a local,
5066 -- that's why we reset it.
5067 is_target_of_creation_instruction := False
5068 l_target_type := last_type
5069 if l_needs_byte_node then
5070 l_access ?= last_byte_node
5071 end
5072
5073 if not last_access_writable then
5074 create l_vgcc7
5075 context.init_error (l_vgcc7)
5076 l_vgcc7.set_target_name (l_as.target.access_name)
5077 l_vgcc7.set_type (l_target_type)
5078 l_vgcc7.set_location (l_as.target.start_location)
5079 error_handler.insert_error (l_vgcc7)
5080 else
5081 if l_as.type /= Void then
5082 l_as.type.process (Current)
5083 l_explicit_type := last_type
5084 end
5085
5086 -- Check validity of creation type.
5087 if
5088 l_target_type.is_none or else (l_explicit_type /= Void and then
5089 (l_explicit_type.is_none or else
5090 (l_target_type.is_expanded and then l_explicit_type.is_expanded and then
5091 not l_explicit_type.same_as (l_target_type))))
5092 then
5093 -- Cannot create instance of NONE.
5094 -- Cannot create an expanded type which is different from
5095 -- the declared type of `l_as.target'.
5096 create l_vgcc3
5097 context.init_error (l_vgcc3)
5098 l_vgcc3.set_type (l_explicit_type)
5099 l_vgcc3.set_target_name (l_as.target.access_name)
5100 l_vgcc3.set_location (l_as.target.start_location)
5101 error_handler.insert_error (l_vgcc3)
5102 error_handler.raise_error
5103 end
5104
5105 if
5106 l_explicit_type /= Void and then
5107 not l_explicit_type.conform_to (l_target_type)
5108 then
5109 -- Specified creation type must conform to
5110 -- the entity type
5111 create l_vgcc31
5112 context.init_error (l_vgcc31)
5113 l_vgcc31.set_target_name (l_as.target.access_name)
5114 l_vgcc31.set_type (l_explicit_type)
5115 l_vgcc31.set_location (l_as.type.start_location)
5116 error_handler.insert_error (l_vgcc31)