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

Contents of /branches/CAT_mono/Src/Eiffel/API/evaluated_type/formal_a.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 69629 - (show annotations)
Mon Jul 23 21:36:18 2007 UTC (12 years, 6 months ago) by manus
File size: 13569 byte(s)
Creation of CAT_mono branch to implement variant/invariant proposal
1 indexing
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 NAMED_TYPE_A
12 redefine
13 is_formal,
14 instantiation_in,
15 has_formal_generic,
16 is_loose,
17 instantiated_in,
18 evaluated_type_in_descendant,
19 same_as,
20 format,
21 is_full_named_type,
22 convert_to,
23 check_const_gen_conformance,
24 is_reference,
25 is_expanded
26 end
27
28 REFACTORING_HELPER
29 create
30 make
31
32 feature {NONE} -- Initialization
33
34 make (is_ref: like is_reference; is_exp: like is_expanded; i: like position) is
35 -- Initialize new instance of FORMAL_A which is garanteed to
36 -- be instantiated as a reference type if `is_ref'.
37 do
38 is_reference := is_ref
39 is_expanded := is_exp
40 position := i
41 ensure
42 is_reference_set: is_reference = is_ref
43 is_expanded_set: is_expanded = is_exp
44 position_set: position = i
45 end
46
47 feature -- Visitor
48
49 process (v: TYPE_A_VISITOR) is
50 -- Process current element.
51 do
52 v.process_formal_a (Current)
53 end
54
55 feature -- Property
56
57 is_formal: BOOLEAN is True
58 -- Is the current actual type a formal generic type ?
59
60 is_multi_constrained (a_context_class: CLASS_C): BOOLEAN is
61 -- Is Current a multi constraint formal relative to current context class?
62 --
63 -- `a_context_class': Used to resolve formals to their constraints.
64 require
65 a_context_class_not_void: a_context_class /= Void
66 a_context_class_valid: a_context_class.is_generic and then a_context_class.is_valid_formal_position (position)
67 local
68 l_generics: EIFFEL_LIST[FORMAL_DEC_AS]
69 do
70 l_generics := a_context_class.generics
71 Result := l_generics.i_th (position).is_multi_constrained (l_generics)
72 end
73
74 is_full_named_type: BOOLEAN is True
75 -- Current is a named type.
76
77 is_reference: BOOLEAN
78 -- Is current constrained to be always a reference?
79
80 is_expanded: BOOLEAN
81 -- Is current constrained to be always an expanded?
82
83 hash_code: INTEGER is
84 --
85 do
86 Result := position
87 end
88
89 is_single_constraint_without_renaming (a_context_class: CLASS_C): BOOLEAN
90 -- Is current type a formal type which is single constrained and the constraint has not a feature renaming?
91 --
92 -- `a_context_class' is the context class where the type occurs in.
93 --| G -> A -> True
94 --| G -> A rename a as b end -> False
95 --| G -> {A, B} -> False
96 --| This means there is exactly one constraint class which can be directly used without applying a feature renaming.
97 local
98 l_generics: EIFFEL_LIST[FORMAL_DEC_AS]
99 do
100 l_generics := a_context_class.generics
101 check l_generics_not_void: l_generics /= Void end
102 Result := l_generics.i_th (position).is_single_constraint_without_renaming (l_generics)
103 end
104
105 feature -- Comparison
106
107 is_equivalent (other: like Current): BOOLEAN is
108 -- Is `other' equivalent to the current object ?
109 do
110 Result := position = other.position and then
111 is_reference = other.is_reference and then
112 is_expanded = other.is_expanded
113 end
114
115 feature -- Access
116
117 constrained_type (a_context_class: CLASS_C): TYPE_A
118 -- Constraint of Current.
119 require
120 a_context_class_attached: a_context_class /= Void
121 not_multi_constraint: not is_multi_constrained (a_context_class)
122 do
123 Result := a_context_class.constrained_type (position)
124 ensure
125 Result_not_void: Result /= Void
126 Result_is_named_but_not_formal: (Result.is_none or Result.is_named_type) and not Result.is_formal
127 end
128
129 constrained_types (a_context_class: CLASS_C): TYPE_SET_A
130 -- Constrained types of Current.
131 --
132 -- `a_context_class' is the context class where the formal occurs in.
133 --| It is a list of class types which constraint the current Formal.
134 require
135 a_context_class_attached: a_context_class /= Void
136 do
137 Result := a_context_class.constrained_types (position)
138 ensure
139 Result_not_void_and_not_empty: Result /= Void and not Result.is_empty
140 end
141
142 constrained_type_if_possible (a_context_class: CLASS_C): TYPE_A
143 -- Constraint of Current.
144 require
145 a_context_class_attached: a_context_class /= Void
146 not_multi_constraint: not is_multi_constrained (a_context_class)
147 local
148 l_formal_type: FORMAL_A
149 do
150 from
151 -- Unfold the chain of formal generics
152 Result := Current
153 until
154 Result = Void or else not Result.is_formal
155 loop
156 l_formal_type ?= Result
157 Result := a_context_class.constraint_if_possible (l_formal_type.position)
158 end
159 end
160
161 constrained_types_if_possible (a_context_class: CLASS_C): TYPE_SET_A
162 -- Constraint of Current.
163 require
164 a_context_class_attached: a_context_class /= Void
165 do
166 Result := constraints (a_context_class).constraining_types (a_context_class)
167 end
168
169 constraint (a_context_class: CLASS_C): TYPE_A is
170 -- Constraint type of `Current'.
171 --| Return excatly what is written. For a formal like G -> H we return H.
172 --| If you want to resolve formal chains use `constrained_type'.
173 --| If there are several formals in the type set we merge the results.
174 require
175 a_a_context_classt_not_void: a_context_class /= Void
176 do
177 Result := a_context_class.constraint (position)
178 ensure
179 Result_sane: Result /= Void
180 end
181
182
183 constraints (a_context_class: CLASS_C): TYPE_SET_A is
184 -- Constraint types of `Current'.
185 --| Return excatly what is written. For a formal like G -> {H,STRING} we return {H, STRING}.
186 --| If there are several formals in the type set we merge the results.
187 --| If you want to get rid of recursive formals call `constraining_types' on the resulting TYPE_SET_A.
188 require
189 a_a_context_classt_not_void: a_context_class /= Void
190 do
191 Result := a_context_class.constraints (position)
192 ensure
193 Result_sane: Result /= Void and then not Result.is_empty
194 end
195
196 constraints_if_possible (a_context_class: CLASS_C): TYPE_SET_A is
197 -- Constraint types of `Current'.
198 --| Return excatly what is written. For a formal like G -> {H,STRING} we return {H, STRING}.
199 --| If there are several formals in the type set we merge the results.
200 require
201 a_a_context_classt_not_void: a_context_class /= Void
202 do
203 Result := a_context_class.constraints_if_possible (position)
204 ensure
205 Result_sane: Result /= Void
206 end
207
208 same_as (other: TYPE_A): BOOLEAN is
209 -- Is `other' the same as Current ?
210 local
211 other_formal: FORMAL_A
212 do
213 other_formal ?= other
214 if other_formal /= Void then
215 Result := is_equivalent (other_formal)
216 end
217 end
218
219 associated_class: CLASS_C is
220 do
221 -- No associated class
222 end
223
224 position: INTEGER
225 -- Position of the formal parameter in the
226 -- generic class declaration
227
228 feature -- Output
229
230 dump: STRING is
231 -- Dumped trace
232 do
233 create Result.make (3)
234 Result.append ("G#")
235 Result.append_integer (position)
236 end
237
238 ext_append_to (st: TEXT_FORMATTER; c: CLASS_C) is
239 local
240 s: STRING
241 l_class: CLASS_AS
242 do
243 if c /= Void then
244 l_class := c.ast
245 if l_class.generics /= Void and then l_class.generics.valid_index (position) then
246 s := l_class.generics.i_th (position).name.name.as_upper
247 st.process_generic_text (s)
248 else
249 -- We are in case where actual generic position does not match
250 -- any generics in written class of `f'. E.g: A [H, G] inherits
251 -- from B [G], therefore in B, `G' at position 2 does not make sense.
252 --| FIXME: Manu 05/29/2002: we cannot let this happen, the reason is
253 -- due to bad initialization of `f' in wrong class.
254 st.add (Ti_generic_index)
255 st.add_int (position)
256 end
257 else
258 st.add (Ti_generic_index)
259 st.add_int (position)
260 end
261 end
262
263 feature {COMPILER_EXPORTER} -- Type checking
264
265 check_const_gen_conformance (a_gen_type: GEN_TYPE_A; a_target_type: TYPE_A; a_class: CLASS_C; i: INTEGER) is
266 -- Is `Current' a valid generic parameter at position `i' of `gen_type'?
267 -- For formal generic parameter, we do check that their constraint
268 -- conforms to `a_target_type'.
269 local
270 l_is_ref, l_is_exp: BOOLEAN
271 do
272 -- We simply consider conformance as if current formal
273 -- was constrained to be a reference type, it enables us
274 -- to accept the following code:
275 -- class B [G -> STRING]
276 -- class A [G -> STRING, H -> B [G]]
277 l_is_ref := is_reference
278 l_is_exp := is_expanded
279 is_reference := True
280 is_expanded := False
281 Precursor {NAMED_TYPE_A} (a_gen_type, a_target_type, a_class, i)
282 is_reference := l_is_ref
283 is_expanded := l_is_exp
284
285 -- Note that even if the constraint is not valid, e.g.
286 -- class B [reference G -> STRING]
287 -- class A [expanded G -> STRING, H -> B [G]]
288 -- we do not trigger an error. This is ok, because an
289 -- error will be triggered when trying to write a generic
290 -- derivation of A as none is possible.
291 end
292
293 feature {COMPILER_EXPORTER}
294
295 has_formal_generic: BOOLEAN is
296 -- Does the current actual type have formal generic type ?
297 do
298 Result := True
299 end
300
301 is_loose: BOOLEAN is True
302 -- Does type depend on formal generic parameters and/or anchors?
303
304 conform_to (other: TYPE_A): BOOLEAN is
305 -- Does Current conform to `other'?
306 local
307 l_constraints: TYPE_SET_A
308 do
309 Result := same_as (other.conformance_type)
310 if not Result then
311 -- We do not treat the case `is_expanded' as if it is an
312 -- expanded then it does not conform to anything but itself
313 -- so this is automatically taken care by `same_as' above.
314 if not is_expanded then
315 -- Check conformance of constrained generic type to `other'.
316 fixme ("As soon as conform_to takes a context class as an argument, do no longer use System.current_class but the argument.")
317 check
318 has_generics: System.current_class.generics /= Void
319 count_ok: System.current_class.generics.count >= position
320 end
321 -- Get the actual type for the formal generic parameter
322 l_constraints := System.current_class.constraints_if_possible (position)
323 Result := l_constraints.constraining_types (system.current_class).conform_to_type (other)
324 end
325 end
326 end
327
328 convert_to (a_context_class: CLASS_C; a_target_type: TYPE_A): BOOLEAN is
329 -- Does current convert to `a_target_type' in `a_context_class'?
330 -- Update `last_conversion_info' of AST_CONTEXT.
331 local
332 l_checker: CONVERTIBILITY_CHECKER
333 do
334 -- Check conformance of constained generic type
335 -- to `other'
336 check
337 has_generics: System.current_class.generics /= Void
338 count_ok: System.current_class.generics.count >= position
339 end
340
341 create l_checker
342 l_checker.check_formal_conversion (System.current_class, Current, a_target_type)
343 Result := l_checker.last_conversion_check_successful
344 if Result then
345 context.set_last_conversion_info (l_checker.last_conversion_info)
346 else
347 context.set_last_conversion_info (Void)
348 end
349 end
350
351 instantiation_in (type: TYPE_A; written_id: INTEGER): TYPE_A is
352 -- Instantiation of Current in the context of `class_type',
353 -- assuming that Current is written in class of id `written_id'.
354 local
355 class_type: CL_TYPE_A
356 do
357 class_type ?= type
358 if class_type /= Void then
359 Result := class_type.instantiation_of (Current, written_id)
360 else
361 Result := Current
362 end
363 end
364
365 instantiated_in (class_type: TYPE_A): TYPE_A is
366 -- Instantiation of Current in the context of `class_type'
367 -- assuming that Current is written in the associated class
368 -- of `class_type'.
369 do
370 Result := class_type.generics.item (position)
371 end
372
373 evaluated_type_in_descendant (a_ancestor, a_descendant: CLASS_C; a_feature: FEATURE_I): TYPE_A is
374 local
375 l_feat: TYPE_FEATURE_I
376 do
377 -- Get associated feature in parent.
378 l_feat := a_ancestor.formal_at_position (position)
379 -- Get associated feature in descendant.
380 l_feat := a_descendant.generic_features.item (l_feat.rout_id_set.first)
381 check l_feat_not_void: l_feat /= Void end
382 Result := l_feat.type.actual_type
383 end
384
385 type_i: FORMAL_I is
386 -- C type
387 do
388 create Result.make (is_reference, is_expanded, position)
389 end
390
391 create_info: CREATE_FORMAL_TYPE is
392 -- Create formal type info.
393 do
394 create Result.make (type_i)
395 end
396
397 format (ctxt: TEXT_FORMATTER_DECORATOR) is
398 -- reconstitute text
399 do
400 ctxt.process_generic_text (ctxt.formal_name (position))
401 end
402
403 indexing
404 copyright: "Copyright (c) 1984-2006, Eiffel Software"
405 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
406 licensing_options: "http://www.eiffel.com/licensing"
407 copying: "[
408 This file is part of Eiffel Software's Eiffel Development Environment.
409
410 Eiffel Software's Eiffel Development Environment is free
411 software; you can redistribute it and/or modify it under
412 the terms of the GNU General Public License as published
413 by the Free Software Foundation, version 2 of the License
414 (available at the URL listed under "license" above).
415
416 Eiffel Software's Eiffel Development Environment is
417 distributed in the hope that it will be useful, but
418 WITHOUT ANY WARRANTY; without even the implied warranty
419 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
420 See the GNU General Public License for more details.
421
422 You should have received a copy of the GNU General Public
423 License along with Eiffel Software's Eiffel Development
424 Environment; if not, write to the Free Software Foundation,
425 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
426 ]"
427 source: "[
428 Eiffel Software
429 356 Storke Road, Goleta, CA 93117 USA
430 Telephone 805-685-1006, Fax 805-685-6869
431 Website http://www.eiffel.com
432 Customer support http://support.eiffel.com
433 ]"
434
435 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