bitclust-core 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. data/ChangeLog +2907 -0
  2. data/Gemfile +7 -0
  3. data/README +21 -0
  4. data/Rakefile +20 -0
  5. data/bin/bitclust +14 -0
  6. data/bin/refe +36 -0
  7. data/bitclust-dev.gemspec +33 -0
  8. data/bitclust.gemspec +30 -0
  9. data/config.in +23 -0
  10. data/config.ru +48 -0
  11. data/config.ru.sample +31 -0
  12. data/data/bitclust/catalog/ja_JP.EUC-JP +78 -0
  13. data/data/bitclust/catalog/ja_JP.UTF-8 +78 -0
  14. data/data/bitclust/template.lillia/class +98 -0
  15. data/data/bitclust/template.lillia/class-index +28 -0
  16. data/data/bitclust/template.lillia/doc +48 -0
  17. data/data/bitclust/template.lillia/layout +19 -0
  18. data/data/bitclust/template.lillia/library +129 -0
  19. data/data/bitclust/template.lillia/library-index +32 -0
  20. data/data/bitclust/template.lillia/method +20 -0
  21. data/data/bitclust/template.lillia/rd_file +6 -0
  22. data/data/bitclust/template.offline/class +67 -0
  23. data/data/bitclust/template.offline/class-index +28 -0
  24. data/data/bitclust/template.offline/doc +13 -0
  25. data/data/bitclust/template.offline/function +22 -0
  26. data/data/bitclust/template.offline/function-index +24 -0
  27. data/data/bitclust/template.offline/layout +18 -0
  28. data/data/bitclust/template.offline/library +87 -0
  29. data/data/bitclust/template.offline/library-index +32 -0
  30. data/data/bitclust/template.offline/method +21 -0
  31. data/data/bitclust/template.offline/rd_file +6 -0
  32. data/data/bitclust/template/class +133 -0
  33. data/data/bitclust/template/class-index +30 -0
  34. data/data/bitclust/template/doc +14 -0
  35. data/data/bitclust/template/function +21 -0
  36. data/data/bitclust/template/function-index +25 -0
  37. data/data/bitclust/template/layout +19 -0
  38. data/data/bitclust/template/library +89 -0
  39. data/data/bitclust/template/library-index +35 -0
  40. data/data/bitclust/template/method +24 -0
  41. data/data/bitclust/template/opensearchdescription +10 -0
  42. data/data/bitclust/template/search +57 -0
  43. data/lib/bitclust.rb +9 -0
  44. data/lib/bitclust/app.rb +129 -0
  45. data/lib/bitclust/classentry.rb +425 -0
  46. data/lib/bitclust/compat.rb +39 -0
  47. data/lib/bitclust/completion.rb +531 -0
  48. data/lib/bitclust/crossrubyutils.rb +91 -0
  49. data/lib/bitclust/database.rb +181 -0
  50. data/lib/bitclust/docentry.rb +83 -0
  51. data/lib/bitclust/entry.rb +223 -0
  52. data/lib/bitclust/exception.rb +38 -0
  53. data/lib/bitclust/functiondatabase.rb +115 -0
  54. data/lib/bitclust/functionentry.rb +81 -0
  55. data/lib/bitclust/functionreferenceparser.rb +76 -0
  56. data/lib/bitclust/htmlutils.rb +80 -0
  57. data/lib/bitclust/interface.rb +87 -0
  58. data/lib/bitclust/libraryentry.rb +211 -0
  59. data/lib/bitclust/lineinput.rb +165 -0
  60. data/lib/bitclust/messagecatalog.rb +95 -0
  61. data/lib/bitclust/methoddatabase.rb +401 -0
  62. data/lib/bitclust/methodentry.rb +202 -0
  63. data/lib/bitclust/methodid.rb +209 -0
  64. data/lib/bitclust/methodsignature.rb +82 -0
  65. data/lib/bitclust/nameutils.rb +236 -0
  66. data/lib/bitclust/parseutils.rb +60 -0
  67. data/lib/bitclust/preprocessor.rb +273 -0
  68. data/lib/bitclust/rdcompiler.rb +507 -0
  69. data/lib/bitclust/refsdatabase.rb +66 -0
  70. data/lib/bitclust/requesthandler.rb +330 -0
  71. data/lib/bitclust/ridatabase.rb +349 -0
  72. data/lib/bitclust/rrdparser.rb +522 -0
  73. data/lib/bitclust/runner.rb +143 -0
  74. data/lib/bitclust/screen.rb +554 -0
  75. data/lib/bitclust/searcher.rb +518 -0
  76. data/lib/bitclust/server.rb +59 -0
  77. data/lib/bitclust/simplesearcher.rb +84 -0
  78. data/lib/bitclust/subcommand.rb +746 -0
  79. data/lib/bitclust/textutils.rb +51 -0
  80. data/lib/bitclust/version.rb +3 -0
  81. data/packer.rb +224 -0
  82. data/refe2.gemspec +29 -0
  83. data/server.exe +0 -0
  84. data/server.exy +159 -0
  85. data/server.rb +10 -0
  86. data/setup.rb +1596 -0
  87. data/standalone.rb +193 -0
  88. data/test/run_test.rb +15 -0
  89. data/test/test_bitclust.rb +81 -0
  90. data/test/test_entry.rb +39 -0
  91. data/test/test_functiondatabase.rb +55 -0
  92. data/test/test_libraryentry.rb +31 -0
  93. data/test/test_methoddatabase.rb +81 -0
  94. data/test/test_methodsignature.rb +14 -0
  95. data/test/test_nameutils.rb +324 -0
  96. data/test/test_preprocessor.rb +84 -0
  97. data/test/test_rdcompiler.rb +534 -0
  98. data/test/test_refsdatabase.rb +76 -0
  99. data/test/test_rrdparser.rb +26 -0
  100. data/test/test_runner.rb +102 -0
  101. data/test/test_simplesearcher.rb +48 -0
  102. data/theme/default/images/external.png +0 -0
  103. data/theme/default/rurema.png +0 -0
  104. data/theme/default/style.css +288 -0
  105. data/theme/default/test.css +254 -0
  106. data/theme/lillia/rurema.png +0 -0
  107. data/theme/lillia/style.css +331 -0
  108. data/theme/lillia/test.css +254 -0
  109. data/tools/bc-ancestors.rb +153 -0
  110. data/tools/bc-checkparams.rb +246 -0
  111. data/tools/bc-classes.rb +80 -0
  112. data/tools/bc-convert.rb +165 -0
  113. data/tools/bc-list.rb +63 -0
  114. data/tools/bc-methods.rb +171 -0
  115. data/tools/bc-preproc.rb +42 -0
  116. data/tools/bc-rdoc.rb +343 -0
  117. data/tools/bc-tochm.rb +301 -0
  118. data/tools/bc-tohtml.rb +125 -0
  119. data/tools/bc-tohtmlpackage.rb +241 -0
  120. data/tools/check-signature.rb +19 -0
  121. data/tools/forall-ruby.rb +20 -0
  122. data/tools/gencatalog.rb +69 -0
  123. data/tools/statrefm.rb +98 -0
  124. data/tools/stattodo.rb +150 -0
  125. data/tools/update-database.rb +146 -0
  126. data/view.cgi +6 -0
  127. metadata +222 -0
