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