origen 0.44.0 → 0.50.0

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 (158) hide show
  1. checksums.yaml +4 -4
  2. data/config/application.rb +2 -2
  3. data/config/boot.rb +0 -7
  4. data/config/commands.rb +3 -74
  5. data/config/rubocop/easy_disabled.yml +4 -0
  6. data/config/rubocop/easy_enabled.yml +0 -4
  7. data/config/rubocop/strict_disabled.yml +4 -0
  8. data/config/rubocop/strict_enabled.yml +0 -4
  9. data/config/version.rb +1 -2
  10. data/lib/origen/application/deployer.rb +3 -1
  11. data/lib/origen/application/release.rb +2 -2
  12. data/lib/origen/application/runner.rb +9 -2
  13. data/lib/origen/application.rb +91 -2
  14. data/lib/origen/boot/app.rb +0 -4
  15. data/lib/origen/boot.rb +2 -1
  16. data/lib/origen/code_generators/actions.rb +244 -34
  17. data/lib/origen/code_generators/base.rb +9 -2
  18. data/lib/origen/code_generators/block.rb +203 -0
  19. data/lib/origen/code_generators/block_common.rb +100 -0
  20. data/lib/origen/code_generators/dut.rb +62 -0
  21. data/lib/origen/code_generators/feature.rb +50 -0
  22. data/lib/origen/code_generators/klass.rb +41 -0
  23. data/lib/origen/code_generators/model.rb +60 -0
  24. data/lib/origen/code_generators/module.rb +92 -0
  25. data/lib/origen/code_generators.rb +30 -10
  26. data/lib/origen/commands/lint.rb +6 -1
  27. data/lib/origen/commands/new.rb +1 -1
  28. data/lib/origen/commands/new_resource.rb +41 -0
  29. data/lib/origen/commands/web.rb +11 -6
  30. data/lib/origen/commands.rb +18 -0
  31. data/lib/{option_parser → origen/core_ext/option_parser}/optparse.rb +0 -0
  32. data/lib/origen/dependencies.rb +0 -0
  33. data/lib/origen/file_handler.rb +8 -4
  34. data/lib/origen/generator/pattern_finder.rb +3 -3
  35. data/lib/origen/loader.rb +377 -0
  36. data/lib/origen/model.rb +22 -1
  37. data/lib/origen/model_initializer.rb +5 -1
  38. data/lib/origen/parameters/set.rb +2 -1
  39. data/lib/origen/parameters.rb +95 -3
  40. data/lib/origen/sub_blocks.rb +21 -7
  41. data/lib/origen/top_level.rb +11 -0
  42. data/lib/origen.rb +3 -1
  43. data/origen_app_generators/Gemfile +6 -2
  44. data/origen_app_generators/Gemfile.lock +83 -72
  45. data/origen_app_generators/bin/boot.rb +4 -2
  46. data/origen_app_generators/config/commands.rb +3 -3
  47. data/origen_app_generators/config/shared_commands.rb +11 -6
  48. data/origen_app_generators/lbin/bundle +105 -0
  49. data/origen_app_generators/lbin/byebug +29 -0
  50. data/origen_app_generators/lbin/coderay +29 -0
  51. data/origen_app_generators/lbin/htmldiff +29 -0
  52. data/origen_app_generators/lbin/httparty +29 -0
  53. data/origen_app_generators/lbin/httpclient +29 -0
  54. data/origen_app_generators/lbin/kramdown +29 -0
  55. data/origen_app_generators/lbin/ldiff +29 -0
  56. data/origen_app_generators/lbin/nanoc +29 -0
  57. data/origen_app_generators/lbin/nokogiri +29 -0
  58. data/origen_app_generators/lbin/origen +62 -0
  59. data/origen_app_generators/lbin/pry +29 -0
  60. data/origen_app_generators/lbin/rackup +29 -0
  61. data/origen_app_generators/lbin/rake +29 -0
  62. data/origen_app_generators/lbin/rspec +29 -0
  63. data/origen_app_generators/lbin/rubocop +29 -0
  64. data/origen_app_generators/lbin/ruby-parse +29 -0
  65. data/origen_app_generators/lbin/ruby-rewrite +29 -0
  66. data/origen_app_generators/lbin/thor +29 -0
  67. data/origen_app_generators/lbin/tilt +29 -0
  68. data/origen_app_generators/lbin/yard +29 -0
  69. data/origen_app_generators/lbin/yardoc +29 -0
  70. data/origen_app_generators/lbin/yri +29 -0
  71. data/origen_app_generators/lib/origen_app_generators/application.rb +12 -12
  72. data/origen_app_generators/lib/origen_app_generators/base.rb +34 -8
  73. data/origen_app_generators/lib/origen_app_generators/new.rb +17 -9
  74. data/origen_app_generators/lib/{tasks/new_app_tests.rake → origen_app_generators/new_app_tests.rb} +1 -5
  75. data/origen_app_generators/lib/origen_app_generators/origen_infrastructure/app_generator_plugin.rb +6 -8
  76. data/origen_app_generators/lib/origen_app_generators/plugin.rb +4 -7
  77. data/origen_app_generators/lib/origen_app_generators/test_engineering/common.rb +29 -0
  78. data/origen_app_generators/lib/origen_app_generators/test_engineering/stand_alone_application.rb +9 -181
  79. data/origen_app_generators/lib/origen_app_generators/test_engineering/test_block.rb +4 -105
  80. data/origen_app_generators/lib/origen_app_generators.rb +6 -4
  81. data/origen_app_generators/origen_app_generators.gemspec +7 -7
  82. data/origen_app_generators/templates/app_generators/application/Gemfile +14 -3
  83. data/origen_app_generators/templates/app_generators/application/{lib → app/blocks}/top_level.rb +1 -1
  84. data/origen_app_generators/templates/app_generators/application/app/lib/module.rb +6 -0
  85. data/origen_app_generators/templates/app_generators/application/{templates → app/templates}/web/index.md.erb +0 -0
  86. data/origen_app_generators/templates/app_generators/application/{templates → app/templates}/web/layouts/_basic.html.erb +0 -0
  87. data/origen_app_generators/templates/app_generators/application/{templates → app/templates}/web/partials/_navbar.html.erb +0 -0
  88. data/origen_app_generators/templates/app_generators/application/{templates → app/templates}/web/release_notes.md.erb +0 -0
  89. data/origen_app_generators/templates/app_generators/application/config/application.rb +51 -55
  90. data/origen_app_generators/templates/app_generators/application/{spec → test/spec}/spec_helper.rb +0 -0
  91. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/{lib → app/lib}/application.rb +0 -0
  92. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/{lib → app/lib}/base.rb +0 -0
  93. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/{lib → app/lib}/module.rb +0 -0
  94. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/{lib → app/lib}/plugin.rb +0 -0
  95. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/config/load_generators.rb +1 -1
  96. data/origen_app_generators/templates/app_generators/plugin/Gemfile +5 -2
  97. data/origen_app_generators/templates/app_generators/plugin/{templates → app/templates}/web/index.md.erb +0 -0
  98. data/origen_app_generators/templates/app_generators/plugin/{templates → app/templates}/web/partials/_navbar_external.html.erb +0 -0
  99. data/origen_app_generators/templates/app_generators/plugin/{templates → app/templates}/web/partials/_navbar_internal.html.erb +0 -0
  100. data/origen_app_generators/templates/app_generators/plugin/gemspec.rb +4 -3
  101. data/origen_app_generators/templates/app_generators/test_engineering/{stand_alone_application/environment → environment}/j750.rb +0 -0
  102. data/origen_app_generators/templates/app_generators/test_engineering/{stand_alone_application/environment → environment}/uflex.rb +0 -0
  103. data/origen_app_generators/templates/app_generators/test_engineering/{stand_alone_application/environment → environment}/v93k.rb +0 -0
  104. data/origen_site_config.yml +0 -7
  105. data/templates/code_generators/attributes.rb +20 -0
  106. data/templates/code_generators/class.rb +9 -0
  107. data/templates/code_generators/controller.rb +87 -0
  108. data/templates/code_generators/model.rb +21 -0
  109. data/templates/code_generators/module.rb +4 -0
  110. data/templates/code_generators/parameters.rb +19 -0
  111. data/templates/code_generators/pins.rb +28 -0
  112. data/templates/code_generators/registers.rb +20 -0
  113. data/templates/code_generators/sub_blocks.rb +24 -0
  114. data/templates/code_generators/timesets.rb +24 -0
  115. data/templates/code_generators/version.rb +0 -1
  116. metadata +66 -77
  117. data/lib/c99/ate_interface.rb +0 -77
  118. data/lib/c99/nvm.rb +0 -110
  119. data/lib/c99/target/mock2.rb +0 -1
  120. data/lib/c99/target/subdir/mock3.rb +0 -1
  121. data/lib/origen/code_generators/bundler.rb +0 -17
  122. data/lib/origen/code_generators/gem_setup.rb +0 -49
  123. data/lib/origen/code_generators/rake.rb +0 -13
  124. data/lib/origen/code_generators/rspec.rb +0 -12
  125. data/lib/origen/commands/add.rb +0 -12
  126. data/lib/tasks/private/build.rake +0 -8
  127. data/origen_app_generators/bin/fix_my_workspace +0 -100
  128. data/origen_app_generators/lib/origen_app_generators/sub_block_parser.rb +0 -81
  129. data/origen_app_generators/lib/tasks/app_generators.rake +0 -6
  130. data/origen_app_generators/spec/sub_block_spec.rb +0 -36
  131. data/origen_app_generators/templates/app_generators/application/lib/app.rake +0 -6
  132. data/origen_app_generators/templates/app_generators/application/lib/module.rb +0 -22
  133. data/origen_app_generators/templates/app_generators/plugin/lib/README +0 -4
  134. data/origen_app_generators/templates/app_generators/plugin/lib_dev/README +0 -5
  135. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/Gemfile +0 -23
  136. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/environment/jlink.rb +0 -1
  137. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/lib/ip_block.rb +0 -23
  138. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/lib/ip_block_controller.rb +0 -5
  139. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/lib/top_level.rb +0 -33
  140. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/lib/top_level_controller.rb +0 -21
  141. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/pattern/example.rb +0 -4
  142. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/target/top_level.rb +0 -4
  143. data/origen_app_generators/templates/app_generators/test_engineering/test_block/environment/j750.rb +0 -2
  144. data/origen_app_generators/templates/app_generators/test_engineering/test_block/environment/ultraflex.rb +0 -2
  145. data/origen_app_generators/templates/app_generators/test_engineering/test_block/environment/v93k.rb +0 -2
  146. data/origen_app_generators/templates/app_generators/test_engineering/test_block/lib/controller.rb +0 -12
  147. data/origen_app_generators/templates/app_generators/test_engineering/test_block/lib/interface.rb +0 -21
  148. data/origen_app_generators/templates/app_generators/test_engineering/test_block/lib/model.rb +0 -18
  149. data/origen_app_generators/templates/app_generators/test_engineering/test_block/lib_dev/dut.rb +0 -27
  150. data/origen_app_generators/templates/app_generators/test_engineering/test_block/lib_dev/dut_controller.rb +0 -26
  151. data/origen_app_generators/templates/app_generators/test_engineering/test_block/pattern/example.rb +0 -5
  152. data/origen_app_generators/templates/app_generators/test_engineering/test_block/program/prb1.rb +0 -11
  153. data/origen_app_generators/templates/app_generators/test_engineering/test_block/target/default.rb +0 -2
  154. data/templates/code_generators/gemfile_app.rb +0 -4
  155. data/templates/code_generators/gemfile_plugin.rb +0 -6
  156. data/templates/code_generators/gemspec.rb +0 -33
  157. data/templates/code_generators/rakefile.rb +0 -10
  158. data/templates/code_generators/spec_helper.rb +0 -49