@@ -0,0 +1,401 @@
1
+ #
2
+ # bitclust/methoddatabase.rb
3
+ #
4
+ # Copyright (c) 2006-2008 Minero Aoki
5
+ #
6
+ # This program is free software.
7
+ # You can distribute/modify this program under the Ruby License.
8
+ #
9
+
10
+ require 'bitclust/database'
11
+ require 'bitclust/libraryentry'
12
+ require 'bitclust/classentry'
13
+ require 'bitclust/methodentry'
14
+ require 'bitclust/docentry'
15
+ require 'bitclust/completion'
16
+ require 'bitclust/refsdatabase'
17
+ require 'bitclust/rrdparser'
18
+ require 'bitclust/exception'
19
+ require 'fileutils'
20
+
21
+ module BitClust
22
+
23
+ class MethodDatabase < Database
24
+
25
+ include Completion
26
+
27
+ def MethodDatabase.dummy(params = {})
28
+ db = super
29
+ db.refs = RefsDatabase.new
30
+ db
31
+ end
32
+
33
+ def initialize(prefix)
34
+ super prefix
35
+ @librarymap = nil
36
+ @classmap = {}
37
+ @class_extent_loaded = false
38
+ @in_transaction = false
39
+ @dirty_libraries = {}
40
+ @dirty_classes = {}
41
+ @dirty_methods = {}
42
+ @refs = nil
43
+ end
44
+
45
+ attr_writer :refs
46
+
47
+ def init
48
+ FileUtils.rm_rf @prefix
49
+ FileUtils.mkdir_p @prefix
50
+ Dir.mkdir "#{@prefix}/library"
51
+ Dir.mkdir "#{@prefix}/class"
52
+ Dir.mkdir "#{@prefix}/method"
53
+ Dir.mkdir "#{@prefix}/doc"
54
+ FileUtils.touch "#{@prefix}/properties"
55
+ FileUtils.touch "#{@prefix}/refs"
56
+ end
57
+
58
+ #
59
+ # Transaction
60
+ #
61
+
62
+ def commit
63
+ update_requires
64
+ update_sublibraries
65
+ # FIXME: many require loops in tk
66
+ #each_dirty_library do |lib|
67
+ # lib.check_link
68
+ #end
69
+ each_dirty_class do |c|
70
+ c.clear_cache
71
+ c.check_ancestor_type
72
+ end
73
+ each_dirty_class do |c|
74
+ c.check_ancestors_link
75
+ end
76
+ each_dirty_entry do |x|
77
+ x.save
78
+ end
79
+ clear_dirty
80
+ save_completion_index
81
+ copy_doc
82
+ make_refs
83
+ refs().save(realpath('refs'))
84
+ end
85
+ private :commit
86
+
87
+ def dirty?
88
+ not @dirty_libraries.empty? or
89
+ not @dirty_classes.empty? or
90
+ not @dirty_methods.empty?
91
+ end
92
+
93
+ def each_dirty_entry(&block)
94
+ (@dirty_libraries.keys +
95
+ @dirty_classes.keys +
96
+ @dirty_methods.keys).each(&block)
97
+ end
98
+
99
+ def dirty_library(lib)
100
+ @dirty_libraries[lib] = true
101
+ end
102
+
103
+ def each_dirty_library(&block)
104
+ @dirty_libraries.each_key(&block)
105
+ end
106
+
107
+ def dirty_class(c)
108
+ @dirty_classes[c] = true
109
+ end
110
+
111
+ def each_dirty_class(&block)
112
+ @dirty_classes.each_key(&block)
113
+ end
114
+
115
+ def dirty_method(m)
116
+ @dirty_methods[m] = true
117
+ end
118
+
119
+ def each_dirty_method(&block)
120
+ @dirty_methods.each_key(&block)
121
+ end
122
+
123
+ def clear_dirty
124
+ @dirty_libraries.clear
125
+ @dirty_classes.clear
126
+ @dirty_methods.clear
127
+ end
128
+
129
+ def update_requires
130
+ libraries.each{|lib|
131
+ lib.requires = lib.all_requires
132
+ }
133
+ end
134
+
135
+ def update_sublibraries
136
+ libraries.each{|lib|
137
+ re = /\A#{lib.name}\//
138
+ libraries.each{|l|
139
+ lib.sublibrary(l) if re =~ l.name
140
+ }
141
+ }
142
+ end
143
+
144
+ def update_by_stdlibtree(root)
145
+ @root = root
146
+ parse_LIBRARIES("#{root}/LIBRARIES", properties()).each do |libname|
147
+ update_by_file "#{root}/#{libname}.rd", libname
148
+ end
149
+ end
150
+
151
+ def parse_LIBRARIES(path, properties)
152
+ fopen(path, 'r:UTF-8') {|f|
153
+ BitClust::Preprocessor.wrap(f, properties).map {|line| line.strip }
154
+ }
155
+ end
156
+ private :parse_LIBRARIES
157
+
158
+ def update_by_file(path, libname)
159
+ check_transaction
160
+ RRDParser.new(self).parse_file(path, libname, properties())
161
+ end
162
+
163
+ def refs
164
+ @refs ||= RefsDatabase.load(realpath('refs'))
165
+ end
166
+
167
+ def make_refs
168
+ [classes, libraries, methods, docs].each do |es|
169
+ es.each do |e|
170
+ refs().extract(e)
171
+ end
172
+ end
173
+ refs
174
+ end
175
+
176
+ def copy_doc
177
+ Dir.glob("#{@root}/../../doc/**/*.rd").each do |f|
178
+ if %r!\A#{Regexp.escape(@root)}/\.\./\.\./doc/([-\./\w]+)\.rd\z! =~ f
179
+ id = libname2id($1)
180
+ se = DocEntry.new(self, id)
181
+ s = Preprocessor.read(f, properties)
182
+ title, source = RRDParser.split_doc(s)
183
+ se.title = title
184
+ se.source = source
185
+ se.save
186
+ end
187
+ end
188
+ end
189
+
190
+ #
191
+ # Doc Entry
192
+ #
193
+
194
+ def docs
195
+ docmap().values
196
+ end
197
+
198
+ def docmap
199
+ @docmap ||= load_extent(DocEntry)
200
+ end
201
+ private :docmap
202
+
203
+ def get_doc(name)
204
+ id = libname2id(name)
205
+ docmap()[id] ||= DocEntry.new(self, id)
206
+ end
207
+
208
+ def fetch_doc(name)
209
+ docmap()[libname2id(name)] or
210
+ raise DocNotFound, "doc not found: #{name.inspect}"
211
+ end
212
+
213
+ #
214
+ # Library Entry
215
+ #
216
+
217
+ def libraries
218
+ librarymap().values
219
+ end
220
+
221
+ def librarymap
222
+ @librarymap ||= load_extent(LibraryEntry)
223
+ end
224
+ private :librarymap
225
+
226
+ def get_library(name)
227
+ id = libname2id(name)
228
+ librarymap()[id] ||= LibraryEntry.new(self, id)
229
+ end
230
+
231
+ def fetch_library(name)
232
+ librarymap()[libname2id(name)] or
233
+ raise LibraryNotFound, "library not found: #{name.inspect}"
234
+ end
235
+
236
+ def fetch_library_id(id)
237
+ librarymap()[id] or
238
+ raise LibraryNotFound, "library not found: #{id.inspect}"
239
+ end
240
+
241
+ def open_library(name, reopen = false)
242
+ check_transaction
243
+ map = librarymap()
244
+ id = libname2id(name)
245
+ if lib = map[id]
246
+ lib.clear unless reopen
247
+ else
248
+ lib = (map[id] ||= LibraryEntry.new(self, id))
249
+ end
250
+ dirty_library lib
251
+ lib
252
+ end
253
+
254
+ #
255
+ # Classe Entry
256
+ #
257
+
258
+ def classes
259
+ classmap().values
260
+ end
261
+
262
+ def classmap
263
+ return @classmap if @class_extent_loaded
264
+ id_extent(ClassEntry).each do |id|
265
+ @classmap[id] ||= ClassEntry.new(self, id)
266
+ end
267
+ @class_extent_loaded = true
268
+ @classmap
269
+ end
270
+ private :classmap
271
+
272
+ # get a class entry if it exists, or create a new class entry object
273
+ # if it doesn't exist.
274
+ def get_class(name)
275
+ if id = intern_classname(name)
276
+ load_class(id) or
277
+ raise "must not happen: #{name.inspect}, #{id.inspect}"
278
+ else
279
+ id = classname2id(name)
280
+ @classmap[id] ||= ClassEntry.new(self, id)
281
+ end
282
+ end
283
+
284
+ # This method does not work in transaction.
285
+ def fetch_class(name)
286
+ id = intern_classname(name) or
287
+ raise ClassNotFound, "class not found: #{name.inspect}"
288
+ load_class(id) or
289
+ raise "must not happen: #{name.inspect}, #{id.inspect}"
290
+ end
291
+
292
+ def fetch_class_id(id)
293
+ load_class(id) or
294
+ raise ClassNotFound, "class not found: #{id.inspect}"
295
+ end
296
+
297
+ def search_classes(pattern)
298
+ cs = _search_classes(pattern)
299
+ if cs.empty?
300
+ raise ClassNotFound, "no such class: #{pattern}"
301
+ end
302
+ cs
303
+ end
304
+
305
+ def open_class(name)
306
+ check_transaction
307
+ id = classname2id(name)
308
+ if exist?("class/#{id}")
309
+ c = load_class(id)
310
+ c.clear
311
+ else
312
+ c = (@classmap[id] ||= ClassEntry.new(self, id))
313
+ end
314
+ yield c
315
+ dirty_class c
316
+ c
317
+ end
318
+
319
+ def load_class(id)
320
+ @classmap[id] ||=
321
+ begin
322
+ return nil unless exist?("class/#{id}")
323
+ ClassEntry.new(self, id)
324
+ end
325
+ end
326
+ private :load_class
327
+
328
+ def load_extent(entry_class)
329
+ h = {}
330
+ id_extent(entry_class).each do |id|
331
+ h[id] = entry_class.new(self, id)
332
+ end
333
+ h
334
+ end
335
+ private :load_extent
336
+
337
+ def id_extent(entry_class)
338
+ entries(entry_class.type_id.to_s)
339
+ end
340
+ private :id_extent
341
+
342
+ #
343
+ # Method Entry
344
+ #
345
+
346
+ # FIXME: see kind
347
+ def open_method(id)
348
+ check_transaction
349
+ if m = id.klass.get_method(id)
350
+ m.clear
351
+ else
352
+ m = MethodEntry.new(self, id.idstring)
353
+ id.klass.add_method m
354
+ end
355
+ m.library = id.library
356
+ m.klass = id.klass
357
+ yield m
358
+ dirty_method m
359
+ m
360
+ end
361
+
362
+ def methods
363
+ classes().map {|c| c.entries }.flatten
364
+ end
365
+
366
+ def get_method(spec)
367
+ get_class(spec.klass).get_method(spec)
368
+ end
369
+
370
+ def fetch_methods(spec)
371
+ fetch_class(spec.klass).fetch_methods(spec)
372
+ end
373
+
374
+ def fetch_method(spec)
375
+ fetch_class(spec.klass).fetch_method(spec)
376
+ end
377
+
378
+ def search_method(pattern)
379
+ search_methods(pattern).first
380
+ end
381
+
382
+ def search_methods(pattern)
383
+ result = _search_methods(pattern)
384
+ if result.fail?
385
+ if result.classes.empty?
386
+ loc = pattern.klass ? pattern.klass + '.' : ''
387
+ raise MethodNotFound, "no such method: #{loc}#{pattern.method}"
388
+ end
389
+ if result.classes.size <= 5
390
+ loc = result.classes.map {|c| c.label }.join(', ')
391
+ else
392
+ loc = "#{result.classes.size} classes"
393
+ end
394
+ raise MethodNotFound, "no such method in #{loc}: #{pattern.method}"
395
+ end
396
+ result
397
+ end
398
+
399
+ end
400
+
401
+ end
@@ -0,0 +1,202 @@
1
+ #
2
+ # bitclust/methodentry.rb
3
+ #
4
+ # Copyright (c) 2006-2008 Minero Aoki
5
+ #
6
+ # This program is free software.
7
+ # You can distribute/modify this program under the Ruby License.
8
+ #
9
+
10
+ require 'bitclust/entry'
11
+ require 'bitclust/exception'
12
+
13
+ module BitClust
14
+
15
+ # Represents a method, a constant, and a special variable.
16
+ class MethodEntry < Entry
17
+
18
+ def MethodEntry.type_id
19
+ :method
20
+ end
21
+
22
+ def initialize(db, id)
23
+ super db
24
+ @id = id
25
+ init_properties
26
+ end
27
+
28
+ attr_reader :id
29
+
30
+ def ==(other)
31
+ @id == other.id
32
+ end
33
+
34
+ alias eql? ==
35
+
36
+ def hash
37
+ @id.hash
38
+ end
39
+
40
+ def <=>(other)
41
+ sort_key() <=> other.sort_key
42
+ end
43
+
44
+ KIND_NUM = {:defined => 0, :redefined => 1, :added => 2}
45
+
46
+ def sort_key
47
+ [label(), KIND_NUM[kind()]]
48
+ end
49
+
50
+ def name
51
+ methodid2mname(@id)
52
+ end
53
+
54
+ # typename = :singleton_method
55
+ # | :instance_method
56
+ # | :module_function
57
+ # | :constant
58
+ # | :special_variable
59
+ def typename
60
+ methodid2typename(@id)
61
+ end
62
+
63
+ alias type typename
64
+
65
+ def typemark
66
+ methodid2typemark(@id)
67
+ end
68
+
69
+ def typechar
70
+ methodid2typechar(@id)
71
+ end
72
+
73
+ def type_label
74
+ case typemark()
75
+ when '.' then 'singleton method'
76
+ when '#' then 'instance method'
77
+ when '.#' then 'module function'
78
+ when '::' then 'constant'
79
+ when '$' then 'variable'
80
+ end
81
+ end
82
+
83
+ def library
84
+ @library ||= @db.fetch_library_id(methodid2libid(@id))
85
+ end
86
+
87
+ attr_writer :library
88
+
89
+ def klass
90
+ @klass ||= @db.fetch_class_id(methodid2classid(@id))
91
+ end
92
+
93
+ attr_writer :klass
94
+
95
+ persistent_properties {
96
+ property :names, '[String]'
97
+ property :visibility, 'Symbol' # :public | :private | :protected
98
+ property :kind, 'Symbol' # :defined | :added | :redefined
99
+ property :source, 'String'
100
+ }
101
+
102
+ def inspect
103
+ c, t, m, lib = methodid2specparts(@id)
104
+ "\#<method #{c}#{t}#{names().join(',')}>"
105
+ end
106
+
107
+ def spec
108
+ MethodSpec.new(*methodid2specparts(@id))
109
+ end
110
+
111
+ def spec_string
112
+ methodid2specstring(@id)
113
+ end
114
+
115
+ def label
116
+ c, t, m, lib = methodid2specparts(@id)
117
+ "#{t == '$' ? '' : c}#{t}#{m}"
118
+ end
119
+
120
+ def short_label
121
+ c, t, m, lib = methodid2specparts(@id)
122
+ "#{t == '#' ? '' : t}#{m}"
123
+ end
124
+
125
+ def labels
126
+ c, t, m, lib = methodid2specparts(@id)
127
+ names().map {|name| "#{c}#{t}#{name}" }
128
+ end
129
+
130
+ def name?(name)
131
+ names().include?(name)
132
+ end
133
+
134
+ def name_match?(re)
135
+ names().any? {|n| re =~ n }
136
+ end
137
+
138
+ def really_public?
139
+ visibility() == :public
140
+ end
141
+
142
+ def public?
143
+ visibility() != :private
144
+ end
145
+
146
+ def protected?
147
+ visibility() == :protected
148
+ end
149
+
150
+ def private?
151
+ visibility() == :private
152
+ end
153
+
154
+ def public_singleton_method?
155
+ singleton_method? and public?
156
+ end
157
+
158
+ def private_singleton_method?
159
+ singleton_method? and private?
160
+ end
161
+
162
+ def public_instance_method?
163
+ instance_method? and public?
164
+ end
165
+
166
+ def private_instance_method?
167
+ instance_method? and public?
168
+ end
169
+
170
+ def singleton_method?
171
+ t = typename()
172
+ t == :singleton_method or t == :module_function
173
+ end
174
+
175
+ def instance_method?
176
+ t = typename()
177
+ t == :instance_method or t == :module_function
178
+ end
179
+
180
+ def constant?
181
+ typename() == :constant
182
+ end
183
+
184
+ def special_variable?
185
+ typename() == :special_variable
186
+ end
187
+
188
+ def defined?
189
+ kind() == :defined
190
+ end
191
+
192
+ def added?
193
+ kind() == :added
194
+ end
195
+
196
+ def redefined?
197
+ kind() == :redefined
198
+ end
199
+
200
+ end
201
+
202
+ end