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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23