@@ -0,0 +1,377 @@
1
+ module Origen
2
+ # This module is responsible for enhancing how Ruby requires and loads files to support loading of
3
+ # classes and modules from an application's app dir without having to require them.
4
+ #
5
+ # It also implements the <model>.load_block method that loads files from app/blocks.
6
+ module Loader
7
+ # @api private
8
+ #
9
+ # Unload all constants (classes and modules) that have been auto-loaded since this was last called
10
+ def self.unload
11
+ # puts "******** LOADED CONSTS@ #{@loaded_consts}"
12
+ path = []
13
+ (@consts_hierarchy || {}).each do |name, children|
14
+ _unload(path, name, children)
15
+ end
16
+ @consts_hierarchy = {}
17
+ @loaded_consts = {}
18
+ (Origen.app.plugins + [Origen.app]).each do |app|
19
+ app.instance_variable_set(:@blocks_files, nil)
20
+ end
21
+ nil
22
+ end
23
+
24
+ # @api private
25
+ def self._unload(path, name, children)
26
+ path << name
27
+ children.each do |name, children|
28
+ _unload(path, name, children)
29
+ end
30
+ const = path.join('::')
31
+ if @loaded_consts[const]
32
+ path[0...-1].join('::').constantize.send :remove_const, path.last
33
+ # puts "******** Unloading: #{const}"
34
+ end
35
+ path.pop
36
+ end
37
+
38
+ # @api private
39
+ def self.record_const(name)
40
+ @consts_hierarchy ||= {}
41
+ @loaded_consts ||= {}
42
+ @loaded_consts[name] = true
43
+ pointer = nil
44
+ name.split('::').each do |name|
45
+ if pointer
46
+ pointer[name] ||= {}
47
+ pointer = pointer[name]
48
+ else
49
+ @consts_hierarchy[name] ||= {}
50
+ pointer = @consts_hierarchy[name]
51
+ end
52
+ end
53
+ end
54
+
55
+ # @api private
56
+ def self.load_attributes(file, model)
57
+ if model.respond_to?(:is_an_origen_model?)
58
+ attributes = model.attributes.dup
59
+ else
60
+ attributes = {}
61
+ end
62
+ vars = model.instance_variables
63
+ if load_block_file(file, model)
64
+ # Update the value of any pre-existing attribute that could have just changed
65
+ attributes.each do |a, v|
66
+ attributes[a] = model.instance_variable_get("@#{a}")
67
+ end
68
+ # And add any new ones that were encountered for the first time
69
+ (model.instance_variables - vars).each do |var|
70
+ val = model.instance_variable_get(var)
71
+ attribute = var.to_s.sub('@', '')
72
+ attributes[attribute.to_sym] = val
73
+ unless model.respond_to?(attribute)
74
+ model.define_singleton_method(attribute) do
75
+ instance_variable_get(var)
76
+ end
77
+ end
78
+ if val == true || val == false
79
+ attribute += '?'
80
+ unless model.respond_to?(attribute)
81
+ model.define_singleton_method(attribute) do
82
+ instance_variable_get(var)
83
+ end
84
+ end
85
+ end
86
+ end
87
+ if model.respond_to?(:is_an_origen_model?)
88
+ attributes.freeze
89
+ model.instance_variable_set(:@attributes, attributes)
90
+ end
91
+ true
92
+ end
93
+ end
94
+
95
+ # @api private
96
+ def self.load_block_file(file, model)
97
+ e = File.exist?(file.to_s)
98
+ model.instance_eval(file.read, file.to_s) if e
99
+ true
100
+ end
101
+
102
+ # @api private
103
+ def self.with_parameters_transaction(type)
104
+ if type == :parameters
105
+ Origen::Parameters.transaction do
106
+ yield
107
+ end
108
+ else
109
+ yield
110
+ end
111
+ end
112
+
113
+ # If a block definition exists for the given model, then this will load it and apply it to
114
+ # the model.
115
+ # Returns true if a model is found and loaded, otherwise nil.
116
+ def self.load_block(model, options = {})
117
+ model = model.model # Ensure we have a handle on the model and not its controller
118
+ loaded = nil
119
+ if app = options[:app] || model.app
120
+ if options[:path]
121
+ full_paths = Array(options[:path])
122
+ else
123
+ full_paths = model.class.to_s.split('::')
124
+ full_paths.shift # Throw away the app namespace
125
+ full_paths = [full_paths.join('/')]
126
+ end
127
+ full_paths.each do |full_path|
128
+ paths = full_path.to_s.split('/')
129
+ key = ''
130
+ only = Array(options[:only]) if options[:only]
131
+ except = Array(options[:except]) if options[:except]
132
+ path = paths.map(&:underscore).join('/')
133
+ # If the path refers to a nested sub-block then don't load the full hierarchy since they
134
+ # don't support inheritance or derivatives, modify the paths array so that only the sub-block
135
+ # level will be loaded and nothing else.
136
+ paths = [path] if app.blocks_files[path] && app.blocks_files[path][:_sub_block]
137
+ # These will be loaded first, followed by the rest in an undefined order.
138
+ # Attributes and parameters are first so that they may be referenced in the other files.
139
+ # Sub-blocks was added early due to a corner case issue that could be encountered if the pins or
140
+ # regs imported an Origen exported file that defined a module with the same name as a sub-block
141
+ # class, in that case the sub-block class would not be auto-loaded.
142
+ load_first = [:attributes, :parameters, :sub_blocks]
143
+
144
+ load_first.each do |type|
145
+ unless (only && !only.include?(type)) || (except && except.include?(type))
146
+ with_parameters_transaction(type) do
147
+ paths.each_with_index do |path, i|
148
+ key = i == 0 ? path.underscore : "#{key}/#{path.underscore}"
149
+ if app.blocks_files[key] && app.blocks_files[key][type]
150
+ app.blocks_files[key][type].each do |f|
151
+ if type == :attributes
152
+ success = load_attributes(f, model)
153
+ else
154
+ success = load_block_file(f, model)
155
+ end
156
+ loaded ||= success
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+
164
+ # Now load the rest
165
+ paths.each_with_index do |path, i|
166
+ key = i == 0 ? path.underscore : "#{key}/#{path.underscore}"
167
+ if app.blocks_files[key]
168
+ app.blocks_files[key].each do |type, files|
169
+ unless type == :_sub_block || load_first.include?(type) || (only && !only.include?(type)) || (except && except.include?(type))
170
+ files.each { |f| success = load_block_file(f, model); loaded ||= success }
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
177
+ loaded
178
+ end
179
+
180
+ # This is inspired by Rails' ActiveSupport::Dependencies module.
181
+ module ModuleConstMissing
182
+ def self.append_features(base)
183
+ base.class_eval do
184
+ # Emulate #exclude via an ivar
185
+ return if defined?(@_const_missing) && @_const_missing
186
+ @_const_missing = instance_method(:const_missing)
187
+ remove_method(:const_missing)
188
+ end
189
+ super
190
+ end
191
+
192
+ def self.exclude_from(base)
193
+ base.class_eval do
194
+ define_method :const_missing, @_const_missing
195
+ @_const_missing = nil
196
+ end
197
+ end
198
+
199
+ # @api private
200
+ # Substitutes a single occurrence of 'derivatives' in the given dirs array, starting
201
+ # from the end of it and replacing it with the given new value.
202
+ # Returns true if a substitution is made, else false.
203
+ def _sub_derivatives_from_end(new_val, dirs)
204
+ subbed = false
205
+ size = dirs.size - 1
206
+ dirs.reverse_each.with_index do |val, i|
207
+ if val == 'derivatives'
208
+ dirs[size - i] = new_val
209
+ subbed = true
210
+ break
211
+ end
212
+ end
213
+ dirs if subbed
214
+ end
215
+
216
+ # Allows classes and modules to be defined in app/blocks and app/lib without needing to
217
+ # require them and in the case of app/blocks to use a custom directory structure.
218
+ #
219
+ # The first time a reference is made to a class or module name it will trigger this hook,
220
+ # and we then work out what the file name should be and require it.
221
+ def const_missing(name)
222
+ if Origen.in_app_workspace?
223
+ if self == Object
224
+ name = name.to_s
225
+ else
226
+ name = "#{self}::#{name}"
227
+ end
228
+ return nil if @_checking_name == name
229
+ names = name.split('::')
230
+ namespace = names.shift
231
+ if app = Origen::Application.from_namespace(namespace)
232
+ # First we are going to check for a match in the app/blocks directory, this needs to be handled
233
+ # specially since it follows a non-std structure, e.g. use of derivatives/ and sub_blocks/ folders
234
+ # for organization without having them as part of the class name-spacing
235
+ altname = nil
236
+ dirs = [app.root, 'app', 'blocks']
237
+ names.each_with_index do |name, i|
238
+ dirs << 'derivatives' unless i == 0
239
+ dirs << name.underscore
240
+ end
241
+
242
+ # Is this a reference to a model?
243
+ if File.exist?(f = File.join(*dirs, 'model.rb'))
244
+ model = _load_const(f, name)
245
+ # Also load the model's controller if it exists
246
+ if File.exist?(f = File.join(*dirs, 'controller.rb'))
247
+ controller = _load_const(f, name + 'Controller')
248
+ end
249
+ return model
250
+ end
251
+
252
+ # Is this a reference to a controller?
253
+ if dirs.last.to_s =~ /_controller$/
254
+ controller_reference = true
255
+ dirs << dirs.pop.sub(/_controller$/, '')
256
+ if File.exist?(f = File.join(*dirs, 'controller.rb'))
257
+ return _load_const(f, name)
258
+ end
259
+ end
260
+
261
+ # Is this a reference to a sub-block model or controller that is nested within a block?
262
+ dirs_ = dirs.dup
263
+ while dirs_ = _sub_derivatives_from_end('sub_blocks', dirs_)
264
+ if controller_reference
265
+ if File.exist?(f = File.join(*dirs_, 'controller.rb'))
266
+ return _load_const(f, name)
267
+ end
268
+ elsif File.exist?(f = File.join(*dirs_, 'model.rb'))
269
+ model = _load_const(f, name)
270
+ # Also load the model's controller if it exists
271
+ if File.exist?(f = File.join(*dirs_, 'controller.rb'))
272
+ controller = _load_const(f, name + 'Controller')
273
+ end
274
+ return model
275
+ end
276
+ end
277
+
278
+ # Is this a reference to a module that has been added to a model or controller?
279
+ # In this case dirs contains something like:
280
+ # [..., "my_model", "derivatives", "my_module"]
281
+ # [..., "my_model_controller", "derivatives", "my_module"]
282
+ # So let's try by transforming these into:
283
+ # [..., "my_model", "model"] + "my_module.rb"
284
+ # [..., "my_model", "controller"] + "my_module.rb"
285
+ filename = dirs.pop + '.rb'
286
+ dirs.pop # Lose 'derivatives'
287
+ if dirs.last.to_s =~ /_controller$/
288
+ dirs << dirs.pop.sub(/_controller$/, '')
289
+ dirs << 'controller'
290
+ else
291
+ dirs << 'model'
292
+ end
293
+ if File.exist?(f = File.join(*dirs, filename))
294
+ return _load_const(f, name)
295
+ end
296
+
297
+ # Now that we have established that it is not a reference to a block (which has a non-std code
298
+ # organization structure), we can now check for a match in the app/lib directory following std
299
+ # Ruby code organization conventions
300
+ until names.empty?
301
+ path = File.join(*names.map(&:underscore)) + '.rb'
302
+
303
+ f = File.join(app.root, 'app', 'lib', namespace.underscore, path)
304
+ if File.exist?(f)
305
+ model = _load_const(f, name, altname)
306
+ # Try and reference the controller to load it too, though don't raise an error if it
307
+ # doesn't exist
308
+ @@pre_loading_controller = true
309
+ eval "#{altname || name}Controller"
310
+ return model
311
+ # If a folder exists that is named after this constant, then assume it is an otherwise
312
+ # undeclared namespace module and declare it now
313
+ elsif File.exist?(f.sub('.rb', ''))
314
+ return const_set path.sub('.rb', '').camelcase, Module.new
315
+ end
316
+
317
+ # Don't waste time looking up the namespace hierarchy for the controller, if it exists it
318
+ # should be within the exact same namespace as the model
319
+ return nil if defined?(@@pre_loading_controller) && @@pre_loading_controller
320
+
321
+ # Remove the highest level namespace and then search again in the parent namespace
322
+ if discarded_namespace = names.delete_at(-2)
323
+ altname ||= name
324
+ altname = altname.sub("#{discarded_namespace}::", '')
325
+ else
326
+ names.pop
327
+ end
328
+ end
329
+
330
+ _raise_uninitialized_constant_error(name)
331
+ else
332
+ _raise_uninitialized_constant_error(name)
333
+ end
334
+ else
335
+ _raise_uninitialized_constant_error(name)
336
+ end
337
+ ensure
338
+ @@pre_loading_controller = false
339
+ end
340
+
341
+ # @api_private
342
+ def _load_const(file, name, altname = nil)
343
+ load file
344
+ if defined?(@@pre_loading_controller)
345
+ return if @@pre_loading_controller
346
+ end
347
+ @_checking_name = altname || name
348
+ const = eval(altname || name)
349
+ @_checking_name = nil
350
+ if const
351
+ Origen::Loader.record_const(altname || name)
352
+ return const
353
+ end
354
+ msg ||= "uninitialized constant #{name} (expected it to be defined in: #{file})"
355
+ _raise_uninitialized_constant_error(name, msg)
356
+ end
357
+
358
+ # @api private
359
+ def _raise_uninitialized_constant_error(name, msg = nil)
360
+ msg ||= "uninitialized constant #{name}"
361
+ name_error = NameError.new(msg, name)
362
+ name_error.set_backtrace(caller.reject { |l| l =~ /^#{__FILE__}/ })
363
+ fail name_error
364
+ end
365
+ end
366
+
367
+ def self.enable_origen_load_extensions!
368
+ Module.class_eval { include ModuleConstMissing }
369
+ end
370
+
371
+ def self.disable_origen_load_extensions!
372
+ ModuleConstMissing.exclude_from(Module)
373
+ end
374
+ end
375
+ end
376
+
377
+ Origen::Loader.enable_origen_load_extensions!
data/lib/origen/model.rb CHANGED
@@ -43,6 +43,12 @@ module Origen
43
43
  end
44
44
  end
45
45
 
46
+ # Returns a frozen hash containing any attributes that were
47
+ # derived from a block definition
48
+ def attributes
49
+ @attributes ||= {}.freeze
50
+ end
51
+
46
52
  def inspect
47
53
  if controller
48
54
  "<Model/Controller: #{self.class}:#{object_id}/#{controller.class}:#{controller.object_id}>"
@@ -63,7 +69,7 @@ module Origen
63
69
 
64
70
  # Returns true if the model is the current DUT/top-level model
65
71
  def is_top_level?
66
- Origen.top_level == self
72
+ respond_to?(:includes_origen_top_level?)
67
73
  end
68
74
  alias_method :is_dut?, :is_top_level?
69
75
  alias_method :top_level?, :is_top_level?
@@ -75,6 +81,21 @@ module Origen
75
81
  self
76
82
  end
77
83
 
84
+ # Returns the application instance that defines the model, often the current app but it could
85
+ # also be one of the plugins.
86
+ # Returns nil if the application cannot be resolved, usually because the model's class has
87
+ # not been correctly namespaced.
88
+ def app
89
+ @app ||= Origen::Application.from_namespace(self.class.to_s)
90
+ end
91
+
92
+ # Load the block definitions from the given path to the model.
93
+ # Returns true if a block is found and loaded, otherwise nil.
94
+ def load_block(path, options = {})
95
+ options[:path] = path
96
+ Origen::Loader.load_block(self, options)
97
+ end
98
+
78
99
  def ==(obj)
79
100
  if obj.is_a?(Origen::SubBlocks::Placeholder)
80
101
  obj = obj.materialize
@@ -46,7 +46,10 @@ module Origen
46
46
  else
47
47
  x.send(:initialize, *args, &block)
48
48
  end
49
- x.send(:_initialized) if x.respond_to?(:is_an_origen_model?)
49
+ if x.respond_to?(:is_an_origen_model?)
50
+ x.send(:_initialized)
51
+ Origen::Loader.load_block(x)
52
+ end
50
53
  if x.respond_to?(:register_callback_listener)
51
54
  Origen.after_app_loaded do |app|
52
55
  x.register_callback_listener
@@ -55,6 +58,7 @@ module Origen
55
58
  # Do this before wrapping, otherwise the respond to method in the controller will
56
59
  # be looking for the model to be instantiated when it is not fully done yet
57
60
  is_top_level = x.respond_to?(:includes_origen_top_level?)
61
+
58
62
  if x.respond_to?(:wrap_in_controller)
59
63
  x = x.wrap_in_controller
60
64
  end
@@ -21,7 +21,7 @@ module Origen
21
21
  @defining = true
22
22
  yield self, parent
23
23
  @defining = false
24
- finalize
24
+ finalize unless Origen::Parameters.transaction_open
25
25
  end
26
26
 
27
27
  # Returns the current parameter context
@@ -114,6 +114,7 @@ module Origen
114
114
  end
115
115
 
116
116
  def defining?
117
+ return true if Origen::Parameters.transaction_open
117
118
  if top_level?
118
119
  @defining
119
120
  else
@@ -1,4 +1,5 @@
1
1
  require 'active_support/concern'
2
+ require 'set'
2
3
  module Origen
3
4
  module Parameters
4
5
  extend ActiveSupport::Concern
@@ -8,6 +9,75 @@ module Origen
8
9
 
9
10
  attr_accessor :current
10
11
 
12
+ # @api private
13
+ #
14
+ # Any define_params blocks contained within the given block will be allowed to be re-opened later
15
+ # in the block to override existing parameter settings or to add new ones.
16
+ #
17
+ # This is not allowed normally since already-defined child parameter sets could have referenced the
18
+ # original parameter and they would not reflect the final value after re-opening the parent parameter
19
+ # set.
20
+ #
21
+ # By defining the parameters within this block, Origen will keep track of relationships between parameter
22
+ # sets and any time a parent is changed the definitions of existing children will be re-executed to ensure
23
+ # that they reflect the new values.
24
+ #
25
+ # This is initially intended to support the concept of a app/parameters/application.rb being
26
+ # used to define baseline parameter sets, and then target-specific files can then override them.
27
+ def self.transaction
28
+ start_transaction
29
+ yield
30
+ stop_transaction
31
+ end
32
+
33
+ # @api private
34
+ def self.start_transaction
35
+ @transaction_data = {}
36
+ @transaction_open = true
37
+ @transaction_counter ||= 0
38
+ @transaction_counter += 1
39
+ end
40
+
41
+ # @api private
42
+ def self.stop_transaction
43
+ @transaction_counter -= 1
44
+ if @transaction_counter == 0
45
+ # Now finalize (freeze) all parameter sets we have just defined, this was deferred at define time due
46
+ # to running within a transaction
47
+ @transaction_data.each do |model, parameter_sets|
48
+ parameter_sets.keys.each do |name|
49
+ model._parameter_sets[name].finalize
50
+ end
51
+ end
52
+ @transaction_data = nil
53
+ @transaction_open = false
54
+ end
55
+ end
56
+
57
+ # @api private
58
+ def self.transaction_data
59
+ @transaction_data
60
+ end
61
+
62
+ # @api private
63
+ def self.transaction_open
64
+ @transaction_open
65
+ end
66
+
67
+ # @api private
68
+ def self.transaction_redefine
69
+ @transaction_redefine
70
+ end
71
+
72
+ # @api private
73
+ def self.redefine(model, name)
74
+ @transaction_redefine = true
75
+ model._parameter_sets.delete(name)
76
+ @transaction_data[model][name][:definitions].each { |options, block| model.define_params(name, options, &block) }
77
+ @transaction_data[model][name][:children].each { |model, name| redefine(model, name) }
78
+ @transaction_redefine = false
79
+ end
80
+
11
81
  module ClassMethods
12
82
  def parameters_context(obj = nil)
13
83
  if obj
@@ -25,19 +95,41 @@ module Origen
25
95
  end
26
96
  end
27
97
 
98
+ # @api private
99
+ def define_params_transaction
100
+ Origen::Parameters.transaction_data
101
+ end
102
+
28
103
  def define_params(name, options = {}, &block)
29
- if _parameter_sets[name]
104
+ name = name.to_sym
105
+ if _parameter_sets[name] && !Origen::Parameters.transaction_open
30
106
  fail "Parameter set '#{name}' cannot be re-opened once originally defined!"
31
107
  else
32
- _parameter_sets[name] = Set.new(top_level: true, owner: self)
108
+ if Origen::Parameters.transaction_open && !Origen::Parameters.transaction_redefine
109
+ define_params_transaction[self] ||= {}
110
+ define_params_transaction[self][name] ||= { children: ::Set[], definitions: [] }
111
+ define_params_transaction[self][name][:definitions] << [options.dup, block]
112
+ redefine_children = define_params_transaction[self][name][:children] if _parameter_sets[name]
113
+ end
114
+ if _parameter_sets[name]
115
+ defaults_already_set = true
116
+ else
117
+ _parameter_sets[name] = Origen::Parameters::Set.new(top_level: true, owner: self)
118
+ end
33
119
  if options[:inherit]
34
120
  kontext = _validate_parameter_set_name(options[:inherit])
35
121
  parent = kontext[:obj]._parameter_sets[kontext[:context]]
36
- _parameter_sets[name].copy_defaults_from(parent)
122
+ if Origen::Parameters.transaction_open && !Origen::Parameters.transaction_redefine
123
+ define_params_transaction[kontext[:obj]][kontext[:context]][:children] << [self, name]
124
+ end
125
+ _parameter_sets[name].copy_defaults_from(parent) unless defaults_already_set
37
126
  _parameter_sets[name].define(parent, &block)
38
127
  else
39
128
  _parameter_sets[name].define(&block)
40
129
  end
130
+ if redefine_children
131
+ redefine_children.each { |model, set_name| Origen::Parameters.redefine(model, set_name) }
132
+ end
41
133
  end
42
134
  end
43
135
  alias_method :define_parameters, :define_params
@@ -407,6 +407,11 @@ module Origen
407
407
 
408
408
  # Make this appear like a sub-block to any application code
409
409
  def is_a?(klass)
410
+ # Because sub_blocks are stored in a hash.with_indifferent_access, the value is tested
411
+ # against being a Hash or Array when it is added to the hash. This prevents the class being
412
+ # looking up and loaded by the autoload system straight away, especially if the sub-block
413
+ # has been specified to lazy load
414
+ return false if klass == Hash || klass == Array
410
415
  klass == self.klass || klass == Placeholder
411
416
  end
412
417
 
@@ -424,13 +429,16 @@ module Origen
424
429
  end
425
430
 
426
431
  def materialize
432
+ block = nil
427
433
  file = attributes.delete(:file)
434
+ load_block = attributes.delete(:load_block)
428
435
  dir = attributes.delete(:dir) || owner.send(:export_dir)
429
436
  block = owner.send(:instantiate_sub_block, name, klass, attributes)
430
437
  if file
431
438
  require File.join(dir, file)
432
439
  block.extend owner.send(:export_module_names_from_path, file).join('::').constantize
433
440
  end
441
+ block.load_block(load_block) if load_block
434
442
  block.owner = owner
435
443
  block
436
444
  end
@@ -464,17 +472,17 @@ module Origen
464
472
  @klass ||= begin
465
473
  class_name = attributes.delete(:class_name)
466
474
  if class_name
467
- if eval("defined? ::#{owner.namespace}::#{class_name}")
475
+ begin
468
476
  klass = eval("::#{owner.namespace}::#{class_name}")
469
- else
470
- if eval("defined? #{class_name}")
477
+ rescue NameError
478
+ begin
471
479
  klass = eval(class_name)
472
- else
473
- if eval("defined? #{owner.class}::#{class_name}")
480
+ rescue NameError
481
+ begin
474
482
  klass = eval("#{owner.class}::#{class_name}")
475
- else
483
+ rescue NameError
476
484
  puts "Could not find class: #{class_name}"
477
- fail 'Unknown sub block class!'
485
+ raise 'Unknown sub block class!'
478
486
  end
479
487
  end
480
488
  end
@@ -502,6 +510,12 @@ module Origen
502
510
  class SubBlock
503
511
  include Origen::Model
504
512
 
513
+ # Since no application defined this sub-block class, consider its parent's app to be
514
+ # the owning application
515
+ def app
516
+ parent.app
517
+ end
518
+
505
519
  # Used to create attribute accessors on the fly.
506
520
  #
507
521
  # On first call of a missing method a method is generated to avoid the missing lookup
@@ -24,6 +24,17 @@ module Origen
24
24
  include Origen::Model
25
25
  end
26
26
 
27
+ # Unloads all modules class defined by the application and reloads the target, use
28
+ # this in the console to pick up changes made to files since you opened it.
29
+ # It will only work if your application uses Origen auto-loading from the app/dir,
30
+ # any files that you have manually required will not be re-loaded and may generally
31
+ # cause problems with the use of this method.
32
+ def reload!
33
+ Loader.unload
34
+ Origen.app.reload_target!
35
+ true
36
+ end
37
+
27
38
  # Top-level timing manager/API, returns an instance of Origen::Pins::Timing
28
39
  def timing
29
40
  @timing ||= Pins::Timing.new
data/lib/origen.rb CHANGED
@@ -13,6 +13,7 @@ unless defined? RGen::ORIGENTRANSITION
13
13
  $_origen_invocation_pwd ||= Pathname.pwd
14
14
  require 'fileutils'
15
15
  # Force these to re-load since they could have been loaded from an earlier version of Origen during boot
16
+ load 'origen/loader.rb'
16
17
  load 'origen/site_config.rb'
17
18
  load 'origen/operating_systems.rb'
18
19
  require 'origen/core_ext'
@@ -25,7 +26,7 @@ unless defined? RGen::ORIGENTRANSITION
25
26
  require 'origen/remote_manager'
26
27
  require 'origen/utility'
27
28
  require 'origen/logger_methods'
28
- require 'option_parser/optparse'
29
+ require 'origen/core_ext/option_parser/optparse'
29
30
  require 'bundler'
30
31
  require 'origen/undefined'
31
32
  require 'origen/componentable'
@@ -290,6 +291,7 @@ unless defined? RGen::ORIGENTRANSITION
290
291
 
291
292
  # Returns true if Origen is running in an application workspace
292
293
  def in_app_workspace?
294
+ return @in_app_workspace if defined? @in_app_workspace
293
295
  @in_app_workspace ||= begin
294
296
  path = Pathname.new(Dir.pwd)
295
297
  until path.root? || File.exist?(File.join(path, APP_CONFIG))