1 # $Id: module-infobox.rb,v 1.18 2012/04/17 02:49:40 machan Exp $
2
3 require 'tmdoc/tmstd'
4 require 'tmdoc/constant'
5 require 'tmdoc/model/object'
6 require 'tmdoc/model/document'
7
8
9 module TmDoc
10
11 module Transformer::ObjectIntoDocument
12
13 module Module
14
15 module InfoBox
16
17 module_function
18
19 def transform(
20 mo_module, env, show_module_siblings, show_class_siblings
21 )
22 ASSERT.kind_of mo_module, MOLA::GenericModule
23 ASSERT.kind_of env, ENV::Environment
24 ASSERT.boolean show_module_siblings
25 ASSERT.boolean show_class_siblings
26
27 md_above_module_row =
28 if mo_module.kind_of?(MOLA::ChildModule)
29 mo_above_module = mo_module.an_above_module
30 if mo_above_module
31 transform_module(
32 mo_above_module, MDM::InfoBox::Row::AboveModule
33 )
34 else
35 nil
36 end
37 else
38 nil
39 end
40
41 md_below_modules_row = transform_modules(
42 mo_module.below_modules, MDM::InfoBox::Row::BelowModules
43 )
44
45 md_sibling_modules_row =
46 if show_module_siblings &&
47 mo_module.kind_of?(MOLA::ChildModule)
48 transform_modules(
49 mo_module.sibling_modules,
50 MDM::InfoBox::Row::SiblingModules
51 )
52 else
53 nil
54 end
55
56 md_extendee_modules_row = transform_modules(
57 mo_module.extendee_modules, MDM::InfoBox::Row::ExtendeeModules
58 )
59
60 md_extender_modules_row = transform_modules(
61 mo_module.extender_modules, MDM::InfoBox::Row::ExtenderModules
62 )
63
64 md_includee_modules_row = transform_modules(
65 mo_module.includee_modules, MDM::InfoBox::Row::IncludeeModules
66 )
67
68 md_includer_modules_row = transform_modules(
69 mo_module.includer_modules, MDM::InfoBox::Row::IncluderModules
70 )
71
72 md_superclass_row =
73 if mo_module.kind_of?(MOLA::ChildClass)
74 mo_superclass = mo_module.a_superclass
75 if mo_superclass
76 transform_module(
77 mo_superclass, MDM::InfoBox::Row::Superclass
78 )
79 else
80 nil
81 end
82 else
83 nil
84 end
85
86 md_subclasses_row =
87 if mo_module.kind_of?(MOLA::GenericClass)
88 transform_modules(
89 mo_module.subclasses, MDM::InfoBox::Row::Subclasses
90 )
91 else
92 nil
93 end
94
95 md_sibling_classes_row =
96 if show_class_siblings &&
97 mo_module.kind_of?(MOLA::ChildClass)
98 transform_modules(
99 mo_module.sibling_classes,
100 MDM::InfoBox::Row::SiblingClasses
101 )
102 else
103 nil
104 end
105
106 md_properties_row =
107 transform_properties(
108 mo_module.properties,
109 mo_module.kind_of?(MOLA::GenericClass)
110 )
111
112 md_locations_row = transform_locations(mo_module.locations)
113
114 rows = [
115 md_above_module_row,
116 md_below_modules_row,
117 md_sibling_modules_row,
118 md_extendee_modules_row,
119 md_extender_modules_row,
120 md_includee_modules_row,
121 md_includer_modules_row,
122 md_superclass_row,
123 md_subclasses_row,
124 md_sibling_classes_row,
125 md_properties_row,
126 md_locations_row
127 ].compact
128 return nil if rows.empty?
129
130 MDM::InfoBox::InfoBox.new(MDM::InfoBox::Row::SeqOfRow.new(rows))
131 end
132
133
134 def transform_module(mo_module, row_class)
135 ASSERT.opt_kind_of mo_module, MOLA::GenericModule
136 ASSERT.subclass_of row_class, MDA::InfoBox::Row
137
138 return nil unless mo_module
139
140 md_row = row_class.new(
141 MDM::InfoBox::EntryRow::SeqOfEntryRow.new(
142 [transform_module_entry_row(mo_module)]
143 )
144 )
145
146 ASSERT.kind_of md_row, MDA::InfoBox::Row
147 end
148
149
150 def transform_modules(mo_modules, row_class)
151 ASSERT.kind_of mo_modules, MOLA::SetOfGenericModule
152 ASSERT.subclass_of row_class, MDA::InfoBox::Row
153
154 return nil if mo_modules.empty?
155
156 md_entry_rows = mo_modules.reject { |mo_module|
157 ASSERT.kind_of mo_module, MOLA::GenericModule
158
159 mo_module.suppressable?
160 }.sort.map { |mo_module|
161 ASSERT.kind_of mo_module, MOLA::GenericModule
162
163 transform_module_entry_row(mo_module)
164 }
165 return nil if md_entry_rows.empty?
166
167 md_row = row_class.new(
168 MDM::InfoBox::EntryRow::SeqOfEntryRow.new(md_entry_rows)
169 )
170
171 ASSERT.kind_of md_row, MDA::InfoBox::Row
172 end
173
174
175 def transform_module_entry_row(mo_module)
176 ASSERT.kind_of mo_module, MOLA::GenericModule
177
178 args = [mo_module.name, Link.transform_link_to_module(mo_module)]
179
180 md_module_entry_row =
181 if mo_module.kind_of?(MOLA::GenericClass)
182 MDM::InfoBox::EntryRow::Class.new *args
183 else
184 MDM::InfoBox::EntryRow::Module.new *args
185 end
186
187 ASSERT.kind_of md_module_entry_row, MDM::InfoBox::EntryRow::Module
188 end
189
190
191 def transform_properties(
192 mo_properties, is_belongs_to_class, mo_file = nil
193 )
194 ASSERT.kind_of mo_properties, MOLA::SetOfProperty
195 ASSERT.boolean is_belongs_to_class
196 ASSERT.opt_kind_of mo_file, MOP::File
197
198 md_entry_rows = mo_properties.reject { |mo_property|
199 ASSERT.kind_of mo_property, MOLA::Property
200
201 mo_file && mo_property.location.a_file != mo_file
202 }.sort.map { |mo_property|
203 ASSERT.kind_of mo_property, MOLA::Property
204
205 name = mo_property.name
206 tag = Module.transform_property_tag(
207 mo_property, is_belongs_to_class
208 )
209 mo_location = mo_property.location
210 line_num = MDL::Line.new(
211 mo_location.a_file.name,
212 mo_location.line_num
213 )
214 uniq_num = mo_property.uniq_num
215 max_uniq_num = mo_property.max_uniq_num
216
217 case mo_property
218 when MOLL::Constant
219 MDM::InfoBox::EntryRow::Constant.new(name, tag, line_num)
220 when MOLL::Alias
221 MDM::InfoBox::EntryRow::Alias.new(
222 name, tag, line_num, uniq_num, max_uniq_num,
223 mo_property.orig_name
224 )
225 when MOLL::Attribute
226 MDM::InfoBox::EntryRow::Attribute.new(
227 name, tag, line_num, uniq_num, max_uniq_num,
228 Module.transform_attr_accessor(mo_property.accessor)
229 )
230 when MOLL::Method
231 MDM::InfoBox::EntryRow::Method.new(
232 name, tag, line_num, uniq_num, max_uniq_num,
233 mo_property.args.length
234 )
235 else
236 ASSERT.abort(
237 "Unknown mo_property: %s", mo_property.class.to_s
238 )
239 end
240 }
241 return nil if md_entry_rows.empty?
242
243 MDM::InfoBox::Row::Properties.new(
244 MDM::InfoBox::EntryRow::SeqOfEntryRow.new(md_entry_rows)
245 )
246 end
247
248
249 def transform_locations(mo_locations)
250 ASSERT.kind_of mo_locations, MOL::SetOfLocation
251
252 return nil if mo_locations.empty?
253
254 hash_of_file_to_locations = mo_locations.inject({}) {
255 |hash, mo_location|
256
257 hash.merge(
258 mo_location.a_file => MOL::SetOfLocation.new(
259 [mo_location]
260 )
261 ) { |_mo_file, self_mo_locations, other_mo_locations|
262
263 other_mo_locations + self_mo_locations
264 }
265 }
266 md_entry_rows = hash_of_file_to_locations.keys.sort.map { |mo_file|
267 mo_locations_by_file = hash_of_file_to_locations[mo_file]
268 ASSERT.kind_of mo_locations_by_file, MOL::SetOfLocation
269 ASSERT.assert mo_locations_by_file.size > 0
270
271 MDM::InfoBox::EntryRow::Location.new(
272 Link.transform_links_to_line(mo_locations_by_file),
273 Link.transform_link_to_file(mo_file)
274 )
275 }
276 return nil if md_entry_rows.empty?
277
278 MDM::InfoBox::Row::Locations.new(
279 MDM::InfoBox::EntryRow::SeqOfEntryRow.new(md_entry_rows)
280 )
281 end
282 end
283
284 end # TmDoc::Transformer::ObjectIntoDocument::Module
285
286 end # TmDoc::Transformer::ObjectIntoDocument
287
288 end # TmDoc