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

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

Parent Directory Parent Directory | Revision Log Revision Log


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