metaruby 1.0.0.rc1 → 1.0.0.rc2
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 +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +3 -0
- data/Rakefile +9 -36
- data/{.gemtest → bin/.gitattributes} +0 -0
- data/lib/metaruby/class.rb +5 -0
- data/lib/metaruby/gui/exception_view.rb +58 -15
- data/lib/metaruby/gui/html/collection.rb +10 -3
- data/lib/metaruby/gui/html/fragment.rhtml +5 -0
- data/lib/metaruby/gui/html/list.rhtml +1 -1
- data/lib/metaruby/gui/html/page.css +2 -0
- data/lib/metaruby/gui/html/page.rb +39 -19
- data/lib/metaruby/gui/html/page.rhtml +4 -1
- data/lib/metaruby/gui/html/page_body.rhtml +3 -10
- data/lib/metaruby/gui/model_browser.rb +55 -24
- data/lib/metaruby/gui/model_selector.rb +6 -6
- data/lib/metaruby/gui/ruby_constants_item_model.rb +12 -3
- data/lib/metaruby/inherited_attribute.rb +6 -0
- data/lib/metaruby/module.rb +2 -2
- data/lib/metaruby/registration.rb +3 -3
- data/lib/metaruby/test.rb +4 -20
- data/lib/metaruby/version.rb +3 -0
- data/lib/yard-metaruby.rb +117 -0
- data/manifest.xml +1 -4
- data/metaruby.gemspec +26 -0
- metadata +50 -48
- data/History.txt +0 -1
- data/Manifest.txt +0 -40
- data/test/suite.rb +0 -15
- data/test/test_attributes.rb +0 -323
- data/test/test_class.rb +0 -68
- data/test/test_dsls.rb +0 -49
- data/test/test_module.rb +0 -105
- data/test/test_registration.rb +0 -182
@@ -5,9 +5,12 @@
|
|
5
5
|
<link rel="stylesheet" href="<%= prefix %><%= File.join(ressource_dir, 'page.css') %>" type="text/css" />
|
6
6
|
<script type="text/javascript" src="<%= prefix %><%= File.join(ressource_dir, 'jquery.min.js') %>"></script>
|
7
7
|
<script type="text/javascript" src="<%= prefix %><%= File.join(ressource_dir, 'jquery.selectfilter.js') %>"></script>
|
8
|
+
<% javascript.each do |js| %>
|
9
|
+
<script type="text/javascript" src="<%= prefix %><%= File.expand_path(js, ressource_dir) %>"></script>
|
10
|
+
<% end %>
|
8
11
|
<title><%= page_name %></title>
|
9
12
|
</html>
|
10
13
|
<body>
|
11
|
-
<%= html_body(:
|
14
|
+
<%= html_body(ressource_dir: ressource_dir) %>
|
12
15
|
</body>
|
13
16
|
|
@@ -1,17 +1,10 @@
|
|
1
1
|
<% if title %>
|
2
|
-
<h1><%= title %></h1>
|
2
|
+
<h1><%= title %></h1>
|
3
3
|
<% end %>
|
4
4
|
<% fragments.each do |fragment| %>
|
5
|
-
|
6
|
-
<h2><%= fragment.title %></h2>
|
7
|
-
<% end %>
|
8
|
-
<%= HTML.render_button_bar(fragment.buttons) %>
|
9
|
-
<% if fragment.id %>
|
10
|
-
<div id="<%= fragment.id %>">
|
11
|
-
<% end %>
|
12
|
-
<%= fragment.html %>
|
5
|
+
<%= html_fragment(fragment, ressource_dir: ressource_dir) %>
|
13
6
|
<% if fragment.id %>
|
14
|
-
</div>
|
7
|
+
</div>
|
15
8
|
<% end %>
|
16
9
|
<% end %>
|
17
10
|
|
@@ -32,8 +32,6 @@ module MetaRuby
|
|
32
32
|
# @return [ExceptionView] view that allows to display errors to the
|
33
33
|
# user
|
34
34
|
attr_reader :exception_view
|
35
|
-
# @return [Qt::PushButton] button that causes model reloading
|
36
|
-
attr_reader :btn_reload_models
|
37
35
|
# @return [RenderingManager] the object that manages all the
|
38
36
|
# rendering objects available
|
39
37
|
attr_reader :manager
|
@@ -46,12 +44,21 @@ module MetaRuby
|
|
46
44
|
attr_reader :history
|
47
45
|
# @return [Integer] the index of the current link in the history
|
48
46
|
attr_reader :history_index
|
47
|
+
# @return [Qt::BoxLayout] the main layout
|
48
|
+
attr_reader :main_layout
|
49
|
+
|
50
|
+
# @return [Qt::Splitter] the toplevel splitter (between model
|
51
|
+
# browser and exception view)
|
52
|
+
attr_reader :vertical_splitter
|
53
|
+
# @return [Qt::Splitter] the horizontal splitter between the model browser and
|
54
|
+
# the model view
|
55
|
+
attr_reader :central_splitter
|
49
56
|
|
50
57
|
# A Page object with a #link_to method that is suitable for the
|
51
58
|
# model browser
|
52
59
|
class Page < HTML::Page
|
53
60
|
def uri_for(object)
|
54
|
-
if (obj_name = object.name) && (obj_name =~ /^[\w:]+$/)
|
61
|
+
if object.respond_to?(:name) && (obj_name = object.name) && (obj_name =~ /^[\w:]+$/)
|
55
62
|
path = obj_name.split("::")
|
56
63
|
"/" + path.join("/")
|
57
64
|
else super
|
@@ -60,36 +67,52 @@ module MetaRuby
|
|
60
67
|
end
|
61
68
|
|
62
69
|
|
63
|
-
def initialize(main = nil)
|
64
|
-
super
|
70
|
+
def initialize(main = nil, exception_view: nil)
|
71
|
+
super(main)
|
72
|
+
|
73
|
+
@available_renderers = Hash.new
|
74
|
+
@registered_exceptions = Array.new
|
75
|
+
|
76
|
+
@history = Array.new
|
77
|
+
@history_index = -1
|
65
78
|
|
66
79
|
@manager = RenderingManager.new
|
67
80
|
|
68
|
-
main_layout = Qt::VBoxLayout.new(self)
|
81
|
+
@main_layout = Qt::VBoxLayout.new(self)
|
82
|
+
@vertical_splitter = Qt::Splitter.new(Qt::Vertical, self)
|
83
|
+
main_layout.add_widget(vertical_splitter)
|
69
84
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
central_layout.add_widget(splitter)
|
76
|
-
@exception_view = ExceptionView.new
|
77
|
-
main_layout.add_widget(exception_view, 1)
|
85
|
+
@central_splitter = Qt::Splitter.new(vertical_splitter)
|
86
|
+
@exception_view = (exception_view ||= ExceptionView.new)
|
87
|
+
exception_view.parent = vertical_splitter
|
88
|
+
connect(exception_view, SIGNAL('fileOpenClicked(const QUrl&)'), self, SLOT('fileOpenClicked(const QUrl&)'))
|
89
|
+
add_central_widgets(central_splitter)
|
78
90
|
|
79
|
-
|
80
|
-
|
91
|
+
vertical_splitter.add_widget(central_splitter)
|
92
|
+
vertical_splitter.add_widget(exception_view)
|
93
|
+
setTabOrder(model_selector, display)
|
81
94
|
|
82
|
-
@btn_reload_models = Qt::PushButton.new("Reload", self)
|
83
|
-
menu_layout.add_widget(btn_reload_models)
|
84
|
-
menu_layout.add_stretch(1)
|
85
95
|
update_exceptions
|
96
|
+
end
|
86
97
|
|
87
|
-
|
88
|
-
|
98
|
+
def restore_from_settings(settings)
|
99
|
+
%w{central_splitter vertical_splitter}.each do |object_name|
|
100
|
+
sizes = settings.value(object_name)
|
101
|
+
if !sizes.null?
|
102
|
+
sizes = sizes.to_list.map do |obj|
|
103
|
+
obj.to_int
|
104
|
+
end
|
105
|
+
send(object_name).sizes = sizes
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
89
109
|
|
90
|
-
|
91
|
-
|
92
|
-
|
110
|
+
def save_to_settings(settings)
|
111
|
+
%w{central_splitter vertical_splitter}.each do |object_name|
|
112
|
+
sizes = send(object_name).sizes
|
113
|
+
sizes = sizes.map { |o| Qt::Variant.new(o) }
|
114
|
+
settings.set_value(object_name, Qt::Variant.new(sizes))
|
115
|
+
end
|
93
116
|
end
|
94
117
|
|
95
118
|
# Update the model selector after {register_type} got called
|
@@ -171,10 +194,13 @@ module MetaRuby
|
|
171
194
|
end
|
172
195
|
end
|
173
196
|
connect(page, SIGNAL('updated()'), self, SLOT('update_exceptions()'))
|
197
|
+
connect(page, SIGNAL('fileOpenClicked(const QUrl&)'), self, SLOT('fileOpenClicked(const QUrl&)'))
|
174
198
|
connect(manager, SIGNAL('updated()'), self, SLOT('update_exceptions()'))
|
175
199
|
@page = page
|
176
200
|
end
|
177
201
|
|
202
|
+
signals 'fileOpenClicked(const QUrl&)'
|
203
|
+
|
178
204
|
# Call to render the given model
|
179
205
|
#
|
180
206
|
# @param [Model] mod the model that should be rendered
|
@@ -257,6 +283,11 @@ module MetaRuby
|
|
257
283
|
else select_by_module(h)
|
258
284
|
end
|
259
285
|
end
|
286
|
+
|
287
|
+
# Update the model list
|
288
|
+
def reload
|
289
|
+
model_selector.reload
|
290
|
+
end
|
260
291
|
end
|
261
292
|
end
|
262
293
|
end
|
@@ -19,6 +19,9 @@ module MetaRuby
|
|
19
19
|
super
|
20
20
|
|
21
21
|
@type_info = Hash.new
|
22
|
+
@browser_model = RubyConstantsItemModel.new(type_info) do |mod|
|
23
|
+
model?(mod)
|
24
|
+
end
|
22
25
|
@type_filters = Hash.new
|
23
26
|
|
24
27
|
layout = Qt::VBoxLayout.new(self)
|
@@ -141,6 +144,7 @@ module MetaRuby
|
|
141
144
|
model_filter.dynamic_sort_filter = true
|
142
145
|
model_filter.filter_role = Qt::UserRole
|
143
146
|
model_list.model = model_filter
|
147
|
+
model_filter.source_model = browser_model
|
144
148
|
|
145
149
|
@filter_box = Qt::LineEdit.new(self)
|
146
150
|
filter_box.connect(SIGNAL('textChanged(QString)')) do |text|
|
@@ -175,11 +179,7 @@ module MetaRuby
|
|
175
179
|
end
|
176
180
|
end
|
177
181
|
|
178
|
-
@browser_model = RubyConstantsItemModel.new(type_info) do |mod|
|
179
|
-
model?(mod)
|
180
|
-
end
|
181
182
|
browser_model.reload
|
182
|
-
model_filter.source_model = browser_model
|
183
183
|
|
184
184
|
if current_path && !select_by_path(*current_path)
|
185
185
|
select_by_module(current_module)
|
@@ -229,7 +229,7 @@ module MetaRuby
|
|
229
229
|
def select_by_path(*path)
|
230
230
|
if index = browser_model.find_index_by_path(*path)
|
231
231
|
index = map_index_from_source(index)
|
232
|
-
model_list.
|
232
|
+
model_list.current_index = index
|
233
233
|
true
|
234
234
|
end
|
235
235
|
end
|
@@ -242,7 +242,7 @@ module MetaRuby
|
|
242
242
|
def select_by_module(model)
|
243
243
|
if index = browser_model.find_index_by_model(model)
|
244
244
|
index = map_index_from_source(index)
|
245
|
-
model_list.
|
245
|
+
model_list.current_index = index
|
246
246
|
true
|
247
247
|
end
|
248
248
|
end
|
@@ -29,6 +29,7 @@ module MetaRuby
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def reload
|
32
|
+
begin_reset_model
|
32
33
|
@id_to_module = []
|
33
34
|
@filtered_out_modules = Set.new
|
34
35
|
|
@@ -41,8 +42,12 @@ module MetaRuby
|
|
41
42
|
|
42
43
|
@object_paths = Hash.new
|
43
44
|
generate_paths(object_paths, info, "")
|
45
|
+
ensure
|
46
|
+
end_reset_model
|
47
|
+
end
|
44
48
|
|
45
|
-
|
49
|
+
def root_info
|
50
|
+
id_to_module.last
|
46
51
|
end
|
47
52
|
|
48
53
|
def generate_paths(paths, info, current)
|
@@ -176,7 +181,7 @@ module MetaRuby
|
|
176
181
|
type_info[type].name
|
177
182
|
end.sort.join(",")
|
178
183
|
paths = [compute_path(info)]
|
179
|
-
paths.concat info.children.map { |child|
|
184
|
+
paths.concat info.children.map { |child| compute_keyword_string(child) }
|
180
185
|
info.keyword_string = "#{types};#{paths.join(",")}"
|
181
186
|
end
|
182
187
|
end
|
@@ -205,7 +210,7 @@ module MetaRuby
|
|
205
210
|
|
206
211
|
def parent(child)
|
207
212
|
if info = info_from_index(child)
|
208
|
-
if info.parent
|
213
|
+
if info.parent && info.parent != root_info
|
209
214
|
return create_index(info.parent.row, 0, info.parent.id)
|
210
215
|
end
|
211
216
|
end
|
@@ -239,6 +244,10 @@ module MetaRuby
|
|
239
244
|
|
240
245
|
def find_index_by_path(*path)
|
241
246
|
current = id_to_module.last
|
247
|
+
if path.first == current.name
|
248
|
+
path.shift
|
249
|
+
end
|
250
|
+
|
242
251
|
path.each do |name|
|
243
252
|
current = id_to_module.find do |info|
|
244
253
|
info.name == name && info.parent == current
|
data/lib/metaruby/module.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'utilrb/value_set'
|
2
1
|
require 'utilrb/module/const_defined_here_p'
|
2
|
+
|
3
3
|
module MetaRuby
|
4
4
|
# Extend in modules that are used as models
|
5
5
|
#
|
@@ -150,7 +150,7 @@ module MetaRuby
|
|
150
150
|
self.supermodel = model.supermodel
|
151
151
|
end
|
152
152
|
self.supermodel.register_submodel(self)
|
153
|
-
self.parent_models
|
153
|
+
self.parent_models.merge(model.parent_models)
|
154
154
|
self.parent_models << model
|
155
155
|
end
|
156
156
|
end
|
@@ -21,7 +21,7 @@ module MetaRuby
|
|
21
21
|
# @return [Boolean]
|
22
22
|
attr_predicate :permanent_model?, true
|
23
23
|
|
24
|
-
# [Set] the set of models that are children of this one
|
24
|
+
# @return [Set] the set of models that are children of this one
|
25
25
|
attribute(:submodels) { Set.new }
|
26
26
|
|
27
27
|
# Returns the model that is parent of this one
|
@@ -141,10 +141,10 @@ module MetaRuby
|
|
141
141
|
#
|
142
142
|
# This is usually not called directly. Use #clear_submodels instead
|
143
143
|
#
|
144
|
-
# @param [
|
144
|
+
# @param [ValueSet] set the set of submodels to remove
|
145
145
|
def deregister_submodels(set)
|
146
146
|
current_size = submodels.size
|
147
|
-
submodels.subtract(set)
|
147
|
+
submodels.subtract(set.to_value_set)
|
148
148
|
if m = supermodel
|
149
149
|
m.deregister_submodels(set)
|
150
150
|
end
|
data/lib/metaruby/test.rb
CHANGED
@@ -3,7 +3,9 @@
|
|
3
3
|
if ENV['TEST_ENABLE_COVERAGE'] == '1'
|
4
4
|
begin
|
5
5
|
require 'simplecov'
|
6
|
-
SimpleCov.start
|
6
|
+
SimpleCov.start do
|
7
|
+
add_filter "test"
|
8
|
+
end
|
7
9
|
rescue LoadError
|
8
10
|
require 'metaruby'
|
9
11
|
MetaRuby.warn "coverage is disabled because the 'simplecov' gem cannot be loaded"
|
@@ -16,7 +18,7 @@ end
|
|
16
18
|
require 'metaruby'
|
17
19
|
require 'minitest/autorun'
|
18
20
|
require 'minitest/spec'
|
19
|
-
require 'flexmock/
|
21
|
+
require 'flexmock/minitest'
|
20
22
|
|
21
23
|
if ENV['TEST_ENABLE_PRY'] != '0'
|
22
24
|
begin
|
@@ -41,33 +43,15 @@ module MetaRuby
|
|
41
43
|
# end
|
42
44
|
#
|
43
45
|
module SelfTest
|
44
|
-
if defined? FlexMock
|
45
|
-
include FlexMock::ArgumentTypes
|
46
|
-
include FlexMock::MockContainer
|
47
|
-
end
|
48
|
-
|
49
46
|
def setup
|
50
47
|
# Setup code for all the tests
|
51
48
|
end
|
52
49
|
|
53
50
|
def teardown
|
54
|
-
if defined? FlexMock
|
55
|
-
flexmock_teardown
|
56
|
-
end
|
57
|
-
# Teardown code for all the tests
|
58
51
|
end
|
59
52
|
end
|
60
53
|
end
|
61
54
|
|
62
|
-
# Workaround a problem with flexmock and minitest not being compatible with each
|
63
|
-
# other (currently). See github.com/jimweirich/flexmock/issues/15.
|
64
|
-
if defined?(FlexMock) && !FlexMock::TestUnitFrameworkAdapter.method_defined?(:assertions)
|
65
|
-
class FlexMock::TestUnitFrameworkAdapter
|
66
|
-
attr_accessor :assertions
|
67
|
-
end
|
68
|
-
FlexMock.framework_adapter.assertions = 0
|
69
|
-
end
|
70
|
-
|
71
55
|
module Minitest
|
72
56
|
class Spec
|
73
57
|
include MetaRuby::SelfTest
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'pp'
|
2
|
+
module MetaRuby
|
3
|
+
module YARD
|
4
|
+
include ::YARD
|
5
|
+
class InheritedAttributeHandler < YARD::Handlers::Ruby::AttributeHandler
|
6
|
+
handles method_call(:inherited_attribute)
|
7
|
+
namespace_only
|
8
|
+
|
9
|
+
def self.process(handler, name, attr_name, is_map, key_name = nil, return_type = nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
def process
|
13
|
+
name = statement.parameters[0].jump(:tstring_content, :ident).source
|
14
|
+
if statement.parameters.size == 4
|
15
|
+
attr_name = statement.parameters[1].jump(:tstring_content, :ident).source
|
16
|
+
else
|
17
|
+
attr_name = name
|
18
|
+
end
|
19
|
+
options = statement.parameters.jump(:assoc)
|
20
|
+
|
21
|
+
is_map = false
|
22
|
+
if options != statement.parameters
|
23
|
+
key = options[0].jump(:ident).source
|
24
|
+
value = options[1].jump(:ident).source
|
25
|
+
if key == "map" && value == "true"
|
26
|
+
is_map = true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
key_type, value_type = nil
|
31
|
+
|
32
|
+
object = YARD::CodeObjects::MethodObject.new(namespace, attr_name, scope) do |o|
|
33
|
+
o.dynamic = true
|
34
|
+
o.aliases << "self_#{name}"
|
35
|
+
end
|
36
|
+
register(object)
|
37
|
+
key_name ||=
|
38
|
+
if object.docstring.has_tag?('key_name')
|
39
|
+
object.docstring.tag('key_name').text
|
40
|
+
else
|
41
|
+
'key'
|
42
|
+
end
|
43
|
+
return_type ||=
|
44
|
+
if object.docstring.has_tag?('return')
|
45
|
+
object.docstring.tag('return').types.first
|
46
|
+
elsif is_map
|
47
|
+
'Hash<Object,Object>'
|
48
|
+
else
|
49
|
+
'Array<Object>'
|
50
|
+
end
|
51
|
+
if return_type =~ /^\w+\<(.*)\>$/
|
52
|
+
if is_map
|
53
|
+
key_type, value_type = $1.split(',')
|
54
|
+
else
|
55
|
+
value_type = $1
|
56
|
+
end
|
57
|
+
else
|
58
|
+
key_type = "Object"
|
59
|
+
value_type = "Object"
|
60
|
+
end
|
61
|
+
|
62
|
+
object = YARD::CodeObjects::MethodObject.new(namespace, "all_#{name}", scope)
|
63
|
+
object.dynamic = true
|
64
|
+
register(object)
|
65
|
+
object.docstring.replace("The union, along the class hierarchy, of all the values stored in #{name}\n@return [Array<#{value_type}>]")
|
66
|
+
|
67
|
+
if is_map
|
68
|
+
object = YARD::CodeObjects::MethodObject.new(namespace, "find_#{name}", scope)
|
69
|
+
object.dynamic = true
|
70
|
+
register(object)
|
71
|
+
object.parameters << [key_name]
|
72
|
+
object.docstring.replace("
|
73
|
+
Looks for objects registered in #{name} under the given key, and returns the first one in the ancestor chain
|
74
|
+
(i.e. the one tha thas been registered in the most specialized class)
|
75
|
+
|
76
|
+
@return [#{value_type},nil] the found object, or nil if none is registered under that key")
|
77
|
+
|
78
|
+
object = YARD::CodeObjects::MethodObject.new(namespace, "has_#{name}?", scope)
|
79
|
+
object.dynamic = true
|
80
|
+
register(object)
|
81
|
+
object.parameters << [key_name]
|
82
|
+
object.docstring.replace("Returns true if an object is registered in #{name} anywhere in the class hierarchy\n@return [Boolean]")
|
83
|
+
object.signature = "def has_#{name}?(key)"
|
84
|
+
|
85
|
+
object = YARD::CodeObjects::MethodObject.new(namespace, "each_#{name}", scope)
|
86
|
+
object.dynamic = true
|
87
|
+
register(object)
|
88
|
+
object.parameters << [key_name, "nil"] << ["uniq", "true"]
|
89
|
+
object.docstring.replace("
|
90
|
+
@overload each_#{name}(#{key_name}, uniq = true)
|
91
|
+
Enumerates all objects registered in #{name} under the given key
|
92
|
+
@yield [element]
|
93
|
+
@yieldparam [#{value_type}] element
|
94
|
+
@overload each_#{name}(nil, uniq = true)
|
95
|
+
Enumerates all objects registered in #{name}
|
96
|
+
@yield [#{key_name}, element]
|
97
|
+
@yieldparam [#{key_type}] #{key_name}
|
98
|
+
@yieldparam [#{value_type}] element
|
99
|
+
")
|
100
|
+
else
|
101
|
+
object = YARD::CodeObjects::MethodObject.new(namespace, "each_#{name}", scope)
|
102
|
+
object.dynamic = true
|
103
|
+
register(object)
|
104
|
+
object.docstring.replace("Enumerates all objects registered in #{name}\n@return []\n@yield [element]\n@yieldparam [#{value_type}] element")
|
105
|
+
end
|
106
|
+
|
107
|
+
if is_map
|
108
|
+
return key_type, value_type
|
109
|
+
else
|
110
|
+
return value_type
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
YARD::Tags::Library.define_tag("Key for inherited_attribute(_, :map => true)", :key_name)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|