rgen 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +20 -1
- data/MIT-LICENSE +1 -1
- data/README +12 -9
- data/lib/instantiators/ea_instantiator.rb +36 -0
- data/lib/metamodels/uml13_metamodel.rb +559 -0
- data/lib/metamodels/uml13_metamodel_ext.rb +26 -0
- data/lib/mmgen/metamodel_generator.rb +5 -5
- data/lib/mmgen/mm_ext/ecore_ext.rb +95 -0
- data/lib/mmgen/mmgen.rb +6 -4
- data/lib/mmgen/templates/annotations.tpl +37 -0
- data/lib/mmgen/templates/metamodel_generator.tpl +171 -0
- data/lib/rgen/ecore/ecore.rb +190 -0
- data/lib/rgen/ecore/ecore_instantiator.rb +25 -0
- data/lib/rgen/ecore/ecore_transformer.rb +85 -0
- data/lib/rgen/environment.rb +9 -24
- data/lib/rgen/find_helper.rb +68 -0
- data/lib/rgen/{instantiator.rb → instantiator/abstract_instantiator.rb} +6 -2
- data/lib/rgen/instantiator/abstract_xml_instantiator.rb +59 -0
- data/lib/rgen/instantiator/default_xml_instantiator.rb +117 -0
- data/lib/rgen/instantiator/ecore_xml_instantiator.rb +144 -0
- data/lib/rgen/instantiator/nodebased_xml_instantiator.rb +157 -0
- data/lib/rgen/instantiator/xmi11_instantiator.rb +164 -0
- data/lib/rgen/metamodel_builder.rb +103 -9
- data/lib/rgen/metamodel_builder/build_helper.rb +26 -4
- data/lib/rgen/metamodel_builder/builder_extensions.rb +285 -88
- data/lib/rgen/metamodel_builder/builder_runtime.rb +7 -1
- data/lib/rgen/metamodel_builder/data_types.rb +67 -0
- data/lib/rgen/metamodel_builder/intermediate/annotation.rb +30 -0
- data/lib/rgen/metamodel_builder/metamodel_description.rb +232 -0
- data/lib/rgen/metamodel_builder/mm_multiple.rb +23 -0
- data/lib/rgen/metamodel_builder/module_extension.rb +33 -0
- data/lib/rgen/model_comparator.rb +56 -0
- data/lib/rgen/model_dumper.rb +5 -5
- data/lib/rgen/name_helper.rb +17 -1
- data/lib/rgen/template_language.rb +148 -28
- data/lib/rgen/template_language/directory_template_container.rb +56 -38
- data/lib/rgen/template_language/output_handler.rb +93 -77
- data/lib/rgen/template_language/template_container.rb +186 -143
- data/lib/rgen/transformer.rb +19 -14
- data/lib/transformers/uml13_to_ecore.rb +75 -0
- data/redist/xmlscan/ChangeLog +1301 -0
- data/redist/xmlscan/README +34 -0
- data/redist/xmlscan/THANKS +11 -0
- data/redist/xmlscan/doc/changes.html +74 -0
- data/redist/xmlscan/doc/changes.rd +80 -0
- data/redist/xmlscan/doc/en/conformance.html +136 -0
- data/redist/xmlscan/doc/en/conformance.rd +152 -0
- data/redist/xmlscan/doc/en/manual.html +356 -0
- data/redist/xmlscan/doc/en/manual.rd +402 -0
- data/redist/xmlscan/doc/ja/conformance.ja.html +118 -0
- data/redist/xmlscan/doc/ja/conformance.ja.rd +134 -0
- data/redist/xmlscan/doc/ja/manual.ja.html +325 -0
- data/redist/xmlscan/doc/ja/manual.ja.rd +370 -0
- data/redist/xmlscan/doc/src/Makefile +41 -0
- data/redist/xmlscan/doc/src/conformance.rd.src +256 -0
- data/redist/xmlscan/doc/src/langsplit.rb +110 -0
- data/redist/xmlscan/doc/src/manual.rd.src +614 -0
- data/redist/xmlscan/install.rb +41 -0
- data/redist/xmlscan/lib/xmlscan/encoding.rb +311 -0
- data/redist/xmlscan/lib/xmlscan/htmlscan.rb +289 -0
- data/redist/xmlscan/lib/xmlscan/namespace.rb +352 -0
- data/redist/xmlscan/lib/xmlscan/parser.rb +299 -0
- data/redist/xmlscan/lib/xmlscan/scanner.rb +1109 -0
- data/redist/xmlscan/lib/xmlscan/version.rb +22 -0
- data/redist/xmlscan/lib/xmlscan/visitor.rb +158 -0
- data/redist/xmlscan/lib/xmlscan/xmlchar.rb +441 -0
- data/redist/xmlscan/memo/CONFORMANCE +1249 -0
- data/redist/xmlscan/memo/PRODUCTIONS +195 -0
- data/redist/xmlscan/memo/contentspec.ry +335 -0
- data/redist/xmlscan/samples/chibixml.rb +105 -0
- data/redist/xmlscan/samples/getxmlchar.rb +122 -0
- data/redist/xmlscan/samples/rexml.rb +159 -0
- data/redist/xmlscan/samples/xmlbench.rb +88 -0
- data/redist/xmlscan/samples/xmlbench/parser/chibixml.rb +22 -0
- data/redist/xmlscan/samples/xmlbench/parser/nqxml.rb +29 -0
- data/redist/xmlscan/samples/xmlbench/parser/rexml.rb +62 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlparser.rb +22 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlscan-0.0.10.rb +62 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlscan-chibixml.rb +22 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlscan-rexml.rb +22 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlscan.rb +99 -0
- data/redist/xmlscan/samples/xmlbench/xmlbench-lib.rb +116 -0
- data/redist/xmlscan/samples/xmlconftest.rb +200 -0
- data/redist/xmlscan/test.rb +7 -0
- data/redist/xmlscan/tests/deftestcase.rb +73 -0
- data/redist/xmlscan/tests/runtest.rb +47 -0
- data/redist/xmlscan/tests/testall.rb +14 -0
- data/redist/xmlscan/tests/testencoding.rb +438 -0
- data/redist/xmlscan/tests/testhtmlscan.rb +752 -0
- data/redist/xmlscan/tests/testnamespace.rb +457 -0
- data/redist/xmlscan/tests/testparser.rb +591 -0
- data/redist/xmlscan/tests/testscanner.rb +1749 -0
- data/redist/xmlscan/tests/testxmlchar.rb +143 -0
- data/redist/xmlscan/tests/visitor.rb +34 -0
- data/test/array_extensions_test.rb +2 -2
- data/test/ea_instantiator_test.rb +41 -0
- data/test/ecore_self_test.rb +53 -0
- data/test/environment_test.rb +11 -6
- data/test/metamodel_builder_test.rb +404 -245
- data/test/metamodel_roundtrip_test.rb +52 -0
- data/test/metamodel_roundtrip_test/TestModel.rb +65 -0
- data/test/metamodel_roundtrip_test/TestModel_Regenerated.rb +64 -0
- data/test/metamodel_roundtrip_test/houseMetamodel.ecore +32 -0
- data/test/metamodel_roundtrip_test/houseMetamodel_from_ecore.rb +39 -0
- data/test/rgen_test.rb +3 -3
- data/test/template_language_test.rb +65 -39
- data/test/template_language_test/expected_result.txt +24 -3
- data/test/template_language_test/templates/code/array.tpl +11 -0
- data/test/template_language_test/templates/content/author.tpl +7 -0
- data/test/template_language_test/templates/content/chapter.tpl +1 -1
- data/test/template_language_test/templates/root.tpl +17 -8
- data/test/template_language_test/testout.txt +24 -3
- data/test/testmodel/class_model_checker.rb +119 -0
- data/test/{xmi_instantiator_test/testmodel.eap → testmodel/ea_testmodel.eap} +0 -0
- data/test/{xmi_instantiator_test/testmodel.xml → testmodel/ea_testmodel.xml} +81 -14
- data/test/testmodel/ea_testmodel_partial.xml +317 -0
- data/test/testmodel/ecore_model_checker.rb +101 -0
- data/test/testmodel/manual_testmodel.xml +22 -0
- data/test/testmodel/object_model_checker.rb +67 -0
- data/test/transformer_test.rb +18 -10
- data/test/xml_instantiator_test.rb +81 -8
- data/test/xml_instantiator_test/simple_ecore_model_checker.rb +94 -0
- data/test/xml_instantiator_test/simple_xmi_ecore_instantiator.rb +53 -0
- data/test/xml_instantiator_test/simple_xmi_metamodel.rb +49 -0
- data/test/xml_instantiator_test/simple_xmi_to_ecore.rb +75 -0
- metadata +126 -28
- data/lib/ea/xmi_class_instantiator.rb +0 -46
- data/lib/ea/xmi_helper.rb +0 -26
- data/lib/ea/xmi_metamodel.rb +0 -34
- data/lib/ea/xmi_object_instantiator.rb +0 -46
- data/lib/ea/xmi_to_classmodel.rb +0 -78
- data/lib/ea/xmi_to_objectmodel.rb +0 -92
- data/lib/mmgen/mm_ext/uml_classmodel_ext.rb +0 -71
- data/lib/mmgen/templates/uml_classmodel.tpl +0 -63
- data/lib/rgen/xml_instantiator.rb +0 -132
- data/lib/uml/objectmodel_instantiator.rb +0 -53
- data/lib/uml/uml_classmodel.rb +0 -92
- data/lib/uml/uml_objectmodel.rb +0 -65
- data/test/metamodel_generator_test.rb +0 -44
- data/test/metamodel_generator_test/TestModel.rb +0 -40
- data/test/metamodel_generator_test/expected_result.txt +0 -40
- data/test/xmi_class_instantiator_test.rb +0 -24
- data/test/xmi_instantiator_test/class_model_checker.rb +0 -97
- data/test/xmi_object_instantiator_test.rb +0 -65
- data/test/xml_instantiator_test/testmodel.xml +0 -7
@@ -13,6 +13,11 @@ module MetamodelBuilder
|
|
13
13
|
module BuilderRuntime
|
14
14
|
include NameHelper
|
15
15
|
|
16
|
+
def is_a?(c)
|
17
|
+
return super unless c.respond_to?(:_class_module)
|
18
|
+
kind_of?(c._class_module)
|
19
|
+
end
|
20
|
+
|
16
21
|
def addGeneric(role, value)
|
17
22
|
send("add#{firstToUpper(role)}",value)
|
18
23
|
end
|
@@ -56,7 +61,8 @@ module BuilderRuntime
|
|
56
61
|
end
|
57
62
|
valueId = value.class.name
|
58
63
|
valueId += "(" + value.name + ")" if value.respond_to?(:name) and value.name
|
59
|
-
|
64
|
+
valueId += "(:" + value.to_s + ")" if value.is_a?(Symbol)
|
65
|
+
text += "Can not use a #{valueId} where a #{expected} is expected"
|
60
66
|
StandardError.new(text)
|
61
67
|
end
|
62
68
|
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module RGen
|
2
|
+
|
3
|
+
module MetamodelBuilder
|
4
|
+
|
5
|
+
module DataTypes
|
6
|
+
|
7
|
+
# An enum object is used to describe possible attribute values within a
|
8
|
+
# MetamodelBuilder attribute definition. An attribute defined this way can only
|
9
|
+
# take the values specified when creating the Enum object.
|
10
|
+
# Literal values can only be symbols or true or false.
|
11
|
+
# Optionally a name may be specified for the enum object.
|
12
|
+
#
|
13
|
+
# Examples:
|
14
|
+
#
|
15
|
+
# Enum.new(:name => "AnimalEnum", :literals => [:cat, :dog])
|
16
|
+
# Enum.new(:literals => [:cat, :dog])
|
17
|
+
# Enum.new([:cat, :dog])
|
18
|
+
#
|
19
|
+
class Enum
|
20
|
+
attr_reader :name, :literals
|
21
|
+
|
22
|
+
# Creates a new named enum type object consisting of the elements passed as arguments.
|
23
|
+
def initialize(params)
|
24
|
+
if params.is_a?(Array)
|
25
|
+
@literals = params
|
26
|
+
@name = "anonymous"
|
27
|
+
elsif params.is_a?(Hash)
|
28
|
+
raise StandardError.new("Hash entry :literals is missing") unless params[:literals]
|
29
|
+
@literals = params[:literals]
|
30
|
+
@name = params[:name] || "anonymous"
|
31
|
+
else
|
32
|
+
raise StandardError.new("Pass an Array or a Hash")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# This method can be used to check if an object can be used as value for
|
37
|
+
# variables having this enum object as type.
|
38
|
+
def validLiteral?(l)
|
39
|
+
literals.include?(l)
|
40
|
+
end
|
41
|
+
|
42
|
+
def literals_as_strings
|
43
|
+
literals.collect do |l|
|
44
|
+
if l.is_a?(Symbol)
|
45
|
+
":"+l.to_s
|
46
|
+
elsif l.is_a?(TrueClass) || l.is_a?(FalseClass)
|
47
|
+
l.to_s
|
48
|
+
else
|
49
|
+
raise StandardError.new("Literal values can only be symbols or true/false")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_s # :nodoc:
|
55
|
+
name
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Boolean is a predefined enum object having Ruby's true and false singletons
|
60
|
+
# as possible values.
|
61
|
+
Boolean = Enum.new(:name => "Boolean", :literals => [true, false])
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RGen
|
2
|
+
|
3
|
+
module MetamodelBuilder
|
4
|
+
|
5
|
+
module Intermediate
|
6
|
+
|
7
|
+
class Annotation
|
8
|
+
attr_reader :details, :source
|
9
|
+
|
10
|
+
def initialize(hash)
|
11
|
+
if hash[:source] || hash[:details]
|
12
|
+
restKeys = hash.keys - [:source, :details]
|
13
|
+
raise "Hash key #{restKeys.first} not allowed." unless restKeys.empty?
|
14
|
+
raise "Details not provided, key :details is missing" unless hash[:details]
|
15
|
+
raise "Details must be provided as a hash" unless hash[:details].is_a?(Hash)
|
16
|
+
@details = hash[:details]
|
17
|
+
@source = hash[:source]
|
18
|
+
else
|
19
|
+
raise "Details must be provided as a hash" unless hash.is_a?(Hash)
|
20
|
+
@details = hash
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
require 'rgen/metamodel_builder'
|
2
|
+
|
3
|
+
module RGen
|
4
|
+
|
5
|
+
module MetamodelBuilder
|
6
|
+
|
7
|
+
class MetamodelDescription
|
8
|
+
|
9
|
+
attr_reader :etype, :impl_type
|
10
|
+
|
11
|
+
def self.default_value(prop)
|
12
|
+
checkProperty(prop)
|
13
|
+
defaultValues[prop]
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.has_default?(prop)
|
17
|
+
checkProperty(prop)
|
18
|
+
defaultValues.has_key?(prop)
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(props)
|
22
|
+
@props = props.dup
|
23
|
+
end
|
24
|
+
|
25
|
+
def value(prop)
|
26
|
+
self.class.checkProperty(prop)
|
27
|
+
@props[prop]
|
28
|
+
end
|
29
|
+
|
30
|
+
def annotations
|
31
|
+
@annotations ||= []
|
32
|
+
end
|
33
|
+
|
34
|
+
def many?
|
35
|
+
value(:upperBound) > 1 || value(:upperBound) == -1
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def setupDefaults
|
41
|
+
self.class.propertySet.each do |p|
|
42
|
+
@props[p] = self.class.default_value(p) unless @props.has_key?(p)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def checkAllPropertiesSet
|
47
|
+
self.class.propertySet.each do |p|
|
48
|
+
raise StandardError.new("'#{p}' property not set") if !self.class.optionalProperties.include?(p) && @props[p].nil?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def checkForInvalidProperties
|
53
|
+
@props.keys.each do |p|
|
54
|
+
raise StandardError.new("invalid property #{p}") unless self.class.propertySet.include?(p)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def descendent?(clazz1, clazz2)
|
61
|
+
return true if clazz1 == clazz2 || clazz1.superclass == clazz2
|
62
|
+
return false if clazz1.superclass.nil?
|
63
|
+
descendent?(clazz1.superclass, clazz2)
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.checkProperty(prop)
|
67
|
+
raise ArgumentError.new("Not a valid property: #{prop}") unless propertySet.include?(prop)
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_s
|
71
|
+
self.class.to_s + ": " +
|
72
|
+
self.class.propertySet.collect{|p| "#{p}=>#{value(p)}"}.join(", ")
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.propertySet
|
76
|
+
[ :name ]
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
def self.optionalProperties
|
81
|
+
[]
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.defaultValues
|
85
|
+
{ }
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.typeMap
|
89
|
+
{ :EString => String,
|
90
|
+
:EInt => Integer,
|
91
|
+
:EFloat => Float,
|
92
|
+
:EBoolean => RGen::MetamodelBuilder::DataTypes::Boolean,
|
93
|
+
:EJavaObject => Object,
|
94
|
+
:ERubyObject => Object,
|
95
|
+
:EJavaClass => Class,
|
96
|
+
:ERubyClass => Class }
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
# DERIVED: ordered = true, unique = false, lowerBound = 0/1, upperBound = 1
|
102
|
+
# DERIVED: when :derived : changeable= false, :volatile=true, transient=true
|
103
|
+
class AttributeDescription < MetamodelDescription
|
104
|
+
|
105
|
+
def initialize(type, props)
|
106
|
+
super(props)
|
107
|
+
# type default
|
108
|
+
type ||= :EString
|
109
|
+
setupType(type)
|
110
|
+
# fixed values can not be changed by user
|
111
|
+
setupDefaults
|
112
|
+
checkForInvalidProperties
|
113
|
+
if @props[:derived]
|
114
|
+
@props[:changeable] = false
|
115
|
+
@props[:volatile] = true
|
116
|
+
@props[:transient] = true
|
117
|
+
end
|
118
|
+
checkAllPropertiesSet
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
def setupType(type)
|
124
|
+
if self.class.typeMap.keys.include?(type)
|
125
|
+
@etype = type
|
126
|
+
@impl_type = self.class.typeMap[type]
|
127
|
+
elsif self.class.typeMap.invert.keys.include?(type)
|
128
|
+
@etype = self.class.typeMap.invert[type]
|
129
|
+
@impl_type = type
|
130
|
+
elsif type.is_a?(RGen::MetamodelBuilder::DataTypes::Enum)
|
131
|
+
@etype = :EEnumerable
|
132
|
+
@impl_type = type
|
133
|
+
else
|
134
|
+
raise ArgumentError.new("Type invalid: " + type.to_s)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.propertySet
|
139
|
+
super | [
|
140
|
+
:ordered,
|
141
|
+
:unique,
|
142
|
+
:changeable,
|
143
|
+
:volatile,
|
144
|
+
:transient,
|
145
|
+
:unsettable,
|
146
|
+
:derived,
|
147
|
+
:lowerBound,
|
148
|
+
:upperBound,
|
149
|
+
:defaultValueLiteral ]
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.optionalProperties
|
153
|
+
super | [
|
154
|
+
:defaultValueLiteral
|
155
|
+
]
|
156
|
+
end
|
157
|
+
|
158
|
+
def self.defaultValues
|
159
|
+
super.merge(
|
160
|
+
{ :ordered => true,
|
161
|
+
:unique => true,
|
162
|
+
:changeable => true,
|
163
|
+
:volatile => false,
|
164
|
+
:transient => false,
|
165
|
+
:unsettable => false,
|
166
|
+
:derived => false,
|
167
|
+
:lowerBound => 0 })
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
# DERIVED default: lowerBound => 0/1 (required?), upperBound => 1/-1 (many?), containment (contains_xxx?),
|
173
|
+
# DERIVED: when :derived : changeable= false, :volatile=true, transient=true
|
174
|
+
class ReferenceDescription < MetamodelDescription
|
175
|
+
attr_accessor :opposite
|
176
|
+
|
177
|
+
def initialize(type, props)
|
178
|
+
super(props)
|
179
|
+
setupType(type)
|
180
|
+
setupDefaults
|
181
|
+
checkForInvalidProperties
|
182
|
+
if @props[:derived]
|
183
|
+
@props[:changeable] = false
|
184
|
+
@props[:volatile] = true
|
185
|
+
@props[:transient] = true
|
186
|
+
end
|
187
|
+
checkAllPropertiesSet
|
188
|
+
end
|
189
|
+
|
190
|
+
private
|
191
|
+
|
192
|
+
def setupType(type)
|
193
|
+
if type.is_a?(Class) && descendent?(type, RGen::MetamodelBuilder::MMBase)
|
194
|
+
@etype = nil
|
195
|
+
@impl_type = type
|
196
|
+
else
|
197
|
+
raise ArgumentError.new("Type is not a MMBase: " + type.to_s)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def self.propertySet
|
202
|
+
super | [
|
203
|
+
:ordered,
|
204
|
+
:unique,
|
205
|
+
:changeable,
|
206
|
+
:volatile,
|
207
|
+
:transient,
|
208
|
+
:unsettable,
|
209
|
+
:derived,
|
210
|
+
:lowerBound,
|
211
|
+
:upperBound,
|
212
|
+
:resolveProxies,
|
213
|
+
:containment ]
|
214
|
+
end
|
215
|
+
|
216
|
+
def self.defaultValues
|
217
|
+
super.merge({
|
218
|
+
:ordered => true,
|
219
|
+
:unique => true,
|
220
|
+
:changeable => true,
|
221
|
+
:volatile => false,
|
222
|
+
:transient => false,
|
223
|
+
:unsettable => false,
|
224
|
+
:derived => false,
|
225
|
+
:lowerBound => 0,
|
226
|
+
:resolveProxies => true })
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
|
232
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
module RGen
|
3
|
+
|
4
|
+
module MetamodelBuilder
|
5
|
+
|
6
|
+
def self.MMMultiple(*superclasses)
|
7
|
+
c = Class.new(MMBase)
|
8
|
+
class << c
|
9
|
+
attr_reader :multiple_superclasses
|
10
|
+
end
|
11
|
+
c.instance_variable_set(:@multiple_superclasses, superclasses)
|
12
|
+
superclasses.collect{|sc| sc.ancestors}.flatten.
|
13
|
+
reject{|m| m.is_a?(Class)}.each do |arg|
|
14
|
+
c.instance_eval do
|
15
|
+
include arg
|
16
|
+
end
|
17
|
+
end
|
18
|
+
return c
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rgen/ecore/ecore_instantiator'
|
2
|
+
require 'rgen/metamodel_builder/intermediate/annotation'
|
3
|
+
|
4
|
+
module RGen
|
5
|
+
|
6
|
+
module MetamodelBuilder
|
7
|
+
|
8
|
+
# This module is used to extend modules which should be
|
9
|
+
# part of RGen metamodels
|
10
|
+
module ModuleExtension
|
11
|
+
include RGen::ECore::ECoreInstantiator
|
12
|
+
|
13
|
+
def annotation(hash)
|
14
|
+
_annotations << Intermediate::Annotation.new(hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
def _annotations
|
18
|
+
@_annotations ||= []
|
19
|
+
end
|
20
|
+
|
21
|
+
def final_method(m)
|
22
|
+
@final_methods ||= []
|
23
|
+
@final_methods << m
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_added(m)
|
27
|
+
raise "Method #{m} can not be redefined" if @final_methods && @final_methods.include?(m)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rgen/ecore/ecore'
|
2
|
+
|
3
|
+
module RGen
|
4
|
+
|
5
|
+
module ModelComparator
|
6
|
+
|
7
|
+
# This method compares to models regarding equality
|
8
|
+
# For this the identity of a model element is defined based on identity
|
9
|
+
# of all attributes and referenced elements.
|
10
|
+
# Arrays are sorted before comparison if possible (if <=> is provided).
|
11
|
+
#
|
12
|
+
def modelEqual?(a, b, featureIgnoreList=[])
|
13
|
+
@modelEqual_visited = {}
|
14
|
+
_modelEqual_internal(a, b, featureIgnoreList, [])
|
15
|
+
end
|
16
|
+
|
17
|
+
def _modelEqual_internal(a, b, featureIgnoreList, path)
|
18
|
+
return true if @modelEqual_visited[[a,b]]
|
19
|
+
@modelEqual_visited[[a,b]] = true
|
20
|
+
return true if a.nil? && b.nil?
|
21
|
+
unless a.class == b.class
|
22
|
+
puts "#{path.inspect}\n Classes differ: #{a} vs. #{b}"
|
23
|
+
return false
|
24
|
+
end
|
25
|
+
if a.is_a?(Array)
|
26
|
+
unless a.size == b.size
|
27
|
+
puts "#{path.inspect}\n Array size differs: #{a.size} vs. #{b.size}"
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
as = a
|
31
|
+
as = a.sort if a.all?{|o| o.respond_to?('<=>')}
|
32
|
+
bs = b
|
33
|
+
bs = b.sort if b.all?{|o| o.respond_to?('<=>')}
|
34
|
+
a.each_index do |i|
|
35
|
+
return false unless _modelEqual_internal(as[i], bs[i], featureIgnoreList, path+[i])
|
36
|
+
end
|
37
|
+
else
|
38
|
+
a.class.ecore.eAllStructuralFeatures.reject{|f| f.derived}.each do |feat|
|
39
|
+
next if featureIgnoreList.include?(feat.name)
|
40
|
+
if feat.eType.is_a?(RGen::ECore::EDataType)
|
41
|
+
unless a.getGeneric(feat.name) == b.getGeneric(feat.name)
|
42
|
+
puts "#{path.inspect}\n Value '#{feat.name}' differs: #{a.getGeneric(feat.name)} vs. #{b.getGeneric(feat.name)}"
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
else
|
46
|
+
return false unless _modelEqual_internal(a.getGeneric(feat.name), b.getGeneric(feat.name), featureIgnoreList, path+["#{a.respond_to?(:name) && a.name}:#{feat.name}"])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
return true
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|