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