bitclust-core 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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