1 # $Id: abstraction.rb,v 1.26 2011/12/15 01:06:15 machan Exp $
2
3 require 'tmdoc/tmstd'
4 require 'tmdoc/tmstd/treeable'
5 require 'tmdoc/model/object/logical/path'
6 require 'tmdoc/model/object/logical/location'
7 require 'tmdoc/constant'
8
9
10 module TmDoc
11
12 module Model::Object::Logical::Abstraction
13
14 class Subject < Model::Abstraction::Subject::LogicalSubject; end
15
16
17 class SeqOfSubject < Model::Abstraction::Subject::SeqOfLogicalSubject
18 LSM_ELEMENT_CLASS = Subject
19 end
20
21
22 class SetOfSubject < Model::Abstraction::Subject::SetOfLogicalSubject
23 LSM_ELEMENT_CLASS = Subject
24 end
25
26
27
28 class Property < Subject
29 attr_reader :uniq_num, :max_uniq_num, :does_attach_to_instance
30
31 alias attach_to_instance? does_attach_to_instance
32
33 def initialize(
34 location,
35 above_path,
36 name,
37 seq_num = 0,
38 uniq_num = 0,
39 max_uniq_num = 0,
40 does_attach_to_instance = false
41 )
42 ASSERT.kind_of location, MOL::Location
43 ASSERT.kind_of above_path, MOL::Path
44 ASSERT.kind_of name, String
45 ASSERT.kind_of seq_num, Integer
46 ASSERT.kind_of uniq_num, Integer
47 ASSERT.kind_of max_uniq_num, Integer
48 ASSERT.boolean does_attach_to_instance
49
50 super(location, above_path, name, seq_num)
51
52 @uniq_num = uniq_num
53 @max_uniq_num = max_uniq_num
54 @does_attach_to_instance = does_attach_to_instance
55 end
56
57
58 def to_s(label, opt_str = nil)
59 self_opt_str = format " (%d/%d)", self.uniq_num, self.max_uniq_num
60
61 str = super(
62 label,
63 format("[%s] %s",
64 if self.attach_to_instance? then 'I' else '*' end,
65 if opt_str then opt_str + self_opt_str else '' end
66 )
67 )
68
69 ASSERT.kind_of str, String
70 end
71 end
72
73
74
75 class SetOfProperty < SetOfSubject
76 LSM_ELEMENT_CLASS = Property
77 end
78
79
80
81 class GenericModule < Subject
82 include TmStd::Treeable
83
84 attr_reader :locations,
85 :properties,
86 :below_module_paths,
87 :extendee_module_paths,
88 :includee_module_paths
89
90
91 def initialize(
92 locations,
93 above_path,
94 name,
95 store,
96 properties,
97 below_module_paths,
98 extendee_module_paths,
99 includee_module_paths
100 )
101 ASSERT.kind_of locations, MOL::SetOfLocation
102 ASSERT.kind_of above_path, MOL::Path
103 ASSERT.kind_of name, String
104 ASSERT.opt_kind_of store, MO::Store
105 ASSERT.kind_of properties, MOLA::SetOfProperty
106 ASSERT.kind_of below_module_paths, MOL::SetOfPath
107 ASSERT.kind_of extendee_module_paths, MOL::SetOfPath
108 ASSERT.kind_of includee_module_paths, MOL::SetOfPath
109
110 super(nil, above_path, name)
111
112 @store = store
113
114 @locations = locations
115
116 @properties = properties
117
118 @below_module_paths = below_module_paths
119 @extendee_module_paths = extendee_module_paths
120 @includee_module_paths = includee_module_paths
121
122
123 # Cache variables.
124
125 @set_of_ancestor_module =
126 @seq_of_below_module =
127 @seq_of_descendant_module =
128 @set_of_neighboring_module = nil
129 end
130
131
132 def to_s(label = 'module', opt_str = nil)
133 ASSERT.kind_of label, String
134 ASSERT.opt_kind_of opt_str, String
135
136 str = format("%s %s(%s)%s",
137 label,
138
139 self.name,
140
141 self.above_path.to_s,
142
143 if opt_str then opt_str else '' end
144 )
145
146 ASSERT.kind_of str, String
147 end
148
149
150 def print(indent)
151 ASSERT.kind_of indent, Integer
152
153 super
154
155 is = "\t" * indent
156 is1 = "\t" * (indent + 1)
157
158 los = self.locations
159 unless los.empty?
160 LOG::Debug.log "%slocations:", is
161 for lo in los.sort
162 LOG::Debug.log "%s%s", is1, lo.to_s
163 end
164 end
165
166 bms = self.below_module_paths
167 unless bms.empty?
168 LOG::Debug.log "%sbelow_module_paths:", is
169 for bm in bms.sort
170 LOG::Debug.log "%s%s", is1, bm.to_s
171 end
172 end
173
174 ems = self.extendee_module_paths
175 unless ems.empty?
176 LOG::Debug.log "%sextendee_module_paths:", is
177 for em in ems.sort
178 LOG::Debug.log "%s%s", is1, em.to_s
179 end
180 end
181
182 ims = self.includee_module_paths
183 unless ims.empty?
184 LOG::Debug.log "%sincludee_module_paths:", is
185 for im in ims.sort
186 LOG::Debug.log "%s%s", is1, im.to_s
187 end
188 end
189
190 subs = self.properties
191 unless subs.empty?
192 LOG::Debug.log "%sproperties:", is
193 for sub in subs.sort
194 LOG::Debug.log "%s%s", is1, sub.to_s
195 end
196 end
197
198 nil
199 end
200
201
202 def location
203 loc = unless self.locations.empty?
204 self.locations.sort.first
205 else
206 nil
207 end
208
209 ASSERT.opt_kind_of loc, MOL::Location
210 end
211
212
213 def path
214 p = if self.above_path
215 self.above_path << self.name
216 else
217 MOL::Path.new_root
218 end
219
220 ASSERT.kind_of p, MOL::Path
221 end
222
223
224 def children
225 unless @seq_of_below_module
226 array_of_below_module =
227 @below_module_paths.map { |below_module_path|
228 a_below_module =
229 @store.map_of_path_to_module.at below_module_path
230 ASSERT.kind_of(
231 a_below_module, GenericModule,
232 "below_module_path: %s -- self module: %s",
233 below_module_path.to_s, self.to_s
234 )
235
236 a_below_module
237 }
238
239 @seq_of_below_module =
240 unless array_of_below_module.empty?
241 SeqOfGenericModule.new(
242 array_of_below_module.sort
243 )
244 else
245 EMPTY_SEQ_OF_GENERIC_MODULE
246 end
247 end
248
249 ASSERT.kind_of @seq_of_below_module, SeqOfGenericModule
250 end
251
252
253 def empty?
254 result = self.below_modules.empty?
255
256 ASSERT.boolean result
257 end
258
259
260 def has_any_properties?
261 result = self.properties.size > 0
262
263 ASSERT.boolean result
264 end
265
266
267 def suppressable?
268 false
269 end
270
271
272 def ancestor_modules
273 unless @set_of_ancestor_module
274 @set_of_ancestor_module = SetOfGenericModule.new [self]
275 end
276
277 ASSERT.kind_of @set_of_ancestor_module, SetOfGenericModule
278 end
279
280
281 def below_modules
282 set_of_below_module =
283 @store.map_of_above_module_to_below_modules.at self
284 mo_below_modules = if set_of_below_module
285 set_of_below_module
286 else
287 EMPTY_SET_OF_GENERIC_MODULE
288 end
289
290 ASSERT.kind_of mo_below_modules, SetOfGenericModule
291 end
292
293
294 def descendant_modules(&block)
295 descendants =
296 if block
297 array_of_descendant_module =
298 self.__array_of_descendant_module__(&block)
299
300 unless array_of_descendant_module.empty?
301 SeqOfGenericModule.new array_of_descendant_module
302 else
303 EMPTY_SEQ_OF_GENERIC_MODULE
304 end
305 else
306 unless @seq_of_descendant_module
307 array_of_descendant_module =
308 self.__array_of_descendant_module__
309 @seq_of_descendant_module =
310 unless array_of_descendant_module.empty?
311 SeqOfGenericModule.new(
312 array_of_descendant_module
313 )
314 else
315 EMPTY_SEQ_OF_GENERIC_MODULE
316 end
317 end
318
319 @seq_of_descendant_module
320 end
321
322 ASSERT.kind_of descendants, SeqOfGenericModule
323 end
324
325
326 def descendant_modules_any?(&block)
327 ASSERT.kind_of block, Proc
328
329 result = self.descendant_any?(&block)
330
331 ASSERT.boolean result
332 end
333
334
335 def __array_of_descendant_module__(&block)
336 descendants = self.descendants(&block)
337
338 ASSERT.kind_of descendants, Array
339 end
340
341
342 def extendee_modules
343 mo_extendees =
344 @store.map_of_extender_module_to_extendee_modules.at self
345 set_of_extendee_module = if mo_extendees
346 mo_extendees
347 else
348 EMPTY_SET_OF_GENERIC_MODULE
349 end
350
351 ASSERT.kind_of(
352 set_of_extendee_module, SetOfGenericModule,
353 "extender module: %s", self.to_s
354 )
355 end
356
357
358 def extender_modules
359 mo_extenders =
360 @store.map_of_extendee_module_to_extender_modules.at self
361 set_of_extender_module = if mo_extenders
362 mo_extenders
363 else
364 EMPTY_SET_OF_GENERIC_MODULE
365 end
366
367 ASSERT.kind_of(
368 set_of_extender_module, SetOfGenericModule,
369 "extendee module: %s", self.to_s
370 )
371 end
372
373
374 def includee_modules
375 mo_includees =
376 @store.map_of_includer_module_to_includee_modules.at self
377 set_of_includee_module = if mo_includees
378 mo_includees
379 else
380 EMPTY_SET_OF_GENERIC_MODULE
381 end
382
383 ASSERT.kind_of(
384 set_of_includee_module, SetOfGenericModule,
385 "includer module: %s", self.to_s
386 )
387 end
388
389
390 def includer_modules
391 mo_includers =
392 @store.map_of_includee_module_to_includer_modules.at self
393 set_of_includer_module = if mo_includers
394 mo_includers
395 else
396 EMPTY_SET_OF_GENERIC_MODULE
397 end
398
399 ASSERT.kind_of(
400 set_of_includer_module, SetOfGenericModule,
401 "includee module: %s", self.to_s
402 )
403 end
404
405
406 def neighboring_modules(show_module_siblings = true)
407 ASSERT.boolean show_module_siblings
408
409 unless @set_of_neighboring_module
410 @set_of_neighboring_module = SetOfGenericModule.union(
411 [
412 self.below_modules,
413 self.extendee_modules,
414 self.extender_modules,
415 self.includee_modules,
416 self.includer_modules
417 ]
418 )
419 end
420
421 ASSERT.kind_of @set_of_neighboring_module, SetOfGenericModule
422 end
423
424
425 def has_any_module_in_the_source?(target_file_name)
426 ASSERT.kind_of target_file_name, String
427
428 result =
429 if self.locations.any? { |location|
430 ASSERT.kind_of location, MOL::Location
431
432 location &&
433 location.file_name == target_file_name
434 }
435 true
436 else
437 self.below_modules.any? { |a_below_module|
438 a_below_module.has_any_module_in_the_source?(
439 target_file_name
440 )
441 }
442 end
443
444 ASSERT.boolean result
445 end
446
447
448 def store!(store)
449 ASSERT.kind_of store, MO::Store
450
451 @store = store
452
453 nil
454 end
455 end
456
457
458
459 class SeqOfGenericModule < SeqOfSubject
460 LSM_ELEMENT_CLASS = GenericModule
461 end
462
463 EMPTY_SEQ_OF_GENERIC_MODULE = SeqOfGenericModule.new
464
465
466
467 class SetOfGenericModule < SetOfSubject
468 LSM_ELEMENT_CLASS = GenericModule
469 end
470
471 EMPTY_SET_OF_GENERIC_MODULE = SetOfGenericModule.new
472
473
474
475 class MapOfPathToModule < TmStd::Lsm::Collection::Map::Abstract
476 include TmStd::Lsm::Collection::Map::Mutable
477
478 LSM_DOMAIN_CLASS = MOL::Path
479 LSM_RANGE_CLASS = GenericModule
480
481 alias paths domains
482 alias modules ranges
483 end
484
485
486
487 class RootModule < GenericModule
488 def initialize(
489 above_path,
490 name,
491 properties,
492 below_module_paths,
493 extendee_module_paths,
494 includee_module_paths
495 )
496 ASSERT.kind_of above_path, MOL::Path
497 ASSERT.kind_of name, String
498 ASSERT.kind_of properties, MOLA::SetOfProperty
499 ASSERT.kind_of below_module_paths, MOL::SetOfPath
500 ASSERT.kind_of extendee_module_paths, MOL::SetOfPath
501 ASSERT.kind_of includee_module_paths, MOL::SetOfPath
502
503 super(
504 MOL::SetOfLocation.new,
505 above_path,
506 name,
507 nil, # store
508 properties,
509 below_module_paths,
510 extendee_module_paths,
511 includee_module_paths
512 )
513 end
514
515
516 def suppressable?
517 set_of_below_module =
518 @store.map_of_above_module_to_below_modules.at self
519
520 result = set_of_below_module.all? { |a_below_module|
521 a_below_module.suppressable?
522 }
523
524 ASSERT.boolean result
525 end
526 end
527
528
529
530 class ChildModule < GenericModule
531 attr_reader :above_module_path
532
533
534 def initialize(
535 locations,
536 above_path,
537 name,
538 store,
539 properties,
540 below_module_paths,
541 extendee_module_paths,
542 includee_module_paths,
543 above_module_path
544 )
545 ASSERT.kind_of locations, MOL::SetOfLocation
546 ASSERT.kind_of above_path, MOL::Path
547 ASSERT.kind_of name, String
548 ASSERT.opt_kind_of store, MO::Store
549 ASSERT.kind_of properties, MOLA::SetOfProperty
550 ASSERT.kind_of below_module_paths, MOL::SetOfPath
551 ASSERT.kind_of extendee_module_paths, MOL::SetOfPath
552 ASSERT.kind_of includee_module_paths, MOL::SetOfPath
553 ASSERT.kind_of above_module_path, MOL::Path
554
555 super(
556 locations,
557 above_path,
558 name,
559 store,
560 properties,
561 below_module_paths,
562 extendee_module_paths,
563 includee_module_paths
564 )
565
566 @above_module_path = above_module_path
567
568
569 # Cache variable.
570
571 @set_of_sibling_module = nil
572 end
573
574
575 def print(indent)
576 ASSERT.kind_of indent, Integer
577
578 super
579
580 is = "\t" * indent
581
582 LOG::Debug.log(
583 "%sabove_module_path: %s", is, self.above_module_path.to_s
584 )
585
586 nil
587 end
588
589
590 def an_above_module
591 an_above = @store.map_of_path_to_module.at self.above_module_path
592
593 ASSERT.kind_of an_above, MOLA::GenericModule
594 end
595
596
597 def ancestor_modules
598 unless @set_of_ancestor_module
599 @set_of_ancestor_module =
600 self.an_above_module.ancestor_modules << self
601 end
602
603 ASSERT.kind_of @set_of_ancestor_module, SetOfGenericModule
604 end
605
606
607 def sibling_modules
608 unless @set_of_sibling_module
609 array_of_sibling_module =
610 self.an_above_module.below_modules.reject {
611 |a_below_module|
612
613 a_below_module == self
614 }
615 @set_of_sibling_module =
616 unless array_of_sibling_module.empty?
617 SetOfGenericModule.new array_of_sibling_module
618 else
619 EMPTY_SET_OF_GENERIC_MODULE
620 end
621 end
622
623 ASSERT.kind_of @set_of_sibling_module, SetOfGenericModule
624 end
625
626
627 def neighboring_modules(show_module_siblings = true)
628 ASSERT.boolean show_module_siblings
629
630 unless @set_of_neighboring_module
631 @set_of_neighboring_module = SetOfGenericModule.union(
632 [
633 super,
634
635 SetOfGenericModule.new([self.an_above_module]),
636
637 if show_module_siblings
638 self.sibling_modules
639 else
640 EMPTY_SET_OF_GENERIC_MODULE
641 end
642 ]
643 )
644 end
645
646 ASSERT.kind_of @set_of_neighboring_module, SetOfGenericModule
647 end
648 end
649
650
651
652 class SeqOfChildModule < SeqOfGenericModule
653 LSM_ELEMENT_CLASS = ChildModule
654 end
655
656 EMPTY_SEQ_OF_CHILD_MODULE = SeqOfChildModule.new
657
658
659
660 class SetOfChildModule < SetOfGenericModule
661 LSM_ELEMENT_CLASS = ChildModule
662 end
663
664 EMPTY_SET_OF_CHILD_MODULE = SetOfChildModule.new
665
666
667
668 class GenericClass < ChildModule
669 def initialize(
670 locations,
671 above_path,
672 name,
673 store,
674 properties,
675 below_module_paths,
676 extendee_module_paths,
677 includee_module_paths,
678 above_module_path
679 )
680 ASSERT.kind_of locations, MOL::SetOfLocation
681 ASSERT.kind_of above_path, MOL::Path
682 ASSERT.kind_of name, String
683 ASSERT.opt_kind_of store, MO::Store
684 ASSERT.kind_of properties, MOLA::SetOfProperty
685 ASSERT.kind_of below_module_paths, MOL::SetOfPath
686 ASSERT.kind_of extendee_module_paths, MOL::SetOfPath
687 ASSERT.kind_of includee_module_paths, MOL::SetOfPath
688 ASSERT.kind_of above_module_path, MOL::Path
689
690 super
691
692
693 # Cache variables.
694
695 @set_of_ancestor_class =
696 @set_of_neighboring_class = nil
697 end
698
699
700 def to_s(opt_str = nil)
701 ASSERT.opt_kind_of opt_str, String
702
703 str = super 'class', opt_str
704
705 ASSERT.kind_of str, String
706 end
707
708
709 def ancestor_classes
710 raise Exception::SubclassResponsibility
711 end
712
713
714 def subclasses
715 set_of_subclass = @store.map_of_superclass_to_subclasses.at self
716 mo_subclasses = if set_of_subclass
717 set_of_subclass
718 else
719 EMPTY_SET_OF_GENERIC_CLASS
720 end
721
722 ASSERT.kind_of mo_subclasses, SetOfGenericClass
723 end
724
725
726 def sibling_classes
727 raise Exception::SubclassResponsibility
728 end
729
730
731 def neighboring_classes(show_class_siblings = true)
732 ASSERT.boolean show_class_siblings
733
734 unless @set_of_neighboring_class
735 @set_of_neighboring_class =
736 if show_class_siblings
737 self.subclasses + self.sibling_classes
738 else
739 self.subclasses
740 end
741 end
742
743 ASSERT.kind_of @set_of_neighboring_class, SetOfGenericClass
744 end
745
746
747 def has_any_subclass_in_the_source?(target_file_name)
748 ASSERT.kind_of target_file_name, String
749
750 result =
751 if self.locations.any? { |location|
752 ASSERT.kind_of location, MOL::Location
753
754 location && location.file_name == target_file_name
755 }
756 true
757 else
758 self.subclasses.any? { |a_subclass|
759 ASSERT.kind_of a_subclass, ChildClass
760
761 a_subclass.has_any_subclass_in_the_source?(
762 target_file_name
763 )
764 }
765 end
766
767 ASSERT.boolean result
768 end
769 end
770
771
772
773 class SeqOfGenericClass < SeqOfChildModule
774 LSM_ELEMENT_CLASS = GenericClass
775 end
776
777 EMPTY_SEQ_OF_GENERIC_CLASS = SeqOfGenericClass.new
778
779
780
781 class SetOfGenericClass < SetOfChildModule
782 LSM_ELEMENT_CLASS = GenericClass
783 end
784
785 EMPTY_SET_OF_GENERIC_CLASS = SetOfGenericClass.new
786
787
788
789 class ChildClass < GenericClass
790 attr_reader :superclass_path
791
792
793 def initialize(
794 locations,
795 above_path,
796 name,
797 store,
798 properties,
799 below_module_paths,
800 extendee_module_paths,
801 includee_module_paths,
802 above_module_path,
803 superclass_path
804 )
805 ASSERT.kind_of locations, MOL::SetOfLocation
806 ASSERT.kind_of above_path, MOL::Path
807 ASSERT.kind_of name, String
808 ASSERT.opt_kind_of store, MO::Store
809 ASSERT.kind_of properties, MOLA::SetOfProperty
810 ASSERT.kind_of below_module_paths, MOL::SetOfPath
811 ASSERT.kind_of extendee_module_paths, MOL::SetOfPath
812 ASSERT.kind_of includee_module_paths, MOL::SetOfPath
813 ASSERT.kind_of above_module_path, MOL::Path
814 ASSERT.kind_of superclass_path, MOL::Path
815
816 super(
817 locations,
818 above_path,
819 name,
820 store,
821 properties,
822 below_module_paths,
823 extendee_module_paths,
824 includee_module_paths,
825 above_module_path
826 )
827
828 @superclass_path = superclass_path
829
830
831 # Cache variable.
832
833 @set_of_sibling_class = nil
834 end
835
836
837 def to_s
838 str = super(' < ' + self.superclass_path.to_s)
839
840 ASSERT.kind_of str, String
841 end
842
843
844 def print(indent)
845 ASSERT.kind_of indent, Integer
846
847 super
848
849 is = "\t" * indent
850
851 LOG::Debug.log "%ssuperclass_path: %s", is, superclass_path.to_s
852
853 nil
854 end
855
856
857 def a_superclass
858 sclass = @store.map_of_path_to_module.at @superclass_path
859 ASSERT.not_nil(
860 sclass,
861 "Not found superclass: '%s' of '%s (%s)'",
862 @superclass_path, self.name, self.above_path.to_s
863 )
864 ASSERT.assert(
865 self != sclass,
866 "superclass: %s(%s)",
867 self.to_s, self.class.to_s
868 )
869
870 ASSERT.kind_of sclass, MOLA::GenericClass
871 end
872
873
874 def above_module_equal_to_superclass?
875 result = self.an_above_module == self.a_superclass.an_above_module
876
877 ASSERT.boolean result
878 end
879
880
881 def ancestor_classes
882 unless @set_of_ancestor_class
883 @set_of_ancestor_class =
884 self.a_superclass.ancestor_classes << self
885 end
886
887 ASSERT.kind_of @set_of_ancestor_class, SetOfGenericClass
888 end
889
890
891 def sibling_classes
892 unless @set_of_sibling_class
893 array_of_sibling_class =
894 self.a_superclass.subclasses.reject { |a_subclass|
895 a_subclass == self
896 }
897 @set_of_sibling_class =
898 unless array_of_sibling_class.empty?
899 SetOfGenericClass.new array_of_sibling_class
900 else
901 EMPTY_SET_OF_GENERIC_CLASS
902 end
903 end
904
905 ASSERT.kind_of @set_of_sibling_class, SetOfGenericClass
906 end
907
908
909 def neighboring_classes(show_class_siblings = true)
910 ASSERT.boolean show_class_siblings
911
912 unless @set_of_neighboring_class
913 @set_of_neighboring_class =
914 super + SetOfGenericClass.new([self.a_superclass])
915 end
916
917 ASSERT.kind_of @set_of_neighboring_class, SetOfGenericClass
918 end
919 end
920
921
922
923 class SeqOfChildClass < SeqOfGenericClass
924 LSM_ELEMENT_CLASS = ChildClass
925 end
926
927 EMPTY_SEQ_OF_CHILD_CLASS = SeqOfChildClass.new
928
929
930
931 class SetOfChildClass < SetOfGenericClass
932 LSM_ELEMENT_CLASS = ChildClass
933 end
934
935 EMPTY_SET_OF_CHILD_CLASS = SetOfChildClass.new
936
937 end # TmDoc::Model::Object::Logical::Abstraction
938
939 end # TmDoc