rgen 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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)]
|