1 # $Id: evaluater.rb,v 1.41 2012/04/17 02:49:40 machan Exp $
2
3 require 'tmdoc/tmstd'
4 require 'tmdoc/constant'
5 require 'tmdoc/environment'
6 require 'tmdoc/model/module'
7 require 'tmdoc/transformer/core-into-module/constant'
8
9
10 module TmDoc
11
12 module Transformer::CoreIntoModule
13
14 module Evaluater
15
16 class MapOfPathToModuleFuncNames < TmStd::Lsm::Collection::Map::Abstract
17 include TmStd::Lsm::Collection::Map::Mutable
18
19 LSM_DOMAIN_CLASS = MMLP::AbsolutePath
20 LSM_RANGE_CLASS = LSM::MutableSetOfString
21 end
22
23
24
25 def self.evaluate!(
26 mc_toplevel_module, env, map_of_path_to_module, mm_file
27 )
28 ASSERT.kind_of mc_toplevel_module, MCLN::ToplevelModule
29 ASSERT.kind_of env, ENV::Environment
30 ASSERT.kind_of map_of_path_to_module, MMLA::MapOfPathToModule
31 ASSERT.kind_of mm_file, MMP::File
32
33 LOG::Debug.msgout "CALLED" if env.debug?
34
35 map_of_path_to_func_names = MapOfPathToModuleFuncNames.new
36
37 for mc_record in mc_toplevel_module.traverse(env)
38 mc_above_path = mc_record.path
39 mc_name = mc_record.name
40 mc_subject = mc_record.subject
41 line_num = mc_subject.line_num
42 mm_location = MML::Location.new mm_file, line_num
43
44 if env.debug?
45 LOG::Debug.log(
46 "mc_above_path: %s, mc_name: %s, mc_subject: %s",
47 mc_above_path.to_s, mc_name, mc_subject.to_s
48 )
49
50 for path in map_of_path_to_module.domains.sort
51 LOG::Debug.log "path: %s", path
52 m = map_of_path_to_module.at path
53 LOG::Debug.log "\tmm_module: %s", m.to_s
54 end
55 end
56
57 mm_above_path = MMLP::AbsolutePath.new mc_above_path.to_a
58 mm_above_module = map_of_path_to_module.at mm_above_path
59 unless mm_above_module
60 mm_above_module = map_of_path_to_module.at(
61 BUILTIN_MODULE_PATH +
62 MMLP::RelativePath.new(mm_above_path.to_a)
63 )
64 end
65 unless mm_above_module
66 LOG::Error.log(
67 "Failed to resolve the module/class name: %s\n" +
68 "\tat %s in %s",
69 mm_above_path.to_s,
70 mc_subject.to_s, mm_file.to_s
71 )
72 CMD.test_sensitive_level env, LOG::Error
73 next
74 end
75 ASSERT.kind_of(
76 mm_above_module, MMLA::GenericModule,
77 "mm_above_path: %s", mm_above_path
78 )
79
80 case mc_subject
81 when MCLA::NodeSubject
82 mc_node_subject = mc_subject
83
84 case mc_node_subject
85 when MCLN::Module
86 self.evaluate_module!(
87 mc_node_subject, mm_location,
88 mm_above_path, mm_above_module, mc_name,
89 env, map_of_path_to_module
90 )
91
92 mm_module_path = mm_above_path << mc_name
93 if mc_record.module_func_names
94 LOG::Debug.log(
95 "mc_record.module_func_names: %s -- #%d",
96 mc_record.module_func_names.inspect, __LINE__
97 ) if env.debug?
98
99 module_func_names = map_of_path_to_func_names.at(
100 mm_module_path
101 )
102
103 if module_func_names
104 module_func_names.union!(
105 [mc_record.module_func_names]
106 )
107 else
108 map_of_path_to_func_names.update!(
109 mm_module_path, mc_record.module_func_names
110 )
111 end
112 end
113 when MCLN::Method
114 self.evaluate_property_or_method!(
115 mc_node_subject, mm_location,
116 mm_above_path, mm_above_module,
117 env, map_of_path_to_func_names
118 )
119 else
120 ASSERT.abort(
121 "Unknown node subject: %s(%s)",
122 mc_node_subject.to_s, mc_node_subject.class
123 )
124 end
125
126 when MCLA::LeafSubject
127 mc_property = mc_subject
128
129 case mc_property
130 when MCLA::Directive
131 self.evaluate_directive!(
132 mc_property, mm_location,
133 mm_above_path, mm_above_module,
134 env, mm_file
135 )
136 when MCLL::Constant
137 mm_constant = MMLL::Constant.new(
138 mm_location, mm_above_path,
139 mc_property.name,
140 mc_property.value
141 )
142
143 unless mm_above_module.constants.include?(mm_constant)
144 mm_above_module.constants.add! mm_constant
145 else
146 LOG::Warning.log(
147 "Conflicted constant definiation: %s",
148 mm_constant.to_s(false)
149 )
150 end
151 when MCLA::Property
152 self.evaluate_property_or_method!(
153 mc_property, mm_location,
154 mm_above_path, mm_above_module,
155 env, map_of_path_to_func_names
156 )
157 else
158 ASSERT.abort(
159 "Unknown property: %s(%s)",
160 mc_property.to_s, mc_property.class
161 )
162 end
163
164 else
165 ASSERT.abort(
166 "Unknown subject: %s(%s)",
167 mc_subject.to_s, mc_subject.class
168 )
169 end
170 end
171
172 nil
173 end
174
175
176 def self.evaluate_module!(
177 mc_module, mm_location, mm_above_path, mm_above_module, name, env,
178 map_of_path_to_module
179 )
180 ASSERT.kind_of mc_module, MCLA::NodeSubject
181 ASSERT.kind_of mm_location, MML::Location
182 ASSERT.kind_of mm_above_path, MMLP::AbsolutePath
183 ASSERT.kind_of mm_above_module, MMLA::GenericModule
184 ASSERT.kind_of name, String
185 ASSERT.kind_of env, ENV::Environment
186 ASSERT.kind_of map_of_path_to_module, MMLA::MapOfPathToModule
187
188 mm_module_path = mm_above_path << name
189
190 mm_module = self.resolve_module_name!(
191 mm_module_path, env, map_of_path_to_module
192 )
193 if mm_module
194 LOG::Debug.log(
195 "Distributed module definiation: %s",
196 mc_module.to_s
197 ) if env.debug?
198
199 if mm_module.kind_of?(MMLA::ChildClass)
200 self.validate_class_consistency!(
201 mc_module, mm_location, mm_module, env
202 )
203 end
204
205 mm_module.locations.add! mm_location
206 else
207 LOG::Debug.log(
208 "Adding module definiation: %s", mc_module.to_s
209 ) if env.debug?
210
211 mm_module = if mc_module.kind_of?(MCLN::Class)
212 MMLN::Class.new(
213 mm_location, mm_above_path, name,
214 MMLA::SetOfModule.new,
215 if mc_module.inherit_path_string
216 mc_module.inherit_path_string
217 else
218 OBJECT_CLASS_NAME
219 end
220 )
221 else
222 MMLN::Module.new(
223 mm_location, mm_above_path, name,
224 MMLA::SetOfModule.new
225 )
226 end
227 mm_above_module.add! mm_module
228
229 map_of_path_to_module.update! mm_module_path, mm_module
230 end
231
232 nil
233 end
234
235
236 def self.evaluate_directive!(
237 mc_directive, mm_location, mm_above_path, mm_above_module, env,
238 mm_file
239 )
240 ASSERT.kind_of mc_directive, MCLA::Directive
241 ASSERT.kind_of mm_location, MML::Location
242 ASSERT.kind_of mm_above_path, MMLP::AbsolutePath
243 ASSERT.kind_of mm_above_module, MMLA::GenericModule
244 ASSERT.kind_of env, ENV::Environment
245 ASSERT.kind_of mm_file, MMP::File
246
247 case mc_directive
248 when MCLL::Require
249 mm_file.require_files.add!(
250 MMP::RequireFile.new(
251 mc_directive.require_file_name, mc_directive.line_num
252 )
253 )
254
255 when MCLL::Extend
256 mm_above_module.extendees.add!(
257 MMLL::Extend.new(
258 mm_location, mm_above_path,
259 mc_directive.seq_num,
260 if mc_directive.extendee_path_string
261 mc_directive.extendee_path_string
262 else
263 mm_above_path.to_s
264 end
265 )
266 )
267
268 when MCLL::Include
269 mm_above_module.includees.add!(
270 MMLL::Include.new(
271 mm_location, mm_above_path,
272 mc_directive.seq_num,
273 if mc_directive.includee_path_string
274 mc_directive.includee_path_string
275 else
276 mm_above_path.to_s
277 end
278 )
279 )
280
281 when MCLL::ModuleFunc
282 ; # Nop
283
284 else
285 ASSERT.abort(
286 "Unknown directive: %s(%s)",
287 mc_directive.to_s, mc_directive.class
288 )
289 end
290
291 nil
292 end
293
294
295 def self.evaluate_property_or_method!(
296 mc_subject, mm_location, mm_above_path, mm_above_module, env,
297 map_of_path_to_func_names
298 )
299 ASSERT.kind_of mc_subject, MCLA::Subject
300 ASSERT.kind_of mm_location, MML::Location
301 ASSERT.kind_of mm_above_path, MMLP::AbsolutePath
302 ASSERT.kind_of mm_above_module, MMLA::GenericModule
303 ASSERT.kind_of env, ENV::Environment
304 ASSERT.kind_of(
305 map_of_path_to_func_names,
306 MapOfPathToModuleFuncNames
307 )
308
309 mm_property =
310 case mc_subject
311 when MCLL::Alias
312 MMLL::Alias.new(
313 mm_location, mm_above_path, mc_subject.name,
314 mc_subject.orig_name,
315 mc_subject.attach_to_instance?
316 )
317
318 when MCLL::Attribute
319 MMLL::Attribute.new(
320 mm_location, mm_above_path, mc_subject.name,
321 mc_subject.seq_num, mc_subject.accessor,
322 mc_subject.attach_to_instance?
323 )
324
325 when MCLN::Method
326 if (! mc_subject.attach_name) ||
327 mc_subject.attach_name == mm_above_module.name
328 name = mc_subject.name
329 is_module_func =
330 if mc_subject.module_func?
331 true
332 else
333 func_names = map_of_path_to_func_names.at(
334 mm_above_path
335 )
336 LOG::Debug.log(
337 "func_names: %s -- #%d",
338 func_names.inspect, __LINE__
339 ) if env.debug?
340
341 if func_names && func_names.include?(name)
342 true
343 else
344 false
345 end
346 end
347
348 MMLL::Method.new(
349 mm_location, mm_above_path, name,
350 mc_subject.args,
351 mc_subject.attach_to_instance?,
352 is_module_func
353 )
354 else
355 LOG::Warning.log(
356 "I can't recognize the Id: <%s> " +
357 "for module name of the unique method.\n" +
358 "\t-- #%d in '%s'",
359 mc_subject.attach_name,
360 mm_location.line_num, mm_location.file_name
361 )
362 CMD.test_sensitive_level env, LOG::Warning
363 end
364
365 else
366 ASSERT.abort(
367 "Unknown subject: %s(%s)",
368 mc_subject.to_s, mc_subject.class
369 )
370 end
371 mm_above_module.properties.add! mm_property
372
373 nil
374 end
375
376
377 def self.resolve_module_name!(target_path, env, map_of_path_to_module)
378 ASSERT.kind_of target_path, MMLP::AbsolutePath
379 ASSERT.kind_of env, ENV::Environment
380 ASSERT.kind_of map_of_path_to_module, MMLA::MapOfPathToModule
381
382 LOG::Debug.msgout "CALLED" if env.debug?
383
384 resolved_module = map_of_path_to_module.at(target_path)
385 if resolved_module
386 return ASSERT.kind_of resolved_module, MMLA::GenericModule
387 end
388
389 case target_path.first
390 when 'TmDoc', 'TmStd'
391 return nil
392 end
393
394 klass = nil
395 begin
396 klass = Kernel.const_get(target_path.join('::'))
397 rescue NameError
398 ; # Nop
399 end
400 if klass
401 resolved_path =
402 BUILTIN_MODULE_PATH +
403 MMLP::RelativePath.new(target_path.to_a)
404 resolved_module = map_of_path_to_module.at(target_path)
405 resolved_above_path, resolved_name = resolved_path.pop
406
407 resolved_module = map_of_path_to_module.at resolved_path
408 unless resolved_module
409 child_module = nil
410
411 while resolved_above_path.length > 0 && ! resolved_module
412 args = [nil, resolved_above_path, resolved_name]
413 if klass.is_a?(::Class)
414
415 # It should be resolved inheritance recursivily ...
416
417 resolved_module = MMLN::Class.new *(
418 args + [
419 MMLA::SetOfModule.new, OBJECT_CLASS_NAME
420 ]
421 )
422 resolved_module.inherit_path! OBJECT_CLASS_PATH
423 else
424 resolved_module = MMLN::Module.new *args
425 end
426
427 if child_module
428 resolved_module.add! child_module
429 end
430
431 LOG::Debug.log(
432 "Add found built-in module: '%s'\n" +
433 "to table: '%s'",
434 resolved_module.to_s,
435 resolved_path.to_s
436 ) if env.debug?
437
438 map_of_path_to_module.update!(
439 resolved_path.dup, resolved_module
440 )
441
442 child_module = resolved_module
443
444 resolved_path.pop!
445 resolved_above_path, resolved_name = resolved_path.pop
446 end
447
448 MM_BUILTIN_MODULE.add! resolved_module
449 end
450 else
451 resolved_module = nil
452 end
453
454 ASSERT.opt_kind_of resolved_module, MMLA::GenericModule
455 end
456
457
458 def self.validate_class_consistency!(
459 mc_my_subject, mm_my_location, mm_other_module, env
460 )
461 ASSERT.kind_of mc_my_subject, MCLN::Class
462 ASSERT.kind_of mm_my_location, MML::Location
463 ASSERT.kind_of mm_other_module, MMLA::GenericModule
464 ASSERT.kind_of env, ENV::Environment
465
466 LOG::Debug.msgout "CALLED" if env.debug?
467
468 my_mc_inherit_path_string =
469 if mc_my_subject.inherit_path_string
470 mc_my_subject.inherit_path_string
471 else
472 OBJECT_CLASS_NAME
473 end
474
475 is_consistent, my_inherit, other_inherit =
476 if mm_other_module.inherit_path_string == OBJECT_CLASS_NAME
477 if my_mc_inherit_path_string == OBJECT_CLASS_NAME
478 [true, nil, nil]
479 else
480 [
481 false,
482 my_mc_inherit_path_string,
483 OBJECT_CLASS_NAME
484 ]
485 end
486 else
487 if my_mc_inherit_path_string == OBJECT_CLASS_NAME
488 [true, nil, nil]
489 else
490 [
491 mm_other_module.inherit_path_string ==
492 my_mc_inherit_path_string,
493 my_mc_inherit_path_string,
494 mm_other_module.inherit_path_string
495 ]
496 end
497 end
498
499 unless is_consistent
500 LOG::Warning.log(
501 "Impossible to fix " +
502 "class inheritance inconsistency: %s.\n" +
503 "\tprevious superclass: %s,\n" +
504 "\tbut my superclass: %s -- %s.",
505 mm_other_module.path.to_s,
506 other_inherit,
507 my_inherit, mm_my_location.to_s
508 )
509 CMD.test_sensitive_level env, LOG::Warning
510 end
511
512 nil
513 end
514 end
515
516 end # TmDoc::Transformer::CoreIntoModule
517
518 end # TmDoc