1 # $Id: physical.rb,v 1.7 2011/12/08 22:54:35 machan Exp $
2
3 require 'tmdoc/tmstd'
4 require 'tmdoc/tmstd/treeable'
5 require 'tmdoc/constant'
6 require 'tmdoc/model/object/logical/abstraction'
7
8
9 module TmDoc
10
11 module Model::Object::Physical
12
13 module Abstraction
14
15 class Source < Model::Abstraction::Subject::PhysicalSubject; end
16
17
18
19 class SetOfSource < Model::Abstraction::Subject::SetOfPhysicalSubject
20 LSM_ELEMENT_CLASS = Source
21 end
22
23 end # TmDoc::Model::Object::Physical::Abstraction
24
25
26
27 class MapOfLineNumToLogicalSubjects < TmStd::Lsm::Collection::Map::Abstract
28 LSM_DOMAIN_CLASS = Integer
29 LSM_RANGE_CLASS = MOLA::SeqOfSubject
30
31 alias :line_num :domains
32 alias :subjects :ranges
33 end
34
35
36
37 class File < Abstraction::Source
38 attr_reader :require_files, :map_of_line_num_to_logical_subjects
39
40
41 def initialize(name, seq_num, require_files = [])
42 ASSERT.kind_of name, String
43 ASSERT.kind_of seq_num, Integer
44 ASSERT.kind_of require_files, SetOfRequireFile
45
46 @require_files =
47 require_files
48 @map_of_line_num_to_logical_subjects =
49 MapOfLineNumToLogicalSubjects.new
50
51 super(name, seq_num)
52 end
53
54
55 def map_of_line_num_to_logical_subjects!(
56 map_of_line_num_to_logical_subjects
57 )
58 ASSERT.kind_of(
59 map_of_line_num_to_logical_subjects,
60 MapOfLineNumToLogicalSubjects
61 )
62
63 @map_of_line_num_to_logical_subjects =
64 map_of_line_num_to_logical_subjects
65
66 nil
67 end
68
69
70 def to_s
71 str = super('file')
72
73 ASSERT.kind_of str, String
74 end
75
76
77 def print(indent)
78 ASSERT.kind_of indent, Integer
79
80 super(indent)
81
82 is = "\t" * indent
83 is1 = "\t" * (indent + 1)
84 is2 = "\t" * (indent + 2)
85
86 unless self.require_files.empty?
87 LOG::Debug.log "%srequire_files:", is
88 for require_file in self.require_files.sort
89 LOG::Debug.log "%s%s", is1, require_file.to_s
90 end
91 end
92
93 ms = self.map_of_line_num_to_logical_subjects
94 unless ms.empty?
95 LOG::Debug.log "%smap_of_line_num_to_logical_subjects:", is
96 for num in ms.domains.sort
97 LOG::Debug.log "%sline_num: %d", is1, num
98 LOG::Debug.log "%slogical_subjects:", is1
99 for sub in ms.at num
100 LOG::Debug.log "%s%s", is2, sub.to_s
101 end
102 end
103 end
104
105 nil
106 end
107 end
108
109
110
111 class MapOfNameToFile < TmStd::Lsm::Collection::Map::Abstract
112 LSM_DOMAIN_CLASS = ::String
113 LSM_RANGE_CLASS = File
114
115 alias :names :domains
116 alias :files :ranges
117 end
118
119
120
121 class Files < TmStd::Lsm::Product::Abstract
122 include Enumerable
123
124 attr_reader :map_of_name_to_file
125
126
127 def initialize(map_of_name_to_file)
128 ASSERT.kind_of map_of_name_to_file, MapOfNameToFile
129
130 @map_of_name_to_file = map_of_name_to_file
131 end
132
133
134 def empty?
135 result = self.map_of_name_to_file.empty?
136
137 ASSERT.boolean result
138 end
139
140
141 def each(&block)
142 self.map_of_name_to_file.files.each(&block)
143
144 nil
145 end
146
147
148 def at(file_name)
149 ASSERT.kind_of file_name, String
150
151 mo_file = self.map_of_name_to_file.at file_name
152
153 ASSERT.kind_of mo_file, Model::Object::Physical::File
154 end
155 end
156
157
158
159 class RequireFile < Abstraction::Source
160 def to_s
161 str = super('require file')
162
163 ASSERT.kind_of str, String
164 end
165 end
166
167
168
169 class SetOfRequireFile < Abstraction::SetOfSource
170 LSM_ELEMENT_CLASS = RequireFile
171 end
172
173
174
175 module Relationship
176
177 class RelationshipOfFileToLogicalSubject < TmStd::Lsm::Product::Abstract
178 attr_reader :file,
179 :line_num,
180 :logical_subject
181
182
183 def initialize(file, line_num, logical_subject)
184 ASSERT.kind_of file, MOP::File
185 ASSERT.kind_of line_num, Integer
186 ASSERT.kind_of logical_subject, MOLA::Subject
187
188 @file = file
189 @line_num = line_num
190 @logical_subject = logical_subject
191 end
192 end
193
194
195 def Relationship.update_files(all_modules)
196 ASSERT.kind_of all_modules, MOLA::SeqOfGenericModule
197
198 all_modules.map { |a_module|
199 a_module.locations.map { |location|
200 RelationshipOfFileToLogicalSubject.new(
201 location.a_file,
202 location.line_num,
203 a_module
204 )
205 } + (
206 a_module.properties.map { |a_property|
207 location = a_property.location
208
209 if location
210 RelationshipOfFileToLogicalSubject.new(
211 location.a_file,
212 location.line_num,
213 a_property
214 )
215 else
216 nil
217 end
218 }
219 ).compact
220 }.flatten.inject({}) { |hash, relationship|
221 hash.merge(relationship.file => [relationship]) {
222 |_file, self_relationships, other_relationships|
223
224 self_relationships + other_relationships
225 }
226 }.each do |file, relationships|
227 map_of_line_num_to_logical_subjects = relationships.sort_by {
228 |relationship|
229
230 relationship.logical_subject
231 }.inject(
232 MOP::MapOfLineNumToLogicalSubjects.new
233 ) { |map, relationship|
234 map.update(
235 relationship.line_num,
236 MOLA::SeqOfSubject.new(
237 [relationship.logical_subject]
238 )
239 ) { |_line_num, self_subjects, other_subjects|
240
241 self_subjects + other_subjects
242 }
243 }
244
245 yield file, map_of_line_num_to_logical_subjects
246 end
247
248 nil
249 end
250 end
251
252 end # TmDoc::Model::Object::Physical
253
254 end # TmDoc