/[eiffelstudio]/vendor/gobosoft.com/gobo/4.0d/library/tools/src/eiffel/processor/et_expression_type_finder.e
ViewVC logotype

Contents of /vendor/gobosoft.com/gobo/4.0d/library/tools/src/eiffel/processor/et_expression_type_finder.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 98698 - (show annotations)
Mon May 9 13:53:54 2016 UTC (3 years, 5 months ago) by manus
File size: 139597 byte(s)
Update 4.0d version with changes in Gobo from 2016/05/09

1 note
2
3 description:
4
5 "Eiffel expression type finders"
6
7 library: "Gobo Eiffel Tools Library"
8 copyright: "Copyright (c) 2008-2016, Eric Bezault and others"
9 license: "MIT License"
10 date: "$Date$"
11 revision: "$Revision$"
12
13 class ET_EXPRESSION_TYPE_FINDER
14
15 inherit
16
17 ET_CLASS_SUBPROCESSOR
18 redefine
19 make
20 end
21
22 ET_AST_NULL_PROCESSOR
23 undefine
24 make
25 redefine
26 process_across_expression,
27 process_binary_integer_constant,
28 process_bracket_expression,
29 process_c1_character_constant,
30 process_c2_character_constant,
31 process_c3_character_constant,
32 process_call_agent,
33 process_convert_builtin_expression,
34 process_convert_from_expression,
35 process_convert_to_expression,
36 process_create_expression,
37 process_current,
38 process_current_address,
39 process_do_function_inline_agent,
40 process_do_procedure_inline_agent,
41 process_equality_expression,
42 process_expression_address,
43 process_external_function_inline_agent,
44 process_external_procedure_inline_agent,
45 process_false_constant,
46 process_feature_address,
47 process_hexadecimal_integer_constant,
48 process_identifier,
49 process_infix_cast_expression,
50 process_infix_expression,
51 process_manifest_array,
52 process_manifest_tuple,
53 process_manifest_type,
54 process_named_object_test,
55 process_object_equality_expression,
56 process_object_test,
57 process_octal_integer_constant,
58 process_old_expression,
59 process_old_object_test,
60 process_once_function_inline_agent,
61 process_once_manifest_string,
62 process_once_procedure_inline_agent,
63 process_parenthesized_expression,
64 process_precursor_expression,
65 process_prefix_expression,
66 process_qualified_call_expression,
67 process_regular_integer_constant,
68 process_regular_manifest_string,
69 process_regular_real_constant,
70 process_result,
71 process_result_address,
72 process_special_manifest_string,
73 process_static_call_expression,
74 process_strip_expression,
75 process_true_constant,
76 process_underscored_integer_constant,
77 process_underscored_real_constant,
78 process_unqualified_call_expression,
79 process_verbatim_string,
80 process_void
81 end
82
83 create
84
85 make
86
87 feature {NONE} -- Initialization
88
89 make
90 -- Create a new feature validity checker.
91 do
92 create type_checker.make
93 current_class := tokens.unknown_class
94 current_type := current_class
95 current_feature := dummy_feature
96 current_feature_impl := dummy_feature.implementation_feature
97 current_class_impl := current_feature_impl.implementation_class
98 -- Type contexts.
99 create unused_contexts.make (20)
100 current_context := new_context (current_type)
101 current_target_type := tokens.unknown_class
102 free_context (current_context)
103 end
104
105 feature -- Basic operations
106
107 find_expression_type_in_feature (a_expression: ET_EXPRESSION; a_feature: ET_FEATURE; a_context: ET_NESTED_TYPE_CONTEXT; a_target_type: ET_TYPE_CONTEXT)
108 -- Expression `a_expression' (whose possible attachment target is of type
109 -- `a_target_type') appears in the body of `a_feature' and is viewed from
110 -- `a_context' (`a_feature' is a feature of the root context of `a_context').
111 -- Alter `a_context' so that it represents the type of `a_expression'.
112 -- Set `has_fatal_error' if a fatal error occurred.
113 --
114 -- Note that it is assumed that `a_feature' has been successfully checked
115 -- in the context of `a_context.root_context' (using ET_FEATURE_CHECKER for example).
116 -- Otherwise internal errors may be reported (using ET_ERROR_HANDLER.report_giaaa_error)
117 -- if `a_feature' has not been checked or if `internal_error_enabled' has been set.
118 require
119 a_expression_not_void: a_expression /= Void
120 a_feature_not_void: a_feature /= Void
121 a_context_not_void: a_context /= Void
122 a_current_class_preparsed: a_context.root_context.base_class.is_preparsed
123 a_target_type_not_void: a_target_type /= Void
124 valid_target_context: a_target_type.is_valid_context
125 local
126 old_feature: ET_STANDALONE_CLOSURE
127 old_feature_impl: ET_STANDALONE_CLOSURE
128 old_class: ET_CLASS
129 old_class_impl: ET_CLASS
130 old_type: ET_BASE_TYPE
131 old_target_type: ET_TYPE_CONTEXT
132 old_context: ET_NESTED_TYPE_CONTEXT
133 do
134 reset_fatal_error (False)
135 old_feature_impl := current_feature_impl
136 current_feature_impl := a_feature.implementation_feature
137 old_feature := current_feature
138 current_feature := a_feature
139 old_type := current_type
140 current_type := a_context.root_context
141 old_class := current_class
142 current_class := current_type.base_class
143 old_class_impl := current_class_impl
144 current_class_impl := a_feature.implementation_class
145 old_context := current_context
146 current_context := a_context
147 old_target_type := current_target_type
148 current_target_type := a_target_type
149 current_universe_impl.resolve_unfolded_tuple_actual_parameters
150 a_expression.process (Current)
151 current_target_type := old_target_type
152 current_context := old_context
153 current_class := old_class
154 current_type := old_type
155 current_class_impl := old_class_impl
156 current_feature := old_feature
157 current_feature_impl := old_feature_impl
158 end
159
160 find_expression_type_in_agent (a_expression: ET_EXPRESSION; a_agent: ET_INLINE_AGENT; a_feature: ET_STANDALONE_CLOSURE; a_context: ET_NESTED_TYPE_CONTEXT; a_target_type: ET_TYPE_CONTEXT)
161 -- Expression `a_expression' (whose possible attachment target is of type
162 -- `a_target_type') appears in inline agent `a_agent' in the body of feature
163 -- or invariant `a_feature' and is viewed from `a_context' (`a_feature' is
164 -- a feature of the root context of `a_context').
165 -- Alter `a_context' so that it represents the type of `a_expression'.
166 -- Set `has_fatal_error' if a fatal error occurred.
167 --
168 -- Note that it is assumed that `a_feature' has been successfully checked
169 -- in the context of `a_context.root_context' (using ET_FEATURE_CHECKER for example).
170 -- Otherwise internal errors may be reported (using ET_ERROR_HANDLER.report_giaaa_error)
171 -- if `a_feature' has not been checked or if `internal_error_enabled' has been set.
172 require
173 a_expression_not_void: a_expression /= Void
174 a_agent_not_void: a_agent /= Void
175 a_feature_not_void: a_feature /= Void
176 a_context_not_void: a_context /= Void
177 a_current_class_preparsed: a_context.root_context.base_class.is_preparsed
178 a_target_type_not_void: a_target_type /= Void
179 valid_target_context: a_target_type.is_valid_context
180 local
181 old_feature: ET_STANDALONE_CLOSURE
182 old_feature_impl: ET_STANDALONE_CLOSURE
183 old_class: ET_CLASS
184 old_class_impl: ET_CLASS
185 old_type: ET_BASE_TYPE
186 old_target_type: ET_TYPE_CONTEXT
187 old_context: ET_NESTED_TYPE_CONTEXT
188 do
189 reset_fatal_error (False)
190 current_inline_agent := a_agent
191 old_feature_impl := current_feature_impl
192 current_feature_impl := a_feature.implementation_feature
193 old_feature := current_feature
194 current_feature := a_feature
195 old_type := current_type
196 current_type := a_context.root_context
197 old_class := current_class
198 current_class := current_type.base_class
199 old_class_impl := current_class_impl
200 current_class_impl := a_feature.implementation_class
201 old_context := current_context
202 current_context := a_context
203 old_target_type := current_target_type
204 current_target_type := a_target_type
205 current_universe_impl.resolve_unfolded_tuple_actual_parameters
206 a_expression.process (Current)
207 current_target_type := old_target_type
208 current_context := old_context
209 current_class := old_class
210 current_type := old_type
211 current_class_impl := old_class_impl
212 current_feature := old_feature
213 current_feature_impl := old_feature_impl
214 current_inline_agent := Void
215 end
216
217 find_expression_type_in_precondition (a_expression: ET_EXPRESSION; a_feature_impl, a_feature: ET_FEATURE; a_context: ET_NESTED_TYPE_CONTEXT; a_target_type: ET_TYPE_CONTEXT)
218 -- Expression `a_expression' (whose possible attachment target is of type
219 -- `a_target_type') appears in the precondition of `a_feature' (written in
220 -- `a_feature_impl') and is viewed from `a_context' (`a_feature' is a feature
221 -- of the root context of `a_context').
222 -- `a_feature' and `a_feature_impl' are assumed to have been successfully
223 -- checked (using ET_FEATURE_CHECKER for example).
224 -- Alter `a_context' so that it represents the type of `a_expression'.
225 -- Set `has_fatal_error' if a fatal error occurred.
226 --
227 -- Note that it is assumed that `a_feature' has been successfully checked
228 -- in the context of `a_context.root_context' as well as `a_feature_impl'
229 -- in the context of `a_feature_impl.implementation_class' (using
230 -- ET_FEATURE_CHECKER for example). Otherwise internal errors may be
231 -- reported (using ET_ERROR_HANDLER.report_giaaa_error) if `a_feature' or
232 -- `a_feature_impl' has not been checked or if `internal_error_enabled'
233 -- has been set.
234 require
235 a_expression_not_void: a_expression /= Void
236 a_feature_impl_not_void: a_feature_impl /= Void
237 a_feature_not_void: a_feature /= Void
238 a_context_not_void: a_context /= Void
239 a_current_class_preparsed: a_context.root_context.base_class.is_preparsed
240 a_target_type_not_void: a_target_type /= Void
241 valid_target_context: a_target_type.is_valid_context
242 local
243 old_feature: ET_STANDALONE_CLOSURE
244 old_feature_impl: ET_STANDALONE_CLOSURE
245 old_class: ET_CLASS
246 old_class_impl: ET_CLASS
247 old_type: ET_BASE_TYPE
248 old_target_type: ET_TYPE_CONTEXT
249 old_context: ET_NESTED_TYPE_CONTEXT
250 old_in_assertion: BOOLEAN
251 old_in_precondition: BOOLEAN
252 do
253 reset_fatal_error (False)
254 old_feature_impl := current_feature_impl
255 current_feature_impl := a_feature_impl.implementation_feature
256 old_feature := current_feature
257 current_feature := a_feature
258 old_type := current_type
259 current_type := a_context.root_context
260 old_class := current_class
261 current_class := current_type.base_class
262 old_class_impl := current_class_impl
263 current_class_impl := a_feature_impl.implementation_class
264 old_context := current_context
265 current_context := a_context
266 old_target_type := current_target_type
267 current_target_type := a_target_type
268 old_in_assertion := in_assertion
269 in_assertion := True
270 old_in_precondition := in_precondition
271 in_precondition := True
272 current_universe_impl.resolve_unfolded_tuple_actual_parameters
273 a_expression.process (Current)
274 in_assertion := old_in_assertion
275 in_precondition := old_in_precondition
276 current_target_type := old_target_type
277 current_context := old_context
278 current_class := old_class
279 current_type := old_type
280 current_class_impl := old_class_impl
281 current_feature := old_feature
282 current_feature_impl := old_feature_impl
283 end
284
285 find_expression_type_in_postcondition (a_expression: ET_EXPRESSION; a_feature_impl, a_feature: ET_FEATURE; a_context: ET_NESTED_TYPE_CONTEXT; a_target_type: ET_TYPE_CONTEXT)
286 -- Expression `a_expression' (whose possible attachment target is of type
287 -- `a_target_type') appears in the postcondition of `a_feature' (written in
288 -- `a_feature_impl') and is viewed from `a_context' (`a_feature' is a feature
289 -- of the root context of `a_context').
290 -- Alter `a_context' so that it represents the type of `a_expression'.
291 -- Set `has_fatal_error' if a fatal error occurred.
292 --
293 -- Note that it is assumed that `a_feature' has been successfully checked
294 -- in the context of `a_context.root_context' as well as `a_feature_impl'
295 -- in the context of `a_feature_impl.implementation_class' (using
296 -- ET_FEATURE_CHECKER for example). Otherwise internal errors may be
297 -- reported (using ET_ERROR_HANDLER.report_giaaa_error) if `a_feature' or
298 -- `a_feature_impl' has not been checked or if `internal_error_enabled'
299 -- has been set.
300 require
301 a_expression_not_void: a_expression /= Void
302 a_feature_impl_not_void: a_feature_impl /= Void
303 a_feature_not_void: a_feature /= Void
304 a_context_not_void: a_context /= Void
305 a_current_class_preparsed: a_context.root_context.base_class.is_preparsed
306 a_target_type_not_void: a_target_type /= Void
307 valid_target_context: a_target_type.is_valid_context
308 local
309 old_feature: ET_STANDALONE_CLOSURE
310 old_feature_impl: ET_STANDALONE_CLOSURE
311 old_class: ET_CLASS
312 old_class_impl: ET_CLASS
313 old_type: ET_BASE_TYPE
314 old_target_type: ET_TYPE_CONTEXT
315 old_context: ET_NESTED_TYPE_CONTEXT
316 old_in_assertion: BOOLEAN
317 old_in_postcondition: BOOLEAN
318 do
319 reset_fatal_error (False)
320 old_feature_impl := current_feature_impl
321 current_feature_impl := a_feature_impl.implementation_feature
322 old_feature := current_feature
323 current_feature := a_feature
324 old_type := current_type
325 current_type := a_context.root_context
326 old_class := current_class
327 current_class := current_type.base_class
328 old_class_impl := current_class_impl
329 current_class_impl := a_feature_impl.implementation_class
330 old_context := current_context
331 current_context := a_context
332 old_target_type := current_target_type
333 current_target_type := a_target_type
334 old_in_assertion := in_assertion
335 in_assertion := True
336 old_in_postcondition := in_postcondition
337 in_postcondition := True
338 current_universe_impl.resolve_unfolded_tuple_actual_parameters
339 a_expression.process (Current)
340 in_assertion := old_in_assertion
341 in_postcondition := old_in_postcondition
342 current_target_type := old_target_type
343 current_context := old_context
344 current_class := old_class
345 current_type := old_type
346 current_class_impl := old_class_impl
347 current_feature := old_feature
348 current_feature_impl := old_feature_impl
349 end
350
351 find_expression_type_in_invariant (a_expression: ET_EXPRESSION; a_invariant: ET_INVARIANTS; a_context: ET_NESTED_TYPE_CONTEXT; a_target_type: ET_TYPE_CONTEXT)
352 -- Expression `a_expression' (whose possible attachment target is of type
353 -- `a_target_type') appears in `a_invariant' and is viewed from `a_context'
354 -- (`a_invariant' is an invariant of the root context of `a_context').
355 -- Alter `a_context' so that it represents the type of `a_expression'.
356 -- Set `has_fatal_error' if a fatal error occurred.
357 --
358 -- Note that it is assumed that `a_invariant' has been successfully checked
359 -- in the context of `a_context.root_context' (using ET_FEATURE_CHECKER for example).
360 -- Otherwise internal errors may be reported (using ET_ERROR_HANDLER.report_giaaa_error)
361 -- if `a_invariant' has not been checked or if `internal_error_enabled' has been set.
362 require
363 a_expression_not_void: a_expression /= Void
364 a_invariant_not_void: a_invariant /= Void
365 a_context_not_void: a_context /= Void
366 a_current_class_preparsed: a_context.root_context.base_class.is_preparsed
367 a_target_type_not_void: a_target_type /= Void
368 valid_target_context: a_target_type.is_valid_context
369 local
370 old_feature: ET_STANDALONE_CLOSURE
371 old_feature_impl: ET_STANDALONE_CLOSURE
372 old_class: ET_CLASS
373 old_class_impl: ET_CLASS
374 old_type: ET_BASE_TYPE
375 old_target_type: ET_TYPE_CONTEXT
376 old_context: ET_NESTED_TYPE_CONTEXT
377 old_in_assertion: BOOLEAN
378 old_in_invariant: BOOLEAN
379 do
380 reset_fatal_error (False)
381 old_feature_impl := current_feature_impl
382 current_feature_impl := a_invariant
383 old_feature := current_feature
384 current_feature := a_invariant
385 old_type := current_type
386 current_type := a_context.root_context
387 old_class := current_class
388 current_class := current_type.base_class
389 old_class_impl := current_class_impl
390 current_class_impl := a_invariant.implementation_class
391 old_context := current_context
392 current_context := a_context
393 old_target_type := current_target_type
394 current_target_type := a_target_type
395 old_in_assertion := in_assertion
396 in_assertion := True
397 old_in_invariant := in_invariant
398 in_invariant := True
399 current_universe_impl.resolve_unfolded_tuple_actual_parameters
400 a_expression.process (Current)
401 in_assertion := old_in_assertion
402 in_invariant := old_in_invariant
403 current_target_type := old_target_type
404 current_context := old_context
405 current_class := old_class
406 current_type := old_type
407 current_class_impl := old_class_impl
408 current_feature := old_feature
409 current_feature_impl := old_feature_impl
410 end
411
412 feature -- Status report
413
414 internal_error_enabled: BOOLEAN
415 -- Should an internal error be reported even when errors have already
416 -- been reported on the feature being processed?
417
418 feature -- Status setting
419
420 set_internal_error_enabled (b: BOOLEAN)
421 -- Set `internal_error_enabled' to `b'.
422 do
423 internal_error_enabled := b
424 ensure
425 internal_error_enabled_set: internal_error_enabled = b
426 end
427
428 feature {NONE} -- Expression processing
429
430 find_across_cursor_type (a_name: ET_IDENTIFIER; a_context: ET_NESTED_TYPE_CONTEXT)
431 -- `a_context' represents the type in which `a_name' appears.
432 -- It will be altered on exit to represent the type of `a_name'.
433 -- Set `has_fatal_error' if a fatal error occurred.
434 require
435 a_name_not_void: a_name /= Void
436 a_name_object_test_local: a_name.is_across_cursor
437 a_context_not_void: a_context /= Void
438 local
439 l_seed: INTEGER
440 l_across_component: ET_ACROSS_COMPONENT
441 l_across_components: detachable ET_ACROSS_COMPONENT_LIST
442 do
443 reset_fatal_error (False)
444 l_seed := a_name.seed
445 l_across_components := current_closure_impl.across_components
446 if l_across_components = Void then
447 -- Internal error.
448 -- This error should have already been reported when checking
449 -- `current_feature' (using ET_FEATURE_CHECKER for example).
450 set_fatal_error
451 if internal_error_enabled or not current_class.has_implementation_error then
452 error_handler.report_giaaa_error
453 end
454 elseif l_seed < 1 or l_seed > l_across_components.count then
455 -- Internal error.
456 -- This error should have already been reported when checking
457 -- `current_feature' (using ET_FEATURE_CHECKER for example).
458 set_fatal_error
459 if internal_error_enabled or not current_class.has_implementation_error then
460 error_handler.report_giaaa_error
461 end
462 else
463 l_across_component := l_across_components.across_component (l_seed)
464 find_expression_type (l_across_component.new_cursor_expression, a_context, current_system.detachable_any_type)
465 end
466 end
467
468 find_across_expression_type (an_expression: ET_ACROSS_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
469 -- `a_context' represents the type in which `an_expression' appears.
470 -- It will be altered on exit to represent the type of `an_expression'.
471 -- Set `has_fatal_error' if a fatal error occurred.
472 require
473 an_expression_not_void: an_expression /= Void
474 a_context_not_void: a_context /= Void
475 do
476 reset_fatal_error (False)
477 a_context.force_last (current_universe_impl.boolean_type)
478 end
479
480 find_binary_integer_constant_type (a_constant: ET_BINARY_INTEGER_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
481 -- `a_context' represents the type in which `a_constant' appears.
482 -- It will be altered on exit to represent the type of `a_constant'.
483 -- Set `has_fatal_error' if a fatal error occurred.
484 require
485 a_constant_not_void: a_constant /= Void
486 a_context_not_void: a_context /= Void
487 do
488 find_integer_constant_type (a_constant, a_context)
489 end
490
491 find_bracket_expression_type (an_expression: ET_BRACKET_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
492 -- `a_context' represents the type in which `an_expression' appears.
493 -- It will be altered on exit to represent the type of `an_expression'.
494 -- Set `has_fatal_error' if a fatal error occurred.
495 require
496 an_expression_not_void: an_expression /= Void
497 a_context_not_void: a_context /= Void
498 do
499 find_qualified_call_expression_type (an_expression, a_context)
500 end
501
502 find_c1_character_constant_type (a_constant: ET_C1_CHARACTER_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
503 -- `a_context' represents the type in which `a_constant' appears.
504 -- It will be altered on exit to represent the type of `a_constant'.
505 -- Set `has_fatal_error' if a fatal error occurred.
506 require
507 a_constant_not_void: a_constant /= Void
508 a_context_not_void: a_context /= Void
509 do
510 find_character_constant_type (a_constant, a_context)
511 end
512
513 find_c2_character_constant_type (a_constant: ET_C2_CHARACTER_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
514 -- `a_context' represents the type in which `a_constant' appears.
515 -- It will be altered on exit to represent the type of `a_constant'.
516 -- Set `has_fatal_error' if a fatal error occurred.
517 require
518 a_constant_not_void: a_constant /= Void
519 a_context_not_void: a_context /= Void
520 do
521 find_character_constant_type (a_constant, a_context)
522 end
523
524 find_c3_character_constant_type (a_constant: ET_C3_CHARACTER_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
525 -- `a_context' represents the type in which `a_constant' appears.
526 -- It will be altered on exit to represent the type of `a_constant'.
527 -- Set `has_fatal_error' if a fatal error occurred.
528 require
529 a_constant_not_void: a_constant /= Void
530 a_context_not_void: a_context /= Void
531 do
532 find_character_constant_type (a_constant, a_context)
533 end
534
535 find_character_constant_type (a_constant: ET_CHARACTER_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
536 -- `a_context' represents the type in which `a_constant' appears.
537 -- It will be altered on exit to represent the type of `a_constant'.
538 -- Set `has_fatal_error' if a fatal error occurred.
539 require
540 a_constant_not_void: a_constant /= Void
541 a_context_not_void: a_context /= Void
542 local
543 l_type: detachable ET_CLASS_TYPE
544 do
545 reset_fatal_error (False)
546 l_type := a_constant.type
547 if l_type = Void then
548 l_type := current_universe_impl.character_type
549 end
550 a_context.force_last (l_type)
551 end
552
553 find_convert_builtin_expression_type (an_expression: ET_CONVERT_BUILTIN_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
554 -- `a_context' represents the type in which `an_expression' appears.
555 -- It will be altered on exit to represent the type of `an_expression'.
556 -- Set `has_fatal_error' if a fatal error occurred.
557 require
558 an_expression_not_void: an_expression /= Void
559 a_context_not_void: a_context /= Void
560 local
561 l_type: ET_TYPE
562 do
563 reset_fatal_error (False)
564 l_type := an_expression.type
565 a_context.force_last (l_type)
566 end
567
568 find_convert_from_expression_type (an_expression: ET_CONVERT_FROM_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
569 -- `a_context' represents the type in which `an_expression' appears.
570 -- It will be altered on exit to represent the type of `an_expression'.
571 -- Set `has_fatal_error' if a fatal error occurred.
572 require
573 an_expression_not_void: an_expression /= Void
574 a_context_not_void: a_context /= Void
575 do
576 find_creation_expression_type (an_expression, a_context)
577 end
578
579 find_convert_to_expression_type (an_expression: ET_CONVERT_TO_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
580 -- `a_context' represents the type in which `an_expression' appears.
581 -- It will be altered on exit to represent the type of `an_expression'.
582 -- Set `has_fatal_error' if a fatal error occurred.
583 require
584 an_expression_not_void: an_expression /= Void
585 a_context_not_void: a_context /= Void
586 do
587 find_qualified_call_expression_type (an_expression, a_context)
588 end
589
590 find_create_expression_type (an_expression: ET_CREATION_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
591 -- `a_context' represents the type in which `an_expression' appears.
592 -- It will be altered on exit to represent the type of `an_expression'.
593 -- Set `has_fatal_error' if a fatal error occurred.
594 require
595 an_expression_not_void: an_expression /= Void
596 a_context_not_void: a_context /= Void
597 do
598 find_creation_expression_type (an_expression, a_context)
599 end
600
601 find_creation_expression_type (an_expression: ET_CREATION_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
602 -- `a_context' represents the type in which `an_expression' appears.
603 -- It will be altered on exit to represent the type of `an_expression'.
604 -- Set `has_fatal_error' if a fatal error occurred.
605 require
606 an_expression_not_void: an_expression /= Void
607 a_context_not_void: a_context /= Void
608 local
609 l_creation_type: ET_TYPE
610 do
611 reset_fatal_error (False)
612 l_creation_type := an_expression.type
613 a_context.force_last (l_creation_type)
614 end
615
616 find_current_type (an_expression: ET_CURRENT; a_context: ET_NESTED_TYPE_CONTEXT)
617 -- `a_context' represents the type in which `an_expression' appears.
618 -- It will be altered on exit to represent the type of `an_expression'.
619 -- Set `has_fatal_error' if a fatal error occurred.
620 require
621 an_expression_not_void: an_expression /= Void
622 a_context_not_void: a_context /= Void
623 do
624 reset_fatal_error (False)
625 a_context.force_last (current_type)
626 end
627
628 find_current_address_type (an_expression: ET_CURRENT_ADDRESS; a_context: ET_NESTED_TYPE_CONTEXT)
629 -- `a_context' represents the type in which `an_expression' appears.
630 -- It will be altered on exit to represent the type of `an_expression'.
631 -- Set `has_fatal_error' if a fatal error occurred.
632 require
633 an_expression_not_void: an_expression /= Void
634 a_context_not_void: a_context /= Void
635 local
636 l_typed_pointer_class: ET_NAMED_CLASS
637 l_typed_pointer_type: ET_CLASS_TYPE
638 do
639 reset_fatal_error (False)
640 l_typed_pointer_type := current_universe_impl.typed_pointer_like_current_type
641 l_typed_pointer_class := l_typed_pointer_type.named_base_class
642 if l_typed_pointer_class.actual_class.is_preparsed then
643 -- Class TYPED_POINTER has been found in the universe.
644 -- Use ISE's implementation: the type of '$Current' is 'TYPED_POINTER [like Current]'.
645 a_context.force_last (l_typed_pointer_type)
646 else
647 -- Use the ETL2 implementation: the type of '$Current' is POINTER.
648 a_context.force_last (current_universe_impl.pointer_type)
649 end
650 end
651
652 find_equality_expression_type (an_expression: ET_EQUALITY_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
653 -- `a_context' represents the type in which `an_expression' appears.
654 -- It will be altered on exit to represent the type of `an_expression'.
655 -- Set `has_fatal_error' if a fatal error occurred.
656 require
657 an_expression_not_void: an_expression /= Void
658 a_context_not_void: a_context /= Void
659 do
660 reset_fatal_error (False)
661 a_context.force_last (current_universe_impl.boolean_type)
662 end
663
664 find_expression_address_type (an_expression: ET_EXPRESSION_ADDRESS; a_context: ET_NESTED_TYPE_CONTEXT)
665 -- `a_context' represents the type in which `an_expression' appears.
666 -- It will be altered on exit to represent the type of `an_expression'.
667 -- Set `has_fatal_error' if a fatal error occurred.
668 require
669 an_expression_not_void: an_expression /= Void
670 a_context_not_void: a_context /= Void
671 local
672 l_typed_pointer_class: ET_NAMED_CLASS
673 l_typed_pointer_type: ET_CLASS_TYPE
674 do
675 reset_fatal_error (False)
676 l_typed_pointer_type := current_universe_impl.typed_pointer_like_current_type
677 l_typed_pointer_class := l_typed_pointer_type.named_base_class
678 if l_typed_pointer_class.actual_class.is_preparsed then
679 -- Class TYPED_POINTER has been found in the universe.
680 -- Use ISE's implementation: the type of '$(expr)' is 'TYPED_POINTER [<type-of-expr>]'.
681 find_expression_type (an_expression.expression, a_context, current_system.detachable_any_type)
682 if not has_fatal_error then
683 -- TODO: the type might not be accurate if a_context.count /= 1
684 -- Same thing in ET_FEATURE_CHECKER
685 a_context.force_last (l_typed_pointer_type)
686 end
687 else
688 -- Use the ETL2 implementation: the type of '$(expr)' is POINTER.
689 a_context.force_last (current_universe_impl.pointer_type)
690 end
691 end
692
693 find_false_constant_type (a_constant: ET_FALSE_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
694 -- `a_context' represents the type in which `a_constant' appears.
695 -- It will be altered on exit to represent the type of `a_constant'.
696 -- Set `has_fatal_error' if a fatal error occurred.
697 require
698 a_constant_not_void: a_constant /= Void
699 a_context_not_void: a_context /= Void
700 do
701 reset_fatal_error (False)
702 a_context.force_last (current_universe_impl.boolean_type)
703 end
704
705 find_feature_address_type (an_expression: ET_FEATURE_ADDRESS; a_context: ET_NESTED_TYPE_CONTEXT)
706 -- `a_context' represents the type in which `an_expression' appears.
707 -- It will be altered on exit to represent the type of `an_expression'.
708 -- Set `has_fatal_error' if a fatal error occurred.
709 require
710 an_expression_not_void: an_expression /= Void
711 a_context_not_void: a_context /= Void
712 local
713 l_procedure: detachable ET_PROCEDURE
714 l_query: detachable ET_QUERY
715 l_name: ET_FEATURE_NAME
716 l_seed: INTEGER
717 l_arguments: detachable ET_FORMAL_ARGUMENT_LIST
718 l_argument: ET_FORMAL_ARGUMENT
719 l_type: detachable ET_TYPE
720 l_locals: detachable ET_LOCAL_VARIABLE_LIST
721 l_local: ET_LOCAL_VARIABLE
722 l_typed_pointer_class: ET_NAMED_CLASS
723 l_typed_pointer_type: ET_CLASS_TYPE
724 l_object_test: ET_NAMED_OBJECT_TEST
725 l_object_tests: detachable ET_OBJECT_TEST_LIST
726 l_across_component: ET_ACROSS_COMPONENT
727 l_across_components: detachable ET_ACROSS_COMPONENT_LIST
728 l_class_impl: ET_CLASS
729 do
730 reset_fatal_error (False)
731 l_name := an_expression.name
732 l_seed := l_name.seed
733 if l_seed <= 0 then
734 -- This error should have already been reported when checking
735 -- `current_feature' (using ET_FEATURE_CHECKER for example).
736 set_fatal_error
737 if internal_error_enabled or not current_class.has_implementation_error then
738 error_handler.report_giaaa_error
739 end
740 elseif l_name.is_argument then
741 -- This is of the form '$argument'.
742 if attached current_inline_agent as l_current_inline_agent then
743 l_arguments := l_current_inline_agent.formal_arguments
744 l_class_impl := current_class_impl
745 else
746 -- Use arguments of `current_feature' instead of `current_feature_impl'
747 -- because when processing inherited assertions the types of signature
748 -- should be those of the version of the feature in the current class.
749 -- For example:
750 -- deferred class A
751 -- feature
752 -- f (a: ANY)
753 -- require
754 -- pre: g ($a)
755 -- deferred
756 -- end
757 -- g (a: TYPED_POINTER [ANY]): BOOLEAN deferred end
758 -- end
759 -- class B
760 -- inherit
761 -- A
762 -- feature
763 -- f (a: STRING) do ... end
764 -- g (a: TYPED_POINTER [STRING]): BOOLEAN do ... end
765 -- end
766 -- `a' in the inherited precondition "pre" should be considered
767 -- of type STRING (and not ANY) is class B.
768 --
769 -- Use arguments of implementation feature because the types
770 -- of the signature of `current_feature' might not have been
771 -- resolved for `current_class' (when processing precursors
772 -- in the context of current class).
773 l_arguments := current_feature.implementation_feature.arguments
774 l_class_impl := current_feature.implementation_class
775 end
776 if l_arguments = Void then
777 -- Internal error.
778 -- This error should have already been reported when checking
779 -- `current_feature' (using ET_FEATURE_CHECKER for example).
780 set_fatal_error
781 if internal_error_enabled or not current_class.has_implementation_error then
782 error_handler.report_giaaa_error
783 end
784 elseif l_seed < 1 or l_seed > l_arguments.count then
785 -- Internal error.
786 -- This error should have already been reported when checking
787 -- `current_feature' (using ET_FEATURE_CHECKER for example).
788 set_fatal_error
789 if internal_error_enabled or not current_class.has_implementation_error then
790 error_handler.report_giaaa_error
791 end
792 else
793 l_argument := l_arguments.formal_argument (l_seed)
794 l_typed_pointer_type := current_universe_impl.typed_pointer_like_current_type
795 l_typed_pointer_class := l_typed_pointer_type.named_base_class
796 if l_typed_pointer_class.actual_class.is_preparsed then
797 -- Class TYPED_POINTER has been found in the universe.
798 -- Use ISE's implementation: the type of '$argument' is 'TYPED_POINTER [<type-of-argument>]'.
799 l_type := l_argument.type
800 a_context.force_last (l_type)
801 a_context.force_last (l_typed_pointer_type)
802 else
803 -- Use the ETL2 implementation: the type of '$argument' is POINTER.
804 a_context.force_last (current_universe_impl.pointer_type)
805 end
806 end
807 elseif l_name.is_local then
808 -- This is of the form '$local'.
809 l_locals := current_closure_impl.locals
810 if l_locals = Void then
811 -- Internal error.
812 -- This error should have already been reported when checking
813 -- `current_feature' (using ET_FEATURE_CHECKER for example).
814 set_fatal_error
815 if internal_error_enabled or not current_class.has_implementation_error then
816 error_handler.report_giaaa_error
817 end
818 elseif l_seed < 1 or l_seed > l_locals.count then
819 -- Internal error.
820 -- This error should have already been reported when checking
821 -- `current_feature' (using ET_FEATURE_CHECKER for example).
822 set_fatal_error
823 if internal_error_enabled or not current_class.has_implementation_error then
824 error_handler.report_giaaa_error
825 end
826 else
827 l_local := l_locals.local_variable (l_seed)
828 l_typed_pointer_type := current_universe_impl.typed_pointer_like_current_type
829 l_typed_pointer_class := l_typed_pointer_type.named_base_class
830 if l_typed_pointer_class.actual_class.is_preparsed then
831 -- Class TYPED_POINTER has been found in the universe.
832 -- Use ISE's implementation: the type of '$local' is 'TYPED_POINTER [<type-of-local>]'.
833 l_type := l_local.type
834 a_context.force_last (l_type)
835 a_context.force_last (l_typed_pointer_type)
836 else
837 -- Use the ETL2 implementation: the type of '$local' is POINTER.
838 a_context.force_last (current_universe_impl.pointer_type)
839 end
840 end
841 elseif l_name.is_object_test_local then
842 l_object_tests := current_closure_impl.object_tests
843 if l_object_tests = Void then
844 -- Internal error.
845 -- This error should have already been reported when checking
846 -- `current_feature' (using ET_FEATURE_CHECKER for example).
847 set_fatal_error
848 if internal_error_enabled or not current_class.has_implementation_error then
849 error_handler.report_giaaa_error
850 end
851 elseif l_seed < 1 or l_seed > l_object_tests.count then
852 -- Internal error.
853 -- This error should have already been reported when checking
854 -- `current_feature' (using ET_FEATURE_CHECKER for example).
855 set_fatal_error
856 if internal_error_enabled or not current_class.has_implementation_error then
857 error_handler.report_giaaa_error
858 end
859 else
860 l_object_test := l_object_tests.object_test (l_seed)
861 check is_object_test_local: attached {ET_IDENTIFIER} l_name end
862 l_typed_pointer_type := current_universe_impl.typed_pointer_like_current_type
863 l_typed_pointer_class := l_typed_pointer_type.named_base_class
864 if l_typed_pointer_class.actual_class.is_preparsed then
865 -- Class TYPED_POINTER has been found in the universe.
866 -- Use ISE's implementation: the type of '$object_test_local' is
867 -- 'TYPED_POINTER [<type-of-object_test_local>]'.
868 l_type := l_object_test.type
869 if l_type /= Void then
870 a_context.force_last (l_type)
871 a_context.force_last (l_typed_pointer_type)
872 else
873 find_expression_type (l_object_test.expression, a_context, current_system.detachable_any_type)
874 if not has_fatal_error then
875 a_context.force_last (l_typed_pointer_type)
876 end
877 end
878 else
879 -- Use the ETL2 implementation: the type of '$object_test_local' is POINTER.
880 a_context.force_last (current_universe_impl.pointer_type)
881 end
882 end
883 elseif l_name.is_across_cursor then
884 l_across_components := current_closure_impl.across_components
885 if l_across_components = Void then
886 -- Internal error.
887 -- This error should have already been reported when checking
888 -- `current_feature' (using ET_FEATURE_CHECKER for example).
889 set_fatal_error
890 if internal_error_enabled or not current_class.has_implementation_error then
891 error_handler.report_giaaa_error
892 end
893 elseif l_seed < 1 or l_seed > l_across_components.count then
894 -- Internal error.
895 -- This error should have already been reported when checking
896 -- `current_feature' (using ET_FEATURE_CHECKER for example).
897 set_fatal_error
898 if internal_error_enabled or not current_class.has_implementation_error then
899 error_handler.report_giaaa_error
900 end
901 else
902 l_across_component := l_across_components.across_component (l_seed)
903 check is_across_cursor: attached {ET_IDENTIFIER} l_name end
904 l_typed_pointer_type := current_universe_impl.typed_pointer_like_current_type
905 l_typed_pointer_class := l_typed_pointer_type.named_base_class
906 if l_typed_pointer_class.actual_class.is_preparsed then
907 -- Class TYPED_POINTER has been found in the universe.
908 -- Use ISE's implementation: the type of '$across_cursor' is
909 -- 'TYPED_POINTER [<type-of-across-cursor>]'.
910 find_expression_type (l_across_component.new_cursor_expression, a_context, current_system.detachable_any_type)
911 if not has_fatal_error then
912 a_context.force_last (l_typed_pointer_type)
913 end
914 else
915 -- Use the ETL2 implementation: the type of '$across_cursor' is POINTER.
916 a_context.force_last (current_universe_impl.pointer_type)
917 end
918 end
919 else
920 -- This is of the form '$feature_name'.
921 l_procedure := current_class.seeded_procedure (l_seed)
922 if l_procedure /= Void then
923 -- $feature_name is of type POINTER, even
924 -- in ISE and its TYPED_POINTER support.
925 a_context.force_last (current_universe_impl.pointer_type)
926 else
927 l_query := current_class.seeded_query (l_seed)
928 if l_query /= Void then
929 if l_query.is_attribute then
930 l_typed_pointer_type := current_universe_impl.typed_pointer_like_current_type
931 l_typed_pointer_class := l_typed_pointer_type.named_base_class
932 if l_typed_pointer_class.actual_class.is_preparsed then
933 -- Class TYPED_POINTER has been found in the universe.
934 -- Use ISE's implementation: the type of '$attribute' is 'TYPED_POINTER [<type-of-attribute>]'.
935 l_type := l_query.type
936 a_context.force_last (l_type)
937 a_context.force_last (l_typed_pointer_type)
938 else
939 -- Use the ETL2 implementation: the type of '$attribute' is POINTER.
940 a_context.force_last (current_universe_impl.pointer_type)
941 end
942 else
943 -- $feature_name is of type POINTER, even
944 -- in ISE and its TYPED_POINTER support.
945 a_context.force_last (current_universe_impl.pointer_type)
946 end
947 else
948 -- Internal error: if we got a seed, `l_query' should not be void.
949 -- This error should have already been reported when checking
950 -- `current_feature' (using ET_FEATURE_CHECKER for example).
951 set_fatal_error
952 if internal_error_enabled or not current_class.has_implementation_error then
953 error_handler.report_giaaa_error
954 end
955 end
956 end
957 end
958 end
959
960 find_formal_argument_type (a_name: ET_IDENTIFIER; a_context: ET_NESTED_TYPE_CONTEXT)
961 -- `a_context' represents the type in which `a_name' appears.
962 -- It will be altered on exit to represent the type of `a_name'.
963 -- Set `has_fatal_error' if a fatal error occurred.
964 require
965 a_name_not_void: a_name /= Void
966 a_name_argument: a_name.is_argument
967 a_context_not_void: a_context /= Void
968 local
969 l_seed: INTEGER
970 l_arguments: detachable ET_FORMAL_ARGUMENT_LIST
971 l_formal: ET_FORMAL_ARGUMENT
972 l_type: ET_TYPE
973 do
974 reset_fatal_error (False)
975 if attached current_inline_agent as l_current_inline_agent then
976 l_arguments := l_current_inline_agent.formal_arguments
977 else
978 -- Use arguments of `current_feature' instead of `current_feature_impl'
979 -- because when processing inherited assertions the types of signature
980 -- should be those of the version of the feature in the current class.
981 -- For example:
982 -- deferred class A
983 -- feature
984 -- f (a: ANY)
985 -- require
986 -- pre: g (a)
987 -- deferred
988 -- end
989 -- g (a: ANY): BOOLEAN deferred end
990 -- end
991 -- class B
992 -- inherit
993 -- A
994 -- feature
995 -- f (a: STRING) do ... end
996 -- g (a: STRING): BOOLEAN do ... end
997 -- end
998 -- `a' in the inherited precondition "pre" should be considered
999 -- of type STRING (and not ANY) is class B.
1000 l_arguments := current_feature.arguments
1001 end
1002 l_seed := a_name.seed
1003 if l_arguments = Void then
1004 -- Internal error.
1005 -- This error should have already been reported when checking
1006 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1007 set_fatal_error
1008 if internal_error_enabled or not current_class.has_implementation_error then
1009 error_handler.report_giaaa_error
1010 end
1011 elseif l_seed < 1 or l_seed > l_arguments.count then
1012 -- Internal error.
1013 -- This error should have already been reported when checking
1014 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1015 set_fatal_error
1016 if internal_error_enabled or not current_class.has_implementation_error then
1017 error_handler.report_giaaa_error
1018 end
1019 else
1020 l_formal := l_arguments.formal_argument (l_seed)
1021 l_type := l_formal.type
1022 a_context.force_last (l_type)
1023 end
1024 end
1025
1026 find_hexadecimal_integer_constant_type (a_constant: ET_HEXADECIMAL_INTEGER_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
1027 -- `a_context' represents the type in which `a_constant' appears.
1028 -- It will be altered on exit to represent the type of `a_constant'.
1029 -- Set `has_fatal_error' if a fatal error occurred.
1030 require
1031 a_constant_not_void: a_constant /= Void
1032 a_context_not_void: a_context /= Void
1033 do
1034 find_integer_constant_type (a_constant, a_context)
1035 end
1036
1037 find_infix_cast_expression_type (an_expression: ET_INFIX_CAST_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
1038 -- `a_context' represents the type in which `an_expression' appears.
1039 -- It will be altered on exit to represent the type of `an_expression'.
1040 -- Set `has_fatal_error' if a fatal error occurred.
1041 require
1042 an_expression_not_void: an_expression /= Void
1043 a_context_not_void: a_context /= Void
1044 local
1045 l_type: ET_TYPE
1046 do
1047 reset_fatal_error (False)
1048 l_type := an_expression.type
1049 a_context.force_last (l_type)
1050 end
1051
1052 find_infix_expression_type (an_expression: ET_INFIX_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
1053 -- `a_context' represents the type in which `an_expression' appears.
1054 -- It will be altered on exit to represent the type of `an_expression'.
1055 -- Set `has_fatal_error' if a fatal error occurred.
1056 require
1057 an_expression_not_void: an_expression /= Void
1058 a_context_not_void: a_context /= Void
1059 local
1060 l_name: ET_CALL_NAME
1061 l_target: ET_EXPRESSION
1062 l_class: ET_CLASS
1063 l_query: detachable ET_QUERY
1064 l_type: ET_TYPE
1065 l_seed: INTEGER
1066 l_actual: ET_EXPRESSION
1067 l_formal_context: ET_NESTED_TYPE_CONTEXT
1068 do
1069 reset_fatal_error (False)
1070 l_name := an_expression.name
1071 l_target := an_expression.left
1072 l_seed := l_name.seed
1073 find_expression_type (l_target, a_context, current_system.detachable_any_type)
1074 if has_fatal_error then
1075 -- Do nothing.
1076 elseif l_seed <= 0 then
1077 -- This error should have already been reported when checking
1078 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1079 set_fatal_error
1080 if internal_error_enabled or not current_class.has_implementation_error then
1081 error_handler.report_giaaa_error
1082 end
1083 else
1084 l_class := a_context.base_class
1085 l_query := l_class.seeded_query (l_seed)
1086 if l_query = Void then
1087 -- Internal error: if we got a seed, the `l_query' should not be void.
1088 -- This error should have already been reported when checking
1089 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1090 set_fatal_error
1091 if internal_error_enabled or not current_class.has_implementation_error then
1092 error_handler.report_giaaa_error
1093 end
1094 else
1095 -- TODO: like argument (the following is just a workaround
1096 -- which works only in a limited number of cases, in particular
1097 -- for ANY.clone).
1098 l_type := l_query.type
1099 if attached {ET_LIKE_FEATURE} l_type as l_like and then l_like.is_like_argument and then attached l_query.arguments as l_formal_arguments and then l_formal_arguments.count = 1 then
1100 l_formal_context := new_context (current_type)
1101 l_formal_context.copy_type_context (a_context)
1102 l_formal_context.force_last (l_formal_arguments.formal_argument (1).type)
1103 a_context.wipe_out
1104 l_actual := an_expression.right
1105 find_expression_type (l_actual, a_context, l_formal_context)
1106 free_context (l_formal_context)
1107 if not has_fatal_error then
1108 if attached {ET_CONVERT_EXPRESSION} l_actual as l_convert_expression then
1109 if attached {ET_BUILTIN_CONVERT_FEATURE} l_convert_expression.convert_feature as l_builtin then
1110 -- Needed for compatibility with ISE 5.6.0610:
1111 -- a formal generic parameter either conforms or converts to its constraint,
1112 -- then the converted version can still be chained with a conformance to
1113 -- `current_target_type'.
1114 a_context.reset (current_type)
1115 a_context.force_last (l_builtin.type)
1116 end
1117 end
1118 end
1119 else
1120 a_context.force_last (l_type)
1121 end
1122 end
1123 end
1124 end
1125
1126 find_integer_constant_type (a_constant: ET_INTEGER_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
1127 -- `a_context' represents the type in which `a_constant' appears.
1128 -- It will be altered on exit to represent the type of `a_constant'.
1129 -- Set `has_fatal_error' if a fatal error occurred.
1130 require
1131 a_constant_not_void: a_constant /= Void
1132 a_context_not_void: a_context /= Void
1133 local
1134 l_type: detachable ET_CLASS_TYPE
1135 do
1136 reset_fatal_error (False)
1137 l_type := a_constant.type
1138 if l_type = Void then
1139 l_type := current_universe_impl.integer_type
1140 end
1141 a_context.force_last (l_type)
1142 end
1143
1144 find_local_variable_type (a_name: ET_IDENTIFIER; a_context: ET_NESTED_TYPE_CONTEXT)
1145 -- `a_context' represents the type in which `a_name' appears.
1146 -- It will be altered on exit to represent the type of `a_name'.
1147 -- Set `has_fatal_error' if a fatal error occurred.
1148 require
1149 a_name_not_void: a_name /= Void
1150 a_name_local: a_name.is_local
1151 a_context_not_void: a_context /= Void
1152 local
1153 l_seed: INTEGER
1154 l_locals: detachable ET_LOCAL_VARIABLE_LIST
1155 l_local: ET_LOCAL_VARIABLE
1156 l_type: ET_TYPE
1157 do
1158 reset_fatal_error (False)
1159 l_locals := current_closure_impl.locals
1160 l_seed := a_name.seed
1161 if l_locals = Void then
1162 -- Internal error.
1163 -- This error should have already been reported when checking
1164 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1165 set_fatal_error
1166 if internal_error_enabled or not current_class.has_implementation_error then
1167 error_handler.report_giaaa_error
1168 end
1169 elseif l_seed < 1 or l_seed > l_locals.count then
1170 -- Internal error.
1171 -- This error should have already been reported when checking
1172 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1173 set_fatal_error
1174 if internal_error_enabled or not current_class.has_implementation_error then
1175 error_handler.report_giaaa_error
1176 end
1177 else
1178 l_local := l_locals.local_variable (l_seed)
1179 l_type := l_local.type
1180 a_context.force_last (l_type)
1181 end
1182 end
1183
1184 find_manifest_array_type (an_expression: ET_MANIFEST_ARRAY; a_context: ET_NESTED_TYPE_CONTEXT)
1185 -- `a_context' represents the type in which `an_expression' appears.
1186 -- It will be altered on exit to represent the type of `an_expression'.
1187 -- Set `has_fatal_error' if a fatal error occurred.
1188 require
1189 an_expression_not_void: an_expression /= Void
1190 a_context_not_void: a_context /= Void
1191 local
1192 i, nb: INTEGER
1193 had_error: BOOLEAN
1194 hybrid_type: BOOLEAN
1195 l_is_item_type_attached: BOOLEAN
1196 array_class: ET_NAMED_CLASS
1197 l_array_type: detachable ET_CLASS_TYPE
1198 l_array_parameters: detachable ET_ACTUAL_PARAMETERS
1199 l_array_parameter: detachable ET_TYPE
1200 l_detachable_any_type: ET_CLASS_TYPE
1201 l_expression_context: ET_NESTED_TYPE_CONTEXT
1202 l_parameter_context: ET_NESTED_TYPE_CONTEXT
1203 l_item_context: detachable ET_NESTED_TYPE_CONTEXT
1204 l_old_item_context: ET_NESTED_TYPE_CONTEXT
1205 do
1206 reset_fatal_error (False)
1207 array_class := current_universe_impl.array_any_type.named_base_class
1208 -- Try to find out whether the expected type (i.e. `current_target_type')
1209 -- for the manifest array is 'ARRAY [...]'. If this is the case then the
1210 -- manifest array will be created of that type.
1211 if attached {ET_CLASS_TYPE} current_target_type.named_type as l_class_type then
1212 l_array_type := l_class_type
1213 end
1214 if l_array_type /= Void and then l_array_type.base_class.is_array_class then
1215 l_array_parameters := l_array_type.actual_parameters
1216 if l_array_parameters /= Void and then l_array_parameters.count = 1 then
1217 l_array_parameter := l_array_parameters.type (1)
1218 end
1219 end
1220 nb := an_expression.count
1221 if l_array_parameter /= Void then
1222 -- The expected type for the manifest array is 'ARRAY [...]'.
1223 -- So the manifest array will be created of that type.
1224 l_parameter_context := new_context (current_type)
1225 l_parameter_context.force_last (l_array_parameter)
1226 l_expression_context := new_context (current_type)
1227 from i := 1 until i > nb loop
1228 find_expression_type (an_expression.expression (i), l_expression_context, l_parameter_context)
1229 if has_fatal_error then
1230 had_error := True
1231 else
1232 if l_array_type /= Void and then not l_expression_context.conforms_to_type (l_array_parameter, current_type) then
1233 -- The type of this item does not conform to the type of
1234 -- the parameter of the expected array type. Try to see
1235 -- if it converts to it.
1236 if type_checker.convert_feature (l_expression_context, l_parameter_context) = Void then
1237 -- It does not conform nor convert. We are out of luck
1238 -- and revise our position: We will have to find another
1239 -- way to determine the type of the array, and a validity
1240 -- error will be reported when we try to pass this array as
1241 -- argument or in an assignment with a type that does
1242 -- not conform nor convert to the expected type.
1243 -- To determine the type of the array, we will now
1244 -- try to see if all items have the same type. If so then the
1245 -- type of the manifest array will be an array of that type.
1246 -- Otherwise we are out of luck and will consider that it is
1247 -- an 'ARRAY [ANY]' or an 'ARRAY [detachable ANY]' if not all
1248 -- items are attached.
1249 -- TODO: remove convert features from AST.
1250 l_array_type := Void
1251 else
1252 -- TODO: insert convert feature in AST.
1253 end
1254 end
1255 if not had_error then
1256 if l_item_context = Void then
1257 l_item_context := l_expression_context
1258 l_expression_context := new_context (current_type)
1259 elseif not hybrid_type then
1260 if l_expression_context.conforms_to_context (l_item_context) then
1261 -- The type of the current item conforms to the type
1262 -- retained so far. Keep the old type.
1263 elseif l_item_context.conforms_to_context (l_expression_context) then
1264 -- The type retained so far conforms to the type of the
1265 -- current item. Retain this new type.
1266 l_old_item_context := l_item_context
1267 l_item_context := l_expression_context
1268 l_expression_context := l_old_item_context
1269 else
1270 hybrid_type := True
1271 l_is_item_type_attached := l_item_context.is_type_attached
1272 if l_is_item_type_attached then
1273 l_is_item_type_attached := l_expression_context.is_type_attached
1274 end
1275 end
1276 elseif l_is_item_type_attached then
1277 l_is_item_type_attached := l_expression_context.is_type_attached
1278 end
1279 end
1280 end
1281 l_expression_context.wipe_out
1282 i := i + 1
1283 end
1284 free_context (l_expression_context)
1285 free_context (l_parameter_context)
1286 else
1287 -- Try to see if the types of all items conform to one of them.
1288 -- If so then the type of the manifest array will be an array of
1289 -- that type. Otherwise we are out of luck and will consider that
1290 -- it is an 'ARRAY [ANY]' or an 'ARRAY [detachable ANY]' if not
1291 -- all items are attached.
1292 l_array_type := Void
1293 l_detachable_any_type := current_system.detachable_any_type
1294 l_expression_context := new_context (current_type)
1295 from i := 1 until i > nb loop
1296 find_expression_type (an_expression.expression (i), l_expression_context, l_detachable_any_type)
1297 if has_fatal_error then
1298 had_error := True
1299 elseif not had_error then
1300 if l_item_context = Void then
1301 l_item_context := l_expression_context
1302 l_expression_context := new_context (current_type)
1303 elseif not hybrid_type then
1304 if l_expression_context.conforms_to_context (l_item_context) then
1305 -- The type of the current item conforms to the type
1306 -- retained so far. Keep the old type.
1307 elseif l_item_context.conforms_to_context (l_expression_context) then
1308 -- The type retained so far conforms to the type of the
1309 -- current item. Retain this new type.
1310 l_old_item_context := l_item_context
1311 l_item_context := l_expression_context
1312 l_expression_context := l_old_item_context
1313 else
1314 hybrid_type := True
1315 l_is_item_type_attached := l_item_context.is_type_attached
1316 if l_is_item_type_attached then
1317 l_is_item_type_attached := l_expression_context.is_type_attached
1318 end
1319 end
1320 elseif l_is_item_type_attached then
1321 l_is_item_type_attached := l_expression_context.is_type_attached
1322 end
1323 end
1324 l_expression_context.wipe_out
1325 i := i + 1
1326 end
1327 free_context (l_expression_context)
1328 end
1329 if had_error then
1330 set_fatal_error
1331 elseif l_array_type /= Void then
1332 a_context.force_last (l_array_type)
1333 elseif l_item_context = Void then
1334 -- This is an empty manifest array: '<< >>'. We have no way to
1335 -- find out the type of the parameter, so we use 'ARRAY [ANY]'.
1336 l_array_type := current_system.array_any_type
1337 a_context.force_last (l_array_type)
1338 elseif hybrid_type then
1339 -- There are at least two items which don't conform to each other either way.
1340 -- Use 'ARRAY [ANY]' in that case, or 'ARRAY [detachable ANY]' if at least
1341 -- one of the items is not attached.
1342 -- TODO: we could do better than 'ARRAY [ANY]', for example choosing one of the
1343 -- common ancestors of these two types. But which one to choose? ETL2 does not say.
1344 if l_is_item_type_attached then
1345 l_array_type := current_system.array_any_type
1346 else
1347 l_array_type := current_system.array_detachable_any_type
1348 end
1349 a_context.force_last (l_array_type)
1350 else
1351 -- The type of all items conforms to one of them.
1352 -- So the manifest array will be an array of that type.
1353 a_context.copy_type_context (l_item_context)
1354 l_array_type := current_system.array_like_current_type
1355 a_context.force_last (l_array_type)
1356 end
1357 if l_item_context /= Void then
1358 free_context (l_item_context)
1359 end
1360 end
1361
1362 find_manifest_string_type (a_string: ET_MANIFEST_STRING; a_context: ET_NESTED_TYPE_CONTEXT)
1363 -- `a_context' represents the type in which `a_string' appears.
1364 -- It will be altered on exit to represent the type of `a_string'.
1365 -- Set `has_fatal_error' if a fatal error occurred.
1366 require
1367 a_string_not_void: a_string /= Void
1368 a_context_not_void: a_context /= Void
1369 local
1370 l_type: detachable ET_CLASS_TYPE
1371 do
1372 reset_fatal_error (False)
1373 l_type := a_string.type
1374 if l_type = Void then
1375 l_type := current_universe_impl.string_type
1376 end
1377 a_context.force_last (l_type)
1378 end
1379
1380 find_manifest_tuple_type (an_expression: ET_MANIFEST_TUPLE; a_context: ET_NESTED_TYPE_CONTEXT)
1381 -- `a_context' represents the type in which `an_expression' appears.
1382 -- It will be altered on exit to represent the type of `an_expression'.
1383 -- Set `has_fatal_error' if a fatal error occurred.
1384 require
1385 an_expression_not_void: an_expression /= Void
1386 a_context_not_void: a_context /= Void
1387 local
1388 i, nb, nb2: INTEGER
1389 had_error: BOOLEAN
1390 l_actuals: ET_ACTUAL_PARAMETER_LIST
1391 l_tuple_type: ET_TUPLE_TYPE
1392 l_tuple_parameters: detachable ET_ACTUAL_PARAMETERS
1393 l_expression_context: ET_NESTED_TYPE_CONTEXT
1394 l_parameter_context: ET_NESTED_TYPE_CONTEXT
1395 l_detachable_any_type: ET_CLASS_TYPE
1396 do
1397 reset_fatal_error (False)
1398 -- Try to find out whether the expected type (i.e. `current_target_type')
1399 -- for the manifest tuple is 'TUPLE [...]'. If this is the case then we
1400 -- use these item types as expected types for the corresponding items
1401 -- in the manifest tuple. For example if we expect a 'TUPLE [INTEGER_64]'
1402 -- and we have '[3]' then '3' will be considered as a '{INTEGER_64} 3'.
1403 -- Likewise, if we expect a 'TUPLE [ARRAY [HASHABLE]]' and we have
1404 -- '[<<"gobo", 3>>]' then the manifest array '<<"gobo", 3>>' will be
1405 -- considered of type 'ARRAY [HASHABLE]' (rather than of type 'ARRAY [ANY]'
1406 -- if it were analyzed out of context).
1407 if attached {ET_TUPLE_TYPE} current_target_type.named_type as l_target_tuple_type then
1408 l_tuple_parameters := l_target_tuple_type.actual_parameters
1409 if l_tuple_parameters /= Void then
1410 nb2 := l_tuple_parameters.count
1411 end
1412 end
1413 l_detachable_any_type := current_system.detachable_any_type
1414 nb := an_expression.count
1415 if nb = 0 then
1416 l_tuple_type := current_universe_impl.tuple_type
1417 a_context.force_last (l_tuple_type)
1418 elseif nb = 1 then
1419 if l_tuple_parameters /= Void and nb2 >= 1 then
1420 l_parameter_context := new_context (current_type)
1421 -- The expected type for the manifest tuple is 'TUPLE [...]'.
1422 -- Use these item types as expected types for the corresponding items
1423 -- in the manifest tuple. For example if we expect a 'TUPLE [INTEGER_64]'
1424 -- and we have '[3]' then '3' will be considered as a '{INTEGER_64} 3'.
1425 -- Likewise, if we expect a 'TUPLE [ARRAY [HASHABLE]]' and we have
1426 -- '[<<"gobo", 3>>]' then the manifest array '<<"gobo", 3>>' will be
1427 -- considered of type 'ARRAY [HASHABLE]' (rather than of type 'ARRAY [ANY]'
1428 -- if it were analyzed out of context).
1429 l_parameter_context.force_last (l_tuple_parameters.type (1))
1430 find_expression_type (an_expression.expression (1), a_context, l_parameter_context)
1431 free_context (l_parameter_context)
1432 else
1433 find_expression_type (an_expression.expression (1), a_context, l_detachable_any_type)
1434 end
1435 if not has_fatal_error then
1436 l_tuple_type := current_universe_impl.tuple_like_current_type
1437 a_context.force_last (l_tuple_type)
1438 end
1439 else
1440 l_expression_context := new_context (current_type)
1441 create l_actuals.make_with_capacity (nb)
1442 from i := nb until i <= nb2 loop
1443 -- There is no matching tuple item type.
1444 find_expression_type (an_expression.expression (i), l_expression_context, l_detachable_any_type)
1445 if has_fatal_error then
1446 had_error := True
1447 else
1448 l_actuals.put_first (l_expression_context.named_type)
1449 end
1450 l_expression_context.wipe_out
1451 i := i - 1
1452 end
1453 if l_tuple_parameters /= Void then
1454 l_parameter_context := new_context (current_type)
1455 from until i < 1 loop
1456 -- The expected type for the manifest tuple is 'TUPLE [...]'.
1457 -- Use these item types as expected types for the corresponding items
1458 -- in the manifest tuple. For example if we expect a 'TUPLE [INTEGER_64]'
1459 -- and we have '[3]' then '3' will be considered as a '{INTEGER_64} 3'.
1460 -- Likewise, if we expect a 'TUPLE [ARRAY [HASHABLE]]' and we have
1461 -- '[<<"gobo", 3>>]' then the manifest array '<<"gobo", 3>>' will be
1462 -- considered of type 'ARRAY [HASHABLE]' (rather than of type 'ARRAY [ANY]'
1463 -- if it were analyzed out of context).
1464 l_parameter_context.force_last (l_tuple_parameters.type (i))
1465 find_expression_type (an_expression.expression (i), l_expression_context, l_parameter_context)
1466 if has_fatal_error then
1467 had_error := True
1468 else
1469 l_actuals.put_first (l_expression_context.named_type)
1470 end
1471 l_expression_context.wipe_out
1472 l_parameter_context.wipe_out
1473 i := i - 1
1474 end
1475 free_context (l_parameter_context)
1476 end
1477 free_context (l_expression_context)
1478 if had_error then
1479 set_fatal_error
1480 else
1481 create l_tuple_type.make (tokens.implicit_attached_type_mark, l_actuals, current_universe_impl.tuple_type.named_base_class)
1482 a_context.force_last (l_tuple_type)
1483 end
1484 end
1485 end
1486
1487 find_manifest_type_type (an_expression: ET_MANIFEST_TYPE; a_context: ET_NESTED_TYPE_CONTEXT)
1488 -- `a_context' represents the type in which `an_expression' appears.
1489 -- It will be altered on exit to represent the type of `an_expression'.
1490 -- Set `has_fatal_error' if a fatal error occurred.
1491 require
1492 an_expression_not_void: an_expression /= Void
1493 a_context_not_void: a_context /= Void
1494 local
1495 l_type: ET_TYPE
1496 l_type_type: ET_CLASS_TYPE
1497 do
1498 reset_fatal_error (False)
1499 l_type := an_expression.type
1500 -- TODO: I think that the formal generic parameters of `l_type' need to
1501 -- be resolved in the context of `current_type'.
1502 a_context.force_last (l_type)
1503 l_type_type := current_universe_impl.type_like_current_type
1504 a_context.force_last (l_type_type)
1505 end
1506
1507 find_object_equality_expression_type (an_expression: ET_OBJECT_EQUALITY_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
1508 -- `a_context' represents the type in which `an_expression' appears.
1509 -- It will be altered on exit to represent the type of `an_expression'.
1510 -- Set `has_fatal_error' if a fatal error occurred.
1511 require
1512 an_expression_not_void: an_expression /= Void
1513 a_context_not_void: a_context /= Void
1514 do
1515 reset_fatal_error (False)
1516 a_context.force_last (current_universe_impl.boolean_type)
1517 end
1518
1519 find_object_test_type (an_expression: ET_OBJECT_TEST; a_context: ET_NESTED_TYPE_CONTEXT)
1520 -- `a_context' represents the type in which `an_expression' appears.
1521 -- It will be altered on exit to represent the type of `an_expression'.
1522 -- Set `has_fatal_error' if a fatal error occurred.
1523 require
1524 an_expression_not_void: an_expression /= Void
1525 a_context_not_void: a_context /= Void
1526 do
1527 reset_fatal_error (False)
1528 a_context.force_last (current_universe_impl.boolean_type)
1529 end
1530
1531 find_object_test_local_type (a_name: ET_IDENTIFIER; a_context: ET_NESTED_TYPE_CONTEXT)
1532 -- `a_context' represents the type in which `a_name' appears.
1533 -- It will be altered on exit to represent the type of `a_name'.
1534 -- Set `has_fatal_error' if a fatal error occurred.
1535 require
1536 a_name_not_void: a_name /= Void
1537 a_name_object_test_local: a_name.is_object_test_local
1538 a_context_not_void: a_context /= Void
1539 local
1540 l_seed: INTEGER
1541 l_type: detachable ET_TYPE
1542 l_object_test: ET_NAMED_OBJECT_TEST
1543 l_object_tests: detachable ET_OBJECT_TEST_LIST
1544 do
1545 reset_fatal_error (False)
1546 l_seed := a_name.seed
1547 l_object_tests := current_closure_impl.object_tests
1548 if l_object_tests = Void then
1549 -- Internal error.
1550 -- This error should have already been reported when checking
1551 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1552 set_fatal_error
1553 if internal_error_enabled or not current_class.has_implementation_error then
1554 error_handler.report_giaaa_error
1555 end
1556 elseif l_seed < 1 or l_seed > l_object_tests.count then
1557 -- Internal error.
1558 -- This error should have already been reported when checking
1559 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1560 set_fatal_error
1561 if internal_error_enabled or not current_class.has_implementation_error then
1562 error_handler.report_giaaa_error
1563 end
1564 else
1565 l_object_test := l_object_tests.object_test (l_seed)
1566 l_type := l_object_test.type
1567 if l_type /= Void then
1568 a_context.force_last (l_type)
1569 else
1570 find_expression_type (l_object_test.expression, a_context, current_system.detachable_any_type)
1571 end
1572 end
1573 end
1574
1575 find_octal_integer_constant_type (a_constant: ET_OCTAL_INTEGER_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
1576 -- `a_context' represents the type in which `a_constant' appears.
1577 -- It will be altered on exit to represent the type of `a_constant'.
1578 -- Set `has_fatal_error' if a fatal error occurred.
1579 require
1580 a_constant_not_void: a_constant /= Void
1581 a_context_not_void: a_context /= Void
1582 do
1583 find_integer_constant_type (a_constant, a_context)
1584 end
1585
1586 find_old_expression_type (an_expression: ET_OLD_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
1587 -- `a_context' represents the type in which `an_expression' appears.
1588 -- It will be altered on exit to represent the type of `an_expression'.
1589 -- Set `has_fatal_error' if a fatal error occurred.
1590 require
1591 an_expression_not_void: an_expression /= Void
1592 a_context_not_void: a_context /= Void
1593 local
1594 l_expression: ET_EXPRESSION
1595 do
1596 l_expression := an_expression.expression
1597 find_expression_type (l_expression, a_context, current_target_type)
1598 end
1599
1600 find_once_manifest_string_type (an_expression: ET_ONCE_MANIFEST_STRING; a_context: ET_NESTED_TYPE_CONTEXT)
1601 -- `a_context' represents the type in which `an_expression' appears.
1602 -- It will be altered on exit to represent the type of `an_expression'.
1603 -- Set `has_fatal_error' if a fatal error occurred.
1604 require
1605 an_expression_not_void: an_expression /= Void
1606 a_context_not_void: a_context /= Void
1607 local
1608 l_string: ET_MANIFEST_STRING
1609 do
1610 l_string := an_expression.manifest_string
1611 find_expression_type (l_string, a_context, current_target_type)
1612 end
1613
1614 find_parenthesized_expression_type (an_expression: ET_PARENTHESIZED_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
1615 -- `a_context' represents the type in which `an_expression' appears.
1616 -- It will be altered on exit to represent the type of `an_expression'.
1617 -- Set `has_fatal_error' if a fatal error occurred.
1618 require
1619 an_expression_not_void: an_expression /= Void
1620 a_context_not_void: a_context /= Void
1621 local
1622 l_expression: ET_EXPRESSION
1623 do
1624 l_expression := an_expression.expression
1625 find_expression_type (l_expression, a_context, current_target_type)
1626 end
1627
1628 find_precursor_expression_type (an_expression: ET_PRECURSOR_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
1629 -- `a_context' represents the type in which `an_expression' appears.
1630 -- It will be altered on exit to represent the type of `an_expression'.
1631 -- Set `has_fatal_error' if a fatal error occurred.
1632 require
1633 an_expression_not_void: an_expression /= Void
1634 a_context_not_void: a_context /= Void
1635 local
1636 l_precursor_keyword: ET_PRECURSOR_KEYWORD
1637 l_query: detachable ET_QUERY
1638 l_parent_type: detachable ET_BASE_TYPE
1639 l_class: ET_CLASS
1640 l_type: ET_TYPE
1641 do
1642 reset_fatal_error (False)
1643 l_parent_type := an_expression.parent_type
1644 if l_parent_type = Void then
1645 -- Internal error: the Precursor construct should already have been
1646 -- resolved when flattening the features of `current_class_impl'.
1647 -- This error should have already been reported when checking
1648 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1649 set_fatal_error
1650 if internal_error_enabled or not current_class.has_implementation_error then
1651 error_handler.report_giaaa_error
1652 end
1653 else
1654 l_precursor_keyword := an_expression.precursor_keyword
1655 l_class := l_parent_type.base_class
1656 l_query := l_class.seeded_query (l_precursor_keyword.seed)
1657 if l_query = Void then
1658 -- Internal error: the Precursor construct should already have been
1659 -- resolved when flattening the features of `current_class_impl'.
1660 -- This error should have already been reported when checking
1661 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1662 set_fatal_error
1663 if internal_error_enabled or not current_class.has_implementation_error then
1664 error_handler.report_giaaa_error
1665 end
1666 else
1667 -- TODO: like argument.
1668 l_type := l_query.type
1669 a_context.force_last (l_type)
1670 end
1671 end
1672 end
1673
1674 find_prefix_expression_type (an_expression: ET_PREFIX_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
1675 -- `a_context' represents the type in which `an_expression' appears.
1676 -- It will be altered on exit to represent the type of `an_expression'.
1677 -- Set `has_fatal_error' if a fatal error occurred.
1678 require
1679 an_expression_not_void: an_expression /= Void
1680 a_context_not_void: a_context /= Void
1681 do
1682 find_qualified_call_expression_type (an_expression, a_context)
1683 end
1684
1685 find_qualified_call_expression_type (a_call: ET_QUALIFIED_FEATURE_CALL_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
1686 -- `a_context' represents the type in which `a_call' appears.
1687 -- It will be altered on exit to represent the type of `a_call'.
1688 -- Set `has_fatal_error' if a fatal error occurred.
1689 require
1690 a_call_not_void: a_call /= Void
1691 a_context_not_void: a_context /= Void
1692 local
1693 l_target: ET_EXPRESSION
1694 l_name: ET_CALL_NAME
1695 l_actuals: detachable ET_ACTUAL_ARGUMENTS
1696 l_class: ET_CLASS
1697 l_query: detachable ET_QUERY
1698 l_type: ET_TYPE
1699 l_seed: INTEGER
1700 l_actual: ET_EXPRESSION
1701 l_formal_context: ET_NESTED_TYPE_CONTEXT
1702 do
1703 reset_fatal_error (False)
1704 l_target := a_call.target
1705 l_name := a_call.name
1706 l_actuals := a_call.arguments
1707 l_seed := l_name.seed
1708 find_expression_type (l_target, a_context, current_system.detachable_any_type)
1709 if has_fatal_error then
1710 -- Do nothing.
1711 elseif l_seed <= 0 then
1712 -- This error should have already been reported when checking
1713 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1714 set_fatal_error
1715 if internal_error_enabled or not current_class.has_implementation_error then
1716 error_handler.report_giaaa_error
1717 end
1718 elseif l_name.is_tuple_label then
1719 if l_seed > a_context.base_type_actual_count then
1720 -- Internal error: the index of the labeled
1721 -- actual parameter cannot be out of bound because
1722 -- for a Tuple type to conform to another Tuple type
1723 -- it needs to have more actual parameters.
1724 -- This error should have already been reported when checking
1725 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1726 set_fatal_error
1727 if internal_error_enabled or not current_class.has_implementation_error then
1728 error_handler.report_giaaa_error
1729 end
1730 else
1731 l_class := a_context.base_class
1732 l_type := l_class.formal_parameter_type (l_seed)
1733 a_context.force_last (l_type)
1734 end
1735 else
1736 l_class := a_context.base_class
1737 l_query := l_class.seeded_query (l_seed)
1738 if l_query = Void then
1739 -- Internal error: if we got a seed, `l_query' should not be void.
1740 -- This error should have already been reported when checking
1741 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1742 set_fatal_error
1743 if internal_error_enabled or not current_class.has_implementation_error then
1744 error_handler.report_giaaa_error
1745 end
1746 else
1747 l_type := l_query.type
1748 -- TODO: like argument (the following is just a workaround
1749 -- which works only in a limited number of cases, in particular
1750 -- for ANY.clone).
1751 if attached {ET_LIKE_FEATURE} l_type as l_like and then l_like.is_like_argument and then attached l_query.arguments as l_formal_arguments and then l_formal_arguments.count = 1 then
1752 if l_actuals /= Void and then l_actuals.count = 1 then
1753 l_formal_context := new_context (current_type)
1754 l_formal_context.copy_type_context (a_context)
1755 l_formal_context.force_last (l_formal_arguments.formal_argument (1).type)
1756 a_context.wipe_out
1757 l_actual := l_actuals.actual_argument (1)
1758 find_expression_type (l_actual, a_context, l_formal_context)
1759 free_context (l_formal_context)
1760 if not has_fatal_error then
1761 if attached {ET_CONVERT_EXPRESSION} l_actual as l_convert_expression then
1762 if attached {ET_BUILTIN_CONVERT_FEATURE} l_convert_expression.convert_feature as l_builtin then
1763 -- Needed for compatibility with ISE 5.6.0610:
1764 -- a formal generic parameter either conforms or converts to its constraint,
1765 -- then the converted version can still be chained with a conformance to
1766 -- `current_target_type'.
1767 a_context.reset (current_type)
1768 a_context.force_last (l_builtin.type)
1769 end
1770 end
1771 end
1772 else
1773 a_context.force_last (l_type)
1774 end
1775 else
1776 a_context.force_last (l_type)
1777 end
1778 end
1779 end
1780 end
1781
1782 find_real_constant_type (a_constant: ET_REAL_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
1783 -- `a_context' represents the type in which `a_constant' appears.
1784 -- It will be altered on exit to represent the type of `a_constant'.
1785 -- Set `has_fatal_error' if a fatal error occurred.
1786 require
1787 a_constant_not_void: a_constant /= Void
1788 a_context_not_void: a_context /= Void
1789 local
1790 l_type: detachable ET_CLASS_TYPE
1791 do
1792 reset_fatal_error (False)
1793 l_type := a_constant.type
1794 if l_type = Void then
1795 l_type := current_universe_impl.real_type
1796 end
1797 a_context.force_last (l_type)
1798 end
1799
1800 find_regular_integer_constant_type (a_constant: ET_REGULAR_INTEGER_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
1801 -- `a_context' represents the type in which `a_constant' appears.
1802 -- It will be altered on exit to represent the type of `a_constant'.
1803 -- Set `has_fatal_error' if a fatal error occurred.
1804 require
1805 a_constant_not_void: a_constant /= Void
1806 a_context_not_void: a_context /= Void
1807 do
1808 find_integer_constant_type (a_constant, a_context)
1809 end
1810
1811 find_regular_manifest_string_type (a_string: ET_REGULAR_MANIFEST_STRING; a_context: ET_NESTED_TYPE_CONTEXT)
1812 -- `a_context' represents the type in which `a_string' appears.
1813 -- It will be altered on exit to represent the type of `a_string'.
1814 -- Set `has_fatal_error' if a fatal error occurred.
1815 require
1816 a_string_not_void: a_string /= Void
1817 a_context_not_void: a_context /= Void
1818 do
1819 find_manifest_string_type (a_string, a_context)
1820 end
1821
1822 find_regular_real_constant_type (a_constant: ET_REGULAR_REAL_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
1823 -- `a_context' represents the type in which `a_constant' appears.
1824 -- It will be altered on exit to represent the type of `a_constant'.
1825 -- Set `has_fatal_error' if a fatal error occurred.
1826 require
1827 a_constant_not_void: a_constant /= Void
1828 a_context_not_void: a_context /= Void
1829 do
1830 find_real_constant_type (a_constant, a_context)
1831 end
1832
1833 find_result_type (an_expression: ET_RESULT; a_context: ET_NESTED_TYPE_CONTEXT)
1834 -- `a_context' represents the type in which `an_expression' appears.
1835 -- It will be altered on exit to represent the type of `an_expression'.
1836 -- Set `has_fatal_error' if a fatal error occurred.
1837 require
1838 an_expression_not_void: an_expression /= Void
1839 a_context_not_void: a_context /= Void
1840 local
1841 l_type: detachable ET_TYPE
1842 do
1843 reset_fatal_error (False)
1844 if attached current_inline_agent as l_current_inline_agent then
1845 l_type := l_current_inline_agent.type
1846 else
1847 -- Use type of `current_feature' instead of `current_feature_impl'
1848 -- because when processing inherited assertions the types of signature
1849 -- should be those of the version of the feature in the current class.
1850 -- For example:
1851 -- deferred class A
1852 -- feature
1853 -- f: ANY
1854 -- deferred
1855 -- ensure
1856 -- post: g (Result)
1857 -- end
1858 -- g (a: ANY): BOOLEAN deferred end
1859 -- end
1860 -- class B
1861 -- inherit
1862 -- A
1863 -- feature
1864 -- f: STRING do ... end
1865 -- g (a: STRING): BOOLEAN do ... end
1866 -- end
1867 -- 'Result' in the inherited postcondition "post" should be considered
1868 -- of type STRING (and not ANY) is class B.
1869 l_type := current_feature.type
1870 end
1871 if l_type = Void then
1872 -- The entity 'Result' has to appear in a query.
1873 -- This error should have already been reported when checking
1874 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1875 set_fatal_error
1876 if internal_error_enabled or not current_class.has_implementation_error then
1877 error_handler.report_giaaa_error
1878 end
1879 else
1880 a_context.force_last (l_type)
1881 end
1882 end
1883
1884 find_result_address_type (an_expression: ET_RESULT_ADDRESS; a_context: ET_NESTED_TYPE_CONTEXT)
1885 -- `a_context' represents the type in which `an_expression' appears.
1886 -- It will be altered on exit to represent the type of `an_expression'.
1887 -- Set `has_fatal_error' if a fatal error occurred.
1888 require
1889 an_expression_not_void: an_expression /= Void
1890 a_context_not_void: a_context /= Void
1891 local
1892 l_type: detachable ET_TYPE
1893 l_typed_pointer_class: ET_NAMED_CLASS
1894 l_typed_pointer_type: ET_CLASS_TYPE
1895 do
1896 reset_fatal_error (False)
1897 if attached current_inline_agent as l_current_inline_agent then
1898 l_type := l_current_inline_agent.type
1899 else
1900 -- Use type of `current_feature' instead of `current_feature_impl'
1901 -- because when processing inherited assertions the types of signature
1902 -- should be those of the version of the feature in the current class.
1903 -- For example:
1904 -- deferred class A
1905 -- feature
1906 -- f: ANY
1907 -- deferred
1908 -- ensure
1909 -- post: g ($Result)
1910 -- end
1911 -- g (a: TYPED_POINTER [ANY]): BOOLEAN deferred end
1912 -- end
1913 -- class B
1914 -- inherit
1915 -- A
1916 -- feature
1917 -- f: STRING do ... end
1918 -- g (a: TYPED_POINTER [STRING]): BOOLEAN do ... end
1919 -- end
1920 -- 'Result' in the inherited postcondition "post" should be considered
1921 -- of type STRING (and not ANY) is class B.
1922 l_type := current_feature.type
1923 end
1924 if l_type = Void then
1925 -- The entity 'Result' has to appear in a query.
1926 -- This error should have already been reported when checking
1927 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1928 set_fatal_error
1929 if internal_error_enabled or not current_class.has_implementation_error then
1930 error_handler.report_giaaa_error
1931 end
1932 else
1933 l_typed_pointer_type := current_universe_impl.typed_pointer_like_current_type
1934 l_typed_pointer_class := l_typed_pointer_type.named_base_class
1935 if l_typed_pointer_class.actual_class.is_preparsed then
1936 -- Class TYPED_POINTER has been found in the universe.
1937 -- Use ISE's implementation: the type of '$Result' is 'TYPED_POINTER [<type-of-result>]'.
1938 a_context.force_last (l_type)
1939 a_context.force_last (l_typed_pointer_type)
1940 else
1941 -- Use the ETL2 implementation: the type of '$argument' is POINTER.
1942 a_context.force_last (current_universe_impl.pointer_type)
1943 end
1944 end
1945 end
1946
1947 find_special_manifest_string_type (a_string: ET_SPECIAL_MANIFEST_STRING; a_context: ET_NESTED_TYPE_CONTEXT)
1948 -- `a_context' represents the type in which `a_string' appears.
1949 -- It will be altered on exit to represent the type of `a_string'.
1950 -- Set `has_fatal_error' if a fatal error occurred.
1951 require
1952 a_string_not_void: a_string /= Void
1953 a_context_not_void: a_context /= Void
1954 do
1955 find_manifest_string_type (a_string, a_context)
1956 end
1957
1958 find_static_call_expression_type (an_expression: ET_STATIC_CALL_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
1959 -- `a_context' represents the type in which `an_expression' appears.
1960 -- It will be altered on exit to represent the type of `an_expression'.
1961 -- Set `has_fatal_error' if a fatal error occurred.
1962 require
1963 an_expression_not_void: an_expression /= Void
1964 a_context_not_void: a_context /= Void
1965 local
1966 l_class: ET_CLASS
1967 l_query: detachable ET_QUERY
1968 l_type: ET_TYPE
1969 l_result_type: ET_TYPE
1970 l_name: ET_FEATURE_NAME
1971 l_seed: INTEGER
1972 do
1973 reset_fatal_error (False)
1974 l_type := an_expression.type
1975 l_name := an_expression.name
1976 l_seed := l_name.seed
1977 if l_seed <= 0 then
1978 -- This error should have already been reported when checking
1979 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1980 set_fatal_error
1981 if internal_error_enabled or not current_class.has_implementation_error then
1982 error_handler.report_giaaa_error
1983 end
1984 else
1985 a_context.force_last (l_type)
1986 l_class := a_context.base_class
1987 l_query := l_class.seeded_query (l_seed)
1988 if l_query = Void then
1989 -- Internal error: if we got a seed, `l_query' should not be void.
1990 -- This error should have already been reported when checking
1991 -- `current_feature' (using ET_FEATURE_CHECKER for example).
1992 set_fatal_error
1993 if internal_error_enabled or not current_class.has_implementation_error then
1994 error_handler.report_giaaa_error
1995 end
1996 else
1997 -- TODO: check that `l_query' is a constant attribute or an external function.
1998 -- TODO: like argument.
1999 l_result_type := l_query.type
2000 a_context.force_last (l_result_type)
2001 end
2002 end
2003 end
2004
2005 find_strip_expression_type (an_expression: ET_STRIP_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
2006 -- `a_context' represents the type in which `an_expression' appears.
2007 -- It will be altered on exit to represent the type of `an_expression'.
2008 -- Set `has_fatal_error' if a fatal error occurred.
2009 require
2010 an_expression_not_void: an_expression /= Void
2011 a_context_not_void: a_context /= Void
2012 do
2013 reset_fatal_error (False)
2014 a_context.force_last (current_system.array_detachable_any_type)
2015 end
2016
2017 find_true_constant_type (a_constant: ET_TRUE_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
2018 -- `a_context' represents the type in which `a_constant' appears.
2019 -- It will be altered on exit to represent the type of `a_constant'.
2020 -- Set `has_fatal_error' if a fatal error occurred.
2021 require
2022 a_constant_not_void: a_constant /= Void
2023 a_context_not_void: a_context /= Void
2024 do
2025 reset_fatal_error (False)
2026 a_context.force_last (current_universe_impl.boolean_type)
2027 end
2028
2029 find_underscored_integer_constant_type (a_constant: ET_UNDERSCORED_INTEGER_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
2030 -- `a_context' represents the type in which `a_constant' appears.
2031 -- It will be altered on exit to represent the type of `a_constant'.
2032 -- Set `has_fatal_error' if a fatal error occurred.
2033 require
2034 a_constant_not_void: a_constant /= Void
2035 a_context_not_void: a_context /= Void
2036 do
2037 find_integer_constant_type (a_constant, a_context)
2038 end
2039
2040 find_underscored_real_constant_type (a_constant: ET_UNDERSCORED_REAL_CONSTANT; a_context: ET_NESTED_TYPE_CONTEXT)
2041 -- `a_context' represents the type in which `a_constant' appears.
2042 -- It will be altered on exit to represent the type of `a_constant'.
2043 -- Set `has_fatal_error' if a fatal error occurred.
2044 require
2045 a_constant_not_void: a_constant /= Void
2046 a_context_not_void: a_context /= Void
2047 do
2048 find_real_constant_type (a_constant, a_context)
2049 end
2050
2051 find_unqualified_call_expression_type (a_call: ET_UNQUALIFIED_FEATURE_CALL_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
2052 -- `a_context' represents the type in which `a_call' appears.
2053 -- It will be altered on exit to represent the type of `a_call'.
2054 -- Set `has_fatal_error' if a fatal error occurred.
2055 require
2056 a_call_not_void: a_call /= Void
2057 a_context_not_void: a_context /= Void
2058 local
2059 l_name: ET_CALL_NAME
2060 l_actuals: detachable ET_ACTUAL_ARGUMENTS
2061 l_query: detachable ET_QUERY
2062 l_type: ET_TYPE
2063 l_seed: INTEGER
2064 l_actual: ET_EXPRESSION
2065 l_formal_context: ET_NESTED_TYPE_CONTEXT
2066 do
2067 reset_fatal_error (False)
2068 l_name := a_call.name
2069 l_actuals := a_call.arguments
2070 l_seed := l_name.seed
2071 if l_seed <= 0 then
2072 -- This error should have already been reported when checking
2073 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2074 set_fatal_error
2075 if internal_error_enabled or not current_class.has_implementation_error then
2076 error_handler.report_giaaa_error
2077 end
2078 else
2079 l_query := current_class.seeded_query (l_seed)
2080 if l_query = Void then
2081 -- Internal error: if we got a seed, `l_query' should not be void.
2082 -- This error should have already been reported when checking
2083 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2084 set_fatal_error
2085 if internal_error_enabled or not current_class.has_implementation_error then
2086 error_handler.report_giaaa_error
2087 end
2088 else
2089 l_type := l_query.type
2090 -- TODO: like argument (the following is just a workaround
2091 -- which works only in a limited number of cases, in particular
2092 -- for ANY.clone).
2093 if attached {ET_LIKE_FEATURE} l_type as l_like and then l_like.is_like_argument and then attached l_query.arguments as l_formal_arguments and then l_formal_arguments.count = 1 then
2094 if l_actuals /= Void and then l_actuals.count = 1 then
2095 l_formal_context := new_context (current_type)
2096 l_formal_context.force_last (l_formal_arguments.formal_argument (1).type)
2097 a_context.wipe_out
2098 l_actual := l_actuals.actual_argument (1)
2099 find_expression_type (l_actual, a_context, l_formal_context)
2100 free_context (l_formal_context)
2101 if not has_fatal_error then
2102 if attached {ET_CONVERT_EXPRESSION} l_actual as l_convert_expression then
2103 if attached {ET_BUILTIN_CONVERT_FEATURE} l_convert_expression.convert_feature as l_builtin then
2104 -- Needed for compatibility with ISE 5.6.0610:
2105 -- a formal generic parameter either conforms or converts to its constraint,
2106 -- then the converted version can still be chained with a conformance to
2107 -- `current_target_type'.
2108 a_context.reset (current_type)
2109 a_context.force_last (l_builtin.type)
2110 end
2111 end
2112 end
2113 else
2114 a_context.force_last (l_type)
2115 end
2116 else
2117 a_context.force_last (l_type)
2118 end
2119 end
2120 end
2121 end
2122
2123 find_verbatim_string_type (a_string: ET_VERBATIM_STRING; a_context: ET_NESTED_TYPE_CONTEXT)
2124 -- `a_context' represents the type in which `a_string' appears.
2125 -- It will be altered on exit to represent the type of `a_string'.
2126 -- Set `has_fatal_error' if a fatal error occurred.
2127 require
2128 a_string_not_void: a_string /= Void
2129 a_context_not_void: a_context /= Void
2130 do
2131 find_manifest_string_type (a_string, a_context)
2132 end
2133
2134 find_void_type (an_expression: ET_VOID; a_context: ET_NESTED_TYPE_CONTEXT)
2135 -- `a_context' represents the type in which `an_expression' appears.
2136 -- It will be altered on exit to represent the type of `an_expression'.
2137 -- Set `has_fatal_error' if a fatal error occurred.
2138 require
2139 an_expression_not_void: an_expression /= Void
2140 a_context_not_void: a_context /= Void
2141 do
2142 reset_fatal_error (False)
2143 a_context.force_last (current_system.detachable_none_type)
2144 end
2145
2146 find_expression_type (an_expression: ET_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT; a_target_type: ET_TYPE_CONTEXT)
2147 -- Find type of `an_expression' (whose possible attachment target
2148 -- is of type `a_target_type') in `current_feature' of `current_type'.
2149 -- Set `has_fatal_error' if a fatal error occurred. Otherwise
2150 -- the type of `an_expression' is appended to `a_context'.
2151 require
2152 an_expression_not_void: an_expression /= Void
2153 a_context_not_void: a_context /= Void
2154 a_target_type_not_void: a_target_type /= Void
2155 valid_target_context: a_target_type.is_valid_context
2156 local
2157 old_context: ET_NESTED_TYPE_CONTEXT
2158 old_target_type: ET_TYPE_CONTEXT
2159 do
2160 reset_fatal_error (False)
2161 old_target_type := current_target_type
2162 current_target_type := a_target_type
2163 old_context := current_context
2164 current_context := a_context
2165 an_expression.process (Current)
2166 current_context := old_context
2167 current_target_type := old_target_type
2168 end
2169
2170 feature {NONE} -- Agent validity
2171
2172 find_call_agent_type (an_expression: ET_CALL_AGENT; a_context: ET_NESTED_TYPE_CONTEXT)
2173 -- `a_context' represents the type in which `an_expression' appears.
2174 -- It will be altered on exit to represent the type of `an_expression'.
2175 -- Set `has_fatal_error' if a fatal error occurred.
2176 require
2177 an_expression_not_void: an_expression /= Void
2178 a_context_not_void: a_context /= Void
2179 local
2180 a_target: ET_AGENT_TARGET
2181 do
2182 if not an_expression.is_qualified_call then
2183 find_unqualified_call_agent_type (an_expression, a_context)
2184 else
2185 a_target := an_expression.target
2186 if attached {ET_EXPRESSION} a_target as an_expression_target then
2187 find_qualified_call_agent_type (an_expression, an_expression_target, a_context)
2188 elseif attached {ET_AGENT_OPEN_TARGET} a_target as a_type_target then
2189 find_typed_call_agent_type (an_expression, a_type_target, a_context)
2190 else
2191 -- Internal error: no other kind of targets.
2192 -- This error should have already been reported when checking
2193 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2194 set_fatal_error
2195 if internal_error_enabled or not current_class.has_implementation_error then
2196 error_handler.report_giaaa_error
2197 end
2198 end
2199 end
2200 end
2201
2202 find_unqualified_call_agent_type (an_expression: ET_CALL_AGENT; a_context: ET_NESTED_TYPE_CONTEXT)
2203 -- `a_context' represents the type in which `an_expression' appears.
2204 -- It will be altered on exit to represent the type of `an_expression'.
2205 -- Set `has_fatal_error' if a fatal error occurred.
2206 require
2207 an_expression_not_void: an_expression /= Void
2208 unqualified_call_agent: not an_expression.is_qualified_call
2209 a_context_not_void: a_context /= Void
2210 local
2211 a_name: ET_FEATURE_NAME
2212 l_query: detachable ET_QUERY
2213 l_procedure: detachable ET_PROCEDURE
2214 a_seed: INTEGER
2215 do
2216 reset_fatal_error (False)
2217 a_name := an_expression.name
2218 a_seed := a_name.seed
2219 if a_seed <= 0 then
2220 -- This error should have already been reported when checking
2221 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2222 set_fatal_error
2223 if internal_error_enabled or not current_class.has_implementation_error then
2224 error_handler.report_giaaa_error
2225 end
2226 elseif an_expression.is_procedure then
2227 l_procedure := current_class.seeded_procedure (a_seed)
2228 if l_procedure = Void then
2229 -- Internal error: if we got a seed, `l_procedure' should not be void.
2230 -- This error should have already been reported when checking
2231 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2232 set_fatal_error
2233 if internal_error_enabled or not current_class.has_implementation_error then
2234 error_handler.report_giaaa_error
2235 end
2236 else
2237 find_unqualified_procedure_call_agent_type (an_expression, l_procedure, a_context)
2238 end
2239 else
2240 -- We still need to find `l_query'.
2241 l_query := current_class.seeded_query (a_seed)
2242 if l_query = Void then
2243 -- Internal error: if we got a seed, `l_query' should not be void.
2244 -- This error should have already been reported when checking
2245 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2246 set_fatal_error
2247 if internal_error_enabled or not current_class.has_implementation_error then
2248 error_handler.report_giaaa_error
2249 end
2250 else
2251 find_unqualified_query_call_agent_type (an_expression, l_query, a_context)
2252 end
2253 end
2254 end
2255
2256 find_unqualified_query_call_agent_type (an_expression: ET_CALL_AGENT; a_query: ET_QUERY; a_context: ET_NESTED_TYPE_CONTEXT)
2257 -- `a_context' represents the type in which `an_expression' appears.
2258 -- It will be altered on exit to represent the type of `an_expression'.
2259 -- Set `has_fatal_error' if a fatal error occurred.
2260 require
2261 an_expression_not_void: an_expression /= Void
2262 unqualified_call_agent: not an_expression.is_qualified_call
2263 query_call: not an_expression.is_procedure
2264 seeded: an_expression.name.seed /= 0
2265 a_query_not_void: a_query /= Void
2266 a_context_not_void: a_context /= Void
2267 local
2268 a_name: ET_FEATURE_NAME
2269 a_type: ET_TYPE
2270 an_open_operands: detachable ET_ACTUAL_PARAMETER_LIST
2271 a_formal_arguments: detachable ET_FORMAL_ARGUMENT_LIST
2272 a_tuple_type: ET_TUPLE_TYPE
2273 a_parameters: ET_ACTUAL_PARAMETER_LIST
2274 an_agent_type: ET_CLASS_TYPE
2275 an_agent_class: ET_NAMED_CLASS
2276 do
2277 reset_fatal_error (False)
2278 a_name := an_expression.name
2279 a_formal_arguments := a_query.arguments
2280 if a_formal_arguments /= Void then
2281 create an_open_operands.make_with_capacity (a_formal_arguments.count)
2282 fill_open_operands (an_expression, a_query, an_open_operands)
2283 end
2284 if not has_fatal_error then
2285 create a_tuple_type.make (tokens.implicit_attached_type_mark, an_open_operands, current_universe_impl.tuple_type.named_base_class)
2286 a_type := a_query.type
2287 -- TODO: like argument
2288 if a_type.same_named_type (current_universe_impl.boolean_type, current_type, current_type) then
2289 a_context.force_last (a_tuple_type)
2290 an_agent_type := current_universe_impl.predicate_like_current_type
2291 else
2292 an_agent_class := current_universe_impl.function_type.named_base_class
2293 if current_universe_impl.function_type.actual_parameter_count = 3 then
2294 create a_parameters.make_with_capacity (3)
2295 a_parameters.put_first (a_type)
2296 a_parameters.put_first (a_tuple_type)
2297 a_parameters.put_first (current_type)
2298 else
2299 create a_parameters.make_with_capacity (2)
2300 a_parameters.put_first (a_type)
2301 a_parameters.put_first (a_tuple_type)
2302 end
2303 create an_agent_type.make_generic (tokens.implicit_attached_type_mark, an_agent_class.name, a_parameters, an_agent_class)
2304 end
2305 a_context.force_last (an_agent_type)
2306 end
2307 end
2308
2309 find_unqualified_procedure_call_agent_type (an_expression: ET_CALL_AGENT; a_procedure: ET_PROCEDURE; a_context: ET_NESTED_TYPE_CONTEXT)
2310 -- `a_context' represents the type in which `an_expression' appears.
2311 -- It will be altered on exit to represent the type of `an_expression'.
2312 -- Set `has_fatal_error' if a fatal error occurred.
2313 require
2314 an_expression_not_void: an_expression /= Void
2315 unqualified_call_agent: not an_expression.is_qualified_call
2316 procedure_call: an_expression.is_procedure
2317 seeded: an_expression.name.seed /= 0
2318 a_procedure_not_void: a_procedure /= Void
2319 a_context_not_void: a_context /= Void
2320 local
2321 a_name: ET_FEATURE_NAME
2322 an_open_operands: detachable ET_ACTUAL_PARAMETER_LIST
2323 a_formal_arguments: detachable ET_FORMAL_ARGUMENT_LIST
2324 a_tuple_type: ET_TUPLE_TYPE
2325 an_agent_type: ET_CLASS_TYPE
2326 do
2327 reset_fatal_error (False)
2328 a_name := an_expression.name
2329 a_formal_arguments := a_procedure.arguments
2330 if a_formal_arguments /= Void then
2331 create an_open_operands.make_with_capacity (a_formal_arguments.count)
2332 fill_open_operands (an_expression, a_procedure, an_open_operands)
2333 end
2334 if not has_fatal_error then
2335 create a_tuple_type.make (tokens.implicit_attached_type_mark, an_open_operands, current_universe_impl.tuple_type.named_base_class)
2336 a_context.force_last (a_tuple_type)
2337 an_agent_type := current_universe_impl.procedure_like_current_type
2338 a_context.force_last (an_agent_type)
2339 end
2340 end
2341
2342 find_qualified_call_agent_type (an_expression: ET_CALL_AGENT; a_target: ET_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
2343 -- `a_context' represents the type in which `an_expression' appears.
2344 -- It will be altered on exit to represent the type of `an_expression'.
2345 -- Set `has_fatal_error' if a fatal error occurred.
2346 require
2347 an_expression_not_void: an_expression /= Void
2348 qualified_call_agent: an_expression.is_qualified_call
2349 a_target_not_void: a_target /= Void
2350 valid_target: a_target = an_expression.target
2351 a_context_not_void: a_context /= Void
2352 local
2353 a_name: ET_FEATURE_NAME
2354 a_class: ET_CLASS
2355 l_query: detachable ET_QUERY
2356 l_procedure: detachable ET_PROCEDURE
2357 a_seed: INTEGER
2358 do
2359 reset_fatal_error (False)
2360 a_name := an_expression.name
2361 a_seed := a_name.seed
2362 find_expression_type (a_target, a_context, current_system.detachable_any_type)
2363 if has_fatal_error then
2364 -- Do nothing.
2365 elseif a_seed <= 0 then
2366 -- This error should have already been reported when checking
2367 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2368 set_fatal_error
2369 if internal_error_enabled or not current_class.has_implementation_error then
2370 error_handler.report_giaaa_error
2371 end
2372 elseif a_name.is_tuple_label then
2373 -- TODO: when `a_target' is an identifier, check whether it is either
2374 -- a local variable, a formal argument or the name of an attribute.
2375 find_qualified_tuple_label_call_agent_type (an_expression, a_target, a_context)
2376 elseif an_expression.is_procedure then
2377 -- TODO: when `a_target' is an identifier, check whether it is either
2378 -- a local variable, a formal argument or the name of an attribute.
2379 a_class := a_context.base_class
2380 l_procedure := a_class.seeded_procedure (a_seed)
2381 if l_procedure = Void then
2382 -- Internal error: if we got a seed, `l_procedure' should not be void.
2383 -- This error should have already been reported when checking
2384 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2385 set_fatal_error
2386 if internal_error_enabled or not current_class.has_implementation_error then
2387 error_handler.report_giaaa_error
2388 end
2389 else
2390 find_qualified_procedure_call_agent_type (an_expression, a_target, l_procedure, a_context)
2391 end
2392 else
2393 -- TODO: when `a_target' is an identifier, check whether it is either
2394 -- a local variable, a formal argument or the name of an attribute.
2395 a_class := a_context.base_class
2396 l_query := a_class.seeded_query (a_seed)
2397 if l_query = Void then
2398 -- Internal error: if we got a seed, `l_query' should not be void.
2399 -- This error should have already been reported when checking
2400 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2401 set_fatal_error
2402 if internal_error_enabled or not current_class.has_implementation_error then
2403 error_handler.report_giaaa_error
2404 end
2405 else
2406 find_qualified_query_call_agent_type (an_expression, a_target, l_query, a_context)
2407 end
2408 end
2409 end
2410
2411 find_qualified_query_call_agent_type (an_expression: ET_CALL_AGENT; a_target: ET_EXPRESSION; a_query: ET_QUERY; a_context: ET_NESTED_TYPE_CONTEXT)
2412 -- `a_context' represents the type of the target.
2413 -- It will be altered on exit to represent the type of `an_expression'.
2414 -- Set `has_fatal_error' if a fatal error occurred.
2415 require
2416 an_expression_not_void: an_expression /= Void
2417 qualified_call_agent: an_expression.is_qualified_call
2418 a_target_not_void: a_target /= Void
2419 valid_target: a_target = an_expression.target
2420 query_call: not an_expression.is_procedure
2421 seeded: an_expression.name.seed /= 0
2422 a_query_not_void: a_query /= Void
2423 a_context_not_void: a_context /= Void
2424 local
2425 a_name: ET_FEATURE_NAME
2426 a_type: ET_TYPE
2427 a_seed: INTEGER
2428 a_target_type: ET_TYPE
2429 an_open_operands: detachable ET_ACTUAL_PARAMETER_LIST
2430 a_formal_arguments: detachable ET_FORMAL_ARGUMENT_LIST
2431 a_tuple_type: ET_TUPLE_TYPE
2432 a_parameters: ET_ACTUAL_PARAMETER_LIST
2433 an_agent_type: ET_CLASS_TYPE
2434 an_agent_class: ET_NAMED_CLASS
2435 do
2436 reset_fatal_error (False)
2437 a_name := an_expression.name
2438 a_seed := a_name.seed
2439 a_formal_arguments := a_query.arguments
2440 if a_formal_arguments /= Void then
2441 create an_open_operands.make_with_capacity (a_formal_arguments.count)
2442 fill_open_operands (an_expression, a_query, an_open_operands)
2443 end
2444 if not has_fatal_error then
2445 a_target_type := tokens.identity_type
2446 create a_tuple_type.make (tokens.implicit_attached_type_mark, an_open_operands, current_universe_impl.tuple_type.named_base_class)
2447 a_type := a_query.type
2448 -- TODO: like argument
2449 if a_type.same_named_type (current_universe_impl.boolean_type, current_type, current_type) then
2450 a_context.force_last (a_tuple_type)
2451 an_agent_type := current_universe_impl.predicate_like_current_type
2452 else
2453 an_agent_class := current_universe_impl.function_type.named_base_class
2454 if current_universe_impl.function_type.actual_parameter_count = 3 then
2455 create a_parameters.make_with_capacity (3)
2456 a_parameters.put_first (a_type)
2457 a_parameters.put_first (a_tuple_type)
2458 a_parameters.put_first (a_target_type)
2459 else
2460 create a_parameters.make_with_capacity (2)
2461 a_parameters.put_first (a_type)
2462 a_parameters.put_first (a_tuple_type)
2463 end
2464 create an_agent_type.make_generic (tokens.implicit_attached_type_mark, an_agent_class.name, a_parameters, an_agent_class)
2465 end
2466 a_context.force_last (an_agent_type)
2467 end
2468 end
2469
2470 find_qualified_procedure_call_agent_type (an_expression: ET_CALL_AGENT; a_target: ET_EXPRESSION; a_procedure: ET_PROCEDURE; a_context: ET_NESTED_TYPE_CONTEXT)
2471 -- `a_context' represents the type of the target.
2472 -- It will be altered on exit to represent the type of `an_expression'.
2473 -- Set `has_fatal_error' if a fatal error occurred.
2474 require
2475 an_expression_not_void: an_expression /= Void
2476 qualified_call_agent: an_expression.is_qualified_call
2477 a_target_not_void: a_target /= Void
2478 valid_target: a_target = an_expression.target
2479 procedure_call: an_expression.is_procedure
2480 seeded: an_expression.name.seed /= 0
2481 a_procedure_not_void: a_procedure /= Void
2482 a_context_not_void: a_context /= Void
2483 local
2484 a_name: ET_FEATURE_NAME
2485 a_seed: INTEGER
2486 an_open_operands: detachable ET_ACTUAL_PARAMETER_LIST
2487 a_formal_arguments: detachable ET_FORMAL_ARGUMENT_LIST
2488 a_tuple_type: ET_TUPLE_TYPE
2489 an_agent_type: ET_CLASS_TYPE
2490 do
2491 reset_fatal_error (False)
2492 a_name := an_expression.name
2493 a_seed := a_name.seed
2494 a_formal_arguments := a_procedure.arguments
2495 if a_formal_arguments /= Void then
2496 create an_open_operands.make_with_capacity (a_formal_arguments.count)
2497 fill_open_operands (an_expression, a_procedure, an_open_operands)
2498 end
2499 if not has_fatal_error then
2500 create a_tuple_type.make (tokens.implicit_attached_type_mark, an_open_operands, current_universe_impl.tuple_type.named_base_class)
2501 a_context.force_last (a_tuple_type)
2502 an_agent_type := current_universe_impl.procedure_like_current_type
2503 a_context.force_last (an_agent_type)
2504 end
2505 end
2506
2507 find_qualified_tuple_label_call_agent_type (an_expression: ET_CALL_AGENT; a_target: ET_EXPRESSION; a_context: ET_NESTED_TYPE_CONTEXT)
2508 -- `a_context' represents the type of the target.
2509 -- It will be altered on exit to represent the type of `an_expression'.
2510 -- Set `has_fatal_error' if a fatal error occurred.
2511 require
2512 an_expression_not_void: an_expression /= Void
2513 qualified_call_agent: an_expression.is_qualified_call
2514 a_target_not_void: a_target /= Void
2515 valid_target: a_target = an_expression.target
2516 query_call: not an_expression.is_procedure
2517 tuple_label: an_expression.name.is_tuple_label
2518 indexed: an_expression.name.seed /= 0
2519 a_context_not_void: a_context /= Void
2520 local
2521 l_name: ET_FEATURE_NAME
2522 l_index: INTEGER
2523 l_type: ET_TYPE
2524 l_parameters: ET_ACTUAL_PARAMETER_LIST
2525 l_agent_type: ET_CLASS_TYPE
2526 l_agent_class: ET_NAMED_CLASS
2527 l_target_type: ET_TYPE
2528 do
2529 reset_fatal_error (False)
2530 l_name := an_expression.name
2531 l_index := l_name.seed
2532 l_type := a_context.base_class.formal_parameter_type (l_index)
2533 l_target_type := tokens.identity_type
2534 if l_type.same_named_type (current_universe_impl.boolean_type, current_type, current_type) then
2535 a_context.force_last (current_universe_impl.detachable_tuple_type)
2536 l_agent_type := current_universe_impl.predicate_like_current_type
2537 else
2538 l_agent_class := current_universe_impl.function_type.named_base_class
2539 if current_universe_impl.function_type.actual_parameter_count = 3 then
2540 create l_parameters.make_with_capacity (3)
2541 l_parameters.put_first (l_type)
2542 l_parameters.put_first (current_universe_impl.detachable_tuple_type)
2543 l_parameters.put_first (l_target_type)
2544 else
2545 create l_parameters.make_with_capacity (2)
2546 l_parameters.put_first (l_type)
2547 l_parameters.put_first (current_universe_impl.detachable_tuple_type)
2548 end
2549 create l_agent_type.make_generic (tokens.implicit_attached_type_mark, l_agent_class.name, l_parameters, l_agent_class)
2550 end
2551 a_context.force_last (l_agent_type)
2552 end
2553
2554 find_typed_call_agent_type (an_expression: ET_CALL_AGENT; a_target: ET_AGENT_OPEN_TARGET; a_context: ET_NESTED_TYPE_CONTEXT)
2555 -- `a_context' represents the type in which `an_expression' appears.
2556 -- It will be altered on exit to represent the type of `an_expression'.
2557 -- Set `has_fatal_error' if a fatal error occurred.
2558 require
2559 an_expression_not_void: an_expression /= Void
2560 qualified_call_agent: an_expression.is_qualified_call
2561 a_target_not_void: a_target /= Void
2562 valid_target: a_target = an_expression.target
2563 a_context_not_void: a_context /= Void
2564 local
2565 a_name: ET_FEATURE_NAME
2566 a_class: ET_CLASS
2567 l_query: detachable ET_QUERY
2568 l_procedure: detachable ET_PROCEDURE
2569 a_seed: INTEGER
2570 a_target_type: ET_TYPE
2571 do
2572 reset_fatal_error (False)
2573 a_name := an_expression.name
2574 a_target_type := a_target.type
2575 a_seed := a_name.seed
2576 if a_seed <= 0 then
2577 -- This error should have already been reported when checking
2578 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2579 set_fatal_error
2580 if internal_error_enabled or not current_class.has_implementation_error then
2581 error_handler.report_giaaa_error
2582 end
2583 elseif a_name.is_tuple_label then
2584 a_context.force_last (a_target_type)
2585 find_typed_tuple_label_call_agent_type (an_expression, a_target, a_context)
2586 elseif an_expression.is_procedure then
2587 a_context.force_last (a_target_type)
2588 a_class := a_context.base_class
2589 l_procedure := a_class.seeded_procedure (a_seed)
2590 if l_procedure = Void then
2591 -- Internal error: if we got a seed, `l_procedure' should not be void.
2592 -- This error should have already been reported when checking
2593 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2594 set_fatal_error
2595 if internal_error_enabled or not current_class.has_implementation_error then
2596 error_handler.report_giaaa_error
2597 end
2598 else
2599 find_typed_procedure_call_agent_type (an_expression, a_target, l_procedure, a_context)
2600 end
2601 else
2602 a_context.force_last (a_target_type)
2603 a_class := a_context.base_class
2604 l_query := a_class.seeded_query (a_seed)
2605 if l_query = Void then
2606 -- Internal error: if we got a seed, `l_query' should not be void.
2607 -- This error should have already been reported when checking
2608 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2609 set_fatal_error
2610 if internal_error_enabled or not current_class.has_implementation_error then
2611 error_handler.report_giaaa_error
2612 end
2613 else
2614 find_typed_query_call_agent_type (an_expression, a_target, l_query, a_context)
2615 end
2616 end
2617 end
2618
2619 find_typed_query_call_agent_type (an_expression: ET_CALL_AGENT; a_target: ET_AGENT_OPEN_TARGET; a_query: ET_QUERY; a_context: ET_NESTED_TYPE_CONTEXT)
2620 -- `a_context' represents the type of the target.
2621 -- It will be altered on exit to represent the type of `an_expression'.
2622 -- Set `has_fatal_error' if a fatal error occurred.
2623 require
2624 an_expression_not_void: an_expression /= Void
2625 qualified_call_agent: an_expression.is_qualified_call
2626 a_target_not_void: a_target /= Void
2627 valid_target: a_target = an_expression.target
2628 query_call: not an_expression.is_procedure
2629 seeded: an_expression.name.seed /= 0
2630 a_query_not_void: a_query /= Void
2631 a_context_not_void: a_context /= Void
2632 local
2633 a_name: ET_FEATURE_NAME
2634 a_result_type: ET_TYPE
2635 a_seed: INTEGER
2636 a_target_type: ET_TYPE
2637 an_open_operands: ET_ACTUAL_PARAMETER_LIST
2638 a_formal_arguments: detachable ET_FORMAL_ARGUMENT_LIST
2639 a_tuple_type: ET_TUPLE_TYPE
2640 a_parameters: ET_ACTUAL_PARAMETER_LIST
2641 an_agent_type: ET_CLASS_TYPE
2642 an_agent_class: ET_NAMED_CLASS
2643 do
2644 reset_fatal_error (False)
2645 a_name := an_expression.name
2646 a_seed := a_name.seed
2647 a_target_type := a_target.type
2648 a_formal_arguments := a_query.arguments
2649 if a_formal_arguments /= Void then
2650 create an_open_operands.make_with_capacity (a_formal_arguments.count + 1)
2651 fill_open_operands (an_expression, a_query, an_open_operands)
2652 else
2653 create an_open_operands.make_with_capacity (1)
2654 end
2655 if not has_fatal_error then
2656 a_target_type := tokens.identity_type
2657 an_open_operands.put_first (a_target_type)
2658 create a_tuple_type.make (tokens.implicit_attached_type_mark, an_open_operands, current_universe_impl.tuple_type.named_base_class)
2659 a_result_type := a_query.type
2660 -- TODO: like argument
2661 if a_result_type.same_named_type (current_universe_impl.boolean_type, current_type, current_type) then
2662 a_context.force_last (a_tuple_type)
2663 an_agent_type := current_universe_impl.predicate_like_current_type
2664 else
2665 an_agent_class := current_universe_impl.function_type.named_base_class
2666 if current_universe_impl.function_type.actual_parameter_count = 3 then
2667 create a_parameters.make_with_capacity (3)
2668 a_parameters.put_first (a_result_type)
2669 a_parameters.put_first (a_tuple_type)
2670 a_parameters.put_first (a_target_type)
2671 else
2672 create a_parameters.make_with_capacity (2)
2673 a_parameters.put_first (a_result_type)
2674 a_parameters.put_first (a_tuple_type)
2675 end
2676 create an_agent_type.make_generic (tokens.implicit_attached_type_mark, an_agent_class.name, a_parameters, an_agent_class)
2677 end
2678 a_context.force_last (an_agent_type)
2679 end
2680 end
2681
2682 find_typed_procedure_call_agent_type (an_expression: ET_CALL_AGENT; a_target: ET_AGENT_OPEN_TARGET; a_procedure: ET_PROCEDURE; a_context: ET_NESTED_TYPE_CONTEXT)
2683 -- `a_context' represents the type of the target.
2684 -- It will be altered on exit to represent the type of `an_expression'.
2685 -- Set `has_fatal_error' if a fatal error occurred.
2686 require
2687 an_expression_not_void: an_expression /= Void
2688 qualified_call_agent: an_expression.is_qualified_call
2689 a_target_not_void: a_target /= Void
2690 valid_target: a_target = an_expression.target
2691 procedure_call: an_expression.is_procedure
2692 seeded: an_expression.name.seed /= 0
2693 a_procedure_not_void: a_procedure /= Void
2694 a_context_not_void: a_context /= Void
2695 local
2696 a_name: ET_FEATURE_NAME
2697 a_seed: INTEGER
2698 an_open_operands: ET_ACTUAL_PARAMETER_LIST
2699 a_formal_arguments: detachable ET_FORMAL_ARGUMENT_LIST
2700 a_tuple_type: ET_TUPLE_TYPE
2701 an_agent_type: ET_CLASS_TYPE
2702 do
2703 reset_fatal_error (False)
2704 a_name := an_expression.name
2705 a_seed := a_name.seed
2706 a_formal_arguments := a_procedure.arguments
2707 if a_formal_arguments /= Void then
2708 create an_open_operands.make_with_capacity (a_formal_arguments.count + 1)
2709 fill_open_operands (an_expression, a_procedure, an_open_operands)
2710 else
2711 create an_open_operands.make_with_capacity (1)
2712 end
2713 if not has_fatal_error then
2714 an_open_operands.put_first (tokens.identity_type)
2715 create a_tuple_type.make (tokens.implicit_attached_type_mark, an_open_operands, current_universe_impl.tuple_type.named_base_class)
2716 a_context.force_last (a_tuple_type)
2717 an_agent_type := current_universe_impl.procedure_like_current_type
2718 a_context.force_last (an_agent_type)
2719 end
2720 end
2721
2722 find_typed_tuple_label_call_agent_type (an_expression: ET_CALL_AGENT; a_target: ET_AGENT_OPEN_TARGET; a_context: ET_NESTED_TYPE_CONTEXT)
2723 -- `a_context' represents the type of the target.
2724 -- It will be altered on exit to represent the type of `an_expression'.
2725 -- Set `has_fatal_error' if a fatal error occurred.
2726 require
2727 an_expression_not_void: an_expression /= Void
2728 qualified_call_agent: an_expression.is_qualified_call
2729 a_target_not_void: a_target /= Void
2730 valid_target: a_target = an_expression.target
2731 query_call: not an_expression.is_procedure
2732 tuple_label: an_expression.name.is_tuple_label
2733 indexed: an_expression.name.seed /= 0
2734 a_context_not_void: a_context /= Void
2735 local
2736 l_name: ET_FEATURE_NAME
2737 l_index: INTEGER
2738 l_type: ET_TYPE
2739 l_parameters: ET_ACTUAL_PARAMETER_LIST
2740 l_agent_type: ET_CLASS_TYPE
2741 l_agent_class: ET_NAMED_CLASS
2742 l_target_type: ET_TYPE
2743 l_open_operands: ET_ACTUAL_PARAMETER_LIST
2744 l_tuple_type: ET_TUPLE_TYPE
2745 do
2746 reset_fatal_error (False)
2747 l_name := an_expression.name
2748 l_index := l_name.seed
2749 l_type := a_context.base_class.formal_parameter_type (l_index)
2750 l_target_type := a_target.type
2751 create l_open_operands.make_with_capacity (1)
2752 l_open_operands.put_first (l_target_type)
2753 create l_tuple_type.make (tokens.implicit_attached_type_mark, l_open_operands, current_universe_impl.tuple_type.named_base_class)
2754 if l_type.same_named_type (current_universe_impl.boolean_type, current_type, current_type) then
2755 a_context.force_last (l_tuple_type)
2756 l_agent_type := current_universe_impl.predicate_like_current_type
2757 else
2758 l_agent_class := current_universe_impl.function_type.named_base_class
2759 if current_universe_impl.function_type.actual_parameter_count = 3 then
2760 create l_parameters.make_with_capacity (3)
2761 l_parameters.put_first (l_type)
2762 l_parameters.put_first (l_tuple_type)
2763 l_parameters.put_first (l_target_type)
2764 else
2765 create l_parameters.make_with_capacity (2)
2766 l_parameters.put_first (l_type)
2767 l_parameters.put_first (l_tuple_type)
2768 end
2769 create l_agent_type.make_generic (tokens.implicit_attached_type_mark, l_agent_class.name, l_parameters, l_agent_class)
2770 end
2771 a_context.force_last (l_agent_type)
2772 end
2773
2774 find_do_function_inline_agent_type (an_expression: ET_DO_FUNCTION_INLINE_AGENT; a_context: ET_NESTED_TYPE_CONTEXT)
2775 -- `a_context' represents the type in which `an_expression' appears.
2776 -- It will be altered on exit to represent the type of `an_expression'.
2777 -- Set `has_fatal_error' if a fatal error occurred.
2778 require
2779 an_expression_not_void: an_expression /= Void
2780 a_context_not_void: a_context /= Void
2781 do
2782 find_query_inline_agent_type (an_expression, a_context)
2783 end
2784
2785 find_do_procedure_inline_agent_type (an_expression: ET_DO_PROCEDURE_INLINE_AGENT; a_context: ET_NESTED_TYPE_CONTEXT)
2786 -- `a_context' represents the type in which `an_expression' appears.
2787 -- It will be altered on exit to represent the type of `an_expression'.
2788 -- Set `has_fatal_error' if a fatal error occurred.
2789 require
2790 an_expression_not_void: an_expression /= Void
2791 a_context_not_void: a_context /= Void
2792 do
2793 find_procedure_inline_agent_type (an_expression, a_context)
2794 end
2795
2796 find_external_function_inline_agent_type (an_expression: ET_EXTERNAL_FUNCTION_INLINE_AGENT; a_context: ET_NESTED_TYPE_CONTEXT)
2797 -- `a_context' represents the type in which `an_expression' appears.
2798 -- It will be altered on exit to represent the type of `an_expression'.
2799 -- Set `has_fatal_error' if a fatal error occurred.
2800 require
2801 an_expression_not_void: an_expression /= Void
2802 a_context_not_void: a_context /= Void
2803 do
2804 find_query_inline_agent_type (an_expression, a_context)
2805 end
2806
2807 find_external_procedure_inline_agent_type (an_expression: ET_EXTERNAL_PROCEDURE_INLINE_AGENT; a_context: ET_NESTED_TYPE_CONTEXT)
2808 -- `a_context' represents the type in which `an_expression' appears.
2809 -- It will be altered on exit to represent the type of `an_expression'.
2810 -- Set `has_fatal_error' if a fatal error occurred.
2811 require
2812 an_expression_not_void: an_expression /= Void
2813 a_context_not_void: a_context /= Void
2814 do
2815 find_procedure_inline_agent_type (an_expression, a_context)
2816 end
2817
2818 find_once_function_inline_agent_type (an_expression: ET_ONCE_FUNCTION_INLINE_AGENT; a_context: ET_NESTED_TYPE_CONTEXT)
2819 -- `a_context' represents the type in which `an_expression' appears.
2820 -- It will be altered on exit to represent the type of `an_expression'.
2821 -- Set `has_fatal_error' if a fatal error occurred.
2822 require
2823 an_expression_not_void: an_expression /= Void
2824 a_context_not_void: a_context /= Void
2825 do
2826 find_query_inline_agent_type (an_expression, a_context)
2827 end
2828
2829 find_once_procedure_inline_agent_type (an_expression: ET_ONCE_PROCEDURE_INLINE_AGENT; a_context: ET_NESTED_TYPE_CONTEXT)
2830 -- `a_context' represents the type in which `an_expression' appears.
2831 -- It will be altered on exit to represent the type of `an_expression'.
2832 -- Set `has_fatal_error' if a fatal error occurred.
2833 require
2834 an_expression_not_void: an_expression /= Void
2835 a_context_not_void: a_context /= Void
2836 do
2837 find_procedure_inline_agent_type (an_expression, a_context)
2838 end
2839
2840 find_query_inline_agent_type (an_expression: ET_QUERY_INLINE_AGENT; a_context: ET_NESTED_TYPE_CONTEXT)
2841 -- `a_context' represents the type in which `an_expression' appears.
2842 -- It will be altered on exit to represent the type of `an_expression'.
2843 -- Set `has_fatal_error' if a fatal error occurred.
2844 require
2845 an_expression_not_void: an_expression /= Void
2846 a_context_not_void: a_context /= Void
2847 local
2848 a_type: ET_TYPE
2849 an_open_operands: detachable ET_ACTUAL_PARAMETER_LIST
2850 a_formal_arguments: detachable ET_FORMAL_ARGUMENT_LIST
2851 a_tuple_type: ET_TUPLE_TYPE
2852 a_parameters: ET_ACTUAL_PARAMETER_LIST
2853 an_agent_type: ET_CLASS_TYPE
2854 an_agent_class: ET_NAMED_CLASS
2855 do
2856 reset_fatal_error (False)
2857 a_formal_arguments := an_expression.formal_arguments
2858 if a_formal_arguments /= Void then
2859 create an_open_operands.make_with_capacity (a_formal_arguments.count)
2860 fill_open_operands (an_expression, an_expression, an_open_operands)
2861 end
2862 if not has_fatal_error then
2863 create a_tuple_type.make (tokens.implicit_attached_type_mark, an_open_operands, current_universe_impl.tuple_type.named_base_class)
2864 a_type := an_expression.type
2865 -- TODO: like argument
2866 if a_type.same_named_type (current_universe_impl.boolean_type, current_type, current_type) then
2867 a_context.force_last (a_tuple_type)
2868 an_agent_type := current_universe_impl.predicate_like_current_type
2869 else
2870 an_agent_class := current_universe_impl.function_type.named_base_class
2871 if current_universe_impl.function_type.actual_parameter_count = 3 then
2872 create a_parameters.make_with_capacity (3)
2873 a_parameters.put_first (a_type)
2874 a_parameters.put_first (a_tuple_type)
2875 a_parameters.put_first (current_type)
2876 else
2877 create a_parameters.make_with_capacity (2)
2878 a_parameters.put_first (a_type)
2879 a_parameters.put_first (a_tuple_type)
2880 end
2881 create an_agent_type.make_generic (tokens.implicit_attached_type_mark, an_agent_class.name, a_parameters, an_agent_class)
2882 end
2883 a_context.force_last (an_agent_type)
2884 end
2885 end
2886
2887 find_procedure_inline_agent_type (an_expression: ET_PROCEDURE_INLINE_AGENT; a_context: ET_NESTED_TYPE_CONTEXT)
2888 -- `a_context' represents the type in which `an_expression' appears.
2889 -- It will be altered on exit to represent the type of `an_expression'.
2890 -- Set `has_fatal_error' if a fatal error occurred.
2891 require
2892 an_expression_not_void: an_expression /= Void
2893 a_context_not_void: a_context /= Void
2894 local
2895 an_open_operands: detachable ET_ACTUAL_PARAMETER_LIST
2896 a_formal_arguments: detachable ET_FORMAL_ARGUMENT_LIST
2897 a_tuple_type: ET_TUPLE_TYPE
2898 an_agent_type: ET_CLASS_TYPE
2899 do
2900 reset_fatal_error (False)
2901 a_formal_arguments := an_expression.formal_arguments
2902 if a_formal_arguments /= Void then
2903 create an_open_operands.make_with_capacity (a_formal_arguments.count)
2904 fill_open_operands (an_expression, an_expression, an_open_operands)
2905 end
2906 if not has_fatal_error then
2907 create a_tuple_type.make (tokens.implicit_attached_type_mark, an_open_operands, current_universe_impl.tuple_type.named_base_class)
2908 a_context.force_last (a_tuple_type)
2909 an_agent_type := current_universe_impl.procedure_like_current_type
2910 a_context.force_last (an_agent_type)
2911 end
2912 end
2913
2914 fill_open_operands (an_agent: ET_AGENT; a_closure: ET_CLOSURE; an_open_operands: ET_ACTUAL_PARAMETER_LIST)
2915 -- Fill in `an_open_operands' the types of the open arguments of `an_agent'
2916 -- where the corresponding formal arguments are those of `a_closure'.
2917 -- Set `has_fatal_error' if a fatal error occurred.
2918 --
2919 -- Note that the target of `an_agent' is an open operand, it will be
2920 -- inserted in `an_open_operands' elsewhere.
2921 require
2922 an_agent_not_void: an_agent /= Void
2923 a_closure_not_void: a_closure /= Void
2924 an_open_operands_not_void: an_open_operands /= Void
2925 an_open_operands_empty: an_open_operands.is_empty
2926 local
2927 l_actuals: detachable ET_AGENT_ARGUMENT_OPERANDS
2928 l_formal_type: ET_TYPE
2929 i, nb: INTEGER
2930 l_agent_actual: ET_AGENT_ARGUMENT_OPERAND
2931 l_formal: ET_FORMAL_ARGUMENT
2932 had_error: BOOLEAN
2933 l_actual_type: ET_TYPE
2934 l_formals: detachable ET_FORMAL_ARGUMENT_LIST
2935 do
2936 reset_fatal_error (False)
2937 l_formals := a_closure.arguments
2938 l_actuals := an_agent.arguments
2939 if not attached {ET_AGENT_ARGUMENT_OPERAND_LIST} l_actuals as l_actual_list then
2940 if l_formals /= Void then
2941 nb := l_formals.count
2942 from i := nb until i < 1 loop
2943 l_formal_type := l_formals.formal_argument (i).type
2944 an_open_operands.force_first (l_formal_type)
2945 i := i - 1
2946 end
2947 end
2948 else
2949 if l_actual_list.is_empty then
2950 if l_formals /= Void and then not l_formals.is_empty then
2951 -- Invalid number of actual arguments.
2952 -- This error should have already been reported when checking
2953 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2954 set_fatal_error
2955 if internal_error_enabled or not current_class.has_implementation_error then
2956 error_handler.report_giaaa_error
2957 end
2958 end
2959 elseif l_formals = Void or else l_formals.count /= l_actual_list.count then
2960 -- Invalid number of actual arguments.
2961 -- This error should have already been reported when checking
2962 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2963 set_fatal_error
2964 if internal_error_enabled or not current_class.has_implementation_error then
2965 error_handler.report_giaaa_error
2966 end
2967 else
2968 nb := l_actual_list.count
2969 from i := nb until i < 1 loop
2970 had_error := had_error or has_fatal_error
2971 l_formal := l_formals.formal_argument (i)
2972 l_agent_actual := l_actual_list.actual_argument (i)
2973 if attached {ET_EXPRESSION} l_agent_actual then
2974 -- Closed operands.
2975 elseif attached {ET_AGENT_TYPED_OPEN_ARGUMENT} l_agent_actual as l_agent_type then
2976 l_actual_type := l_agent_type.type
2977 an_open_operands.force_first (l_actual_type)
2978 elseif attached {ET_QUESTION_MARK_SYMBOL} l_agent_actual then
2979 l_formal_type := l_formal.type
2980 an_open_operands.force_first (l_formal_type)
2981 else
2982 -- Internal error: no other kind of agent actual arguments.
2983 -- This error should have already been reported when checking
2984 -- `current_feature' (using ET_FEATURE_CHECKER for example).
2985 set_fatal_error
2986 end
2987 i := i - 1
2988 end
2989 reset_fatal_error (has_fatal_error or had_error)
2990 end
2991 end
2992 end
2993
2994 feature {ET_AST_NODE} -- Processing
2995
2996 process_across_expression (an_expression: ET_ACROSS_EXPRESSION)
2997 -- Process `an_expression'.
2998 do
2999 find_across_expression_type (an_expression, current_context)
3000 end
3001
3002 process_binary_integer_constant (a_constant: ET_BINARY_INTEGER_CONSTANT)
3003 -- Process `a_constant'.
3004 do
3005 find_binary_integer_constant_type (a_constant, current_context)
3006 end
3007
3008 process_bracket_expression (an_expression: ET_BRACKET_EXPRESSION)
3009 -- Process `an_expression'.
3010 do
3011 find_bracket_expression_type (an_expression, current_context)
3012 end
3013
3014 process_c1_character_constant (a_constant: ET_C1_CHARACTER_CONSTANT)
3015 -- Process `a_constant'.
3016 do
3017 find_c1_character_constant_type (a_constant, current_context)
3018 end
3019
3020 process_c2_character_constant (a_constant: ET_C2_CHARACTER_CONSTANT)
3021 -- Process `a_constant'.
3022 do
3023 find_c2_character_constant_type (a_constant, current_context)
3024 end
3025
3026 process_c3_character_constant (a_constant: ET_C3_CHARACTER_CONSTANT)
3027 -- Process `a_constant'.
3028 do
3029 find_c3_character_constant_type (a_constant, current_context)
3030 end
3031
3032 process_call_agent (an_expression: ET_CALL_AGENT)
3033 -- Process `an_expression'.
3034 do
3035 find_call_agent_type (an_expression, current_context)
3036 end
3037
3038 process_convert_builtin_expression (an_expression: ET_CONVERT_BUILTIN_EXPRESSION)
3039 -- Process `an_expression'.
3040 do
3041 find_convert_builtin_expression_type (an_expression, current_context)
3042 end
3043
3044 process_convert_from_expression (an_expression: ET_CONVERT_FROM_EXPRESSION)
3045 -- Process `an_expression'.
3046 do
3047 find_convert_from_expression_type (an_expression, current_context)
3048 end
3049
3050 process_convert_to_expression (an_expression: ET_CONVERT_TO_EXPRESSION)
3051 -- Process `an_expression'.
3052 do
3053 find_convert_to_expression_type (an_expression, current_context)
3054 end
3055
3056 process_create_expression (an_expression: ET_CREATE_EXPRESSION)
3057 -- Process `an_expression'.
3058 do
3059 find_create_expression_type (an_expression, current_context)
3060 end
3061
3062 process_current (an_expression: ET_CURRENT)
3063 -- Process `an_expression'.
3064 do
3065 find_current_type (an_expression, current_context)
3066 end
3067
3068 process_current_address (an_expression: ET_CURRENT_ADDRESS)
3069 -- Process `an_expression'.
3070 do
3071 find_current_address_type (an_expression, current_context)
3072 end
3073
3074 process_do_function_inline_agent (an_expression: ET_DO_FUNCTION_INLINE_AGENT)
3075 -- Process `an_expression'.
3076 do
3077 find_do_function_inline_agent_type (an_expression, current_context)
3078 end
3079
3080 process_do_procedure_inline_agent (an_expression: ET_DO_PROCEDURE_INLINE_AGENT)
3081 -- Process `an_expression'.
3082 do
3083 find_do_procedure_inline_agent_type (an_expression, current_context)
3084 end
3085
3086 process_equality_expression (an_expression: ET_EQUALITY_EXPRESSION)
3087 -- Process `an_expression'.
3088 do
3089 find_equality_expression_type (an_expression, current_context)
3090 end
3091
3092 process_expression_address (an_expression: ET_EXPRESSION_ADDRESS)
3093 -- Process `an_expression'.
3094 do
3095 find_expression_address_type (an_expression, current_context)
3096 end
3097
3098 process_external_function_inline_agent (an_expression: ET_EXTERNAL_FUNCTION_INLINE_AGENT)
3099 -- Process `an_expression'.
3100 do
3101 find_external_function_inline_agent_type (an_expression, current_context)
3102 end
3103
3104 process_external_procedure_inline_agent (an_expression: ET_EXTERNAL_PROCEDURE_INLINE_AGENT)
3105 -- Process `an_expression'.
3106 do
3107 find_external_procedure_inline_agent_type (an_expression, current_context)
3108 end
3109
3110 process_false_constant (a_constant: ET_FALSE_CONSTANT)
3111 -- Process `a_constant'.
3112 do
3113 find_false_constant_type (a_constant, current_context)
3114 end
3115
3116 process_feature_address (an_expression: ET_FEATURE_ADDRESS)
3117 -- Process `an_expression'.
3118 do
3119 find_feature_address_type (an_expression, current_context)
3120 end
3121
3122 process_hexadecimal_integer_constant (a_constant: ET_HEXADECIMAL_INTEGER_CONSTANT)
3123 -- Process `a_constant'.
3124 do
3125 find_hexadecimal_integer_constant_type (a_constant, current_context)
3126 end
3127
3128 process_identifier (an_identifier: ET_IDENTIFIER)
3129 -- Process `an_identifier'.
3130 do
3131 if an_identifier.is_argument then
3132 find_formal_argument_type (an_identifier, current_context)
3133 elseif an_identifier.is_local then
3134 find_local_variable_type (an_identifier, current_context)
3135 elseif an_identifier.is_object_test_local then
3136 find_object_test_local_type (an_identifier, current_context)
3137 elseif an_identifier.is_across_cursor then
3138 find_across_cursor_type (an_identifier, current_context)
3139 elseif not an_identifier.is_instruction then
3140 find_unqualified_call_expression_type (an_identifier, current_context)
3141 end
3142 end
3143
3144 process_infix_cast_expression (an_expression: ET_INFIX_CAST_EXPRESSION)
3145 -- Process `an_expression'.
3146 do
3147 find_infix_cast_expression_type (an_expression, current_context)
3148 end
3149
3150 process_infix_expression (an_expression: ET_INFIX_EXPRESSION)
3151 -- Process `an_expression'.
3152 do
3153 find_infix_expression_type (an_expression, current_context)
3154 end
3155
3156 process_manifest_array (an_expression: ET_MANIFEST_ARRAY)
3157 -- Process `an_expression'.
3158 do
3159 find_manifest_array_type (an_expression, current_context)
3160 end
3161
3162 process_manifest_tuple (an_expression: ET_MANIFEST_TUPLE)
3163 -- Process `an_expression'.
3164 do
3165 find_manifest_tuple_type (an_expression, current_context)
3166 end
3167
3168 process_manifest_type (an_expression: ET_MANIFEST_TYPE)
3169 -- Process `an_expression'.
3170 do
3171 find_manifest_type_type (an_expression, current_context)
3172 end
3173
3174 process_named_object_test (an_expression: ET_NAMED_OBJECT_TEST)
3175 -- Process `an_expression'.
3176 do
3177 find_object_test_type (an_expression, current_context)
3178 end
3179
3180 process_object_equality_expression (an_expression: ET_OBJECT_EQUALITY_EXPRESSION)
3181 -- Process `an_expression'.
3182 do
3183 find_object_equality_expression_type (an_expression, current_context)
3184 end
3185
3186 process_object_test (an_expression: ET_OBJECT_TEST)
3187 -- Process `an_expression'.
3188 do
3189 find_object_test_type (an_expression, current_context)
3190 end
3191
3192 process_octal_integer_constant (a_constant: ET_OCTAL_INTEGER_CONSTANT)
3193 -- Process `a_constant'.
3194 do
3195 find_octal_integer_constant_type (a_constant, current_context)
3196 end
3197
3198 process_old_expression (an_expression: ET_OLD_EXPRESSION)
3199 -- Process `an_expression'.
3200 do
3201 find_old_expression_type (an_expression, current_context)
3202 end
3203
3204 process_old_object_test (an_expression: ET_OLD_OBJECT_TEST)
3205 -- Process `an_expression'.
3206 do
3207 find_object_test_type (an_expression, current_context)
3208 end
3209
3210 process_once_function_inline_agent (an_expression: ET_ONCE_FUNCTION_INLINE_AGENT)
3211 -- Process `an_expression'.
3212 do
3213 find_once_function_inline_agent_type (an_expression, current_context)
3214 end
3215
3216 process_once_manifest_string (an_expression: ET_ONCE_MANIFEST_STRING)
3217 -- Process `an_expression'.
3218 do
3219 find_once_manifest_string_type (an_expression, current_context)
3220 end
3221
3222 process_once_procedure_inline_agent (an_expression: ET_ONCE_PROCEDURE_INLINE_AGENT)
3223 -- Process `an_expression'.
3224 do
3225 find_once_procedure_inline_agent_type (an_expression, current_context)
3226 end
3227
3228 process_parenthesized_expression (an_expression: ET_PARENTHESIZED_EXPRESSION)
3229 -- Process `an_expression'.
3230 do
3231 find_parenthesized_expression_type (an_expression, current_context)
3232 end
3233
3234 process_precursor_expression (an_expression: ET_PRECURSOR_EXPRESSION)
3235 -- Process `an_expression'.
3236 do
3237 find_precursor_expression_type (an_expression, current_context)
3238 end
3239
3240 process_prefix_expression (an_expression: ET_PREFIX_EXPRESSION)
3241 -- Process `an_expression'.
3242 do
3243 find_prefix_expression_type (an_expression, current_context)
3244 end
3245
3246 process_qualified_call_expression (an_expression: ET_QUALIFIED_CALL_EXPRESSION)
3247 -- Process `an_expression'.
3248 do
3249 find_qualified_call_expression_type (an_expression, current_context)
3250 end
3251
3252 process_regular_integer_constant (a_constant: ET_REGULAR_INTEGER_CONSTANT)
3253 -- Process `a_constant'.
3254 do
3255 find_regular_integer_constant_type (a_constant, current_context)
3256 end
3257
3258 process_regular_manifest_string (a_string: ET_REGULAR_MANIFEST_STRING)
3259 -- Process `a_string'.
3260 do
3261 find_regular_manifest_string_type (a_string, current_context)
3262 end
3263
3264 process_regular_real_constant (a_constant: ET_REGULAR_REAL_CONSTANT)
3265 -- Process `a_constant'.
3266 do
3267 find_regular_real_constant_type (a_constant, current_context)
3268 end
3269
3270 process_result (an_expression: ET_RESULT)
3271 -- Process `an_expression'.
3272 do
3273 find_result_type (an_expression, current_context)
3274 end
3275
3276 process_result_address (an_expression: ET_RESULT_ADDRESS)
3277 -- Process `an_expression'.
3278 do
3279 find_result_address_type (an_expression, current_context)
3280 end
3281
3282 process_special_manifest_string (a_string: ET_SPECIAL_MANIFEST_STRING)
3283 -- Process `a_string'.
3284 do
3285 find_special_manifest_string_type (a_string, current_context)
3286 end
3287
3288 process_static_call_expression (an_expression: ET_STATIC_CALL_EXPRESSION)
3289 -- Process `an_expression'.
3290 do
3291 find_static_call_expression_type (an_expression, current_context)
3292 end
3293
3294 process_strip_expression (an_expression: ET_STRIP_EXPRESSION)
3295 -- Process `an_expression'.
3296 do
3297 find_strip_expression_type (an_expression, current_context)
3298 end
3299
3300 process_true_constant (a_constant: ET_TRUE_CONSTANT)
3301 -- Process `a_constant'.
3302 do
3303 find_true_constant_type (a_constant, current_context)
3304 end
3305
3306 process_underscored_integer_constant (a_constant: ET_UNDERSCORED_INTEGER_CONSTANT)
3307 -- Process `a_constant'.
3308 do
3309 find_underscored_integer_constant_type (a_constant, current_context)
3310 end
3311
3312 process_underscored_real_constant (a_constant: ET_UNDERSCORED_REAL_CONSTANT)
3313 -- Process `a_constant'.
3314 do
3315 find_underscored_real_constant_type (a_constant, current_context)
3316 end
3317
3318 process_unqualified_call_expression (an_expression: ET_UNQUALIFIED_CALL_EXPRESSION)
3319 -- Process `an_expression'.
3320 do
3321 find_unqualified_call_expression_type (an_expression, current_context)
3322 end
3323
3324 process_verbatim_string (a_string: ET_VERBATIM_STRING)
3325 -- Process `a_string'.
3326 do
3327 find_verbatim_string_type (a_string, current_context)
3328 end
3329
3330 process_void (an_expression: ET_VOID)
3331 -- Process `an_expression'.
3332 do
3333 find_void_type (an_expression, current_context)
3334 end
3335
3336 feature {NONE} -- Access
3337
3338 current_feature: ET_STANDALONE_CLOSURE
3339 -- Feature or invariant being processed
3340
3341 current_feature_impl: ET_STANDALONE_CLOSURE
3342 -- Feature or invariant where the code being processed has been written;
3343 -- It might be different from `current_feature' or even from
3344 -- `current_feature.implementation_feature' when
3345 -- processing inherited assertions. For example:
3346 --
3347 -- deferred class A
3348 -- feature
3349 -- f (a: ANY)
3350 -- require
3351 -- pre: g (a)
3352 -- deferred
3353 -- end
3354 -- g (a: ANY): BOOLEAN deferred end
3355 -- end
3356 -- class B
3357 -- inherit
3358 -- A
3359 -- feature
3360 -- f (a: STRING) do ... end
3361 -- g (a: STRING): BOOLEAN do ... end
3362 -- end
3363 --
3364 -- When processing the inherited precondition 'pre' in B.f,
3365 -- `current_feature' is B.f and `current_feature_impl' is A.f
3366 -- (where the inherited precondition has been written).
3367
3368 current_inline_agent: detachable ET_INLINE_AGENT
3369 -- Inline agent being processed if any, Void otherwise
3370
3371 current_closure: ET_CLOSURE
3372 -- Inner closure being processed
3373 do
3374 if attached current_inline_agent as l_current_inline_agent then
3375 Result := l_current_inline_agent
3376 else
3377 Result := current_feature
3378 end
3379 ensure
3380 current_closure_not_void: Result /= Void
3381 in_agent: current_inline_agent /= Void implies Result = current_inline_agent
3382 not_in_agent: current_inline_agent = Void implies Result = current_feature
3383 end
3384
3385 current_closure_impl: ET_CLOSURE
3386 -- Inner closure where the code being processed has been written
3387 do
3388 if attached current_inline_agent as l_current_inline_agent then
3389 Result := l_current_inline_agent
3390 else
3391 Result := current_feature_impl
3392 end
3393 ensure
3394 current_closure_impl_not_void: Result /= Void
3395 in_agent: current_inline_agent /= Void implies Result = current_inline_agent
3396 not_in_agent: current_inline_agent = Void implies Result = current_feature_impl
3397 end
3398
3399 current_type: ET_BASE_TYPE
3400 -- Type from which `current_feature' is processed;
3401 -- It may not be the type to which `current_feature'
3402 -- belong when processing a precursor of a feature
3403 -- of `current_type'. In that case `current_type' is
3404 -- the type where the precursor call is processed,
3405 -- and `current_feature' is the precursor feature
3406 -- implemented in a proper parent.
3407
3408 current_class_impl: ET_CLASS
3409 -- Class where `current_feature_impl' has been written
3410
3411 current_universe_impl: ET_UNIVERSE
3412 -- Universe to which `current_class_impl' belongs
3413 do
3414 Result := current_class_impl.universe
3415 ensure
3416 universe_impl_not_void: Result /= Void
3417 end
3418
3419 current_context: ET_NESTED_TYPE_CONTEXT
3420 -- Context of expression being checked
3421
3422 current_target_type: ET_TYPE_CONTEXT
3423 -- Type of the target of expression being processed
3424
3425 feature {NONE} -- Status report
3426
3427 in_assertion: BOOLEAN
3428 -- Are we processing an assertion?
3429
3430 in_precondition: BOOLEAN
3431 -- Are we processing a precondition?
3432
3433 in_postcondition: BOOLEAN
3434 -- Are we processing a postcondition?
3435
3436 in_invariant: BOOLEAN
3437 -- Are we processing an invariant?
3438
3439 feature {NONE} -- Type checking
3440
3441 type_checker: ET_TYPE_CHECKER
3442 -- Type checker
3443
3444 feature {NONE} -- Type contexts
3445
3446 new_context (a_root_context: ET_BASE_TYPE): ET_NESTED_TYPE_CONTEXT
3447 -- New nested type context
3448 require
3449 a_root_context_not_void: a_root_context /= Void
3450 a_root_context_valid: a_root_context.is_valid_context
3451 do
3452 if unused_contexts.is_empty then
3453 create Result.make_with_capacity (a_root_context, 10)
3454 else
3455 Result := unused_contexts.last
3456 unused_contexts.remove_last
3457 Result.reset (a_root_context)
3458 end
3459 ensure
3460 new_context_not_void: Result /= Void
3461 root_context_set: Result.root_context = a_root_context
3462 is_empty: Result.is_empty
3463 end
3464
3465 free_context (a_context: ET_NESTED_TYPE_CONTEXT)
3466 -- Free `a_context' so that it can be reused.
3467 require
3468 a_context_not_void: a_context /= Void
3469 do
3470 unused_contexts.force_last (a_context)
3471 a_context.reset (tokens.unknown_class)
3472 end
3473
3474 unused_contexts: DS_ARRAYED_LIST [ET_NESTED_TYPE_CONTEXT]
3475 -- Contexts that are not currently used
3476
3477 feature {NONE} -- Constants
3478
3479 dummy_feature: ET_FEATURE
3480 -- Dummy feature
3481 local
3482 a_name: ET_FEATURE_NAME
3483 once
3484 create {ET_IDENTIFIER} a_name.make ("**dummy**")
3485 create {ET_DEFERRED_PROCEDURE} Result.make (a_name, Void, current_class)
3486 ensure
3487 dummy_feature_not_void: Result /= Void
3488 end
3489
3490 invariant
3491
3492 current_feature_not_void: current_feature /= Void
3493 current_feature_impl_not_void: current_feature_impl /= Void
3494 current_feature_impl_constraint: current_feature_impl = current_feature_impl.implementation_feature
3495 current_type_not_void: current_type /= Void
3496 current_type_valid: current_type.is_valid_context
3497 current_class_definition: current_class = current_type.base_class
3498 current_class_impl_not_void: current_class_impl /= Void
3499 current_class_impl_definition: current_class_impl = current_feature_impl.implementation_class
3500 -- implementation_checked: if inherited, then the code being analyzed has already been checked in implementation class of `current_feature_impl'
3501 type_checker_not_void: type_checker /= Void
3502 current_context_not_void: current_context /= Void
3503 unused_contexts_not_void: unused_contexts /= Void
3504 no_void_unused_context: not unused_contexts.has_void
3505 current_target_type_not_void: current_target_type /= Void
3506
3507 end

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.23