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.
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'