metaruby 1.0.0.rc1 → 1.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|