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,91 @@
|
|
|
1
|
+
#
|
|
2
|
+
# bitclust/crossrubyutils.rb
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2006 Minero Aoki
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
module BitClust
|
|
8
|
+
|
|
9
|
+
module CrossRubyUtils
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def print_crossruby_table(&block)
|
|
14
|
+
print_table(*build_crossruby_table(&block))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def print_table(vers, table)
|
|
18
|
+
thcols = ([20] + table.keys.map {|s| s.size }).max
|
|
19
|
+
versions = vers.map {|ver| version_id(ver) }
|
|
20
|
+
width_list = versions.map{|v| v.size + 1 }
|
|
21
|
+
print_record thcols, '', versions, width_list
|
|
22
|
+
crossrubyutils_sort_entries(table.keys).each do |c|
|
|
23
|
+
print_record thcols, c, vers.map {|ver| table[c][ver] ? 'o' : '-' }, width_list
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def crossrubyutils_sort_entries(ents)
|
|
28
|
+
ents.sort
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def print_record(thcols, th, tds, width_list = nil)
|
|
32
|
+
unless width_list
|
|
33
|
+
width_list = Array.new(tds.size){ 4 }
|
|
34
|
+
end
|
|
35
|
+
printf "%-#{thcols}s ", th
|
|
36
|
+
puts tds.zip(width_list).map {|td, width| "%#{width}s" % td }.join('')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def version_id(ver)
|
|
40
|
+
ver.split[1].tr('.', '')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def get_ruby(version)
|
|
44
|
+
forall_ruby(ENV['PATH']) do |ruby, |
|
|
45
|
+
v = `#{ruby} -e 'print RUBY_VERSION'`
|
|
46
|
+
patch = `#{ruby} -e 'print RUBY_PATCHLEVEL if defined? RUBY_PATCHLEVEL'`
|
|
47
|
+
if version == v or ( version == v.succ and patch == '5000')
|
|
48
|
+
return ruby
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
return nil
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def build_crossruby_table
|
|
55
|
+
ENV.delete 'RUBYOPT'
|
|
56
|
+
ENV.delete 'RUBYLIB'
|
|
57
|
+
ENV.delete 'GEM_HOME'
|
|
58
|
+
vers = []
|
|
59
|
+
table = {}
|
|
60
|
+
forall_ruby(ENV['PATH']) do |ruby, ver|
|
|
61
|
+
puts "#{version_id(ver)}: #{ver}" if @verbose
|
|
62
|
+
vers.push ver
|
|
63
|
+
yield(ruby).each do |c|
|
|
64
|
+
(table[c] ||= {})[ver] = true
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
return vers, table
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def forall_ruby(path, &block)
|
|
71
|
+
rubys(path)\
|
|
72
|
+
.map {|ruby| [ruby, `#{ruby} --version`] }\
|
|
73
|
+
.reject {|ruby, verstr| `which #{ruby}`.include?('@') }\
|
|
74
|
+
.sort_by {|ruby, verstr| verstr }\
|
|
75
|
+
.each(&block)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def rubys(path)
|
|
79
|
+
parse_PATH(path).map {|bindir|
|
|
80
|
+
Dir.glob("#{bindir}/ruby-[12t]*").map {|path| File.basename(path) }
|
|
81
|
+
}\
|
|
82
|
+
.flatten.uniq + ['ruby']
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def parse_PATH(str)
|
|
86
|
+
str.split(':').map {|path| path.empty? ? '.' : path }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
#
|
|
2
|
+
# bitclust/database.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/nameutils'
|
|
11
|
+
require 'bitclust/exception'
|
|
12
|
+
|
|
13
|
+
module BitClust
|
|
14
|
+
|
|
15
|
+
class Database
|
|
16
|
+
|
|
17
|
+
include NameUtils
|
|
18
|
+
|
|
19
|
+
def Database.datadir?(dir)
|
|
20
|
+
File.file?("#{dir}/properties")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def Database.connect(uri)
|
|
24
|
+
case uri.scheme
|
|
25
|
+
when 'file'
|
|
26
|
+
new(uri.path)
|
|
27
|
+
when 'druby'
|
|
28
|
+
DRbObject.new_with_uri(uri.to_s)
|
|
29
|
+
else
|
|
30
|
+
raise InvalidScheme, "unknown database scheme: #{uri.scheme}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def Database.dummy(params = {})
|
|
35
|
+
db = new(nil)
|
|
36
|
+
db.properties['version'] = params['version']
|
|
37
|
+
db
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def initialize(prefix)
|
|
41
|
+
@prefix = prefix
|
|
42
|
+
@properties = nil
|
|
43
|
+
@in_transaction = false
|
|
44
|
+
@properties_dirty = false
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def dummy?
|
|
48
|
+
not @prefix
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
#
|
|
52
|
+
# Transaction
|
|
53
|
+
#
|
|
54
|
+
|
|
55
|
+
def transaction
|
|
56
|
+
@in_transaction = true
|
|
57
|
+
yield
|
|
58
|
+
return if dummy?
|
|
59
|
+
if @properties_dirty
|
|
60
|
+
save_properties 'properties', @properties
|
|
61
|
+
@properties_dirty = false
|
|
62
|
+
end
|
|
63
|
+
commit if dirty?
|
|
64
|
+
ensure
|
|
65
|
+
@in_transaction = false
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# abstract dirty?
|
|
69
|
+
# abstract clear_dirty
|
|
70
|
+
# abstract commit
|
|
71
|
+
|
|
72
|
+
def check_transaction
|
|
73
|
+
return if dummy?
|
|
74
|
+
unless @in_transaction
|
|
75
|
+
raise NotInTransaction, "database changed without transaction"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
private :check_transaction
|
|
79
|
+
|
|
80
|
+
#
|
|
81
|
+
# Properties
|
|
82
|
+
#
|
|
83
|
+
|
|
84
|
+
def properties
|
|
85
|
+
@properties ||=
|
|
86
|
+
begin
|
|
87
|
+
h = load_properties('properties')
|
|
88
|
+
h.delete 'source' if h['source'] and h['source'].strip.empty?
|
|
89
|
+
h
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def propkeys
|
|
94
|
+
properties().keys
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def propget(key)
|
|
98
|
+
properties()[key]
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def propset(key, value)
|
|
102
|
+
check_transaction
|
|
103
|
+
properties()[key] = value
|
|
104
|
+
@properties_dirty = true
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def encoding
|
|
108
|
+
propget('encoding')
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
#
|
|
112
|
+
# Direct File Access Layer: BitClust internal use only
|
|
113
|
+
#
|
|
114
|
+
|
|
115
|
+
def exist?(rel)
|
|
116
|
+
return false unless @prefix
|
|
117
|
+
File.exist?(realpath(rel))
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def entries(rel)
|
|
121
|
+
Dir.entries(realpath(rel))\
|
|
122
|
+
.reject {|ent| /\A[\.=]/ =~ ent }\
|
|
123
|
+
.map {|ent| decodeid(ent) }
|
|
124
|
+
rescue Errno::ENOENT
|
|
125
|
+
return []
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def makepath(rel)
|
|
129
|
+
FileUtils.mkdir_p realpath(rel)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def load_properties(rel)
|
|
133
|
+
h = {}
|
|
134
|
+
fopen(realpath(rel), 'r:UTF-8') {|f|
|
|
135
|
+
while line = f.gets
|
|
136
|
+
k, v = line.strip.split('=', 2)
|
|
137
|
+
break unless k
|
|
138
|
+
h[k] = v
|
|
139
|
+
end
|
|
140
|
+
h['source'] = f.read
|
|
141
|
+
}
|
|
142
|
+
h
|
|
143
|
+
rescue Errno::ENOENT
|
|
144
|
+
return {}
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def save_properties(rel, h)
|
|
148
|
+
source = h.delete('source')
|
|
149
|
+
atomic_write_open(rel) {|f|
|
|
150
|
+
h.each do |key, val|
|
|
151
|
+
f.puts "#{key}=#{val}"
|
|
152
|
+
end
|
|
153
|
+
f.puts
|
|
154
|
+
f.puts source
|
|
155
|
+
}
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def read(rel)
|
|
159
|
+
File.read(realpath(rel))
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def foreach_line(rel, &block)
|
|
163
|
+
File.foreach(realpath(rel), &block)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def atomic_write_open(rel, &block)
|
|
167
|
+
tmppath = realpath(rel) + '.writing'
|
|
168
|
+
fopen(tmppath, 'wb', &block)
|
|
169
|
+
File.rename tmppath, realpath(rel)
|
|
170
|
+
ensure
|
|
171
|
+
File.unlink tmppath rescue nil
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def realpath(rel)
|
|
175
|
+
"#{@prefix}/#{encodeid(rel)}"
|
|
176
|
+
end
|
|
177
|
+
private :realpath
|
|
178
|
+
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#
|
|
2
|
+
# bitclust/docentry.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
|
+
class DocEntry < Entry
|
|
16
|
+
|
|
17
|
+
def self.type_id
|
|
18
|
+
:doc
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def initialize(db, id)
|
|
22
|
+
super db
|
|
23
|
+
@id = id
|
|
24
|
+
init_properties
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
attr_reader :id
|
|
28
|
+
|
|
29
|
+
def ==(other)
|
|
30
|
+
@id == other.id
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
alias eql? ==
|
|
34
|
+
|
|
35
|
+
def hash
|
|
36
|
+
@id.hash
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def <=>(other)
|
|
40
|
+
@id.casecmp(other.id)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def name
|
|
44
|
+
libid2name(@id)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
alias label name
|
|
48
|
+
|
|
49
|
+
def labels
|
|
50
|
+
[label()]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def name?(n)
|
|
54
|
+
name() == n
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
persistent_properties {
|
|
58
|
+
property :title, 'String'
|
|
59
|
+
property :source, 'String'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
def inspect
|
|
63
|
+
"#<doc #{@id}>"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def classes
|
|
67
|
+
@db.classes
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def error_classes
|
|
71
|
+
classes.select{|c| c.ancestors.any?{|k| k.name == 'Exception' }}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def methods
|
|
75
|
+
@db.methods
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def libraries
|
|
79
|
+
@db.libraries
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
#
|
|
2
|
+
# bitclust/entry.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/compat'
|
|
11
|
+
require 'bitclust/nameutils'
|
|
12
|
+
require 'bitclust/exception'
|
|
13
|
+
|
|
14
|
+
module BitClust
|
|
15
|
+
|
|
16
|
+
class Entry
|
|
17
|
+
|
|
18
|
+
include NameUtils
|
|
19
|
+
|
|
20
|
+
def self.persistent_properties
|
|
21
|
+
@slots = []
|
|
22
|
+
yield
|
|
23
|
+
sep = ";"
|
|
24
|
+
module_eval(src = <<-End, __FILE__, __LINE__ + 1)
|
|
25
|
+
def init_properties
|
|
26
|
+
if saved?
|
|
27
|
+
#{@slots.map {|s| "@#{s.name} = nil" }.join(sep)}
|
|
28
|
+
@loaded = false
|
|
29
|
+
else
|
|
30
|
+
clear
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def clear
|
|
35
|
+
#{@slots.map {|s| "@#{s.name} = #{s.initial_value}" }.join(sep)}
|
|
36
|
+
@loaded = true
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def _set_properties(h)
|
|
40
|
+
#{@slots.map {|s| "@#{s.name} = #{s.deserializer}" }.join(sep)}
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def _get_properties
|
|
44
|
+
h = {}
|
|
45
|
+
#{@slots.map {|s| "h['#{s.name}'] = #{s.serializer}" }.join(sep)}
|
|
46
|
+
h
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def unload
|
|
50
|
+
clear
|
|
51
|
+
@loaded = false
|
|
52
|
+
end
|
|
53
|
+
End
|
|
54
|
+
@slots.each do |slot|
|
|
55
|
+
module_eval(<<-End, __FILE__, __LINE__ + 1)
|
|
56
|
+
def #{slot.name}
|
|
57
|
+
load unless @loaded
|
|
58
|
+
@#{slot.name}
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def #{slot.name}=(value)
|
|
62
|
+
load unless @loaded
|
|
63
|
+
@#{slot.name} = value
|
|
64
|
+
end
|
|
65
|
+
End
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def self.property(name, type)
|
|
70
|
+
@slots.push Property.new(name, type)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class Property
|
|
74
|
+
def initialize(name, type)
|
|
75
|
+
@name = name
|
|
76
|
+
@type = type
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
attr_reader :name
|
|
80
|
+
|
|
81
|
+
def initial_value
|
|
82
|
+
case @type
|
|
83
|
+
when 'String' then "'(uninitialized)'"
|
|
84
|
+
when 'Symbol' then "nil"
|
|
85
|
+
when 'bool' then "false"
|
|
86
|
+
when 'LibraryEntry' then "nil"
|
|
87
|
+
when 'ClassEntry' then "nil"
|
|
88
|
+
when 'MethodEntry' then "nil"
|
|
89
|
+
when '[String]' then "[]"
|
|
90
|
+
when '[LibraryEntry]' then "[]"
|
|
91
|
+
when '[ClassEntry]' then "[]"
|
|
92
|
+
when '[MethodEntry]' then "[]"
|
|
93
|
+
else
|
|
94
|
+
raise "must not happen: @type=#{@type.inspect}"
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def deserializer
|
|
99
|
+
case @type
|
|
100
|
+
when 'String' then "h['#{@name}']"
|
|
101
|
+
when 'Symbol' then "h['#{@name}'].intern"
|
|
102
|
+
when 'bool' then "h['#{@name}'] == 'true' ? true : false"
|
|
103
|
+
when 'LibraryEntry' then "restore_library(h['#{@name}'])"
|
|
104
|
+
when 'ClassEntry' then "restore_class(h['#{@name}'])"
|
|
105
|
+
when 'MethodEntry' then "restore_method(h['#{@name}'])"
|
|
106
|
+
when '[String]' then "h['#{@name}'].split(/,(?=.)/)"
|
|
107
|
+
when '[LibraryEntry]' then "restore_libraries(h['#{@name}'])"
|
|
108
|
+
when '[ClassEntry]' then "restore_classes(h['#{@name}'])"
|
|
109
|
+
when '[MethodEntry]' then "restore_methods(h['#{@name}'])"
|
|
110
|
+
else
|
|
111
|
+
raise "must not happen: @type=#{@type.inspect}"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def serializer
|
|
116
|
+
case @type
|
|
117
|
+
when 'String' then "@#{@name}"
|
|
118
|
+
when 'Symbol' then "@#{@name}.to_s"
|
|
119
|
+
when 'bool' then "@#{@name}.to_s"
|
|
120
|
+
when 'LibraryEntry' then "serialize_entry(@#{@name})"
|
|
121
|
+
when 'ClassEntry' then "serialize_entry(@#{@name})"
|
|
122
|
+
when 'MethodEntry' then "serialize_entry(@#{@name})"
|
|
123
|
+
when '[String]' then "@#{@name}.join(',')"
|
|
124
|
+
when '[LibraryEntry]' then "serialize_entries(@#{@name})"
|
|
125
|
+
when '[ClassEntry]' then "serialize_entries(@#{@name})"
|
|
126
|
+
when '[MethodEntry]' then "serialize_entries(@#{@name})"
|
|
127
|
+
else
|
|
128
|
+
raise "must not happen: @type=#{@type.inspect}"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
class << self
|
|
134
|
+
alias load new
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def initialize(db)
|
|
138
|
+
@db = db
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def type_id
|
|
142
|
+
self.class.type_id
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def loaded?
|
|
146
|
+
@loaded
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def encoding
|
|
150
|
+
@db.encoding
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def synopsis_source
|
|
154
|
+
source().split(/\n\n/, 2).first || ''
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def detail_source
|
|
158
|
+
source().split(/\n\n/, 2)[1] || ''
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def save
|
|
162
|
+
@db.save_properties objpath(), _get_properties()
|
|
163
|
+
rescue Errno::ENOENT
|
|
164
|
+
@db.makepath File.dirname(objpath())
|
|
165
|
+
retry
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
private
|
|
169
|
+
|
|
170
|
+
def load
|
|
171
|
+
_set_properties @db.load_properties(objpath())
|
|
172
|
+
@loaded = true
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def saved?
|
|
176
|
+
@db.exist?(objpath())
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def restore_library(id)
|
|
180
|
+
LibraryEntry.load(@db, id)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def restore_class(id)
|
|
184
|
+
id.empty? ? nil : ClassEntry.load(@db, id)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def restore_libraries(str)
|
|
188
|
+
restore_entries(str, LibraryEntry)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def restore_classes(str)
|
|
192
|
+
restore_entries(str, ClassEntry)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def restore_methods(str)
|
|
196
|
+
restore_entries(str, MethodEntry)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def restore_entries(str, klass)
|
|
200
|
+
str.split(',').map {|id| klass.load(@db, id) }
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def serialize_entry(x)
|
|
204
|
+
x ? x.id : ''
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def serialize_entries(xs)
|
|
208
|
+
xs.map {|x| x.id }.join(',')
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def objpath
|
|
212
|
+
"#{type_id()}/#{id()}"
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def path_string(path)
|
|
216
|
+
i = path.index(name())
|
|
217
|
+
(path[i..-1] + [name()]).join(' -> ')
|
|
218
|
+
end
|
|
219
|
+
private :path_string
|
|
220
|
+
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
end
|