rgen 0.4.0 → 0.4.1
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.
- data/CHANGELOG +15 -0
- data/lib/instantiators/ea_instantiator.rb +5 -2
- data/lib/metamodels/uml13_metamodel.rb +10 -10
- data/lib/mmgen/templates/annotations.tpl +1 -1
- data/lib/mmgen/templates/metamodel_generator.tpl +1 -1
- data/lib/rgen/ecore/ecore.rb +2 -2
- data/lib/rgen/ecore/ecore_instantiator.rb +4 -2
- data/lib/rgen/ecore/ecore_transformer.rb +6 -1
- data/lib/rgen/environment.rb +5 -0
- data/lib/rgen/environment.rb.bak +42 -0
- data/lib/rgen/instantiator/abstract_xml_instantiator.rb +40 -5
- data/lib/rgen/instantiator/ecore_xml_instantiator.rb +1 -1
- data/lib/rgen/instantiator/xmi11_instantiator.rb +1 -1
- data/lib/rgen/metamodel_builder/builder_extensions.rb +57 -39
- data/lib/rgen/serializer/xmi20_serializer.rb +60 -0
- data/lib/rgen/serializer/xml_serializer.rb +61 -0
- data/lib/rgen/template_language/output_handler.rb +15 -27
- data/lib/rgen/template_language/template_container.rb +1 -1
- data/lib/rgen/transformer.rb +50 -8
- data/test/metamodel_builder_test.rb +22 -0
- data/test/metamodel_roundtrip_test.rb +10 -0
- data/test/metamodel_roundtrip_test/TestModel.rb +2 -0
- data/test/metamodel_roundtrip_test/TestModel_Regenerated.rb +10 -8
- data/test/metamodel_roundtrip_test/houseMetamodel.ecore +8 -0
- data/test/metamodel_roundtrip_test/houseMetamodel_Regenerated.ecore +268 -0
- data/test/metamodel_roundtrip_test/houseMetamodel_from_ecore.rb +8 -5
- data/test/output_handler_test.rb +10 -0
- data/test/transformer_test.rb +13 -1
- metadata +7 -3
- data/lib/rgen/metamodel_builder/build_helper.rb +0 -51
data/CHANGELOG
CHANGED
@@ -35,3 +35,18 @@
|
|
35
35
|
* Added UML1.3 Metamodel
|
36
36
|
* Added tranformation from UML1.3 to ECore
|
37
37
|
|
38
|
+
=0.4.1 (Nov 25th, 2007)
|
39
|
+
|
40
|
+
* Template language performance improvement
|
41
|
+
* Bugfix: use true/false instead of symbols for boolean attribute default values in metamodel classes
|
42
|
+
* Minor fixes on metamodel generator and ecore primitive type handling
|
43
|
+
* Made transformer implementation non-recursive to prevent "stack level too deep" exception for large models
|
44
|
+
* Minor fixes on EAInstantiator
|
45
|
+
* Made transformer search for matching rules for superclasses
|
46
|
+
* Bugfix: Enums are now added to EPackages created using the "ecore" method on a module
|
47
|
+
* Bugfix: Metamodel generator now writes enum names
|
48
|
+
* Performance improvement: don't require ecore transformer every time someone calls "ecore"
|
49
|
+
* Major performance improvement of template engine (no Regexps to check \n at end of line)
|
50
|
+
* Major performance improvement: AbstractXMLInstantiator optionally controls the garbage collector
|
51
|
+
* Major performance improvement: ERB templates are reused in metamodel_builder
|
52
|
+
* Added delete method to Environment
|
@@ -8,13 +8,16 @@ class EAInstantiator < XMI11Instantiator
|
|
8
8
|
:tags => {
|
9
9
|
"EAStub" => proc { |tag, attr| UML13::Class.new(
|
10
10
|
:name => attr["name"]
|
11
|
-
)}
|
11
|
+
)},
|
12
|
+
"ActivityModel" => "ActivityGraph",
|
13
|
+
"PseudoState" => "Pseudostate"
|
12
14
|
},
|
13
15
|
:feature_names => {
|
14
16
|
"isOrdered" => "ordering",
|
15
17
|
"subtype" => "child",
|
16
18
|
"supertype" => "parent",
|
17
|
-
"changeable" => "changeability"
|
19
|
+
"changeable" => "changeability",
|
20
|
+
"substate" => "subvertex"
|
18
21
|
},
|
19
22
|
:feature_values => {
|
20
23
|
"ordering" => {"true" => "ordered", "false" => "unordered"},
|
@@ -4,16 +4,16 @@ module UML13
|
|
4
4
|
extend RGen::MetamodelBuilder::ModuleExtension
|
5
5
|
include RGen::MetamodelBuilder::DataTypes
|
6
6
|
|
7
|
-
AggregationKind = Enum.new([ :none, :aggregate, :composite ])
|
8
|
-
ChangeableKind = Enum.new([ :changeable, :frozen, :addOnly ])
|
9
|
-
OperationDirectionKind = Enum.new([ ])
|
10
|
-
ParameterDirectionKind = Enum.new([ :in, :inout, :out, :return ])
|
11
|
-
MessageDirectionKind = Enum.new([ ])
|
12
|
-
ScopeKind = Enum.new([ :instance, :classifier ])
|
13
|
-
VisibilityKind = Enum.new([ :public, :protected, :private ])
|
14
|
-
PseudostateKind = Enum.new([ :initial, :deepHistory, :shallowHistory, :join, :fork, :branch, :junction, :final ])
|
15
|
-
CallConcurrencyKind = Enum.new([ :sequential, :guarded, :concurrent ])
|
16
|
-
OrderingKind = Enum.new([ :unordered, :ordered, :sorted ])
|
7
|
+
AggregationKind = Enum.new(:name => "AggregationKind", :literals =>[ :none, :aggregate, :composite ])
|
8
|
+
ChangeableKind = Enum.new(:name => "ChangeableKind", :literals =>[ :changeable, :frozen, :addOnly ])
|
9
|
+
OperationDirectionKind = Enum.new(:name => "OperationDirectionKind", :literals =>[ ])
|
10
|
+
ParameterDirectionKind = Enum.new(:name => "ParameterDirectionKind", :literals =>[ :in, :inout, :out, :return ])
|
11
|
+
MessageDirectionKind = Enum.new(:name => "MessageDirectionKind", :literals =>[ ])
|
12
|
+
ScopeKind = Enum.new(:name => "ScopeKind", :literals =>[ :instance, :classifier ])
|
13
|
+
VisibilityKind = Enum.new(:name => "VisibilityKind", :literals =>[ :public, :protected, :private ])
|
14
|
+
PseudostateKind = Enum.new(:name => "PseudostateKind", :literals =>[ :initial, :deepHistory, :shallowHistory, :join, :fork, :branch, :junction, :final ])
|
15
|
+
CallConcurrencyKind = Enum.new(:name => "CallConcurrencyKind", :literals =>[ :sequential, :guarded, :concurrent ])
|
16
|
+
OrderingKind = Enum.new(:name => "OrderingKind", :literals =>[ :unordered, :ordered, :sorted ])
|
17
17
|
|
18
18
|
class Element < RGen::MetamodelBuilder::MMBase
|
19
19
|
end
|
@@ -33,5 +33,5 @@
|
|
33
33
|
<% end %>
|
34
34
|
|
35
35
|
<% define 'Details', :for => EAnnotation do %>
|
36
|
-
<%= details.sort{|a,b| a.key<=>b.key}.collect{ |d| "\'" + d.key + "\' => \'"+ d.value.gsub('\'','\\\'').to_s + "\'"}.join(', ') %><%nows%>
|
36
|
+
<%= details.sort{|a,b| a.key<=>b.key}.collect{ |d| "\'" + d.key + "\' => \'"+ (d.value || "").gsub('\'','\\\'').to_s + "\'"}.join(', ') %><%nows%>
|
37
37
|
<% end %>
|
@@ -83,7 +83,7 @@
|
|
83
83
|
|
84
84
|
<% define 'EnumTypes', :for => EPackage do %>
|
85
85
|
<% for enum in eClassifiers.select{|c| c.is_a?(EEnum)} %>
|
86
|
-
<%= enum.name %> = Enum.new([ <%nows%>
|
86
|
+
<%= enum.name %> = Enum.new(:name => '<%= enum.name %>', :literals =>[ <%nows%>
|
87
87
|
<%= enum.eLiterals.collect { |lit| ":"+lit.name }.join(', ') %> ])
|
88
88
|
<% end %>
|
89
89
|
<% end %>
|
data/lib/rgen/ecore/ecore.rb
CHANGED
@@ -67,10 +67,10 @@ module RGen
|
|
67
67
|
has_attr 'instanceClassName', String
|
68
68
|
module ClassModule
|
69
69
|
def instanceClass_derived
|
70
|
-
map = {"java.lang.
|
70
|
+
map = {"java.lang.string" => "String", "boolean" => "RGen::MetamodelBuilder::DataTypes::Boolean", "int" => "Integer"}
|
71
71
|
icn = instanceClassName
|
72
72
|
icn = "NilClass" if icn.nil?
|
73
|
-
icn = map[icn] if map[icn]
|
73
|
+
icn = map[icn.downcase] if map[icn.downcase]
|
74
74
|
eval(icn)
|
75
75
|
end
|
76
76
|
end
|
@@ -13,8 +13,10 @@ module ECoreInstantiator
|
|
13
13
|
# class or module using ECoreTransformer.
|
14
14
|
#
|
15
15
|
def ecore
|
16
|
-
|
17
|
-
|
16
|
+
unless defined?(@@transformer)
|
17
|
+
require 'rgen/ecore/ecore_transformer'
|
18
|
+
@@transformer = ECoreTransformer.new
|
19
|
+
end
|
18
20
|
@@transformer.trans(self)
|
19
21
|
end
|
20
22
|
|
@@ -31,8 +31,12 @@ class ECoreTransformer < Transformer
|
|
31
31
|
end
|
32
32
|
|
33
33
|
transform Module, :to => EPackage, :if => :convert? do
|
34
|
+
@enumParentModule ||= {}
|
35
|
+
constants.select {|c| const_get(c).is_a?(MetamodelBuilder::DataTypes::Enum)}.
|
36
|
+
each {|c| @enumParentModule[const_get(c)] = @current_object}
|
34
37
|
{ :name => name.gsub(/.*::(\w+)$/,'\1'),
|
35
|
-
:eClassifiers => trans(constants.collect{|c| const_get(c)}.select{|c| c.is_a?(Class)
|
38
|
+
:eClassifiers => trans(constants.collect{|c| const_get(c)}.select{|c| c.is_a?(Class) ||
|
39
|
+
(c.is_a?(MetamodelBuilder::DataTypes::Enum) && c != MetamodelBuilder::DataTypes::Boolean) }),
|
36
40
|
:eSuperPackage => trans(name =~ /(.*)::\w+$/ ? eval($1) : nil),
|
37
41
|
:eSubpackages => trans(constants.collect{|c| const_get(c)}.select{|c| c.is_a?(Module) && !c.is_a?(Class)}),
|
38
42
|
:eAnnotations => trans(_annotations)
|
@@ -71,6 +75,7 @@ class ECoreTransformer < Transformer
|
|
71
75
|
|
72
76
|
transform MetamodelBuilder::DataTypes::Enum, :to => EEnum do
|
73
77
|
{ :name => name,
|
78
|
+
:instanceClassName => @enumParentModule && @enumParentModule[@current_object] && @enumParentModule[@current_object].name+"::"+name,
|
74
79
|
:eLiterals => literals.collect do |l|
|
75
80
|
lit = EEnumLiteral.new
|
76
81
|
lit.name = l.to_s
|
data/lib/rgen/environment.rb
CHANGED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rgen/find_helper'
|
2
|
+
|
3
|
+
module RGen
|
4
|
+
|
5
|
+
# An Environment is used to hold model elements.
|
6
|
+
#
|
7
|
+
class Environment
|
8
|
+
include RGen::FindHelper
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@elements = []
|
12
|
+
end
|
13
|
+
|
14
|
+
# Add a model element. Returns the environment so <code><<</code> can be chained.
|
15
|
+
#
|
16
|
+
def <<(el)
|
17
|
+
@elements << el
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
# Iterates each element
|
22
|
+
#
|
23
|
+
def each(&b)
|
24
|
+
@elements.each(&b)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Return the elements of the environment as an array
|
28
|
+
#
|
29
|
+
def elements
|
30
|
+
@elements.dup
|
31
|
+
end
|
32
|
+
|
33
|
+
# This method can be used to instantiate a class and automatically put it into
|
34
|
+
# the environment. The new instance is returned.
|
35
|
+
#
|
36
|
+
def new(clazz, *args)
|
37
|
+
@elements << clazz.new(*args)
|
38
|
+
@elements[-1]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -7,9 +7,10 @@ class AbstractXMLInstantiator
|
|
7
7
|
class XMLScanVisitor
|
8
8
|
include XMLScan::NSVisitor
|
9
9
|
|
10
|
-
def initialize(inst)
|
10
|
+
def initialize(inst, gcSuspendCount)
|
11
11
|
@current_attributes = {}
|
12
12
|
@instantiator = inst
|
13
|
+
@gcSuspendCount = gcSuspendCount
|
13
14
|
end
|
14
15
|
|
15
16
|
def on_attribute_ns(qname, prefix, localpart)
|
@@ -30,6 +31,7 @@ class AbstractXMLInstantiator
|
|
30
31
|
end
|
31
32
|
|
32
33
|
def on_stag_end_ns(qname, namespaces)
|
34
|
+
controlGC
|
33
35
|
prefix, tag = split_qname(qname)
|
34
36
|
@instantiator.start_tag(prefix, tag, namespaces, @current_attributes)
|
35
37
|
@current_attributes.each_pair { |k,v| @instantiator.set_attribute(k, v) }
|
@@ -37,6 +39,7 @@ class AbstractXMLInstantiator
|
|
37
39
|
end
|
38
40
|
|
39
41
|
def on_stag_end_empty_ns(qname, namespaces)
|
42
|
+
controlGC
|
40
43
|
prefix, tag = split_qname(qname)
|
41
44
|
@instantiator.start_tag(prefix, tag, namespaces, @current_attributes)
|
42
45
|
@current_attributes.each_pair { |k,v| @instantiator.set_attribute(k, v) }
|
@@ -48,12 +51,44 @@ class AbstractXMLInstantiator
|
|
48
51
|
prefix, tag = split_qname(qname)
|
49
52
|
@instantiator.end_tag(prefix, tag)
|
50
53
|
end
|
54
|
+
|
55
|
+
def on_chardata(str)
|
56
|
+
@instantiator.text(str)
|
57
|
+
end
|
58
|
+
|
59
|
+
def controlGC
|
60
|
+
return unless @gcSuspendCount > 0
|
61
|
+
@gcCounter ||= 0
|
62
|
+
@gcCounter += 1
|
63
|
+
if @gcCounter == @gcSuspendCount
|
64
|
+
@gcCounter = 0
|
65
|
+
GC.enable
|
66
|
+
ObjectSpace.garbage_collect
|
67
|
+
GC.disable
|
68
|
+
end
|
69
|
+
end
|
51
70
|
end
|
52
71
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
72
|
+
# Parses str and calls start_tag, end_tag, set_attribute and text methods of a subclass.
|
73
|
+
#
|
74
|
+
# If gcSuspendCount is specified, the garbage collector will be disabled for that
|
75
|
+
# number of start or end tags. After that period it will clean up and then be disabled again.
|
76
|
+
# A value of about 1000 can significantly improve overall performance.
|
77
|
+
# The memory usage normally does not increase.
|
78
|
+
# Depending on the work done for every xml tag the value might have to be adjusted.
|
79
|
+
#
|
80
|
+
def instantiate(str, gcSuspendCount=0)
|
81
|
+
gcDisabledBefore = GC.disable
|
82
|
+
gcSuspendCount = 0 if gcDisabledBefore
|
83
|
+
begin
|
84
|
+
visitor = XMLScanVisitor.new(self, gcSuspendCount)
|
85
|
+
parser = XMLScan::XMLParserNS.new(visitor)
|
86
|
+
parser.parse(str)
|
87
|
+
ensure
|
88
|
+
GC.enable unless gcDisabledBefore
|
89
|
+
end
|
57
90
|
end
|
58
91
|
|
92
|
+
def text(str)
|
93
|
+
end
|
59
94
|
end
|
@@ -81,7 +81,7 @@ class ECoreXMLInstantiator < AbstractXMLInstantiator
|
|
81
81
|
def instantiate(str)
|
82
82
|
@resolver_descs = []
|
83
83
|
# puts "Instantiating ..."
|
84
|
-
super
|
84
|
+
super(str, 1000)
|
85
85
|
rootpackage = @env.find(:class => EPackage).first
|
86
86
|
# puts "Resolving ..."
|
87
87
|
@resolver_descs.each do |rd|
|
@@ -28,7 +28,7 @@ class XMI11Instantiator < AbstractXMLInstantiator
|
|
28
28
|
def instantiate(str)
|
29
29
|
@resolver_descs = []
|
30
30
|
@element_by_id = {}
|
31
|
-
super(str)
|
31
|
+
super(str, 1000)
|
32
32
|
@resolver_descs.each do |rd|
|
33
33
|
if rd.many
|
34
34
|
newval = rd.value.split(" ").collect{|v| @element_by_id[v]}
|
@@ -2,7 +2,6 @@
|
|
2
2
|
# (c) Martin Thiede, 2006
|
3
3
|
|
4
4
|
require 'erb'
|
5
|
-
require 'rgen/metamodel_builder/build_helper'
|
6
5
|
require 'rgen/metamodel_builder/metamodel_description.rb'
|
7
6
|
|
8
7
|
module RGen
|
@@ -268,39 +267,41 @@ module BuilderExtensions
|
|
268
267
|
if props.value(:derived)
|
269
268
|
build_derived_method(name, props, :one)
|
270
269
|
else
|
271
|
-
|
270
|
+
@@one_read_builder ||= ERB.new <<-CODE
|
272
271
|
|
273
|
-
def
|
272
|
+
def <%= name %>
|
274
273
|
<% if props.is_a?(AttributeDescription) && props.value(:defaultValueLiteral) %>
|
275
274
|
<% defVal = props.value(:defaultValueLiteral) %>
|
276
275
|
<% defVal = '"'+defVal+'"' if props.impl_type == String %>
|
277
|
-
<% defVal = ':'+defVal if props.impl_type.is_a?(DataTypes::Enum) %>
|
278
|
-
|
276
|
+
<% defVal = ':'+defVal if props.impl_type.is_a?(DataTypes::Enum) && props.impl_type != DataTypes::Boolean %>
|
277
|
+
@<%= name %>.nil? ? <%= defVal %> : @<%= name %>
|
279
278
|
<% else %>
|
280
|
-
|
279
|
+
@<%= name %>
|
281
280
|
<% end %>
|
282
281
|
end
|
283
|
-
alias get<%= firstToUpper(name) %>
|
282
|
+
alias get<%= firstToUpper(name) %> <%= name %>
|
284
283
|
|
285
284
|
CODE
|
285
|
+
_class_module.module_eval(@@one_read_builder.result(binding))
|
286
286
|
end
|
287
287
|
|
288
288
|
if props.value(:changeable)
|
289
|
-
|
289
|
+
@@one_write_builder ||= ERB.new <<-CODE
|
290
290
|
|
291
|
-
def
|
292
|
-
return if val ==
|
291
|
+
def <%= name %>=(val)
|
292
|
+
return if val == @<%= name %>
|
293
293
|
<%= type_check_code("val", props) %>
|
294
|
-
oldval =
|
295
|
-
|
294
|
+
oldval = @<%= name %>
|
295
|
+
@<%= name %> = val
|
296
296
|
<% if other_role && other_kind %>
|
297
|
-
_unregister(self,oldval,"
|
298
|
-
_register(self,val,"
|
297
|
+
_unregister(self,oldval,"<%= other_role %>","<%= other_kind %>")
|
298
|
+
_register(self,val,"<%= other_role %>","<%= other_kind %>")
|
299
299
|
<% end %>
|
300
300
|
end
|
301
|
-
alias set<%= firstToUpper(name) %>
|
301
|
+
alias set<%= firstToUpper(name) %> <%= name %>=
|
302
302
|
|
303
303
|
CODE
|
304
|
+
_class_module.module_eval(@@one_write_builder.result(binding))
|
304
305
|
|
305
306
|
end
|
306
307
|
end
|
@@ -315,51 +316,53 @@ module BuilderExtensions
|
|
315
316
|
if props.value(:derived)
|
316
317
|
build_derived_method(name, props, :many)
|
317
318
|
else
|
318
|
-
|
319
|
+
@@many_read_builder ||= ERB.new <<-CODE
|
319
320
|
|
320
|
-
def
|
321
|
-
(
|
321
|
+
def <%= name %>
|
322
|
+
( @<%= name %> ? @<%= name %>.dup : [] )
|
322
323
|
end
|
323
|
-
alias get<%= firstToUpper(name) %>
|
324
|
+
alias get<%= firstToUpper(name) %> <%= name %>
|
324
325
|
|
325
326
|
CODE
|
327
|
+
_class_module.module_eval(@@many_read_builder.result(binding))
|
326
328
|
end
|
327
329
|
|
328
330
|
if props.value(:changeable)
|
329
|
-
|
331
|
+
@@many_write_builder ||= ERB.new <<-CODE
|
330
332
|
|
331
333
|
def add<%= firstToUpper(name) %>(val)
|
332
|
-
|
333
|
-
return if val.nil? or
|
334
|
+
@<%= name %> = [] unless @<%= name %>
|
335
|
+
return if val.nil? or @<%= name %>.include?(val)
|
334
336
|
<%= type_check_code("val", props) %>
|
335
|
-
|
337
|
+
@<%= name %>.push val
|
336
338
|
<% if other_role && other_kind %>
|
337
|
-
_register(self, val, "
|
339
|
+
_register(self, val, "<%= other_role %>", "<%= other_kind %>")
|
338
340
|
<% end %>
|
339
341
|
end
|
340
342
|
|
341
343
|
def remove<%= firstToUpper(name) %>(val)
|
342
|
-
|
343
|
-
return unless
|
344
|
-
|
344
|
+
@<%= name %> = [] unless @<%= name %>
|
345
|
+
return unless @<%= name %>.include?(val)
|
346
|
+
@<%= name %>.delete val
|
345
347
|
<% if other_role && other_kind %>
|
346
|
-
_unregister(self, val, "
|
348
|
+
_unregister(self, val, "<%= other_role %>", "<%= other_kind %>")
|
347
349
|
<% end %>
|
348
350
|
end
|
349
351
|
|
350
|
-
def
|
352
|
+
def <%= name %>=(val)
|
351
353
|
return if val.nil?
|
352
354
|
raise _assignmentTypeError(self, val, Array) unless val.is_a? Array
|
353
|
-
getGeneric(
|
355
|
+
getGeneric(:<%= name %>).each {|e|
|
354
356
|
remove<%= firstToUpper(name) %>(e)
|
355
357
|
}
|
356
358
|
val.each {|v|
|
357
359
|
add<%= firstToUpper(name) %>(v)
|
358
360
|
}
|
359
361
|
end
|
360
|
-
alias set<%= firstToUpper(name) %>
|
362
|
+
alias set<%= firstToUpper(name) %> <%= name %>=
|
361
363
|
|
362
364
|
CODE
|
365
|
+
_class_module.module_eval(@@many_write_builder.result(binding))
|
363
366
|
end
|
364
367
|
|
365
368
|
end
|
@@ -369,12 +372,12 @@ module BuilderExtensions
|
|
369
372
|
def build_derived_method(name, props, kind)
|
370
373
|
raise "Implement method #{name}_derived instead of method #{name}" \
|
371
374
|
if (public_instance_methods+protected_instance_methods+private_instance_methods).include?(name)
|
372
|
-
|
375
|
+
@@derived_builder ||= ERB.new <<-CODE
|
373
376
|
|
374
|
-
def
|
375
|
-
raise "Derived feature requires public implementation of method
|
376
|
-
unless respond_to?(
|
377
|
-
val =
|
377
|
+
def <%= name %>
|
378
|
+
raise "Derived feature requires public implementation of method <%= name %>_derived" \
|
379
|
+
unless respond_to?(:<%= name+"_derived" %>)
|
380
|
+
val = <%= name %>_derived
|
378
381
|
<% if kind == :many %>
|
379
382
|
raise _assignmentTypeError(self,val,Array) unless val && val.is_a?(Array)
|
380
383
|
val.each do |v|
|
@@ -385,13 +388,28 @@ module BuilderExtensions
|
|
385
388
|
<% end %>
|
386
389
|
val
|
387
390
|
end
|
388
|
-
alias get
|
389
|
-
#TODO final_method
|
391
|
+
alias get<%= firstToUpper(name) %> <%= name %>
|
392
|
+
#TODO final_method :<%= name %>
|
390
393
|
|
391
394
|
CODE
|
395
|
+
_class_module.module_eval(@@derived_builder.result(binding))
|
392
396
|
end
|
393
397
|
|
394
|
-
|
398
|
+
def type_check_code(varname, props)
|
399
|
+
code = ""
|
400
|
+
if props.impl_type.is_a?(Class)
|
401
|
+
code << "unless #{varname}.nil? or #{varname}.is_a? #{props.impl_type}\n"
|
402
|
+
expected = props.impl_type.to_s
|
403
|
+
elsif props.impl_type.is_a?(RGen::MetamodelBuilder::DataTypes::Enum)
|
404
|
+
code << "unless #{varname}.nil? or [#{props.impl_type.literals_as_strings.join(',')}].include?(#{varname})\n"
|
405
|
+
expected = "["+props.impl_type.literals_as_strings.join(',')+"]"
|
406
|
+
else
|
407
|
+
raise StandardError.new("Unkown type "+props.impl_type.to_s)
|
408
|
+
end
|
409
|
+
code << "raise _assignmentTypeError(self,#{varname},\"#{expected}\")\n"
|
410
|
+
code << "end"
|
411
|
+
code
|
412
|
+
end
|
395
413
|
|
396
414
|
def _ownProps(props)
|
397
415
|
Hash[*(props.select{|k,v| !(k.to_s =~ /^opposite_/)}.flatten)]
|