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