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.
- data/ChangeLog +2907 -0
- data/Gemfile +7 -0
- data/README +21 -0
- data/Rakefile +20 -0
- data/bin/bitclust +14 -0
- data/bin/refe +36 -0
- data/bitclust-dev.gemspec +33 -0
- data/bitclust.gemspec +30 -0
- data/config.in +23 -0
- data/config.ru +48 -0
- data/config.ru.sample +31 -0
- data/data/bitclust/catalog/ja_JP.EUC-JP +78 -0
- data/data/bitclust/catalog/ja_JP.UTF-8 +78 -0
- data/data/bitclust/template.lillia/class +98 -0
- data/data/bitclust/template.lillia/class-index +28 -0
- data/data/bitclust/template.lillia/doc +48 -0
- data/data/bitclust/template.lillia/layout +19 -0
- data/data/bitclust/template.lillia/library +129 -0
- data/data/bitclust/template.lillia/library-index +32 -0
- data/data/bitclust/template.lillia/method +20 -0
- data/data/bitclust/template.lillia/rd_file +6 -0
- data/data/bitclust/template.offline/class +67 -0
- data/data/bitclust/template.offline/class-index +28 -0
- data/data/bitclust/template.offline/doc +13 -0
- data/data/bitclust/template.offline/function +22 -0
- data/data/bitclust/template.offline/function-index +24 -0
- data/data/bitclust/template.offline/layout +18 -0
- data/data/bitclust/template.offline/library +87 -0
- data/data/bitclust/template.offline/library-index +32 -0
- data/data/bitclust/template.offline/method +21 -0
- data/data/bitclust/template.offline/rd_file +6 -0
- data/data/bitclust/template/class +133 -0
- data/data/bitclust/template/class-index +30 -0
- data/data/bitclust/template/doc +14 -0
- data/data/bitclust/template/function +21 -0
- data/data/bitclust/template/function-index +25 -0
- data/data/bitclust/template/layout +19 -0
- data/data/bitclust/template/library +89 -0
- data/data/bitclust/template/library-index +35 -0
- data/data/bitclust/template/method +24 -0
- data/data/bitclust/template/opensearchdescription +10 -0
- data/data/bitclust/template/search +57 -0
- data/lib/bitclust.rb +9 -0
- data/lib/bitclust/app.rb +129 -0
- data/lib/bitclust/classentry.rb +425 -0
- data/lib/bitclust/compat.rb +39 -0
- data/lib/bitclust/completion.rb +531 -0
- data/lib/bitclust/crossrubyutils.rb +91 -0
- data/lib/bitclust/database.rb +181 -0
- data/lib/bitclust/docentry.rb +83 -0
- data/lib/bitclust/entry.rb +223 -0
- data/lib/bitclust/exception.rb +38 -0
- data/lib/bitclust/functiondatabase.rb +115 -0
- data/lib/bitclust/functionentry.rb +81 -0
- data/lib/bitclust/functionreferenceparser.rb +76 -0
- data/lib/bitclust/htmlutils.rb +80 -0
- data/lib/bitclust/interface.rb +87 -0
- data/lib/bitclust/libraryentry.rb +211 -0
- data/lib/bitclust/lineinput.rb +165 -0
- data/lib/bitclust/messagecatalog.rb +95 -0
- data/lib/bitclust/methoddatabase.rb +401 -0
- data/lib/bitclust/methodentry.rb +202 -0
- data/lib/bitclust/methodid.rb +209 -0
- data/lib/bitclust/methodsignature.rb +82 -0
- data/lib/bitclust/nameutils.rb +236 -0
- data/lib/bitclust/parseutils.rb +60 -0
- data/lib/bitclust/preprocessor.rb +273 -0
- data/lib/bitclust/rdcompiler.rb +507 -0
- data/lib/bitclust/refsdatabase.rb +66 -0
- data/lib/bitclust/requesthandler.rb +330 -0
- data/lib/bitclust/ridatabase.rb +349 -0
- data/lib/bitclust/rrdparser.rb +522 -0
- data/lib/bitclust/runner.rb +143 -0
- data/lib/bitclust/screen.rb +554 -0
- data/lib/bitclust/searcher.rb +518 -0
- data/lib/bitclust/server.rb +59 -0
- data/lib/bitclust/simplesearcher.rb +84 -0
- data/lib/bitclust/subcommand.rb +746 -0
- data/lib/bitclust/textutils.rb +51 -0
- data/lib/bitclust/version.rb +3 -0
- data/packer.rb +224 -0
- data/refe2.gemspec +29 -0
- data/server.exe +0 -0
- data/server.exy +159 -0
- data/server.rb +10 -0
- data/setup.rb +1596 -0
- data/standalone.rb +193 -0
- data/test/run_test.rb +15 -0
- data/test/test_bitclust.rb +81 -0
- data/test/test_entry.rb +39 -0
- data/test/test_functiondatabase.rb +55 -0
- data/test/test_libraryentry.rb +31 -0
- data/test/test_methoddatabase.rb +81 -0
- data/test/test_methodsignature.rb +14 -0
- data/test/test_nameutils.rb +324 -0
- data/test/test_preprocessor.rb +84 -0
- data/test/test_rdcompiler.rb +534 -0
- data/test/test_refsdatabase.rb +76 -0
- data/test/test_rrdparser.rb +26 -0
- data/test/test_runner.rb +102 -0
- data/test/test_simplesearcher.rb +48 -0
- data/theme/default/images/external.png +0 -0
- data/theme/default/rurema.png +0 -0
- data/theme/default/style.css +288 -0
- data/theme/default/test.css +254 -0
- data/theme/lillia/rurema.png +0 -0
- data/theme/lillia/style.css +331 -0
- data/theme/lillia/test.css +254 -0
- data/tools/bc-ancestors.rb +153 -0
- data/tools/bc-checkparams.rb +246 -0
- data/tools/bc-classes.rb +80 -0
- data/tools/bc-convert.rb +165 -0
- data/tools/bc-list.rb +63 -0
- data/tools/bc-methods.rb +171 -0
- data/tools/bc-preproc.rb +42 -0
- data/tools/bc-rdoc.rb +343 -0
- data/tools/bc-tochm.rb +301 -0
- data/tools/bc-tohtml.rb +125 -0
- data/tools/bc-tohtmlpackage.rb +241 -0
- data/tools/check-signature.rb +19 -0
- data/tools/forall-ruby.rb +20 -0
- data/tools/gencatalog.rb +69 -0
- data/tools/statrefm.rb +98 -0
- data/tools/stattodo.rb +150 -0
- data/tools/update-database.rb +146 -0
- data/view.cgi +6 -0
- metadata +222 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
unless Object.method_defined?(:__send)
|
|
2
|
+
class Object
|
|
3
|
+
alias __send __send__
|
|
4
|
+
end
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
unless Object.method_defined?(:funcall)
|
|
8
|
+
class Object
|
|
9
|
+
alias funcall __send
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
unless Fixnum.method_defined?(:ord)
|
|
14
|
+
class Fixnum
|
|
15
|
+
def ord
|
|
16
|
+
self
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
unless String.method_defined?(:lines)
|
|
22
|
+
class String
|
|
23
|
+
alias lines to_a
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
unless String.method_defined?(:bytesize)
|
|
28
|
+
class String
|
|
29
|
+
alias bytesize size
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def fopen(*args, &block)
|
|
34
|
+
option = args[1]
|
|
35
|
+
if option and !Object.const_defined?(:Encoding)
|
|
36
|
+
args[1] = option.sub(/:.*\z/, '')
|
|
37
|
+
end
|
|
38
|
+
File.open(*args, &block)
|
|
39
|
+
end
|
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
#
|
|
2
|
+
# bitclust/completion.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
|
+
module BitClust
|
|
11
|
+
|
|
12
|
+
module Completion
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# Completion Search
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
def _search_classes(pattern)
|
|
21
|
+
expand_ic(classes(), pattern)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def _search_methods(pattern)
|
|
25
|
+
case
|
|
26
|
+
when pattern.empty?
|
|
27
|
+
recordclass = SearchResult::Record
|
|
28
|
+
SearchResult.new(self, pattern, classes(),
|
|
29
|
+
methods().map {|m| s = m.spec; recordclass.new(s, s, m) })
|
|
30
|
+
when pattern.special_variable?
|
|
31
|
+
c = fetch_class('Kernel')
|
|
32
|
+
SearchResult.new(self, pattern, [c], search_svar(c, pattern.method))
|
|
33
|
+
when pattern.class?
|
|
34
|
+
search_methods_from_cname(pattern)
|
|
35
|
+
else
|
|
36
|
+
case
|
|
37
|
+
when pattern.klass && pattern.method
|
|
38
|
+
GC.disable; x =
|
|
39
|
+
search_methods_from_cname_mname(pattern)
|
|
40
|
+
GC.enable; GC.start; x
|
|
41
|
+
when pattern.method
|
|
42
|
+
search_methods_from_mname(pattern)
|
|
43
|
+
when pattern.klass && pattern.type
|
|
44
|
+
search_methods_from_cname(pattern)
|
|
45
|
+
when pattern.type
|
|
46
|
+
raise 'type only search is not supportted yet'
|
|
47
|
+
else
|
|
48
|
+
raise 'must not happen'
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def _search_functions(pattern)
|
|
54
|
+
expand_ic(functions(), pattern)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def search_svar(c, pattern)
|
|
58
|
+
expand(c.special_variables, pattern)\
|
|
59
|
+
.map {|m| SearchResult::Record.new(self, m.spec, m.spec, m) }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def search_methods_from_cname(pattern)
|
|
63
|
+
cs = expand_ic(classes(), pattern.klass)
|
|
64
|
+
return SearchResult.new(self, pattern, [], []) if cs.empty?
|
|
65
|
+
recs = cs.map {|c|
|
|
66
|
+
c.entries.map {|m|
|
|
67
|
+
if not pattern.type or m.typemark == pattern.type
|
|
68
|
+
s = m.spec
|
|
69
|
+
SearchResult::Record.new(s, s, m)
|
|
70
|
+
else
|
|
71
|
+
nil
|
|
72
|
+
end
|
|
73
|
+
}.compact
|
|
74
|
+
}.flatten
|
|
75
|
+
SearchResult.new(self, pattern, cs, recs)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def mspec_from_cref_mname(cref, name)
|
|
79
|
+
m = /\A(#{NameUtils::CLASS_PATH_RE})(#{NameUtils::TYPEMARK_RE})\Z/.match(cref)
|
|
80
|
+
MethodSpec.new(m[1], m[2], name)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def search_methods_from_mname(pattern)
|
|
84
|
+
#timer_init
|
|
85
|
+
names = expand_name_narrow(method_names(), pattern.method)
|
|
86
|
+
#split_time "m expandN (#{names.size})"
|
|
87
|
+
records = names.map {|name|
|
|
88
|
+
crefs = mname2crefs_narrow(name)
|
|
89
|
+
#split_time "c expand (#{crefs.size})"
|
|
90
|
+
crefs.map {|cref|
|
|
91
|
+
spec = mspec_from_cref_mname(classid2name(cref), name)
|
|
92
|
+
SearchResult::Record.new(self, spec, spec)
|
|
93
|
+
}
|
|
94
|
+
}.flatten
|
|
95
|
+
SearchResult.new(self, pattern, [], records)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def search_methods_from_cname_mname(pattern)
|
|
99
|
+
#timer_init
|
|
100
|
+
recs = try(typechars(pattern.type, pattern.method)) {|ts|
|
|
101
|
+
expand_method_name(pattern.klass, ts, pattern.method)
|
|
102
|
+
}
|
|
103
|
+
SearchResult.new(self, pattern, recs.map {|rec| rec.class_name }, recs)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def expand_method_name(c, ts, m)
|
|
107
|
+
names_w = expand_name_wide(method_names(), m)
|
|
108
|
+
return [] if names_w.empty?
|
|
109
|
+
#split_time "m expandW (#{names_w.size})"
|
|
110
|
+
names_n = squeeze_names(names_w, m)
|
|
111
|
+
#split_time "m squeeze (#{names_n.size})"
|
|
112
|
+
if names_n.empty?
|
|
113
|
+
recs = make_cm_combination(c, ts, names_w)
|
|
114
|
+
nclass = count_class(recs)
|
|
115
|
+
#split_time "c expandW (#{nclass}c x #{$cm_comb_m}m -> #{recs.size})"
|
|
116
|
+
else
|
|
117
|
+
recs = make_cm_combination(c, ts, names_n)
|
|
118
|
+
nclass = count_class(recs)
|
|
119
|
+
#split_time "c expandN (#{nclass}c x #{$cm_comb_m}m -> #{recs.size})"
|
|
120
|
+
if recs.empty?
|
|
121
|
+
recs = make_cm_combination(c, ts, names_w)
|
|
122
|
+
nclass = count_class(recs)
|
|
123
|
+
#split_time "c expandW (#{nclass}c x #{$cm_comb_m}m -> #{recs.size})"
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
return [] if recs.empty?
|
|
127
|
+
urecs = nclass > 50 ? recs : unify_entries(recs)
|
|
128
|
+
#split_time "unify (#{urecs.size})"
|
|
129
|
+
urecs
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def timer_init
|
|
133
|
+
@ts = [Time.now]
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def split_time(msg)
|
|
137
|
+
@ts.push Time.now
|
|
138
|
+
$stderr.puts "#{@ts.size - 1}: #{'%.3f' % (@ts[-1] - @ts[-2])}: #{msg}"
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def count_class(recs)
|
|
142
|
+
recs.map {|rec| rec.class_name }.uniq.size
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def make_cm_combination(cpat, ts, mnames)
|
|
146
|
+
result = []
|
|
147
|
+
$cm_comb_m = 0
|
|
148
|
+
mnames.each do |m|
|
|
149
|
+
crefs = expand_name_narrow(mname2crefs_wide(m), cpat, ts)
|
|
150
|
+
next if crefs.empty?
|
|
151
|
+
$cm_comb_m += 1
|
|
152
|
+
crefs.each do |ref|
|
|
153
|
+
spec = MethodSpec.new(classid2name(ref.chop), ref[-1,1], m)
|
|
154
|
+
result.push SearchResult::Record.new(self, spec)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
result
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def try(candidates)
|
|
161
|
+
candidates.each do |c|
|
|
162
|
+
result = yield c
|
|
163
|
+
return result unless result.empty?
|
|
164
|
+
end
|
|
165
|
+
[]
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def typechars(type, mpattern)
|
|
169
|
+
if type then [type]
|
|
170
|
+
elsif /\A[A-Z]/ =~ mpattern then [':', '.#']
|
|
171
|
+
else ['.#', ':']
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def unify_entries(ents)
|
|
176
|
+
h = {}
|
|
177
|
+
ents.each do |ent|
|
|
178
|
+
if ent0 = h[ent]
|
|
179
|
+
ent0.merge ent
|
|
180
|
+
else
|
|
181
|
+
h[ent] = ent
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
h.values
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Case-insensitive search. Optimized for constant search.
|
|
188
|
+
def expand_ic(xs, pattern)
|
|
189
|
+
re1 = /\A#{Regexp.quote(pattern)}/i
|
|
190
|
+
result1 = xs.select {|x| x.name_match?(re1) }
|
|
191
|
+
return [] if result1.empty?
|
|
192
|
+
return result1 if result1.size == 1
|
|
193
|
+
re2 = /\A#{Regexp.quote(pattern)}\z/i
|
|
194
|
+
result2 = result1.select {|x| x.name_match?(re2) }
|
|
195
|
+
return result1 if result2.empty?
|
|
196
|
+
return result2 if result2.size == 1 # no mean
|
|
197
|
+
result2
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def expand(xs, pattern)
|
|
201
|
+
re1 = /\A#{Regexp.quote(pattern)}/i
|
|
202
|
+
result1 = xs.select {|x| x.name_match?(re1) }
|
|
203
|
+
return [] if result1.empty?
|
|
204
|
+
return result1 if result1.size == 1
|
|
205
|
+
re2 = /\A#{Regexp.quote(pattern)}\z/i
|
|
206
|
+
result2 = result1.select {|x| x.name_match?(re2) }
|
|
207
|
+
return result1 if result2.empty?
|
|
208
|
+
return result2 if result2.size == 1
|
|
209
|
+
result3 = result2.select {|x| x.name?(pattern) }
|
|
210
|
+
return result2 if result3.empty?
|
|
211
|
+
return result3 if result3.size == 1 # no mean
|
|
212
|
+
result3
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# list up all matched items (without squeezing)
|
|
216
|
+
def expand_name_wide(names, pattern)
|
|
217
|
+
re1 = /\A#{Regexp.quote(pattern)}/i
|
|
218
|
+
names.grep(re1)
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# list up matched items (with squeezing)
|
|
222
|
+
def expand_name_narrow(names, pattern, suffixes = nil)
|
|
223
|
+
re1 = /\A#{Regexp.quote(pattern)}/i
|
|
224
|
+
result1 = names.grep(re1)
|
|
225
|
+
return [] if result1.empty?
|
|
226
|
+
return result1 if result1.size == 1
|
|
227
|
+
squeeze_names(result1, pattern, suffixes)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# squeeze result of #expand_name_wide
|
|
231
|
+
def squeeze_names(result1, pattern, suffixes = nil)
|
|
232
|
+
regexps =
|
|
233
|
+
[
|
|
234
|
+
/\A#{Regexp.quote(pattern)}.*#{suffix_pattern(suffixes)}\z/i,
|
|
235
|
+
/\A#{Regexp.quote(pattern)}#{suffix_pattern(suffixes)}\z/i,
|
|
236
|
+
/\A#{Regexp.quote(pattern)}#{suffix_pattern(suffixes)}\z/,
|
|
237
|
+
]
|
|
238
|
+
result = result1
|
|
239
|
+
regexps.each do |re|
|
|
240
|
+
new_result = result.grep(re)
|
|
241
|
+
return result if new_result.empty?
|
|
242
|
+
return new_result if new_result.size == 1
|
|
243
|
+
result = new_result
|
|
244
|
+
end
|
|
245
|
+
return result
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def suffix_pattern(suffixes)
|
|
249
|
+
return '' unless suffixes
|
|
250
|
+
"[#{Regexp.quote(suffixes)}]"
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
#
|
|
254
|
+
# Index
|
|
255
|
+
#
|
|
256
|
+
|
|
257
|
+
def save_completion_index
|
|
258
|
+
save_class_index
|
|
259
|
+
save_method_index
|
|
260
|
+
save_method_index_narrow
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def intern_classname(name)
|
|
264
|
+
intern_table()[name]
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def intern_table
|
|
268
|
+
@intern_table ||=
|
|
269
|
+
begin
|
|
270
|
+
h = {}
|
|
271
|
+
classnametable().each do |id, names|
|
|
272
|
+
names.each do |n|
|
|
273
|
+
h[n] = id
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
h
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def save_class_index
|
|
281
|
+
atomic_write_open('class/=index') {|f|
|
|
282
|
+
classes().each do |c|
|
|
283
|
+
#f.puts "#{c.id}\t#{c.names.join(' ')}" # FIXME: support class alias
|
|
284
|
+
f.puts "#{c.id}\t#{c.name}"
|
|
285
|
+
end
|
|
286
|
+
}
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def classnametable
|
|
290
|
+
@classnametable ||=
|
|
291
|
+
begin
|
|
292
|
+
h = {}
|
|
293
|
+
foreach_line('class/=index') do |line|
|
|
294
|
+
id, *names = line.split
|
|
295
|
+
h[id] = names
|
|
296
|
+
end
|
|
297
|
+
h
|
|
298
|
+
rescue Errno::ENOENT
|
|
299
|
+
{}
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def save_method_index_narrow
|
|
304
|
+
index =
|
|
305
|
+
begin
|
|
306
|
+
h = {}
|
|
307
|
+
classes().each do |c|
|
|
308
|
+
c.entries.each do |m|
|
|
309
|
+
ref = c.id + m.typemark
|
|
310
|
+
m.names.each do |name|
|
|
311
|
+
(h[name] ||= []).push ref
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
h
|
|
316
|
+
end
|
|
317
|
+
atomic_write_open('method/=sindex') {|f|
|
|
318
|
+
index.keys.sort.each do |name|
|
|
319
|
+
f.puts "#{name}\t#{index[name].join(' ')}"
|
|
320
|
+
end
|
|
321
|
+
}
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def method_index_small
|
|
325
|
+
@method_index_small ||=
|
|
326
|
+
begin
|
|
327
|
+
h = {}
|
|
328
|
+
foreach_line('method/=sindex') do |line|
|
|
329
|
+
name, *crefs = line.split(nil)
|
|
330
|
+
h[name] = crefs
|
|
331
|
+
end
|
|
332
|
+
h
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
# canonical class name, no inheritance
|
|
337
|
+
def mname2crefs_narrow(name)
|
|
338
|
+
method_index_small()[name]
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def save_method_index
|
|
342
|
+
index =
|
|
343
|
+
begin
|
|
344
|
+
h = {}
|
|
345
|
+
classes().each do |c|
|
|
346
|
+
[ ['#', c._imap.keys],
|
|
347
|
+
['.', c._smap.keys],
|
|
348
|
+
[':', c._cmap.keys] ].each do |t, names|
|
|
349
|
+
ref = c.id + t
|
|
350
|
+
names.each do |name|
|
|
351
|
+
(h[name] ||= []).push ref
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
h
|
|
356
|
+
end
|
|
357
|
+
atomic_write_open('method/=index') {|f|
|
|
358
|
+
index.keys.sort.each do |name|
|
|
359
|
+
f.puts "#{name}\t#{index[name].join(' ')}"
|
|
360
|
+
end
|
|
361
|
+
}
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
def method_names
|
|
365
|
+
@method_names ||= method_index_0().keys
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
# includes class aliases, includes inherited methods
|
|
369
|
+
def mname2crefs_wide(name)
|
|
370
|
+
tbl = classnametable()
|
|
371
|
+
mname2crefs_0(name).map {|ref|
|
|
372
|
+
tbl[ref.chop].map {|c| c + ref[-1,1] }
|
|
373
|
+
}.flatten
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
def mname2crefs_0(name)
|
|
377
|
+
crefs = (@method_index ||= {})[name]
|
|
378
|
+
return crefs if crefs
|
|
379
|
+
crefsstr = method_index_0()[name] or return nil
|
|
380
|
+
@method_index[name] = crefsstr.split(nil)
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
def method_index_0
|
|
384
|
+
@method_index_0 ||=
|
|
385
|
+
begin
|
|
386
|
+
h = {}
|
|
387
|
+
foreach_line('method/=index') do |line|
|
|
388
|
+
name, cnames = line.split(nil, 2)
|
|
389
|
+
h[name] = cnames
|
|
390
|
+
end
|
|
391
|
+
h
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
class SearchResult
|
|
399
|
+
|
|
400
|
+
def SearchResult.empty(db, pattern)
|
|
401
|
+
new(db, pattern, [], [])
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def initialize(db, pattern, classes, records)
|
|
405
|
+
@database = db
|
|
406
|
+
@pattern = pattern
|
|
407
|
+
@classes = classes
|
|
408
|
+
@records = records
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
attr_reader :database
|
|
412
|
+
attr_reader :pattern
|
|
413
|
+
attr_reader :classes
|
|
414
|
+
attr_reader :records
|
|
415
|
+
|
|
416
|
+
def inspect
|
|
417
|
+
"\#<BitClust::SearchResult @pattern=#{@pattern.inspect} @classes=#{@classes.inspect} @database=#{@database.inspect} @records=[#{record.inspect}, ...] >"
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
def fail?
|
|
421
|
+
@records.empty?
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
def success?
|
|
425
|
+
not @records.empty?
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
def determined?
|
|
429
|
+
@records.size == 1
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
def name
|
|
433
|
+
@records.first.name
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
def names
|
|
437
|
+
@records.map {|rec| rec.names }.flatten
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
def record
|
|
441
|
+
@records.first
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
def each_record(&block)
|
|
445
|
+
@records.sort.each(&block)
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
class Record
|
|
449
|
+
def initialize(db, spec, origin = nil, entry = nil)
|
|
450
|
+
@db = db
|
|
451
|
+
@specs = [spec]
|
|
452
|
+
@origin = origin
|
|
453
|
+
@entry = entry
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
attr_writer :db
|
|
457
|
+
attr_reader :specs
|
|
458
|
+
|
|
459
|
+
def origin
|
|
460
|
+
@origin ||=
|
|
461
|
+
begin
|
|
462
|
+
spec = @specs.first
|
|
463
|
+
c = @db.fetch_class(spec.klass)
|
|
464
|
+
MethodSpec.parse(c.match_entry(spec.type, spec.method))
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
def idstring
|
|
469
|
+
origin().to_s
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
def entry
|
|
473
|
+
@entry ||= @db.get_method(origin())
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
def name
|
|
477
|
+
names().first
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
def names
|
|
481
|
+
@specs.map {|spec| spec.display_name }
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
def class_name
|
|
485
|
+
@specs.first.klass
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
def method_name
|
|
489
|
+
@specs.first.method
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
def original_name
|
|
493
|
+
@idstring
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
def ==(other)
|
|
497
|
+
@idstring == other.idstring
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
alias eql? ==
|
|
501
|
+
|
|
502
|
+
def hash
|
|
503
|
+
@hash ||= idstring().hash
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
def <=>(other)
|
|
507
|
+
entry() <=> other.entry
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
def merge(other)
|
|
511
|
+
@specs |= other.specs
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
def owned_method?
|
|
516
|
+
@specs.any? {|spec| spec.klass == origin().klass }
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
def method_of_alias_class?
|
|
520
|
+
@entry.klass.aliases.any?{|aliasclass| aliasclass.name?(class_name())}
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
def inherited_method?
|
|
524
|
+
!owned_method?() && !method_of_alias_class?()
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
end
|