/[eiffelstudio]/branches/CAT_mono/Src/Eiffel/eiffel/genericity/cl_type_i.e
ViewVC logotype

Annotation of /branches/CAT_mono/Src/Eiffel/eiffel/genericity/cl_type_i.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 60994 - (hide annotations)
Wed Jul 5 20:59:00 2006 UTC (13 years, 7 months ago) by manus
Original Path: trunk/Src/Eiffel/eiffel/genericity/cl_type_i.e
File size: 17266 byte(s)
Fixed bug#10520 and eweasel test#term142 when `separate' is used and causing `is_reference'
  to be False, when it should have been True. As a consequence we took a complex path in our
  code generation for assignment where we should not have since `separate' is a no-op.

1 manus 26913 indexing
2     description: "Type class."
3 manus 56535 legal: "See notice at end of class."
4     status: "See notice at end of class."
5 manus 26913 date: "$Date$"
6     revision: "$Revision$"
7 grator 18
8     class CL_TYPE_I
9    
10     inherit
11     TYPE_I
12     redefine
13 alexk 56564 anchor_instantiation_in,
14 grator 18 c_type,
15 manus 10818 conforms_to_array,
16 alexk 56356 created_in,
17 manus 11298 generate_cid,
18 manus 14013 generate_cid_array,
19 manus 30169 generate_cid_init,
20 manus 35665 generate_gen_type_il,
21 manus 41824 generate_expanded_creation,
22 manus 43364 generate_expanded_initialization,
23 alexk 56356 generated_id,
24     generic_derivation,
25 alexk 55897 instantiated_description,
26 manus 41824 instantiation_in,
27 alexk 56356 is_expanded,
28     is_explicit,
29     is_external,
30 alexk 56735 is_frozen,
31 alexk 56356 is_generated_as_single_type,
32     is_reference,
33     is_separate,
34     is_valid,
35     make_gen_type_byte_code,
36     same_as
37 grator 18 end
38    
39 manus 33952 SHARED_IL_CASING
40     export
41     {NONE} all
42     end
43    
44 manus 35665 SHARED_GENERATION
45     export
46     {NONE} all
47     end
48    
49     SHARED_DECLARATIONS
50     export
51     {NONE} all
52     end
53    
54 manus 30224 create
55     make
56 alexk 55707
57 manus 30224 feature {NONE} -- Initialization
58    
59     make (id: INTEGER) is
60 manus 30293 -- Create new instance of `Current' with `class_id'
61 manus 30224 -- assigned with `id'.
62     require
63     valid_id: id > 0
64     do
65 manus 30293 class_id := id
66 manus 30224 ensure
67 manus 30293 class_id_set: class_id = id
68 manus 30224 end
69 alexk 55707
70 manus 26913 feature -- Access
71 grator 18
72 manus 30293 class_id: INTEGER
73 grator 18 -- Base class id of the type class
74    
75     meta_generic: META_GENERIC is
76     -- Meta generic array describing the type class
77     do
78     -- No meta generic in non-generic type
79 manus 9655 end
80 grator 18
81 manus 10890 cr_info : CREATE_INFO
82     -- Additional information for the creation
83     -- of generic types with anchored parameters
84    
85 manus 10818 true_generics : ARRAY [TYPE_I] is
86     -- Array of generics: no mapping reference -> REFERENCE_I
87     do
88     -- Non generic types don't have them
89     end
90    
91 grator 18 base_class: CLASS_C is
92     -- Base class associated to the class type
93     do
94 manus 30293 Result := System.class_of_id (class_id)
95 manus 9655 end
96 grator 18
97 manus 41824 generic_derivation: CL_TYPE_I is
98     -- Precise generic derivation of current type.
99     -- That is to say given a type, it gives the associated TYPE_I
100     -- which can be used to search its associated CLASS_TYPE.
101     do
102     Result := Current
103     end
104 alexk 55707
105 manus 26913 type_a: CL_TYPE_A is
106 grator 236 do
107 manus 30293 create Result.make (class_id)
108 alexk 56011 Result.set_mark (declaration_mark)
109 manus 9655 end
110 grator 236
111 manus 41824 name: STRING is
112     -- String that should be displayed in debugger to represent `Current'.
113     do
114 manus 43828 Result := base_name
115 manus 41824 end
116 alexk 55707
117 alexk 56011 duplicate: like Current is
118     -- Duplication
119     do
120     Result := twin
121     end
122    
123 manus 43828 instantiation_in (other: CLASS_TYPE): CL_TYPE_I is
124 manus 41824 -- Instantation of Current in `other'
125     do
126     Result := Current
127     end
128 alexk 55707
129 alexk 56564 anchor_instantiation_in (other: CLASS_TYPE): CL_TYPE_I is
130     -- Instantation of `like Current' parts of Current in `other'
131     do
132     Result := Current
133     end
134    
135 alexk 56356 created_in (other: CLASS_TYPE): TYPE_I is
136     -- Resulting type of Current as if it was used to create object in `other'.
137     do
138     Result := Current
139     if cr_info /= Void then
140     Result := cr_info.created_in (other)
141     end
142     end
143    
144 manus 33952 il_type_name (a_prefix: STRING): STRING is
145 manus 26913 -- Class name of current type.
146 manus 29681 local
147     l_class_c: like base_class
148 manus 34253 l_is_precompiled: BOOLEAN
149     l_cl_type: like associated_class_type
150 grator 18 do
151 manus 29681 l_class_c := base_class
152 manus 41824 if is_external then
153 manus 40771 Result := l_class_c.external_class_name.twin
154 manus 29681 else
155 manus 34253 l_is_precompiled := l_class_c.is_precompiled
156     if l_is_precompiled then
157     l_cl_type := associated_class_type
158     l_is_precompiled := l_cl_type.is_precompiled
159     if l_is_precompiled then
160 manus 49345 Result := l_cl_type.il_type_name (a_prefix)
161 manus 34253 end
162     end
163     if not l_is_precompiled then
164 raphaels 48802 if l_class_c.external_class_name.is_equal (l_class_c.name) then
165     Result := internal_il_type_name (l_class_c.name.twin, a_prefix)
166     else
167     Result := l_class_c.external_class_name.twin
168     if a_prefix /= Void then
169     if Result.item (Result.count) /= '.' then
170     Result.append_character ('.')
171     end
172     Result.append (a_prefix)
173     end
174     end
175 manus 34253 end
176 manus 29681 end
177 manus 11218 end
178    
179 alexk 55897 description, instantiated_description: ATTR_DESC is
180 grator 18 -- Type description for skeletons
181     local
182 michaels 7681 exp: EXPANDED_DESC
183     ref: REFERENCE_DESC
184 grator 485 do
185 manus 41824 if is_expanded then
186 julieng 37663 create exp
187 manus 42413 exp.set_cl_type_i (Current)
188 manus 13232 exp.set_type_i (Current)
189 manus 9655 Result := exp
190 grator 18 else
191 manus 9655 Result := c_type.description
192 manus 42413 ref ?= Result
193     if ref /= Void then
194     ref.set_type_i (Current)
195     end
196 manus 9655 end
197     end
198 grator 18
199     c_type: TYPE_C is
200     -- Associated C type
201     do
202 manus 9655 Result := Reference_c_type
203     end
204 manus 42413
205 grator 18 associated_class_type: CLASS_TYPE is
206     -- Associated class type
207 michaels 7681 require
208 manus 42865 has: has_associated_class_type
209 grator 485 do
210 manus 41824 Result := base_class.types.search_item (Current)
211 alexk 48670 ensure
212     result_not_void: Result /= Void
213 manus 9655 end
214 grator 18
215     type_id: INTEGER is
216     -- Type id of the correponding class type
217     do
218 manus 9655 Result := associated_class_type.type_id
219     end
220 grator 18
221 manus 26913 sk_value: INTEGER is
222     -- Generate SK value associated to the current type.
223 grator 18 do
224 manus 41824 if is_expanded then
225     Result := Sk_exp | (type_id - 1)
226     else
227 manus 31263 Result := Sk_ref | (type_id - 1)
228 manus 9655 end
229     end
230 grator 18
231     hash_code: INTEGER is
232     -- Hash code for current type
233     do
234 manus 30293 Result := Other_code + class_id
235 manus 9655 end
236 grator 18
237 manus 26913 feature -- Status
238    
239 manus 31541 element_type: INTEGER_8 is
240     -- Void element type
241     do
242 manus 41824 if is_expanded then
243 alexk 55707 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_valuetype
244 manus 31541 else
245 manus 37130 if class_id = System.system_string_class.compiled_class.class_id then
246 manus 49446 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_string
247 manus 44032 elseif class_id = System.system_object_id or class_id = system.any_id then
248     -- For ANY or SYSTEM_OBJECT, we always generate a System.Object
249     -- signature since we can now assign SYSTEM_OBJECTs into ANYs.
250 manus 49446 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_object
251 manus 31541 else
252 manus 49446 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_class
253 manus 31541 end
254     end
255     end
256    
257 manus 41824 tuple_code: INTEGER_8 is
258     -- Tuple code for class type
259     do
260 manus 49446 Result := {SHARED_GEN_CONF_LEVEL}.reference_tuple_code
261 manus 41824 end
262 alexk 55707
263 alexk 56011 has_no_mark: BOOLEAN is
264     -- Has class type no explicit mark?
265     do
266     Result := declaration_mark = {CL_TYPE_A}.no_mark
267     ensure
268     definition: Result = (declaration_mark = {CL_TYPE_A}.no_mark)
269     end
270    
271     has_expanded_mark: BOOLEAN is
272     -- Is class type explicitly marked as expanded?
273     do
274     Result := declaration_mark = {CL_TYPE_A}.expanded_mark
275     ensure
276     definition: Result = (declaration_mark = {CL_TYPE_A}.expanded_mark)
277     end
278    
279     has_reference_mark: BOOLEAN is
280     -- Is class type explicitly marked as reference?
281     do
282     Result := declaration_mark = {CL_TYPE_A}.reference_mark
283     ensure
284     definition: Result = (declaration_mark = {CL_TYPE_A}.reference_mark)
285     end
286    
287     has_separate_mark: BOOLEAN is
288     -- Is class type explicitly marked as reference?
289     do
290     Result := declaration_mark = {CL_TYPE_A}.separate_mark
291     ensure
292     definition: Result = (declaration_mark = {CL_TYPE_A}.separate_mark)
293     end
294    
295     is_expanded: BOOLEAN is
296 manus 26913 -- Is the type expanded?
297 alexk 56011 do
298 manus 60994 -- Do not check for `has_separate_mark' because a separate class cannot be expanded.
299     Result := has_expanded_mark or else (has_no_mark and then base_class.is_expanded)
300 alexk 56011 end
301 manus 26913
302 alexk 56011 is_reference: BOOLEAN is
303     -- Is the type a reference type?
304     do
305 manus 60994 Result := has_reference_mark or else
306     ((has_no_mark or has_separate_mark) and then not base_class.is_expanded)
307 alexk 56011 end
308    
309     is_separate: BOOLEAN is
310 manus 26913 -- Is the type separate?
311 alexk 56011 do
312     Result := has_separate_mark
313     end
314 manus 26913
315     is_enum: BOOLEAN is
316     -- Is current type an IL enum type?
317     -- Useful to find out if some call optimization can be done
318     -- in FEATURE_B.
319     require
320     il_generation: System.il_generation
321 grator 18 do
322 manus 41824 Result := is_expanded and then base_class.is_enum
323 manus 26913 end
324    
325 manus 28380 is_external: BOOLEAN is
326 manus 41824 -- Is current type based on an external class?
327     local
328     l_base_class: like base_class
329 manus 28380 do
330 manus 41824 -- All Eiffel basic types are externals, and only basic types used
331     -- as reference are not external.
332     l_base_class := base_class
333     Result := is_basic or (not l_base_class.is_basic and l_base_class.is_external)
334 manus 28380 end
335 alexk 55707
336 alexk 56735 is_frozen: BOOLEAN is
337     -- Is current type based on a frozen class?
338     do
339     Result := base_class.is_frozen
340     end
341    
342 manus 41824 is_generated_as_single_type: BOOLEAN is
343 alexk 55707 -- Is associated type generated as a single type or as an interface type and
344 manus 41824 -- an implementation type.
345     do
346 manus 44032 -- External classes have only one type.
347     Result := is_external
348 manus 41824 if not Result then
349 manus 44058 -- Classes that inherits from external classes
350 alexk 55396 -- have only one generated type as well as expanded types.
351     Result := base_class.is_single or else is_expanded
352 manus 41824 end
353     end
354 manus 28380
355 manus 26913 is_valid: BOOLEAN is
356 manus 35544 -- Is the base class still in the system and matches its specification?
357 manus 41824 local
358     l_base_class: like base_class
359 manus 26913 do
360 manus 41824 l_base_class := base_class
361     Result := l_base_class /= Void and then (l_base_class.generics = Void)
362 manus 26913 end
363    
364     is_explicit: BOOLEAN is
365 manus 39713 -- Is Current type fixed at compile time?
366 manus 26913 do
367 manus 39713 if cr_info /= Void then
368     Result := cr_info.is_explicit
369     else
370     Result := True
371     end
372 manus 26913 end
373    
374     has_associated_class_type: BOOLEAN is
375     -- Has `Current' an associated class type?
376     do
377 alexk 48670 Result := base_class.types.has_type (Current)
378 manus 9655 end
379 grator 18
380 manus 26913 same_as (other: TYPE_I): BOOLEAN is
381     -- Is `other' equal to Current ?
382     local
383     other_cl_type: CL_TYPE_I
384 grator 508 do
385 manus 26913 other_cl_type ?= other
386     Result := other_cl_type /= Void -- FIXME
387 manus 30293 and then other_cl_type.class_id = class_id
388 manus 41824 and then other_cl_type.is_expanded = is_expanded
389 manus 26913 and then other_cl_type.is_separate = is_separate
390     and then other_cl_type.meta_generic = Void
391     and then other_cl_type.true_generics = Void
392     end
393    
394 alexk 56564 has_actual (type: CL_TYPE_I): BOOLEAN is
395     -- Is `type' an (possibly nested) actual parameter of this type?
396     require
397     non_void_type: type /= Void
398     do
399     -- False here.
400     end
401    
402 manus 26913 feature -- Setting
403    
404 alexk 56011 set_expanded_mark is
405     -- Set class type declaration as expanded.
406 manus 26913 do
407 alexk 56011 declaration_mark := {CL_TYPE_A}.expanded_mark
408 manus 35178 ensure
409 alexk 56011 has_expanded_mark: has_expanded_mark
410 manus 26913 end
411    
412 alexk 56011 set_reference_mark is
413     -- Set class type declaration as reference.
414 manus 26913 do
415 alexk 56011 declaration_mark := {CL_TYPE_A}.reference_mark
416 manus 35178 ensure
417 alexk 56011 has_reference_mark: has_reference_mark
418 manus 26913 end
419    
420 alexk 56011 set_separate_mark is
421     -- Set class type declaration as separate.
422     do
423     declaration_mark := {CL_TYPE_A}.separate_mark
424     ensure
425     has_separate_mark: has_separate_mark
426     end
427    
428 manus 26913 set_cr_info (cinfo : CREATE_INFO) is
429     -- Set `cr_info' to `cinfo'.
430 manus 30224 require
431     create_info_not_void: cinfo /= Void
432 manus 41824 not_expanded: not is_expanded
433 manus 26913 do
434     cr_info := cinfo
435     ensure
436     cr_info_set : cr_info = cinfo
437     end
438    
439     feature -- C generation
440    
441 manus 43364 generate_expanded_creation (buffer: GENERATION_BUFFER; target_name: STRING) is
442 manus 35665 -- Generate creation of expanded object associated to Current.
443     do
444 manus 43364 associated_class_type.generate_expanded_creation (buffer, target_name)
445     end
446 manus 35665
447 manus 43364 generate_expanded_initialization (buffer: GENERATION_BUFFER; target_name: STRING) is
448     -- Generate creation of expanded object associated to Current.
449     do
450     associated_class_type.generate_expanded_initialization (buffer, target_name, target_name, True)
451 manus 35665 end
452    
453 manus 26913 generate_cecil_value (buffer: GENERATION_BUFFER) is
454     -- Generate cecil value
455     do
456 manus 41824 if not is_expanded then
457 manus 43084 buffer.put_string ("SK_REF + (uint32) ")
458 grator 508 else
459 manus 43084 buffer.put_string ("SK_EXP + (uint32) ")
460 manus 9655 end
461 manus 43084 buffer.put_type_id (associated_class_type.type_id)
462 manus 9655 end
463 grator 508
464 grator 930 feature -- Array optimization
465    
466     conforms_to_array: BOOLEAN is
467     do
468     Result := base_class.conform_to (array_class_c)
469 manus 9655 end
470 grator 930
471     feature {NONE} -- Array optimization
472    
473     array_class_c: CLASS_C is
474     once
475     Result := System.array_class.compiled_class
476 manus 9655 end
477 grator 930
478 manus 10818 feature -- Generic conformance
479    
480     generated_id (final_mode : BOOLEAN) : INTEGER is
481 manus 11298
482 manus 10818 do
483 manus 11298 if final_mode then
484     Result := type_id - 1
485 manus 10818 else
486 manus 41824 Result := associated_class_type.static_type_id - 1
487 manus 10818 end
488     end
489    
490 manus 11599 generate_cid (buffer : GENERATION_BUFFER; final_mode, use_info : BOOLEAN) is
491 manus 11298
492 manus 10818 do
493 manus 11209 if
494     use_info and then (cr_info /= Void)
495 manus 26913 and then not is_expanded
496 manus 11209 then
497 alexk 55707 -- It's an anchored type
498 manus 11599 cr_info.generate_cid (buffer, final_mode)
499 manus 39412 else
500 manus 43084 buffer.put_integer (generated_id (final_mode))
501 manus 43156 buffer.put_character (',')
502 manus 10890 end
503 manus 10818 end
504    
505 manus 10890 make_gen_type_byte_code (ba : BYTE_ARRAY; use_info : BOOLEAN) is
506 manus 10818 do
507 manus 11209 if
508     use_info and then (cr_info /= Void)
509 manus 26913 and then not is_expanded
510 manus 11209 then
511 alexk 55707 -- It's an anchored type
512 manus 10890 cr_info.make_gen_type_byte_code (ba)
513 manus 39412 else
514     ba.append_short_integer (generated_id (False))
515 manus 10890 end
516 manus 10818 end
517    
518 alexk 55707 generate_cid_array (buffer : GENERATION_BUFFER;
519 manus 14013 final_mode, use_info : BOOLEAN; idx_cnt : COUNTER) is
520     local
521     dummy : INTEGER
522     do
523     if
524     use_info and then (cr_info /= Void)
525 manus 26913 and then not is_expanded
526 manus 14013 then
527 alexk 55707 -- It's an anchored type
528 manus 14013 cr_info.generate_cid_array (buffer, final_mode, idx_cnt)
529 manus 39412 else
530 manus 43084 buffer.put_integer (generated_id (final_mode))
531 manus 43156 buffer.put_character (',')
532 manus 39412
533     -- Increment counter
534     dummy := idx_cnt.next
535 manus 14013 end
536     end
537    
538 alexk 55707 generate_cid_init (buffer : GENERATION_BUFFER;
539 manus 14013 final_mode, use_info : BOOLEAN; idx_cnt : COUNTER) is
540     local
541     dummy : INTEGER
542     do
543     if
544     use_info and then (cr_info /= Void)
545 manus 26913 and then not is_expanded
546 manus 14013 then
547 alexk 55707 -- It's an anchored type
548 manus 14013 cr_info.generate_cid_init (buffer, final_mode, idx_cnt)
549 manus 39412 else
550     dummy := idx_cnt.next
551 manus 14013 end
552     end
553 manus 30169
554     feature -- Generic conformance for IL
555    
556     generate_gen_type_il (il_generator: IL_CODE_GENERATOR; use_info : BOOLEAN) is
557 alexk 55707 -- `use_info' is true iff we generate code for a
558 manus 30169 -- creation instruction.
559     do
560     if use_info and then cr_info /= Void then
561 manus 30582 -- It's an anchored type, we call feature
562 alexk 55707 -- that will tell us the real type of the
563 manus 30582 -- anchor in the context of Current.
564     cr_info.generate_il_type
565     else
566     il_generator.generate_class_type_instance (Current)
567 alexk 55707 end
568 manus 30169 end
569    
570 manus 33952 feature {NONE} -- Implementation
571    
572 manus 43828 base_name: STRING is
573     -- String that should be displayed in debugger to represent `Current'.
574     local
575     l_base_class: like base_class
576     do
577     create Result.make (32)
578     l_base_class := base_class
579     if is_expanded and not l_base_class.is_expanded then
580     Result.append ("expanded ")
581 alexk 56011 elseif is_reference and l_base_class.is_expanded then
582     Result.append ("reference ")
583 manus 43828 elseif is_separate then
584     Result.append ("separate ")
585     end
586     Result.append (l_base_class.name)
587     end
588    
589 manus 41824 frozen internal_il_type_name (a_base_name, a_prefix: STRING): STRING is
590 manus 33952 -- Full type name of `a_base_name' using `a_prefix' in IL code generation
591     -- with namespace specification
592     require
593     a_base_name_not_void: a_base_name /= Void
594     local
595 manus 41824 l_base_class: like base_class
596 manus 33952 do
597 manus 41824 l_base_class := base_class
598     -- Result needs to be in lower case because that's
599     -- what our casing conversion routines require to perform
600     -- a good job.
601 alexk 46609 if is_expanded and then not l_base_class.is_expanded then
602     create Result.make (6 + a_base_name.count)
603     Result.append ("value_")
604     elseif not is_expanded and then l_base_class.is_expanded then
605     create Result.make (10 + a_base_name.count)
606     Result.append ("reference_")
607 manus 41824 else
608 alexk 46609 create Result.make (a_base_name.count)
609 manus 41824 end
610 alexk 46609 Result.append (a_base_name)
611     Result.to_lower
612 patrickr 57781 Result := il_casing.type_name (l_base_class.original_class.actual_namespace, a_prefix, Result, System.dotnet_naming_convention)
613 manus 33952 ensure
614     internal_il_type_name_not_void: Result /= Void
615     internal_il_type_name_not_empty: not Result.is_empty
616     end
617    
618 alexk 56062 feature {CL_TYPE_A, TUPLE_CLASS_B} -- Implementation: class type declaration marks
619 alexk 56011
620     declaration_mark: NATURAL_8
621     -- Declaration mark associated with a class type (if any)
622    
623     set_mark (mark: like declaration_mark) is
624     -- Set `declaration_mark' to the given value `mark'.
625     require
626     valid_declaration_mark:
627     mark = {CL_TYPE_A}.no_mark or mark = {CL_TYPE_A}.expanded_mark or
628     mark = {CL_TYPE_A}.reference_mark or mark = {CL_TYPE_A}.separate_mark
629     do
630     declaration_mark := mark
631     ensure
632     declaration_mark_set: declaration_mark = mark
633     end
634    
635 manus 41824 invariant
636     class_id_positive: class_id > 0
637 alexk 56011 valid_declaration_mark:
638     declaration_mark = {CL_TYPE_A}.no_mark or
639     declaration_mark = {CL_TYPE_A}.expanded_mark or
640     declaration_mark = {CL_TYPE_A}.reference_mark or
641     declaration_mark = {CL_TYPE_A}.separate_mark
642 manus 41824
643 manus 56535 indexing
644     copyright: "Copyright (c) 1984-2006, Eiffel Software"
645 manus 58027 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
646 manus 56535 licensing_options: "http://www.eiffel.com/licensing"
647     copying: "[
648     This file is part of Eiffel Software's Eiffel Development Environment.
649 manus 58027
650 manus 56535 Eiffel Software's Eiffel Development Environment is free
651     software; you can redistribute it and/or modify it under
652     the terms of the GNU General Public License as published
653     by the Free Software Foundation, version 2 of the License
654     (available at the URL listed under "license" above).
655 manus 58027
656 manus 56535 Eiffel Software's Eiffel Development Environment is
657     distributed in the hope that it will be useful, but
658     WITHOUT ANY WARRANTY; without even the implied warranty
659     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
660     See the GNU General Public License for more details.
661 manus 58027
662 manus 56535 You should have received a copy of the GNU General Public
663     License along with Eiffel Software's Eiffel Development
664     Environment; if not, write to the Free Software Foundation,
665     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
666     ]"
667     source: "[
668     Eiffel Software
669     356 Storke Road, Goleta, CA 93117 USA
670     Telephone 805-685-1006, Fax 805-685-6869
671     Website http://www.eiffel.com
672     Customer support http://support.eiffel.com
673     ]"
674    
675 grator 18 end

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23