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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 69657 - (show annotations)
Tue Jul 24 19:16:42 2007 UTC (12 years, 7 months ago) by juliant
File size: 22028 byte(s)
changed type mark to bitwise operations
1 indexing
2 description: "Type class."
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 CL_TYPE_I
9
10 inherit
11 TYPE_I
12 redefine
13 anchor_instantiation_in,
14 c_type,
15 conforms_to_array,
16 created_in,
17 external_id,
18 full_type_byte_code_type_id,
19 generate_cid,
20 generate_cid_array,
21 generate_cid_init,
22 generate_gen_type_il,
23 generate_expanded_creation,
24 generate_expanded_initialization,
25 generated_id,
26 internal_generic_derivation,
27 instantiated_description,
28 instantiation_in,
29 is_expanded,
30 is_explicit,
31 is_external,
32 is_frozen,
33 is_generated_as_single_type,
34 is_reference,
35 is_separate,
36 is_consistent,
37 make_gen_type_byte_code,
38 same_as,
39 static_type_id
40 end
41
42 SHARED_IL_CASING
43 export
44 {NONE} all
45 end
46
47 SHARED_GENERATION
48 export
49 {NONE} all
50 end
51
52 SHARED_DECLARATIONS
53 export
54 {NONE} all
55 end
56
57 create
58 make
59
60 feature {NONE} -- Initialization
61
62 make (id: INTEGER) is
63 -- Create new instance of `Current' with `class_id'
64 -- assigned with `id'.
65 require
66 valid_id: id > 0
67 do
68 class_id := id
69 ensure
70 class_id_set: class_id = id
71 end
72
73 feature -- Access
74
75 class_id: INTEGER
76 -- Base class id of the type class
77
78 meta_generic: META_GENERIC is
79 -- Meta generic array describing the type class
80 do
81 -- No meta generic in non-generic type
82 end
83
84 cr_info : CREATE_INFO
85 -- Additional information for the creation
86 -- of generic types with anchored parameters
87
88 true_generics : ARRAY [TYPE_I] is
89 -- Array of generics: no mapping reference -> REFERENCE_I
90 do
91 -- Non generic types don't have them
92 end
93
94 base_class: CLASS_C is
95 -- Base class associated to the class type
96 do
97 Result := System.class_of_id (class_id)
98 end
99
100 internal_generic_derivation (a_level: INTEGER): CL_TYPE_I is
101 -- Precise generic derivation of current type.
102 -- That is to say given a type, it gives the associated TYPE_I
103 -- which can be used to search its associated CLASS_TYPE.
104 local
105 c: like cr_info
106 do
107 c := cr_info
108 if c = Void then
109 Result := Current
110 else
111 -- Remove creation information.
112 cr_info := Void
113 Result := twin
114 cr_info := c
115 end
116 end
117
118 type_a: CL_TYPE_A is
119 do
120 create Result.make (class_id)
121 Result.set_mark (declaration_mark)
122 end
123
124 name: STRING is
125 -- String that should be displayed in debugger to represent `Current'.
126 do
127 Result := base_name
128 end
129
130 duplicate: like Current is
131 -- Duplication
132 do
133 Result := twin
134 end
135
136 reference_type: CL_TYPE_I is
137 -- Corresponding reference type
138 require
139 is_expanded: is_expanded
140 do
141 Result := duplicate
142 Result.set_reference_mark
143 ensure
144 result_is_reference: Result.is_reference
145 end
146
147 instantiation_in (other: CLASS_TYPE): CL_TYPE_I is
148 -- Instantation of Current in `other'
149 do
150 Result := Current
151 end
152
153 anchor_instantiation_in (other: CLASS_TYPE): CL_TYPE_I is
154 -- Instantation of `like Current' parts of Current in `other'
155 do
156 Result := Current
157 end
158
159 created_in (other: CLASS_TYPE): TYPE_I is
160 -- Resulting type of Current as if it was used to create object in `other'.
161 do
162 Result := Current
163 if cr_info /= Void then
164 Result := cr_info.created_in (other)
165 end
166 end
167
168 il_type_name (a_prefix: STRING): STRING is
169 -- Class name of current type.
170 local
171 l_class_c: like base_class
172 l_cl_type: like associated_class_type
173 l_alias_name: STRING
174 l_dot_pos: INTEGER
175 do
176 l_class_c := base_class
177 if is_external then
178 Result := l_class_c.external_class_name.twin
179 else
180 if l_class_c.is_precompiled then
181 -- Reuse the name that was computed at precompilation time.
182 l_cl_type := associated_class_type
183 if l_cl_type.is_precompiled then
184 Result := l_cl_type.il_type_name (a_prefix)
185 end
186 end
187 if Result = Void then
188 if not has_no_mark or else is_basic or else l_class_c.external_class_name.is_equal (l_class_c.name) then
189 Result := internal_il_type_name (l_class_c.name.twin, a_prefix)
190 else
191 -- Special case when an external name has been specified.
192 Result := l_class_c.external_class_name.twin
193 Result.left_adjust
194 Result.right_adjust
195 -- Remove leading `.' since it is not a valid .NET name.
196 from
197 until
198 Result.is_empty or else Result.item (1) /= '.'
199 loop
200 Result.remove_head (1)
201 end
202 -- Remove trailing `.' since it is not a valid .NET name.
203 from
204 until
205 Result.is_empty or else Result.item (Result.count) /= '.'
206 loop
207 Result.remove_tail (1)
208 end
209 if Result.is_empty then
210 -- External name is invalid since empty, we use the normal
211 -- way of generating the .Net name
212 Result := internal_il_type_name (l_class_c.name.twin, a_prefix)
213 else
214 if a_prefix /= Void then
215 l_dot_pos := Result.last_index_of ('.', Result.count)
216 if l_dot_pos = 0 then
217 Result.prepend_character ('.')
218 Result.prepend (a_prefix)
219 else
220 check
221 -- Because there are no more leading or trailing `.'.
222 valid_l_dot_pos: l_dot_pos > 1 and l_dot_pos < Result.count
223 end
224 l_alias_name := Result.substring (l_dot_pos + 1, Result.count)
225 check
226 l_alias_name_not_empty: not l_alias_name.is_empty
227 end
228 Result.keep_head (l_dot_pos)
229 l_alias_name := internal_il_base_type_name (l_alias_name)
230 Result.append (a_prefix)
231 Result.append_character ('.')
232 Result.append (l_alias_name)
233 end
234 end
235 end
236 end
237 end
238 end
239 end
240
241 description, instantiated_description: ATTR_DESC is
242 -- Type description for skeletons
243 local
244 exp: EXPANDED_DESC
245 ref: REFERENCE_DESC
246 do
247 if is_expanded then
248 create exp
249 exp.set_cl_type_i (Current)
250 exp.set_type_i (Current)
251 Result := exp
252 else
253 Result := c_type.description
254 ref ?= Result
255 if ref /= Void then
256 ref.set_type_i (Current)
257 end
258 end
259 end
260
261 c_type: TYPE_C is
262 -- Associated C type
263 do
264 Result := Reference_c_type
265 end
266
267 associated_class_type: CLASS_TYPE is
268 -- Associated class type
269 require
270 has: has_associated_class_type
271 do
272 Result := base_class.types.search_item (Current)
273 ensure
274 result_not_void: Result /= Void
275 end
276
277 type_id: INTEGER is
278 -- Type id of the correponding class type
279 do
280 Result := associated_class_type.type_id
281 end
282
283 static_type_id: INTEGER is
284 -- Type id of the correponding class type
285 require else
286 ok: True
287 do
288 Result := associated_class_type.static_type_id
289 end
290
291 external_id: INTEGER is
292 -- External type id of `Current' (or `static_type_id' for pure Eiffel type).
293 do
294 Result := associated_class_type.external_id
295 end
296
297 sk_value: INTEGER is
298 -- Generate SK value associated to the current type.
299 do
300 if is_expanded then
301 Result := Sk_exp | (type_id - 1)
302 else
303 Result := Sk_ref | (type_id - 1)
304 end
305 end
306
307 hash_code: INTEGER is
308 -- Hash code for current type
309 do
310 Result := Other_code + class_id
311 end
312
313 feature -- Type evaluation
314
315 implemented_type (implemented_in: INTEGER): CL_TYPE_I is
316 -- Parent type that corresponds to the current one.
317 require
318 valid_implemented_in: implemented_in > 0
319 local
320 written_class: CLASS_C
321 do
322 -- If it is defined in current class, that's easy and we
323 -- return `current_type'. Otherwise we have to find the
324 -- correct CLASS_TYPE object where it is implemented.
325 if class_id = implemented_in then
326 Result := Current
327 else
328 written_class := System.class_of_id (implemented_in)
329 -- We go through the hierarchy only when `written_class'
330 -- is generic, otherwise for the most general case where
331 -- `written_class' is not generic it will take a long
332 -- time to go through the inheritance hierarchy.
333 if written_class.types.count > 1 then
334 Result := type_a.find_class_type (written_class).type_i
335 else
336 Result := written_class.types.first.type
337 end
338 end
339 end
340
341 feature -- Status
342
343 element_type: INTEGER_8 is
344 -- Void element type
345 do
346 if is_expanded then
347 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_valuetype
348 else
349 if class_id = System.system_string_class.compiled_class.class_id then
350 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_string
351 elseif class_id = System.system_object_id or class_id = system.any_id then
352 -- For ANY or SYSTEM_OBJECT, we always generate a System.Object
353 -- signature since we can now assign SYSTEM_OBJECTs into ANYs.
354 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_object
355 else
356 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_class
357 end
358 end
359 end
360
361 tuple_code: INTEGER_8 is
362 -- Tuple code for class type
363 do
364 Result := {SHARED_GEN_CONF_LEVEL}.reference_tuple_code
365 end
366
367 has_no_mark: BOOLEAN is
368 -- Has class type no explicit mark?
369 do
370 Result := declaration_mark = {CL_TYPE_A}.no_mark
371 ensure
372 definition: Result = (declaration_mark = {CL_TYPE_A}.no_mark)
373 end
374
375 has_expanded_mark: BOOLEAN is
376 -- Is class type explicitly marked as expanded?
377 do
378 Result := declaration_mark.bit_and ({CL_TYPE_A}.expanded_mark) /= 0
379 ensure
380 definition: Result = (declaration_mark.bit_and ({CL_TYPE_A}.expanded_mark) /= 0)
381 end
382
383 has_reference_mark: BOOLEAN is
384 -- Is class type explicitly marked as reference?
385 do
386 Result := declaration_mark.bit_and ({CL_TYPE_A}.reference_mark) /= 0
387 ensure
388 definition: Result = (declaration_mark.bit_and ({CL_TYPE_A}.reference_mark) /= 0)
389 end
390
391 has_separate_mark: BOOLEAN is
392 -- Is class type explicitly marked as reference?
393 do
394 Result := declaration_mark.bit_and ({CL_TYPE_A}.separate_mark) /= 0
395 ensure
396 definition: Result = (declaration_mark.bit_and ({CL_TYPE_A}.separate_mark) /= 0)
397 end
398
399 has_monomorph_mark: BOOLEAN is
400 -- Is class type explicitly marked as monomorph?
401 do
402 Result := declaration_mark.bit_and ({CL_TYPE_A}.monomorph_mark) /= 0
403 ensure
404 definition: Result = (declaration_mark.bit_and ({CL_TYPE_A}.monomorph_mark) /= 0)
405 end
406
407 is_expanded: BOOLEAN is
408 -- Is the type expanded?
409 do
410 Result := has_expanded_mark or else (not has_reference_mark and then base_class.is_expanded)
411 end
412
413 is_reference: BOOLEAN is
414 -- Is the type a reference type?
415 do
416 Result := has_reference_mark or else (not has_expanded_mark and then not base_class.is_expanded)
417 end
418
419 is_separate: BOOLEAN is
420 -- Is the type separate?
421 do
422 Result := has_separate_mark
423 end
424
425 is_monomorph: BOOLEAN is
426 -- Is the type monomorph?
427 do
428 Result := has_monomorph_mark or else is_expanded or else is_frozen
429 end
430
431 is_enum: BOOLEAN is
432 -- Is current type an IL enum type?
433 -- Useful to find out if some call optimization can be done
434 -- in FEATURE_B.
435 require
436 il_generation: System.il_generation
437 do
438 Result := is_expanded and then base_class.is_enum
439 end
440
441 is_external: BOOLEAN is
442 -- Is current type based on an external class?
443 local
444 l_base_class: like base_class
445 do
446 -- All Eiffel basic types are externals, and only basic types used
447 -- as reference are not external.
448 l_base_class := base_class
449 Result := l_base_class.is_external and then not l_base_class.is_basic
450 end
451
452 is_frozen: BOOLEAN is
453 -- Is current type based on a frozen class?
454 do
455 Result := base_class.is_frozen
456 end
457
458 is_generated_as_single_type: BOOLEAN is
459 -- Is associated type generated as a single type or as an interface type and
460 -- an implementation type.
461 do
462 -- External classes have only one type.
463 Result := is_external
464 if not Result then
465 -- Classes that inherits from external classes
466 -- have only one generated type as well as expanded types.
467 Result := base_class.is_single or else is_expanded
468 end
469 end
470
471 is_consistent: BOOLEAN is
472 -- Is the base class still in the system and matches its specification?
473 local
474 l_base_class: like base_class
475 do
476 l_base_class := base_class
477 Result := l_base_class /= Void and then (l_base_class.generics = Void)
478 end
479
480 is_explicit: BOOLEAN is
481 -- Is Current type fixed at compile time?
482 do
483 if cr_info /= Void then
484 Result := cr_info.is_explicit
485 else
486 Result := True
487 end
488 end
489
490 has_associated_class_type: BOOLEAN is
491 -- Has `Current' an associated class type?
492 do
493 Result := base_class.types.has_type (Current)
494 end
495
496 same_as (other: TYPE_I): BOOLEAN is
497 -- Is `other' equal to Current ?
498 local
499 other_cl_type: CL_TYPE_I
500 do
501 other_cl_type ?= other
502 Result := other_cl_type /= Void -- FIXME
503 and then other_cl_type.class_id = class_id
504 and then other_cl_type.is_expanded = is_expanded
505 and then other_cl_type.is_separate = is_separate
506 and then other_cl_type.meta_generic = Void
507 and then other_cl_type.true_generics = Void
508 end
509
510 has_actual (type: CL_TYPE_I): BOOLEAN is
511 -- Is `type' an (possibly nested) actual parameter of this type?
512 require
513 non_void_type: type /= Void
514 do
515 -- False here.
516 end
517
518 feature -- Setting
519
520 set_expanded_mark is
521 -- Set class type declaration as expanded.
522 do
523 declaration_mark := {CL_TYPE_A}.expanded_mark
524 ensure
525 has_expanded_mark: has_expanded_mark
526 end
527
528 set_reference_mark is
529 -- Set class type declaration as reference.
530 do
531 declaration_mark := {CL_TYPE_A}.reference_mark
532 ensure
533 has_reference_mark: has_reference_mark
534 end
535
536 set_separate_mark is
537 -- Set class type declaration as separate.
538 do
539 declaration_mark := {CL_TYPE_A}.separate_mark
540 ensure
541 has_separate_mark: has_separate_mark
542 end
543
544 set_monomorph_mark is
545 -- Set class type declaration as monomorph.
546 do
547 declaration_mark := {CL_TYPE_A}.monomorph_mark
548 ensure
549 has_monomorph_mark: has_monomorph_mark
550 end
551
552 set_cr_info (cinfo : CREATE_INFO) is
553 -- Set `cr_info' to `cinfo'.
554 require
555 create_info_not_void: cinfo /= Void
556 not_expanded: not is_expanded or else cinfo.is_equal (create {CREATE_CURRENT})
557 do
558 cr_info := cinfo
559 ensure
560 cr_info_set : cr_info = cinfo
561 end
562
563 feature -- C generation
564
565 generate_expanded_creation (buffer: GENERATION_BUFFER; target_name: STRING) is
566 -- Generate creation of expanded object associated to Current.
567 do
568 associated_class_type.generate_expanded_creation (buffer, target_name, Current)
569 end
570
571 generate_expanded_initialization (buffer: GENERATION_BUFFER; target_name: STRING) is
572 -- Generate creation of expanded object associated to Current.
573 do
574 associated_class_type.generate_expanded_initialization (buffer, target_name, target_name, True)
575 end
576
577 generate_cecil_value (buffer: GENERATION_BUFFER) is
578 -- Generate cecil value
579 do
580 if not is_expanded then
581 buffer.put_string ("SK_REF + (uint32) ")
582 else
583 buffer.put_string ("SK_EXP + (uint32) ")
584 end
585 buffer.put_type_id (associated_class_type.type_id)
586 end
587
588 feature -- Array optimization
589
590 conforms_to_array: BOOLEAN is
591 do
592 Result := base_class.conform_to (array_class_c)
593 end
594
595 feature {NONE} -- Array optimization
596
597 array_class_c: CLASS_C is
598 once
599 Result := System.array_class.compiled_class
600 end
601
602 feature {NONE} -- Generic conformance
603
604 full_type_byte_code_type_id: INTEGER is
605 -- Associated type ID used in type information byte code.
606 do
607 Result := type_id - 1
608 ensure then
609 definition: Result = type_id - 1
610 end
611
612 feature -- Generic conformance
613
614 generated_id (final_mode : BOOLEAN) : INTEGER is
615
616 do
617 if final_mode then
618 Result := type_id - 1
619 else
620 Result := associated_class_type.static_type_id - 1
621 end
622 end
623
624 generate_cid (buffer : GENERATION_BUFFER; final_mode, use_info : BOOLEAN) is
625
626 do
627 if
628 use_info and then (cr_info /= Void)
629 and then not is_expanded
630 then
631 -- It's an anchored type
632 cr_info.generate_cid (buffer, final_mode)
633 else
634 buffer.put_integer (generated_id (final_mode))
635 buffer.put_character (',')
636 end
637 end
638
639 make_gen_type_byte_code (ba : BYTE_ARRAY; use_info : BOOLEAN) is
640 do
641 if
642 use_info and then (cr_info /= Void)
643 and then not is_expanded
644 then
645 -- It's an anchored type
646 cr_info.make_gen_type_byte_code (ba)
647 else
648 ba.append_short_integer (generated_id (False))
649 end
650 end
651
652 generate_cid_array (buffer : GENERATION_BUFFER;
653 final_mode, use_info : BOOLEAN; idx_cnt : COUNTER) is
654 local
655 dummy : INTEGER
656 do
657 if
658 use_info and then (cr_info /= Void)
659 and then not is_expanded
660 then
661 -- It's an anchored type
662 cr_info.generate_cid_array (buffer, final_mode, idx_cnt)
663 else
664 buffer.put_integer (generated_id (final_mode))
665 buffer.put_character (',')
666
667 -- Increment counter
668 dummy := idx_cnt.next
669 end
670 end
671
672 generate_cid_init (buffer : GENERATION_BUFFER;
673 final_mode, use_info : BOOLEAN; idx_cnt : COUNTER) is
674 local
675 dummy : INTEGER
676 do
677 if
678 use_info and then (cr_info /= Void)
679 and then not is_expanded
680 then
681 -- It's an anchored type
682 cr_info.generate_cid_init (buffer, final_mode, idx_cnt)
683 else
684 dummy := idx_cnt.next
685 end
686 end
687
688 feature -- Generic conformance for IL
689
690 generate_gen_type_il (il_generator: IL_CODE_GENERATOR; use_info : BOOLEAN) is
691 -- `use_info' is true iff we generate code for a
692 -- creation instruction.
693 do
694 if use_info and then cr_info /= Void then
695 -- It's an anchored type, we call feature
696 -- that will tell us the real type of the
697 -- anchor in the context of Current.
698 cr_info.generate_il_type
699 else
700 il_generator.generate_class_type_instance (Current)
701 end
702 end
703
704 feature {NONE} -- Implementation
705
706 base_name: STRING is
707 -- String that should be displayed in debugger to represent `Current'.
708 local
709 l_base_class: like base_class
710 do
711 create Result.make (32)
712 l_base_class := base_class
713 if is_expanded and not l_base_class.is_expanded then
714 Result.append ("expanded ")
715 elseif is_reference and l_base_class.is_expanded then
716 Result.append ("reference ")
717 elseif is_separate then
718 Result.append ("separate ")
719 end
720 Result.append (l_base_class.name)
721 end
722
723 frozen internal_il_type_name (a_base_name, a_prefix: STRING): STRING is
724 -- Full type name of `a_base_name' using `a_prefix' in IL code generation
725 -- with namespace specification
726 require
727 a_base_name_not_void: a_base_name /= Void
728 a_base_name_not_empty: not a_base_name.is_empty
729 do
730 Result := internal_il_base_type_name (a_base_name)
731 -- Result needs to be in lower case because that's
732 -- what our casing conversion routines require to perform
733 -- a good job.
734 Result.to_lower
735 Result := il_casing.type_name (base_class.original_class.actual_namespace, a_prefix, Result, System.dotnet_naming_convention)
736 ensure
737 internal_il_type_name_not_void: Result /= Void
738 internal_il_type_name_not_empty: not Result.is_empty
739 end
740
741 frozen internal_il_base_type_name (a_base_name: STRING): STRING is
742 -- Given `a_base_name' provides its updated name depending on its usage.
743 require
744 a_base_name_not_void: a_base_name /= Void
745 a_base_name_not_empty: not a_base_name.is_empty
746 local
747 l_base_class: like base_class
748 do
749 l_base_class := base_class
750 if is_expanded and then not l_base_class.is_expanded then
751 create Result.make (6 + a_base_name.count)
752 Result.append ("value_")
753 elseif not is_expanded and then l_base_class.is_expanded then
754 create Result.make (10 + a_base_name.count)
755 Result.append ("reference_")
756 else
757 create Result.make (a_base_name.count)
758 end
759 Result.append (a_base_name)
760 ensure
761 internal_il_base_type_name_not_void: Result /= Void
762 internal_il_base_type_name_not_empty: not Result.is_empty
763 end
764
765 feature {CL_TYPE_A, TUPLE_CLASS_B, CIL_CODE_GENERATOR} -- Implementation: class type declaration marks
766
767 declaration_mark: NATURAL_8
768 -- Declaration mark associated with a class type (if any)
769
770 feature {CL_TYPE_A, TUPLE_CLASS_B} -- Implementation: class type declaration marks
771
772 set_mark (mark: like declaration_mark) is
773 -- Set `declaration_mark' to the given value `mark'.
774 require
775 -- valid_declaration_mark:
776 -- mark = {CL_TYPE_A}.no_mark or mark = {CL_TYPE_A}.expanded_mark or
777 -- mark = {CL_TYPE_A}.reference_mark or mark = {CL_TYPE_A}.separate_mark or
778 -- mark = {CL_TYPE_A}.monomorph_mark
779 do
780 declaration_mark := mark
781 ensure
782 declaration_mark_set: declaration_mark = mark
783 end
784
785 invariant
786 class_id_positive: class_id > 0
787 -- Todo: new invariant for mark using bit-mask
788 -- valid_declaration_mark:
789 -- declaration_mark = {CL_TYPE_A}.no_mark or
790 -- declaration_mark = {CL_TYPE_A}.expanded_mark or
791 -- declaration_mark = {CL_TYPE_A}.reference_mark or
792 -- declaration_mark = {CL_TYPE_A}.separate_mark or
793 -- declaration_mark = {CL_TYPE_A}.monomorph_mark
794
795 indexing
796 copyright: "Copyright (c) 1984-2006, Eiffel Software"
797 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
798 licensing_options: "http://www.eiffel.com/licensing"
799 copying: "[
800 This file is part of Eiffel Software's Eiffel Development Environment.
801
802 Eiffel Software's Eiffel Development Environment is free
803 software; you can redistribute it and/or modify it under
804 the terms of the GNU General Public License as published
805 by the Free Software Foundation, version 2 of the License
806 (available at the URL listed under "license" above).
807
808 Eiffel Software's Eiffel Development Environment is
809 distributed in the hope that it will be useful, but
810 WITHOUT ANY WARRANTY; without even the implied warranty
811 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
812 See the GNU General Public License for more details.
813
814 You should have received a copy of the GNU General Public
815 License along with Eiffel Software's Eiffel Development
816 Environment; if not, write to the Free Software Foundation,
817 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
818 ]"
819 source: "[
820 Eiffel Software
821 356 Storke Road, Goleta, CA 93117 USA
822 Telephone 805-685-1006, Fax 805-685-6869
823 Website http://www.eiffel.com
824 Customer support http://support.eiffel.com
825 ]"
826
827 end

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23