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.
@@ -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(:ressource_dir => ressource_dir) %>
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
- <% if fragment.title %>
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
- menu_layout = Qt::HBoxLayout.new
71
- main_layout.add_layout(menu_layout)
72
- central_layout = Qt::HBoxLayout.new
73
- main_layout.add_layout(central_layout, 3)
74
- splitter = Qt::Splitter.new(self)
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
- @available_renderers = Hash.new
80
- @registered_exceptions = Array.new
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
- @history = Array.new
88
- @history_index = -1
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
- add_central_widgets(splitter)
91
- setTabOrder(model_selector, display)
92
- setTabOrder(display, btn_reload_models)
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.selection_model.set_current_index(index, Qt::ItemSelectionModel::ClearAndSelect)
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.selection_model.set_current_index(index, Qt::ItemSelectionModel::ClearAndSelect)
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
- emit dataChanged(Qt::ModelIndex.new, Qt::ModelIndex.new)
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| compute_path(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
@@ -280,6 +280,12 @@ module MetaRuby
280
280
  false
281
281
  end
282
282
  EOF
283
+ else
284
+ class_eval <<-EOF, __FILE__, __LINE__+1
285
+ def has_#{name}?(key)
286
+ each_#{name}.any? { |obj| obj == key }
287
+ end
288
+ EOF
283
289
  end
284
290
 
285
291
  class_eval <<-EOF, __FILE__, __LINE__+1
@@ -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 |= model.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 [Set] set the set of submodels to remove
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
@@ -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/test_unit'
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,3 @@
1
+ module MetaRuby
2
+ VERSION = "1.0.0.rc2"
3
+ end
@@ -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
+