/[eiffelstudio]/branches/eth/eve/Src/Eiffel/eiffel/AST/visitor/ast_type_a_generator.e
ViewVC logotype

Contents of /branches/eth/eve/Src/Eiffel/eiffel/AST/visitor/ast_type_a_generator.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 94983 - (show annotations)
Fri May 2 11:05:28 2014 UTC (5 years, 5 months ago) by jasonw
File size: 14294 byte(s)
<<Merged from trunk#94978.>>
1 note
2 description: "Perform resolution of TYPE_AS into TYPE_A without validity checking."
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
9 AST_TYPE_A_GENERATOR
10
11 inherit
12 AST_NULL_VISITOR
13 redefine
14 process_like_id_as, process_like_cur_as,
15 process_qualified_anchored_type_as,
16 process_formal_as, process_class_type_as,
17 process_generic_class_type_as, process_none_type_as,
18 process_named_tuple_type_as, process_type_dec_as
19 end
20
21 COMPILER_EXPORTER
22 export
23 {NONE} all
24 end
25
26 SHARED_WORKBENCH
27 export
28 {NONE} all
29 end
30
31 SHARED_TYPES
32 export
33 {NONE} all
34 end
35
36 REFACTORING_HELPER
37 export
38 {NONE} all
39 end
40
41 INTERNAL_COMPILER_STRING_EXPORTER
42
43 feature -- Status report
44
45 evaluate_type (a_type: TYPE_AS; a_context_class: CLASS_C): detachable TYPE_A
46 -- Given a TYPE_AS node, find its equivalent TYPE_A node.
47 require
48 a_type_not_void: a_type /= Void
49 a_context_class_not_void: a_context_class /= Void
50 local
51 old_current_class: like current_class
52 old_last_type: like last_type
53 do
54 old_current_class := current_class
55 old_last_type := last_type
56 current_class := a_context_class
57 a_type.process (Current)
58 Result := last_type
59 current_class := old_current_class
60 last_type := old_last_type
61 end
62
63 feature {NONE} -- Implementation: Access
64
65 last_type: TYPE_A
66 -- Last resolved type of checker
67
68 current_class: CLASS_C
69 -- Current class where current type is resolved
70
71 feature {NONE} -- Visitor implementation
72
73 process_like_id_as (l_as: LIKE_ID_AS)
74 local
75 t: UNEVALUATED_LIKE_TYPE
76 do
77 create t.make (l_as.anchor.name)
78 if l_as.has_frozen_mark then
79 t.set_frozen_mark
80 elseif l_as.has_variant_mark then
81 t.set_variant_mark
82 end
83 if l_as.has_attached_mark then
84 t.set_attached_mark
85 elseif l_as.has_detachable_mark then
86 t.set_detachable_mark
87 end
88 if l_as.has_separate_mark then
89 t.set_separate_mark
90 end
91 last_type := t
92 end
93
94 process_like_cur_as (l_as: LIKE_CUR_AS)
95 local
96 l_cur: LIKE_CURRENT
97 do
98 create l_cur.make (current_class.actual_type)
99 if l_as.has_frozen_mark then
100 l_cur.set_frozen_mark
101 elseif l_as.has_variant_mark then
102 l_cur.set_variant_mark
103 end
104 if l_as.has_attached_mark then
105 l_cur.set_attached_mark
106 elseif l_as.has_detachable_mark then
107 l_cur.set_detachable_mark
108 end
109 if l_as.has_separate_mark then
110 l_cur.set_separate_mark
111 end
112 last_type := l_cur
113 end
114
115 process_qualified_anchored_type_as (l_as: QUALIFIED_ANCHORED_TYPE_AS)
116 -- <Precursor>
117 local
118 t: UNEVALUATED_QUALIFIED_ANCHORED_TYPE
119 n: SPECIAL [INTEGER_32]
120 i: INTEGER
121 do
122 l_as.qualifier.process (Current)
123 if attached last_type as q then
124 -- Qualifier type is processed without an error.
125 -- Make an array of names in the chain.
126 create n.make_filled (0, l_as.chain.count)
127 across l_as.chain as l_chain loop
128 n [i] := l_chain.item.name.name_id
129 i := i + 1
130 end
131 create t.make (q, n)
132 if l_as.has_frozen_mark then
133 t.set_frozen_mark
134 elseif l_as.has_variant_mark then
135 t.set_variant_mark
136 end
137 if l_as.has_attached_mark then
138 t.set_attached_mark
139 elseif l_as.has_detachable_mark then
140 t.set_detachable_mark
141 end
142 if l_as.has_separate_mark then
143 t.set_separate_mark
144 end
145 last_type := t
146 end
147 end
148
149 process_formal_as (l_as: FORMAL_AS)
150 local
151 f: FORMAL_A
152 types_done: LINKED_LIST [INTEGER]
153 todo_attached: LINKED_LIST [INTEGER]
154 todo_separate: LINKED_LIST [INTEGER]
155 l: CONSTRAINT_LIST_AS
156 t: TYPE_AS
157 i: INTEGER
158 j: INTEGER
159 s: BOOLEAN
160 l_is_frozen: BOOLEAN
161 do
162 create f.make (l_as.is_reference, l_as.is_expanded, l_as.position)
163 last_type := f
164 if system.is_scoop then
165 -- The formal generic is separate by default.
166 s := True
167 end
168 if l_as.has_frozen_mark then
169 f.set_frozen_mark
170 elseif l_as.has_variant_mark then
171 f.set_variant_mark
172 end
173 if l_as.has_attached_mark then
174 f.set_attached_mark
175 check f.is_attached end
176 elseif l_as.has_detachable_mark then
177 f.set_detachable_mark
178 end
179 if l_as.has_separate_mark then
180 f.set_separate_mark
181 end
182 if current_class.generics [l_as.position].constraints /= Void then
183 -- Check attachment and separateness status of constraints.
184 -- The loop iterates over all constraints recursively.
185 -- The condition to terminate it for attachment status is to
186 -- find an expanded type, since than the type is known to be
187 -- attached, but the initialization is not required.
188 -- The condition to terminate for separate status is to
189 -- find a non-separate constraint since then the formal
190 -- is not separate.
191 from
192 create types_done.make
193 create todo_attached.make
194 create todo_separate.make
195 todo_attached.extend (l_as.position)
196 todo_separate.extend (l_as.position)
197 until
198 todo_attached.is_empty and then todo_separate.is_empty
199 loop
200 from
201 if not todo_attached.is_empty then
202 todo_attached.start
203 j := todo_attached.item_for_iteration
204 todo_attached.remove
205 -- Remove this item from `todo_separate'.
206 todo_separate.search (j)
207 if not todo_separate.exhausted then
208 todo_separate.remove
209 end
210 else
211 todo_separate.start
212 j := todo_separate.item_for_iteration
213 todo_separate.remove
214 end
215 l := current_class.generics [j].constraints
216 types_done.extend (j)
217 i := l.count
218 until
219 i <= 0
220 loop
221 t := l [i].type
222 if t.has_frozen_mark then
223 l_is_frozen := True
224 end
225 if
226 attached {CLASS_TYPE_AS} t as ct and then
227 (ct.is_expanded or else
228 attached universe.class_named (ct.class_name.name, current_class.group) as ci and then
229 ci.is_compiled and then
230 attached ci.compiled_class as c and then
231 c.is_expanded)
232 then
233 -- The actual type should be expanded.
234 f.set_is_expanded
235 f.set_is_attached
236 todo_attached.wipe_out
237 -- The generic is not separate.
238 s := False
239 todo_separate.wipe_out
240 -- Terminate iteration.
241 i := 1
242 elseif attached {FORMAL_AS} t as ff then
243 -- Record new formal generic for processing (if not done yet).
244 if not types_done.has (ff.position) then
245 -- This is a new formal generic type.
246 if current_class.generics [ff.position].constraints = Void then
247 -- Formal generic without constraints does not provide attachment status
248 -- not specifies non-separate status.
249 types_done.extend (ff.position)
250 else
251 if t.has_detachable_mark then
252 -- Skip the detachable type because it does not allow to see
253 -- if the formal is always attached or not.
254 else
255 if t.has_attached_mark and then not f.has_detachable_mark then
256 f.set_is_attached
257 end
258 if not todo_attached.has (ff.position) then
259 -- The constraints have to be checked.
260 todo_attached.extend (ff.position)
261 end
262 end
263 if s then
264 -- The formal is still considered separate.
265 if t.has_separate_mark then
266 -- Skip separate type because it does not allow to see
267 -- if the formal is always non-separate.
268 elseif not todo_separate.has (ff.position) then
269 -- The constraints have to be checked.
270 todo_separate.extend (ff.position)
271 end
272 end
273 end
274 end
275 else
276 -- The type must be a class type.
277 if t.has_detachable_mark then
278 -- Skip the detachable constraint because it does not allow to see
279 -- if the formal is always attached or not.
280 elseif
281 (t.has_attached_mark or else
282 current_class.lace_class.is_attached_by_default) and then
283 not f.has_detachable_mark
284 then
285 -- The type must be a class type with an attached mark
286 -- or without any attachment marks. Let's use the `current_class'
287 -- default attachment settings in the latter case.
288 f.set_is_attached
289 end
290 if not t.has_separate_mark then
291 -- The generic is not separate.
292 s := False
293 todo_separate.wipe_out
294 end
295 end
296 i := i - 1
297 end
298 end
299 end
300 if s then
301 f.set_is_separate
302 end
303 if l_is_frozen then
304 f.set_frozen_mark
305 end
306 end
307
308 process_class_type_as (l_as: CLASS_TYPE_AS)
309 local
310 l_class_i: CLASS_I
311 l_class_c: CLASS_C
312 l_actual_generic: detachable ARRAYED_LIST [TYPE_A]
313 l_generics: TYPE_LIST_AS
314 i, count: INTEGER
315 l_has_error: BOOLEAN
316 l_type: CL_TYPE_A
317 do
318 -- Lookup class in universe, it should be present.
319 l_class_i := universe.class_named (l_as.class_name.name, current_class.group)
320 if l_class_i /= Void and then l_class_i.is_compiled then
321 l_class_c := l_class_i.compiled_class
322 l_generics := l_as.generics
323 if l_generics /= Void then
324 from
325 i := 1
326 count := l_generics.count
327 create l_actual_generic.make (count)
328 until
329 i > count or l_has_error
330 loop
331 l_generics.i_th (i).process (Current)
332 l_has_error := last_type = Void
333 l_actual_generic.extend (last_type)
334 i := i + 1
335 end
336 end
337 if l_has_error then
338 last_type := Void
339 else
340 l_type := l_class_c.partial_actual_type (l_actual_generic, l_as.is_expanded)
341 last_type := set_class_type_marks (l_as, l_type)
342 end
343 else
344 last_type := Void
345 end
346 end
347
348 process_generic_class_type_as (l_as: GENERIC_CLASS_TYPE_AS)
349 do
350 process_class_type_as (l_as)
351 end
352
353 process_named_tuple_type_as (l_as: NAMED_TUPLE_TYPE_AS)
354 local
355 l_class_i: CLASS_I
356 l_class_c: CLASS_C
357 l_actual_generic: ARRAYED_LIST [TYPE_A]
358 i, g, count: INTEGER
359 l_type: NAMED_TUPLE_TYPE_A
360 l_generics: EIFFEL_LIST [TYPE_DEC_AS]
361 l_names: SPECIAL [INTEGER]
362 l_id_list: CONSTRUCT_LIST [INTEGER]
363 l_has_error: BOOLEAN
364 do
365 -- Lookup class in universe, it should be present.
366 l_class_i := System.tuple_class
367 if l_class_i /= Void and then l_class_i.is_compiled then
368 l_class_c := l_class_i.compiled_class
369 l_generics := l_as.generics
370 from
371 i := 1
372 g := 1
373 count := l_as.generic_count
374 create l_actual_generic.make (count)
375 create l_names.make_filled (0, count)
376 until
377 i > count or l_has_error
378 loop
379 l_generics.i_th (g).process (Current)
380 l_has_error := last_type = Void
381 l_id_list := l_generics.i_th (g).id_list
382 from
383 l_id_list.start
384 until
385 l_id_list.after
386 loop
387 l_actual_generic.extend (last_type)
388 l_names.put (l_id_list.item, i - 1)
389 i := i + 1
390 l_id_list.forth
391 end
392 g := g + 1
393 end
394 create l_type.make (l_class_c.class_id, l_actual_generic, l_names)
395 if l_has_error then
396 last_type := Void
397 else
398 check attached l_type end
399 last_type := set_class_type_marks (l_as, l_type)
400 end
401 else
402 last_type := Void
403 end
404 end
405
406 process_type_dec_as (l_as: TYPE_DEC_AS)
407 do
408 l_as.type.process (Current)
409 end
410
411 process_none_type_as (l_as: NONE_TYPE_AS)
412 do
413 last_type := set_class_type_marks (l_as, none_type)
414 end
415
416 feature {NONE} -- Type marks
417
418 set_class_type_marks (a: TYPE_AS; t: TYPE_A): TYPE_A
419 -- Type `t' or its duplicate if `t' may be a result of a once funtion
420 -- with type marks specified in `a'.
421 require
422 a_attached: attached a
423 t_attached: attached t
424 local
425 is_shared: BOOLEAN
426 do
427 -- Basic and NONE type descriptors may be shared, so we duplicate
428 -- if needed to avoid modifying once values.
429 is_shared := t.is_basic or else t.is_none
430 Result := t
431
432 -- Handle frozen/variant mark.
433 if a.has_frozen_mark then
434 -- Avoid modifying once values.
435 if is_shared then
436 Result := Result.duplicate
437 end
438 Result.set_frozen_mark
439 elseif a.has_variant_mark then
440 -- Avoid modifying once values.
441 if is_shared then
442 Result := Result.duplicate
443 end
444 Result.set_variant_mark
445 end
446
447 -- Handle any attachment mark.
448 if a.has_attached_mark then
449 -- Avoid modifying once values.
450 if is_shared then
451 Result := Result.duplicate
452 end
453 Result.set_attached_mark
454 check Result.is_attached end
455 elseif a.has_detachable_mark then
456 -- Avoid modifying once values.
457 if is_shared then
458 Result := Result.duplicate
459 end
460 Result.set_detachable_mark
461 elseif current_class.lace_class.is_attached_by_default then
462 -- Avoid modifying once values.
463 if is_shared then
464 Result := Result.duplicate
465 end
466 Result.set_is_attached
467 end
468
469 -- Handle separate mark.
470 if a.has_separate_mark then
471 -- Avoid modifying once values.
472 if is_shared then
473 Result := Result.duplicate
474
475 end
476 Result.set_separate_mark
477 end
478 ensure
479 result_attached: attached Result
480 end
481
482 note
483 copyright: "Copyright (c) 1984-2014, Eiffel Software"
484 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
485 licensing_options: "http://www.eiffel.com/licensing"
486 copying: "[
487 This file is part of Eiffel Software's Eiffel Development Environment.
488
489 Eiffel Software's Eiffel Development Environment is free
490 software; you can redistribute it and/or modify it under
491 the terms of the GNU General Public License as published
492 by the Free Software Foundation, version 2 of the License
493 (available at the URL listed under "license" above).
494
495 Eiffel Software's Eiffel Development Environment is
496 distributed in the hope that it will be useful, but
497 WITHOUT ANY WARRANTY; without even the implied warranty
498 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
499 See the GNU General Public License for more details.
500
501 You should have received a copy of the GNU General Public
502 License along with Eiffel Software's Eiffel Development
503 Environment; if not, write to the Free Software Foundation,
504 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
505 ]"
506 source: "[
507 Eiffel Software
508 5949 Hollister Ave., Goleta, CA 93117 USA
509 Telephone 805-685-1006, Fax 805-685-6869
510 Website http://www.eiffel.com
511 Customer support http://support.eiffel.com
512 ]"
513
514 end
515

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23