/[eiffelstudio]/branches/eth/eve/Src/Eiffel/API/evaluated_type/formal_a.e
ViewVC logotype

Contents of /branches/eth/eve/Src/Eiffel/API/evaluated_type/formal_a.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 94983 - (show annotations)
Fri May 2 11:05:28 2014 UTC (5 years, 7 months ago) by jasonw
File size: 24867 byte(s)
<<Merged from trunk#94978.>>
1 note
2 description: "Descripion of a formal generic type"
3 legal: "See notice at end of class."
4 status: "See notice at end of class."
5 date: "$Date$"
6 revision: "$Revision$"
7
8 class FORMAL_A
9
10 inherit
11 DEANCHORED_TYPE_A
12 rename
13 is_multi_constrained as has_multi_constrained
14 redefine
15 adapted_in,
16 annotation_flags,
17 as_non_separate,
18 check_const_gen_conformance,
19 convert_to,
20 description,
21 description_with_detachable_type,
22 evaluated_type_in_descendant,
23 formal_instantiation_in,
24 generated_id,
25 generate_cid,
26 generate_cid_array,
27 generate_cid_init,
28 generate_gen_type_il,
29 generic_il_type_name,
30 has_formal_generic,
31 formal_instantiated_in,
32 instantiated_in,
33 instantiation_in,
34 internal_is_valid_for_class,
35 is_expanded,
36 is_explicit,
37 is_formal,
38 is_full_named_type,
39 is_initialization_required,
40 is_loose,
41 is_reference,
42 is_separate,
43 make_type_byte_code,
44 same_as,
45 set_separate_mark,
46 skeleton_adapted_in
47 end
48
49 REFACTORING_HELPER
50
51 create
52 make
53
54 feature {NONE} -- Initialization
55
56 make (is_ref: like is_reference; is_exp: like is_expanded; i: like position)
57 -- Initialize new instance of FORMAL_A which is garanteed to
58 -- be instantiated as a reference type if `is_ref'.
59 do
60 is_reference := is_ref
61 is_expanded := is_exp
62 position := i
63 ensure
64 is_reference_set: is_reference = is_ref
65 is_expanded_set: is_expanded = is_exp
66 position_set: position = i
67 end
68
69 feature -- Modification
70
71 set_is_expanded
72 -- Mark the type as being expanded.
73 do
74 is_expanded := True
75 ensure
76 is_expanded: is_expanded
77 end
78
79 set_is_separate
80 -- Mark the type as being separate.
81 do
82 is_separate := True
83 ensure
84 is_separate: is_separate
85 end
86
87 reset_is_separate
88 -- Mark the type as being non-separate.
89 do
90 reset_separate_mark
91 is_separate := False
92 ensure
93 is_non_separate: not is_separate
94 end
95
96 set_separate_mark
97 -- <Precursor>
98 do
99 Precursor
100 set_is_separate
101 end
102
103 feature -- Duplication
104
105 as_non_separate: like Current
106 -- <Precursor>
107 do
108 Result := duplicate
109 Result.reset_is_separate
110 end
111
112 feature -- Visitor
113
114 process (v: TYPE_A_VISITOR)
115 -- Process current element.
116 do
117 v.process_formal_a (Current)
118 end
119
120 feature -- Property
121
122 is_formal: BOOLEAN = True
123 -- Is the current actual type a formal generic type ?
124
125 is_explicit: BOOLEAN = False
126 -- Is type fixed at compile time without anchors or formals?
127
128 is_multi_constrained (a_context_class: CLASS_C): BOOLEAN
129 -- Is Current a multi constraint formal relative to current context class?
130 --
131 -- `a_context_class': Used to resolve formals to their constraints.
132 require
133 a_context_class_not_void: a_context_class /= Void
134 a_context_class_valid: a_context_class.is_generic and then a_context_class.is_valid_formal_position (position)
135 local
136 l_generics: EIFFEL_LIST[FORMAL_DEC_AS]
137 do
138 l_generics := a_context_class.generics
139 Result := l_generics.i_th (position).is_multi_constrained (l_generics)
140 end
141
142 is_full_named_type: BOOLEAN = True
143 -- Current is a named type.
144
145 is_reference: BOOLEAN
146 -- Is current constrained to be always a reference?
147
148 is_expanded: BOOLEAN
149 -- Is current constrained to be always an expanded?
150
151 is_separate: BOOLEAN
152 -- Is current constrained to be always separate?
153
154 is_single_constraint_without_renaming (a_context_class: CLASS_C): BOOLEAN
155 -- Is current type a formal type which is single constrained and the constraint has not a feature renaming?
156 --
157 -- `a_context_class' is the context class where the type occurs in.
158 --| G -> A -> True
159 --| G -> A rename a as b end -> False
160 --| G -> {A, B} -> False
161 --| This means there is exactly one constraint class which can be directly used without applying a feature renaming.
162 local
163 l_generics: EIFFEL_LIST[FORMAL_DEC_AS]
164 do
165 l_generics := a_context_class.generics
166 check l_generics_not_void: l_generics /= Void end
167 Result := l_generics.i_th (position).is_single_constraint_without_renaming (l_generics)
168 end
169
170 is_initialization_required: BOOLEAN
171 -- Is initialization required for this type in void-safe mode?
172 do
173 Result := not is_expanded and then not has_detachable_mark
174 end
175
176 annotation_flags: NATURAL_16
177 -- <Precursor>
178 do
179 -- Unlike {TYPE_A}, we actually need to know if the formal is declared with
180 -- an attachment mark and if it is which one. When there are no attachment mark
181 -- at runtime, we will use the attachment mark of the actual generic parameter.
182 if has_attached_mark then
183 Result := {SHARED_GEN_CONF_LEVEL}.attached_type
184 elseif has_detachable_mark then
185 Result := {SHARED_GEN_CONF_LEVEL}.detachable_type
186 end
187 -- To uncomment when variant/frozen proposal for generics is supported.
188 -- if is_frozen then
189 -- Result := Result | {SHARED_GEN_CONF_LEVEL}.frozen_type
190 -- end
191 end
192
193 feature -- IL code generation
194
195 generic_il_type_name (a_context_type: TYPE_A): STRING
196 -- <Precursor>
197 once
198 Result := "REFERENCE"
199 end
200
201 feature -- Comparison
202
203 is_equivalent (other: FORMAL_A): BOOLEAN
204 -- Is `other' equivalent to the current object?
205 do
206 Result := is_equivalent_excluding_status (other) and then
207 other.is_attached = is_attached and then
208 other.has_attached_mark = has_attached_mark and then
209 other.has_detachable_mark = has_detachable_mark and then
210 other.has_separate_mark = has_separate_mark
211 end
212
213 is_equivalent_excluding_status (other: FORMAL_A): BOOLEAN
214 -- Is `other' equivalent to the current object without
215 -- taking attachment and separateness status into account?
216 do
217 Result := position = other.position and then
218 is_reference = other.is_reference and then
219 is_expanded = other.is_expanded and then
220 is_separate = other.is_separate
221 end
222
223 feature -- Access
224
225 hash_code: INTEGER
226 do
227 Result := {SHARED_HASH_CODE}.other_code + position
228 end
229
230 description: GENERIC_DESC
231 -- Descritpion of type for skeletons.
232 do
233 create Result
234 Result.set_type_i (Current)
235 end
236
237 description_with_detachable_type: GENERIC_DESC
238 -- Descritpion of type for skeletons.
239 do
240 create Result
241 Result.set_type_i (as_detachable_type)
242 end
243
244 constrained_type (a_context_class: CLASS_C): TYPE_A
245 -- Constraint of Current.
246 require
247 a_context_class_attached: a_context_class /= Void
248 not_multi_constraint: not is_multi_constrained (a_context_class)
249 do
250 Result := a_context_class.constrained_type (position)
251 ensure
252 Result_not_void: Result /= Void
253 Result_is_named_but_not_formal: (Result.is_none or Result.is_named_type) and not Result.is_formal
254 end
255
256 constrained_types (a_context_class: CLASS_C): TYPE_SET_A
257 -- Constrained types of Current.
258 --
259 -- `a_context_class' is the context class where the formal occurs in.
260 --| It is a list of class types which constraint the current Formal.
261 require
262 a_context_class_attached: a_context_class /= Void
263 do
264 Result := a_context_class.constrained_types (position)
265 ensure
266 Result_not_void_and_not_empty: Result /= Void and not Result.is_empty
267 end
268
269 constrained_type_if_possible (a_context_class: CLASS_C): TYPE_A
270 -- Constraint of Current.
271 require
272 a_context_class_attached: a_context_class /= Void
273 not_multi_constraint: not is_multi_constrained (a_context_class)
274 local
275 l_formal_type: FORMAL_A
276 do
277 from
278 -- Unfold the chain of formal generics
279 Result := Current
280 until
281 Result = Void or else not Result.is_formal
282 loop
283 l_formal_type ?= Result
284 Result := a_context_class.constraint_if_possible (l_formal_type.position)
285 end
286 end
287
288 constrained_types_if_possible (a_context_class: CLASS_C): TYPE_SET_A
289 -- Constraint of Current.
290 require
291 a_context_class_attached: a_context_class /= Void
292 do
293 Result := constraints (a_context_class).constraining_types (a_context_class)
294 end
295
296 constraint (a_context_class: CLASS_C): TYPE_A
297 -- Constraint type of `Current'.
298 --| Return excatly what is written. For a formal like G -> H we return H.
299 --| If you want to resolve formal chains use `constrained_type'.
300 --| If there are several formals in the type set we merge the results.
301 require
302 a_a_context_classt_not_void: a_context_class /= Void
303 do
304 Result := a_context_class.constraint (position)
305 ensure
306 Result_sane: Result /= Void
307 end
308
309
310 constraints (a_context_class: CLASS_C): TYPE_SET_A
311 -- Constraint types of `Current'.
312 --| Return excatly what is written. For a formal like G -> {H,STRING} we return {H, STRING}.
313 --| If there are several formals in the type set we merge the results.
314 --| If you want to get rid of recursive formals call `constraining_types' on the resulting TYPE_SET_A.
315 require
316 a_a_context_classt_not_void: a_context_class /= Void
317 do
318 Result := a_context_class.constraints (position)
319 ensure
320 Result_sane: Result /= Void and then not Result.is_empty
321 end
322
323 constraints_if_possible (a_context_class: CLASS_C): TYPE_SET_A
324 -- Constraint types of `Current'.
325 --| Return excatly what is written. For a formal like G -> {H,STRING} we return {H, STRING}.
326 --| If there are several formals in the type set we merge the results.
327 require
328 a_a_context_classt_not_void: a_context_class /= Void
329 do
330 Result := a_context_class.constraints_if_possible (position)
331 ensure
332 Result_sane: Result /= Void
333 end
334
335 same_as (other: TYPE_A): BOOLEAN
336 -- Is `other' the same as Current ?
337 local
338 other_formal: like Current
339 do
340 other_formal ?= other
341 if other_formal /= Void then
342 Result := is_equivalent (other_formal) and then
343 has_same_marks (other_formal)
344 end
345 end
346
347 base_class: CLASS_C
348 do
349 -- No associated class
350 end
351
352 position: INTEGER
353 -- Position of the formal parameter in the
354 -- generic class declaration
355
356 feature -- Generic conformance
357
358 generated_id (final_mode: BOOLEAN; a_context_type: TYPE_A): NATURAL_16
359 -- Id of a `like xxx'.
360 do
361 -- Not really applicable.
362 Result := {SHARED_GEN_CONF_LEVEL}.formal_type
363 end
364
365 generate_cid (buffer: GENERATION_BUFFER; final_mode, use_info: BOOLEAN; a_context_type: TYPE_A)
366 do
367 generate_cid_prefix (buffer, Void)
368 if use_info then
369 initialize_info (shared_create_info)
370 shared_create_info.generate_cid (buffer, final_mode)
371 else
372 buffer.put_hex_natural_16 ({SHARED_GEN_CONF_LEVEL}.formal_type)
373 buffer.put_character (',')
374 buffer.put_integer (position)
375 buffer.put_character (',')
376 end
377 end
378
379 generate_cid_array (buffer: GENERATION_BUFFER; final_mode, use_info: BOOLEAN; idx_cnt: COUNTER; a_context_type: TYPE_A)
380 local
381 dummy: INTEGER
382 do
383 generate_cid_prefix (buffer, idx_cnt)
384 if use_info then
385 initialize_info (shared_create_info)
386 shared_create_info.generate_cid_array (buffer, final_mode, idx_cnt)
387 else
388 buffer.put_hex_natural_16 ({SHARED_GEN_CONF_LEVEL}.formal_type)
389 buffer.put_character (',')
390 buffer.put_integer (position)
391 buffer.put_character (',')
392 dummy := idx_cnt.next
393 dummy := idx_cnt.next
394 end
395 end
396
397 generate_cid_init (buffer: GENERATION_BUFFER; final_mode, use_info: BOOLEAN; idx_cnt: COUNTER; a_context_type: TYPE_A; a_level: NATURAL)
398 local
399 dummy: INTEGER
400 do
401 generate_cid_prefix (Void, idx_cnt)
402 if use_info then
403 initialize_info (shared_create_info)
404 shared_create_info.generate_cid_init (buffer, final_mode, idx_cnt, a_level)
405 else
406 dummy := idx_cnt.next
407 dummy := idx_cnt.next
408 end
409 end
410
411 make_type_byte_code (ba: BYTE_ARRAY; use_info : BOOLEAN; a_context_type: TYPE_A)
412 -- Put type id's in byte array.
413 -- `use_info' is true iff we generate code for a
414 -- creation instruction.
415 do
416 make_type_prefix_byte_code (ba)
417 if use_info then
418 initialize_info (shared_create_info)
419 shared_create_info.make_type_byte_code (ba)
420 else
421 ba.append_natural_16 ({SHARED_GEN_CONF_LEVEL}.formal_type)
422 ba.append_short_integer (position)
423 end
424 end
425
426 generate_gen_type_il (il_generator: IL_CODE_GENERATOR; use_info: BOOLEAN)
427 -- `use_info' is true iff we generate code for a
428 -- creation instruction.
429 do
430 il_generator.generate_type_feature_call_for_formal (position)
431 end
432
433 feature -- Output
434
435 dump: STRING
436 -- Dumped trace
437 do
438 create Result.make (3)
439 dump_marks (Result)
440 Result.append ("G#")
441 Result.append_integer (position)
442 end
443
444 ext_append_to (a_text_formatter: TEXT_FORMATTER; a_context_class: CLASS_C)
445 -- <Precursor>
446 local
447 s: STRING
448 l_class: CLASS_AS
449 do
450 ext_append_marks (a_text_formatter)
451 if a_context_class /= Void then
452 l_class := a_context_class.ast
453 if l_class.generics /= Void and then l_class.generics.valid_index (position) then
454 s := l_class.generics.i_th (position).name.name.as_upper
455 a_text_formatter.process_generic_text (s)
456 else
457 -- We are in case where actual generic position does not match
458 -- any generics in written class of `f'. E.g: A [H, G] inherits
459 -- from B [G], therefore in B, `G' at position 2 does not make sense.
460 --| FIXME: Manu 05/29/2002: we cannot let this happen, the reason is
461 -- due to bad initialization of `f' in wrong class.
462 a_text_formatter.add ({SHARED_TEXT_ITEMS}.Ti_generic_index)
463 a_text_formatter.add_int (position)
464 end
465 else
466 a_text_formatter.add ({SHARED_TEXT_ITEMS}.Ti_generic_index)
467 a_text_formatter.add_int (position)
468 end
469 end
470
471 feature {TYPE_A} -- Helpers
472
473 internal_is_valid_for_class (a_class: CLASS_C): BOOLEAN
474 do
475 Result := a_class = Void or else (a_class.is_generic and then position <= a_class.generics.count)
476 end
477
478 feature {COMPILER_EXPORTER} -- Type checking
479
480 check_const_gen_conformance (a_gen_type: GEN_TYPE_A; a_target_type: TYPE_A; a_class: CLASS_C; i: INTEGER)
481 -- Is `Current' a valid generic parameter at position `i' of `gen_type'?
482 -- For formal generic parameter, we do check that their constraint
483 -- conforms to `a_target_type'.
484 local
485 l_is_ref, l_is_exp: BOOLEAN
486 do
487 -- We simply consider conformance as if current formal
488 -- was constrained to be a reference type, it enables us
489 -- to accept the following code:
490 -- class B [G -> STRING]
491 -- class A [G -> STRING, H -> B [G]]
492 l_is_ref := is_reference
493 l_is_exp := is_expanded
494 is_reference := True
495 is_expanded := False
496 Precursor {DEANCHORED_TYPE_A} (a_gen_type, a_target_type, a_class, i)
497 is_reference := l_is_ref
498 is_expanded := l_is_exp
499
500 -- Note that even if the constraint is not valid, e.g.
501 -- class B [reference G -> STRING]
502 -- class A [expanded G -> STRING, H -> B [G]]
503 -- we do not trigger an error. This is ok, because an
504 -- error will be triggered when trying to write a generic
505 -- derivation of A as none is possible.
506 end
507
508 feature {FORMAL_A} -- Conformance
509
510 direct_conform_to_formal (a_context_class: CLASS_C; other: FORMAL_A): BOOLEAN
511 -- Does Current conform to `other' directly (i.e. without taking constraints into account)?
512 require
513 a_context_class_attached: attached a_context_class
514 other_attached: attached other
515 do
516 if
517 position = other.position and then
518 is_reference = other.is_reference and then
519 is_expanded = other.is_expanded
520 then
521 -- Test frozen/variant status.
522 -- 1. "frozen G" conforms to "G", "frozen G" and "variant G"
523 -- 2. "G" and "variant G" conforms to "G" or "variant G"
524 if has_frozen_mark then
525 -- Case 1.
526 Result := True
527 else
528 -- Case 2.
529 Result := not other.has_frozen_mark
530 end
531 if Result then
532 -- Test attachment status.
533 -- The rules are as follows, but we need to take care about implicit attachment status:
534 -- 1. !G conforms to G, ?G and !G.
535 -- 2. G conforms to G and ?G.
536 -- 3. ?G only conforms to ?G.
537 if not a_context_class.lace_class.is_void_safe_conformance then
538 -- Case 0. In non-void-safe mode attachment status is not taken into account.
539 Result := True
540 elseif is_implicitly_attached then
541 -- Case 1.
542 -- An (implicitly) attached type conforms to a type of any attachment status.
543 Result := True
544 elseif other.has_detachable_mark then
545 -- Case 1-3.
546 -- A type of any attachment status conforms to a detachable type.
547 Result := True
548 elseif not has_detachable_mark then
549 -- Case 2.
550 -- A type without the detachable mark conforms to the one without the detachable mark.
551 Result := not other.is_attached
552 else
553 -- We got ?G but the other is not ?G
554 Result := False
555 end
556 if Result then
557 -- Test separateness status.
558 -- 1. "separate G" conforms to "separate G".
559 -- 2. "G" conforms to "G" and "separate G".
560 Result := has_separate_mark implies other.has_separate_mark
561 end
562 end
563 end
564 end
565
566 feature -- Access
567
568 has_formal_generic: BOOLEAN = True
569 -- Does the current actual type have formal generic type ?
570
571 is_loose: BOOLEAN = True
572 -- Does type depend on formal generic parameters and/or anchors?
573
574 convert_to (a_context_class: CLASS_C; a_target_type: TYPE_A): BOOLEAN
575 -- Does current convert to `a_target_type' in `a_context_class'?
576 -- Update `last_conversion_info' of AST_CONTEXT.
577 local
578 l_checker: CONVERTIBILITY_CHECKER
579 do
580 -- Check conformance of constained generic type
581 -- to `other'
582 create l_checker
583 l_checker.check_formal_conversion (a_context_class, Current, a_target_type)
584 Result := l_checker.last_conversion_check_successful
585 if Result then
586 context.set_last_conversion_info (l_checker.last_conversion_info)
587 else
588 context.set_last_conversion_info (Void)
589 end
590 end
591
592 formal_instantiation_in (type: TYPE_A; constraint_type: TYPE_A; written_id: INTEGER): TYPE_A
593 -- <Precursor>
594 do
595 -- Use constraint type.
596 Result := instantiation_in (constraint_type, written_id)
597 end
598
599 instantiation_in (type: TYPE_A; written_id: INTEGER): TYPE_A
600 -- Instantiation of Current in the context of `type',
601 -- assuming that Current is written in class of id `written_id'.
602 local
603 t: TYPE_A
604 l_class: CLASS_C
605 l_type_set: TYPE_SET_A
606 do
607 -- The type should be evaluated in the context of the associated conformance type.
608 -- `type.conformance_type' is used because `type.actual_type' does not work for {LIKE_CURRENT}.
609 if attached {CL_TYPE_A} type.conformance_type as l_cl_type then
610 Result := separate_adapted (l_cl_type.instantiation_of (Current, written_id).to_other_attachment (Current))
611 else
612 Result := Current
613 end
614 if not Result.is_attached then
615 l_class := system.class_of_id (written_id)
616 if not l_class.lace_class.is_void_unsafe then
617 l_type_set := l_class.constrained_types (position)
618 if l_type_set.is_attached and then not Result.has_detachable_mark then
619 -- Promote attachment setting of the current contraint unless the formal has explicit detachable mark.
620 t := Result.duplicate
621 t.set_is_attached
622 Result := t
623 end
624 end
625 end
626 Result := Result.to_other_variant (Current)
627 end
628
629 adapted_in (class_type: CLASS_TYPE): TYPE_A
630 do
631 Result := class_type.type.generics.i_th (position)
632 end
633
634 skeleton_adapted_in (class_type: CLASS_TYPE): TYPE_A
635 -- <Precursor>
636 do
637 Result := class_type.type.generics.i_th (position)
638 -- We optimize the type only if it is a basic type which is not a TYPED_POINTER.
639 if not Result.is_basic or Result.is_typed_pointer then
640 Result := Current
641 end
642 end
643
644 formal_instantiated_in, instantiated_in (class_type: TYPE_A): TYPE_A
645 -- Instantiation of Current in the context of `class_type'
646 -- assuming that Current is written in the associated class
647 -- of `class_type'.
648 do
649 Result := separate_adapted (class_type.generics.i_th (position).to_other_attachment (Current))
650 Result := Result.to_other_variant (Current)
651 end
652
653 evaluated_type_in_descendant (a_ancestor, a_descendant: CLASS_C; a_feature: FEATURE_I): TYPE_A
654 local
655 l_feat: TYPE_FEATURE_I
656 do
657 if a_ancestor = a_descendant then
658 Result := Current
659 else
660 -- Get associated feature in parent.
661 l_feat := a_ancestor.formal_at_position (position)
662 -- Get associated feature in descendant.
663 l_feat := a_descendant.generic_features.item (l_feat.rout_id_set.first)
664 check l_feat_not_void: l_feat /= Void end
665 Result := separate_adapted (l_feat.type.actual_type.to_other_attachment (Current))
666 Result := Result.to_other_variant (Current)
667 end
668 end
669
670 create_info: CREATE_FORMAL_TYPE
671 -- Create formal type info.
672 do
673 create Result.make (as_attachment_mark_free)
674 end
675
676 shared_create_info: CREATE_FORMAL_TYPE
677 -- Same as `create_info' except that it is a shared instance.
678 once
679 create Result.make (Current)
680 ensure
681 shared_create_info_not_void: Result /= Void
682 end
683
684 initialize_info (an_info: like shared_create_info)
685 -- Initialize `an_info' with current type data.
686 do
687 an_info.make (Current)
688 end
689
690 feature {TYPE_A} -- Helpers
691
692 internal_conform_to (a_context_class: CLASS_C; other: TYPE_A; a_in_generic: BOOLEAN): BOOLEAN
693 -- <Precursor>
694 local
695 l_constraints: TYPE_SET_A
696 t: TYPE_A
697 i: INTEGER
698 do
699 -- Use `other.conformance_type' rather than `other' to get deanchored form.
700 t := other.conformance_type
701 Result := same_as (t)
702 if not Result and then attached {like Current} t as c then
703 Result := direct_conform_to_formal (a_context_class, c)
704 end
705 if not Result then
706 -- Check conformance of constrained generic type to `other'.
707 -- Get the actual type for the formal generic parameter
708 l_constraints := a_context_class.constraints_if_possible (position)
709 if other.is_formal and then attached {FORMAL_A} other as f then
710 -- Take only formal generics into account since there is no other way
711 -- this formal can conform to `other'.
712 from
713 i := 0
714 until
715 i >= l_constraints.count
716 loop
717 i := i + 1
718 -- There are no anchored types in constraints,
719 -- so there is no need to use `conformance_type'.
720 if attached {FORMAL_A} l_constraints.i_th (i).type.to_other_attachment (Current).to_other_variant (Current) as g then
721 if g.direct_conform_to_formal (a_context_class, f) then
722 -- Types conform.
723 Result := True
724 i := l_constraints.count
725 else
726 -- Follow constraints of `g'.
727 across
728 a_context_class.constraints_if_possible (g.position) as c
729 loop
730 -- Only formal generics that are not yet in the list
731 -- are of interest.
732 if
733 c.item.type.is_formal and then
734 across l_constraints as l all not l.item.type.same_as (c.item.type) end
735 then
736 l_constraints.extend (c.item)
737 end
738 end
739 end
740 end
741 end
742 else
743 -- Take only class types into account since there is no other way
744 -- this formal can conform to other and leaving formal generics in
745 -- the type set can lead to infinite recursion for no need.
746 Result := l_constraints.constraining_types (a_context_class).to_other_attachment (Current).to_other_separateness (Current).to_other_variant (Current).conform_to_type (a_context_class, other.to_type_set)
747 end
748 end
749 end
750
751 feature {NONE} -- Status adaptation
752
753 separate_adapted (other: TYPE_A): TYPE_A
754 -- `other' with separateness status adapted from `Current'.
755 do
756 -- If a formal has "separate" mark, it should be applied to `other'.
757 -- Otherwise `other' is used without any changes.
758 if has_separate_mark then
759 Result := other.to_other_separateness (Current)
760 else
761 Result := other
762 end
763 end
764
765 note
766 copyright: "Copyright (c) 1984-2014, Eiffel Software"
767 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
768 licensing_options: "http://www.eiffel.com/licensing"
769 copying: "[
770 This file is part of Eiffel Software's Eiffel Development Environment.
771
772 Eiffel Software's Eiffel Development Environment is free
773 software; you can redistribute it and/or modify it under
774 the terms of the GNU General Public License as published
775 by the Free Software Foundation, version 2 of the License
776 (available at the URL listed under "license" above).
777
778 Eiffel Software's Eiffel Development Environment is
779 distributed in the hope that it will be useful, but
780 WITHOUT ANY WARRANTY; without even the implied warranty
781 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
782 See the GNU General Public License for more details.
783
784 You should have received a copy of the GNU General Public
785 License along with Eiffel Software's Eiffel Development
786 Environment; if not, write to the Free Software Foundation,
787 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
788 ]"
789 source: "[
790 Eiffel Software
791 5949 Hollister Ave., Goleta, CA 93117 USA
792 Telephone 805-685-1006, Fax 805-685-6869
793 Website http://www.eiffel.com
794 Customer support http://support.eiffel.com
795 ]"
796
797 end -- class FORMAL_A

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23