metaruby 1.0.0.rc1
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.
- checksums.yaml +7 -0
- data/.gemtest +0 -0
- data/History.txt +1 -0
- data/Manifest.txt +40 -0
- data/README.md +318 -0
- data/Rakefile +39 -0
- data/lib/metaruby/class.rb +120 -0
- data/lib/metaruby/dsls/doc.rb +78 -0
- data/lib/metaruby/dsls/find_through_method_missing.rb +76 -0
- data/lib/metaruby/dsls.rb +2 -0
- data/lib/metaruby/gui/exception_view.rb +124 -0
- data/lib/metaruby/gui/html/button.rb +65 -0
- data/lib/metaruby/gui/html/collection.rb +103 -0
- data/lib/metaruby/gui/html/exception_view.css +8 -0
- data/lib/metaruby/gui/html/jquery.min.js +154 -0
- data/lib/metaruby/gui/html/jquery.selectfilter.js +65 -0
- data/lib/metaruby/gui/html/jquery.tagcloud.min.js +8 -0
- data/lib/metaruby/gui/html/jquery.tinysort.min.js +8 -0
- data/lib/metaruby/gui/html/list.rhtml +24 -0
- data/lib/metaruby/gui/html/page.css +55 -0
- data/lib/metaruby/gui/html/page.rb +283 -0
- data/lib/metaruby/gui/html/page.rhtml +13 -0
- data/lib/metaruby/gui/html/page_body.rhtml +17 -0
- data/lib/metaruby/gui/html/rock-website.css +694 -0
- data/lib/metaruby/gui/html.rb +16 -0
- data/lib/metaruby/gui/model_browser.rb +262 -0
- data/lib/metaruby/gui/model_selector.rb +266 -0
- data/lib/metaruby/gui/rendering_manager.rb +112 -0
- data/lib/metaruby/gui/ruby_constants_item_model.rb +253 -0
- data/lib/metaruby/gui.rb +9 -0
- data/lib/metaruby/inherited_attribute.rb +482 -0
- data/lib/metaruby/module.rb +158 -0
- data/lib/metaruby/registration.rb +157 -0
- data/lib/metaruby/test.rb +79 -0
- data/lib/metaruby.rb +17 -0
- data/manifest.xml +12 -0
- data/test/suite.rb +15 -0
- data/test/test_attributes.rb +323 -0
- data/test/test_class.rb +68 -0
- data/test/test_dsls.rb +49 -0
- data/test/test_module.rb +105 -0
- data/test/test_registration.rb +182 -0
- metadata +160 -0
@@ -0,0 +1,253 @@
|
|
1
|
+
module MetaRuby
|
2
|
+
module GUI
|
3
|
+
# A Qt item model that lists Ruby modules that match a given predicate
|
4
|
+
# (given at construction time)
|
5
|
+
class RubyConstantsItemModel < Qt::AbstractItemModel
|
6
|
+
ModuleInfo = Struct.new :id, :name, :this, :parent, :children, :row, :types, :full_name, :keyword_string, :path
|
7
|
+
TypeInfo = Struct.new :name, :priority, :color
|
8
|
+
|
9
|
+
attr_reader :predicate
|
10
|
+
attr_reader :id_to_module
|
11
|
+
attr_reader :filtered_out_modules
|
12
|
+
attr_reader :type_info
|
13
|
+
attr_accessor :title
|
14
|
+
attr_reader :object_paths
|
15
|
+
# @return [Set<Object>] a set of objects that should not be
|
16
|
+
# discovered
|
17
|
+
attr_reader :excludes
|
18
|
+
|
19
|
+
def initialize(type_info = Hash.new, &predicate)
|
20
|
+
super()
|
21
|
+
@predicate = predicate || proc { true }
|
22
|
+
@type_info = type_info
|
23
|
+
@title = "Model Browser"
|
24
|
+
@excludes = [Qt].to_set
|
25
|
+
|
26
|
+
@id_to_module = []
|
27
|
+
@filtered_out_modules = Set.new
|
28
|
+
@object_paths = Hash.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def reload
|
32
|
+
@id_to_module = []
|
33
|
+
@filtered_out_modules = Set.new
|
34
|
+
|
35
|
+
info = discover_module(Object)
|
36
|
+
info.id = id_to_module.size
|
37
|
+
info.name = title
|
38
|
+
update_module_type_info(info)
|
39
|
+
info.row = 0
|
40
|
+
id_to_module << info
|
41
|
+
|
42
|
+
@object_paths = Hash.new
|
43
|
+
generate_paths(object_paths, info, "")
|
44
|
+
|
45
|
+
emit dataChanged(Qt::ModelIndex.new, Qt::ModelIndex.new)
|
46
|
+
end
|
47
|
+
|
48
|
+
def generate_paths(paths, info, current)
|
49
|
+
info.children.each do |child|
|
50
|
+
child_uri = current + '/' + child.name
|
51
|
+
paths[child.this] = child_uri
|
52
|
+
generate_paths(paths, child, child_uri)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def update_module_type_info(info)
|
57
|
+
types = info.types.to_set
|
58
|
+
info.children.each do |child_info|
|
59
|
+
types |= child_info.types.to_set
|
60
|
+
end
|
61
|
+
info.types = types.to_a.sort_by do |type|
|
62
|
+
type_info[type].priority
|
63
|
+
end.reverse
|
64
|
+
end
|
65
|
+
|
66
|
+
def discover_module(mod, stack = Array.new)
|
67
|
+
return if excludes.include?(mod)
|
68
|
+
stack.push mod
|
69
|
+
|
70
|
+
children = []
|
71
|
+
mod_info = ModuleInfo.new(nil, nil, mod, nil, children, nil, Set.new)
|
72
|
+
|
73
|
+
is_needed = (mod.kind_of?(Class) && mod == Object) || predicate.call(mod)
|
74
|
+
|
75
|
+
if mod.respond_to?(:constants)
|
76
|
+
children_modules = begin mod.constants
|
77
|
+
rescue TypeError
|
78
|
+
puts "cannot discover module #{mod}"
|
79
|
+
[]
|
80
|
+
end
|
81
|
+
|
82
|
+
children_modules = children_modules.map do |child_name|
|
83
|
+
next if !mod.const_defined_here?(child_name)
|
84
|
+
# Ruby issues a warning when one tries to access Config
|
85
|
+
# (it has been deprecated in favor of RbConfig). Ignore
|
86
|
+
# it explicitly
|
87
|
+
next if mod == Object && child_name == :Config
|
88
|
+
next if mod.autoload?(child_name)
|
89
|
+
child_mod = begin mod.const_get(child_name)
|
90
|
+
rescue LoadError
|
91
|
+
# Handle autoload errors
|
92
|
+
end
|
93
|
+
next if !child_mod
|
94
|
+
next if filtered_out_modules.include?(child_mod)
|
95
|
+
next if stack.include?(child_mod)
|
96
|
+
[child_name.to_s, child_mod]
|
97
|
+
end.compact.sort_by(&:first)
|
98
|
+
|
99
|
+
children_modules.each do |child_name, child_mod|
|
100
|
+
if info = discover_module(child_mod, stack)
|
101
|
+
info.id = id_to_module.size
|
102
|
+
info.name = child_name.to_s
|
103
|
+
info.parent = mod_info
|
104
|
+
info.row = children.size
|
105
|
+
children << info
|
106
|
+
id_to_module << info
|
107
|
+
else
|
108
|
+
filtered_out_modules << child_mod
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
if is_needed
|
114
|
+
klass = if mod.respond_to?(:ancestors) then mod
|
115
|
+
else mod.class
|
116
|
+
end
|
117
|
+
|
118
|
+
current_priority = nil
|
119
|
+
klass.ancestors.each do |ancestor|
|
120
|
+
if info = type_info[ancestor]
|
121
|
+
current_priority ||= info.priority
|
122
|
+
if current_priority < info.priority
|
123
|
+
mod_info.types.clear
|
124
|
+
mod_info.types << ancestor
|
125
|
+
current_priority = info.priority
|
126
|
+
elsif current_priority == info.priority
|
127
|
+
mod_info.types << ancestor
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
update_module_type_info(mod_info)
|
134
|
+
|
135
|
+
if !children.empty? || is_needed
|
136
|
+
mod_info
|
137
|
+
end
|
138
|
+
ensure stack.pop
|
139
|
+
end
|
140
|
+
|
141
|
+
def headerData(section, orientation, role)
|
142
|
+
if role == Qt::DisplayRole && section == 0
|
143
|
+
Qt::Variant.new(title)
|
144
|
+
else Qt::Variant.new
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def compute_full_name(info)
|
149
|
+
if name = info.full_name
|
150
|
+
return name
|
151
|
+
else
|
152
|
+
full_name = []
|
153
|
+
current = info
|
154
|
+
while current.parent
|
155
|
+
full_name << current.name
|
156
|
+
current = current.parent
|
157
|
+
end
|
158
|
+
info.full_name = full_name.reverse
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def compute_path(info)
|
163
|
+
if path = info.path
|
164
|
+
return path
|
165
|
+
else
|
166
|
+
full_name = compute_full_name(info)
|
167
|
+
info.path = ("/" + full_name.map(&:downcase).join("/"))
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def compute_keyword_string(info)
|
172
|
+
if keywords = info.keyword_string
|
173
|
+
return keywords
|
174
|
+
else
|
175
|
+
types = info.types.map do |type|
|
176
|
+
type_info[type].name
|
177
|
+
end.sort.join(",")
|
178
|
+
paths = [compute_path(info)]
|
179
|
+
paths.concat info.children.map { |child| compute_path(child) }
|
180
|
+
info.keyword_string = "#{types};#{paths.join(",")}"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def data(index, role)
|
185
|
+
if info = info_from_index(index)
|
186
|
+
if role == Qt::DisplayRole
|
187
|
+
return Qt::Variant.new(info.name)
|
188
|
+
elsif role == Qt::EditRole
|
189
|
+
return Qt::Variant.new(compute_full_name(info).join("/"))
|
190
|
+
elsif role == Qt::UserRole
|
191
|
+
return Qt::Variant.new(compute_keyword_string(info))
|
192
|
+
end
|
193
|
+
end
|
194
|
+
return Qt::Variant.new
|
195
|
+
end
|
196
|
+
|
197
|
+
def index(row, column, parent)
|
198
|
+
if info = info_from_index(parent)
|
199
|
+
if child_info = info.children[row]
|
200
|
+
return create_index(row, column, child_info.id)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
Qt::ModelIndex.new
|
204
|
+
end
|
205
|
+
|
206
|
+
def parent(child)
|
207
|
+
if info = info_from_index(child)
|
208
|
+
if info.parent
|
209
|
+
return create_index(info.parent.row, 0, info.parent.id)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
Qt::ModelIndex.new
|
213
|
+
end
|
214
|
+
|
215
|
+
def rowCount(parent)
|
216
|
+
if info = info_from_index(parent)
|
217
|
+
info.children.size
|
218
|
+
else 0
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def columnCount(parent)
|
223
|
+
return 1
|
224
|
+
end
|
225
|
+
|
226
|
+
def info_from_index(index)
|
227
|
+
if !index.valid?
|
228
|
+
return id_to_module.last
|
229
|
+
else
|
230
|
+
id_to_module[index.internal_id >> 1]
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def find_index_by_model(model)
|
235
|
+
if info = id_to_module.find { |info| info.this == model }
|
236
|
+
return create_index(info.row, 0, info.id)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def find_index_by_path(*path)
|
241
|
+
current = id_to_module.last
|
242
|
+
path.each do |name|
|
243
|
+
current = id_to_module.find do |info|
|
244
|
+
info.name == name && info.parent == current
|
245
|
+
end
|
246
|
+
return if !current
|
247
|
+
end
|
248
|
+
create_index(current.row, 0, current.id)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
data/lib/metaruby/gui.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'Qt4'
|
2
|
+
require 'qtwebkit'
|
3
|
+
require 'kramdown'
|
4
|
+
require 'metaruby/gui/html'
|
5
|
+
require 'metaruby/gui/ruby_constants_item_model'
|
6
|
+
require 'metaruby/gui/rendering_manager'
|
7
|
+
require 'metaruby/gui/model_browser'
|
8
|
+
require 'metaruby/gui/model_selector'
|
9
|
+
require 'metaruby/gui/exception_view'
|