metaruby 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/History.txt +1 -0
  4. data/Manifest.txt +40 -0
  5. data/README.md +318 -0
  6. data/Rakefile +39 -0
  7. data/lib/metaruby/class.rb +120 -0
  8. data/lib/metaruby/dsls/doc.rb +78 -0
  9. data/lib/metaruby/dsls/find_through_method_missing.rb +76 -0
  10. data/lib/metaruby/dsls.rb +2 -0
  11. data/lib/metaruby/gui/exception_view.rb +124 -0
  12. data/lib/metaruby/gui/html/button.rb +65 -0
  13. data/lib/metaruby/gui/html/collection.rb +103 -0
  14. data/lib/metaruby/gui/html/exception_view.css +8 -0
  15. data/lib/metaruby/gui/html/jquery.min.js +154 -0
  16. data/lib/metaruby/gui/html/jquery.selectfilter.js +65 -0
  17. data/lib/metaruby/gui/html/jquery.tagcloud.min.js +8 -0
  18. data/lib/metaruby/gui/html/jquery.tinysort.min.js +8 -0
  19. data/lib/metaruby/gui/html/list.rhtml +24 -0
  20. data/lib/metaruby/gui/html/page.css +55 -0
  21. data/lib/metaruby/gui/html/page.rb +283 -0
  22. data/lib/metaruby/gui/html/page.rhtml +13 -0
  23. data/lib/metaruby/gui/html/page_body.rhtml +17 -0
  24. data/lib/metaruby/gui/html/rock-website.css +694 -0
  25. data/lib/metaruby/gui/html.rb +16 -0
  26. data/lib/metaruby/gui/model_browser.rb +262 -0
  27. data/lib/metaruby/gui/model_selector.rb +266 -0
  28. data/lib/metaruby/gui/rendering_manager.rb +112 -0
  29. data/lib/metaruby/gui/ruby_constants_item_model.rb +253 -0
  30. data/lib/metaruby/gui.rb +9 -0
  31. data/lib/metaruby/inherited_attribute.rb +482 -0
  32. data/lib/metaruby/module.rb +158 -0
  33. data/lib/metaruby/registration.rb +157 -0
  34. data/lib/metaruby/test.rb +79 -0
  35. data/lib/metaruby.rb +17 -0
  36. data/manifest.xml +12 -0
  37. data/test/suite.rb +15 -0
  38. data/test/test_attributes.rb +323 -0
  39. data/test/test_class.rb +68 -0
  40. data/test/test_dsls.rb +49 -0
  41. data/test/test_module.rb +105 -0
  42. data/test/test_registration.rb +182 -0
  43. 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
+
@@ -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'