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