rgen 0.8.3 → 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +5 -1
- data/Project.yaml +21 -0
- data/Rakefile +7 -0
- data/lib/rgen/ecore/ecore_to_json.rb +188 -0
- data/lib/rgen/ecore/ecore_to_ruby.rb +13 -0
- data/lib/rgen/metamodel_builder/builder_extensions.rb +1 -1
- data/test/metamodel_builder_test.rb +19 -11
- data/test/template_language_test.rb +3 -3
- metadata +38 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e58b57346e1f7e95fcaa15f29112706c911d20ed
|
4
|
+
data.tar.gz: 6551cb4e9579f7e76582018876973edd9a58d0e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e82e58dd4eaf95de47ef1714a778558a6bd3cb76f8229fb43e029a98f9e03c6234ee2fab831adde1d7de1b953665afab031f27f39b0ad7a060a91c4ed7c7328
|
7
|
+
data.tar.gz: 47b73a00783a82d630b0771fb55b01c4da6adffe73a459cd35828dd5040644b8b0f6cd00a565a4abf257d8c4d2e97ca17db2c072cbe05e8ae44fe9b2b3a2637e
|
data/CHANGELOG
CHANGED
@@ -217,4 +217,8 @@
|
|
217
217
|
=0.8.3
|
218
218
|
|
219
219
|
* Performance improvement: getGeneric made a lot faster
|
220
|
-
|
220
|
+
|
221
|
+
=0.8.4
|
222
|
+
|
223
|
+
* Add early loading for types which have attributes conflicting with Ruby reserved words.
|
224
|
+
* Change type checking code to use ObjectSpace to find class objects. This is to find classes with an unbound name.
|
data/Project.yaml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
name: rgen
|
2
|
+
gemspec: rgen.gemspec
|
3
|
+
git: https://github.com/mthiede/rgen.git
|
4
|
+
version: 0.8.4
|
5
|
+
summary: Ruby Modelling and Generator Framework
|
6
|
+
email: martin dot thiede at gmx de
|
7
|
+
homepage: http://ruby-gen.org
|
8
|
+
rubyforge_project: rgen
|
9
|
+
description: RGen is a framework for Model Driven Software Development (MDSD) in Ruby. This means that it helps you build Metamodels, instantiate Models, modify and transform Models and finally generate arbitrary textual content from it.
|
10
|
+
authors: [Martin Thiede]
|
11
|
+
rdoc_options: [--main, README.rdoc, -x, test, -x, metamodels, -x, ea_support/uml13*]
|
12
|
+
extra_rdoc_files: [README.rdoc, CHANGELOG, MIT-LICENSE]
|
13
|
+
include_files: ['lib/**/*', 'test/**/*', README.rdoc, CHANGELOG, MIT-LICENSE, Rakefile]
|
14
|
+
exclude_files: ['**/*.bak']
|
15
|
+
encrypt_sources: false
|
16
|
+
dependencies:
|
17
|
+
https://rubygems.org:
|
18
|
+
- {name: nokogiri, version: ['~> 1.6.0', '>= 1.6.8.1'], development: true}
|
19
|
+
- {name: rake, version: '~> 12.0', development: true}
|
20
|
+
- {name: minitest, version: ['~> 5.0', '>= 5.10.1'], development: true}
|
21
|
+
- {name: minitest-fail-fast, version: '~> 0.1.0', development: true}
|
data/Rakefile
CHANGED
@@ -29,3 +29,10 @@ end
|
|
29
29
|
task :release => [:prepare_package_rdoc, :package]
|
30
30
|
|
31
31
|
task :clobber => [:clobber_rdoc, :clobber_package]
|
32
|
+
|
33
|
+
task :ecore_to_json do
|
34
|
+
require 'rgen/ecore/ecore_to_json'
|
35
|
+
|
36
|
+
exporter = RGen::ECore::ECoreToJson.new
|
37
|
+
File.write('ecore.json', exporter.epackage_to_json_string(RGen.ecore, exporter.ecore_datatypes))
|
38
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'rgen/ecore/ecore'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module RGen
|
5
|
+
|
6
|
+
module ECore
|
7
|
+
|
8
|
+
# ECoreToJson can turn ECore models into their JSON metamodel representations
|
9
|
+
class ECoreToJson
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
def root_elements_to_json_string(root_elements)
|
16
|
+
JSON.pretty_generate(root_elements.map do |el|
|
17
|
+
if el.is_a?(RGen::ECore::EPackage)
|
18
|
+
epackage(el)
|
19
|
+
elsif el.is_a?(RGen::ECore::EClass)
|
20
|
+
eclass(el)
|
21
|
+
else
|
22
|
+
raise "Not implemented for #{el}"
|
23
|
+
end
|
24
|
+
end)
|
25
|
+
end
|
26
|
+
|
27
|
+
def epackage_to_json(package)
|
28
|
+
epackage(package)
|
29
|
+
end
|
30
|
+
|
31
|
+
def ecore_datatypes
|
32
|
+
[RGen::ECore::EString, RGen::ECore::EInt, RGen::ECore::ELong, RGen::ECore::EBoolean, RGen::ECore::EFloat,
|
33
|
+
RGen::ECore::ERubyObject, RGen::ECore::EJavaObject, RGen::ECore::ERubyClass, RGen::ECore::EJavaClass]
|
34
|
+
.map {|dt| edatatype(dt)}
|
35
|
+
end
|
36
|
+
|
37
|
+
def epackage_to_json_pretty_string(package, append = [])
|
38
|
+
JSON.pretty_generate([epackage_to_json(package)] + append)
|
39
|
+
end
|
40
|
+
|
41
|
+
def epackage_to_json_string(package, append = [])
|
42
|
+
JSON.generate([epackage_to_json(package)] + append)
|
43
|
+
end
|
44
|
+
|
45
|
+
def emodelelement(me)
|
46
|
+
{
|
47
|
+
:eAnnotations => me.eAnnotations.map { |e| eannotation(e) }
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def enamedelement(ne)
|
53
|
+
merge(emodelelement(ne), {:name => ne.name})
|
54
|
+
end
|
55
|
+
|
56
|
+
def epackage(package)
|
57
|
+
merge(enamedelement(package), {
|
58
|
+
:_class_ref => 'RGen.ECore.EPackage',
|
59
|
+
:eClassifiers => package.eClassifiers.map do |classifier|
|
60
|
+
if classifier.is_a?(RGen::ECore::EClass)
|
61
|
+
eclass(classifier)
|
62
|
+
elsif classifier.is_a?(RGen::ECore::EEnum)
|
63
|
+
eenum(classifier)
|
64
|
+
else
|
65
|
+
edatatype(classifier)
|
66
|
+
end
|
67
|
+
end,
|
68
|
+
:eSubpackages => package.eSubpackages.map { |sp| epackage(sp) },
|
69
|
+
:nsURI => package.nsURI,
|
70
|
+
:nsPrefix => package.nsPrefix
|
71
|
+
})
|
72
|
+
end
|
73
|
+
|
74
|
+
def eclassifier(classifier)
|
75
|
+
enamedelement(classifier).merge({
|
76
|
+
# omit :instanceClassName => classifier.instanceClassName
|
77
|
+
})
|
78
|
+
end
|
79
|
+
|
80
|
+
def eclass(_class)
|
81
|
+
merge(eclassifier(_class), {
|
82
|
+
:_class_ref => 'RGen.ECore.EClass',
|
83
|
+
:abstract => _class.abstract,
|
84
|
+
:interface => _class.interface,
|
85
|
+
:eStructuralFeatures => _class.eStructuralFeatures.map do |sf|
|
86
|
+
if sf.is_a?(RGen::ECore::EReference)
|
87
|
+
ereference(sf)
|
88
|
+
else
|
89
|
+
eattribute(sf)
|
90
|
+
end
|
91
|
+
end,
|
92
|
+
:eSuperTypes => _class.eSuperTypes.map { |st| {:_ref => ref_id(st)} }
|
93
|
+
})
|
94
|
+
end
|
95
|
+
|
96
|
+
def edatatype(_datatype)
|
97
|
+
merge(eclassifier(_datatype), {
|
98
|
+
:_class_ref => 'RGen.ECore.EDataType',
|
99
|
+
:serializable => _datatype.serializable,
|
100
|
+
:instanceClassName => _datatype.instanceClassName
|
101
|
+
})
|
102
|
+
end
|
103
|
+
|
104
|
+
def eenum(enum)
|
105
|
+
merge(edatatype(enum), {
|
106
|
+
:_class_ref => 'RGen.ECore.EEnum',
|
107
|
+
:eLiterals => enum.eLiterals.map do |l|
|
108
|
+
merge({}, {
|
109
|
+
:_class_ref => 'RGen.ECore.EEnumLiteral',
|
110
|
+
:value => l.value,
|
111
|
+
:literal => l.literal
|
112
|
+
})
|
113
|
+
end
|
114
|
+
})
|
115
|
+
end
|
116
|
+
|
117
|
+
def eannotation(e)
|
118
|
+
merge(emodelelement(e), {
|
119
|
+
:source => e.source,
|
120
|
+
:details => e.details.map do |d|
|
121
|
+
merge({}, {
|
122
|
+
:_class_ref => 'RGen.ECore.EStringToStringMapEntry',
|
123
|
+
:key => d.key,
|
124
|
+
:value => d.value
|
125
|
+
})
|
126
|
+
end
|
127
|
+
})
|
128
|
+
end
|
129
|
+
|
130
|
+
def etypedelement(te)
|
131
|
+
merge(enamedelement(te), {
|
132
|
+
:ordered => te.ordered,
|
133
|
+
:unique => te.unique,
|
134
|
+
:lowerBound => te.lowerBound,
|
135
|
+
:upperBound => te.upperBound,
|
136
|
+
:many => te.many,
|
137
|
+
:required => te.required,
|
138
|
+
:eType => {:_ref => te.eType ? ref_id(te.eType) : nil}
|
139
|
+
})
|
140
|
+
end
|
141
|
+
|
142
|
+
def estructuralfeature(sf)
|
143
|
+
merge(etypedelement(sf), {
|
144
|
+
:changeable => sf.changeable,
|
145
|
+
:volatile => sf.volatile,
|
146
|
+
:transient => sf.transient,
|
147
|
+
:defaultValueLiteral => sf.defaultValueLiteral,
|
148
|
+
:unsettable => sf.unsettable,
|
149
|
+
:derived => sf.derived,
|
150
|
+
})
|
151
|
+
end
|
152
|
+
|
153
|
+
def eattribute(attr)
|
154
|
+
merge(estructuralfeature(attr), {
|
155
|
+
:_class_ref => 'RGen.ECore.EAttribute',
|
156
|
+
:iD => attr.iD
|
157
|
+
})
|
158
|
+
end
|
159
|
+
|
160
|
+
def ereference(ref)
|
161
|
+
merge(estructuralfeature(ref), {
|
162
|
+
:_class_ref => 'RGen.ECore.EReference',
|
163
|
+
:containment => ref.containment,
|
164
|
+
:resolveProxies => ref.resolveProxies,
|
165
|
+
:eOpposite => ref.eOpposite ? {:_ref => "#{ref_id(ref.eOpposite.eContainer)}.#{ref.eOpposite.name}"} : nil
|
166
|
+
})
|
167
|
+
end
|
168
|
+
|
169
|
+
def ref_id(obj)
|
170
|
+
res = ref_parts(obj)
|
171
|
+
res.join('.')
|
172
|
+
end
|
173
|
+
|
174
|
+
def ref_parts(obj)
|
175
|
+
return [obj.name] unless obj&.eContainer
|
176
|
+
ref_parts(obj.eContainer) << obj.name
|
177
|
+
end
|
178
|
+
|
179
|
+
def merge(hash, values)
|
180
|
+
values.each { |k, v| hash[k] = v unless v.nil? }
|
181
|
+
hash
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'set'
|
1
2
|
require 'rgen/ecore/ecore'
|
2
3
|
|
3
4
|
module RGen
|
@@ -11,6 +12,7 @@ class ECoreToRuby
|
|
11
12
|
@modules = {}
|
12
13
|
@classifiers = {}
|
13
14
|
@features_added = {}
|
15
|
+
@reserved = Set.new(Object.methods)
|
14
16
|
end
|
15
17
|
|
16
18
|
# Create a Ruby module representing +epackage+.
|
@@ -50,12 +52,23 @@ class ECoreToRuby
|
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
55
|
+
load_classes_with_reserved_keywords(epackage)
|
53
56
|
mod
|
54
57
|
end
|
55
58
|
end
|
56
59
|
|
57
60
|
private
|
58
61
|
|
62
|
+
def load_classes_with_reserved_keywords(epackage)
|
63
|
+
epackage.eAllClassifiers.each do |eclass|
|
64
|
+
# we early load classes which have ruby reserved keywords
|
65
|
+
if eclass.is_a?(RGen::ECore::EClass)
|
66
|
+
reserved_used = eclass.eStructuralFeatures.any? { |f| @reserved.include?(f.name.to_sym) }
|
67
|
+
add_features(eclass) if reserved_used
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
59
72
|
def create_module_internal(epackage, under, temp)
|
60
73
|
return @modules[epackage] if @modules[epackage]
|
61
74
|
|
@@ -539,7 +539,7 @@ module BuilderExtensions
|
|
539
539
|
code << "\n"
|
540
540
|
expected = "Integer"
|
541
541
|
elsif props.impl_type.is_a?(Class)
|
542
|
-
code << "unless #{varname}.nil? || #{varname}.is_a?(#{props.impl_type}) || #{varname}.is_a?(MMGeneric)"
|
542
|
+
code << "unless #{varname}.nil? || #{varname}.is_a?(ObjectSpace._id2ref(#{props.impl_type.object_id})) || #{varname}.is_a?(MMGeneric)"
|
543
543
|
code << " || #{varname}.is_a?(BigDecimal)" if props.impl_type == Float && defined?(BigDecimal)
|
544
544
|
code << "\n"
|
545
545
|
expected = props.impl_type.to_s
|
@@ -170,10 +170,12 @@ class MetamodelBuilderTest < MiniTest::Test
|
|
170
170
|
|
171
171
|
class ReservedNameClass < RGen::MetamodelBuilder::MMBase
|
172
172
|
has_attr 'class', String
|
173
|
+
has_attr 'method', String
|
173
174
|
end
|
174
175
|
|
175
176
|
class ManyReservedNameClass < RGen::MetamodelBuilder::MMBase
|
176
177
|
has_many_attr 'class', String
|
178
|
+
has_many_attr 'method', String
|
177
179
|
end
|
178
180
|
|
179
181
|
end
|
@@ -1488,22 +1490,28 @@ class MetamodelBuilderTest < MiniTest::Test
|
|
1488
1490
|
|
1489
1491
|
def test_reserved_names
|
1490
1492
|
e = mm::ReservedNameClass.new
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1493
|
+
%w(class method).each do |reserved|
|
1494
|
+
e.setGeneric(reserved, "X")
|
1495
|
+
assert_equal "X", e.getGeneric(reserved.to_sym)
|
1496
|
+
assert_equal "X", e.getGeneric(reserved)
|
1497
|
+
assert_equal ["X"], e.getGenericAsArray(reserved.to_sym)
|
1498
|
+
assert_equal ["X"], e.getGenericAsArray(reserved)
|
1499
|
+
end
|
1496
1500
|
assert_equal "X", e.getClass
|
1501
|
+
assert_equal "X", e.getMethod
|
1497
1502
|
end
|
1498
1503
|
|
1499
1504
|
def test_reserved_names_many
|
1500
1505
|
e = mm::ManyReservedNameClass.new
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1506
|
+
%w(class method).each do |reserved|
|
1507
|
+
e.addGeneric(reserved, "X")
|
1508
|
+
e.addGeneric(reserved, "Y")
|
1509
|
+
assert_equal ["X", "Y"], e.getGeneric(reserved.to_sym)
|
1510
|
+
assert_equal ["X", "Y"], e.getGeneric(reserved)
|
1511
|
+
assert_equal ["X", "Y"], e.getGenericAsArray(reserved.to_sym)
|
1512
|
+
assert_equal ["X", "Y"], e.getGenericAsArray(reserved)
|
1513
|
+
end
|
1507
1514
|
assert_equal ["X", "Y"], e.getClass
|
1515
|
+
assert_equal ["X", "Y"], e.getMethod
|
1508
1516
|
end
|
1509
1517
|
end
|
@@ -181,13 +181,13 @@ class TemplateContainerTest < MiniTest::Test
|
|
181
181
|
tc.expand('line_endings/mixed::Mixed', :for => :dummy)
|
182
182
|
|
183
183
|
unix = binread(OUTPUT_DIR+'/line_endings_unix.txt')
|
184
|
-
assert unix.include?("|\n") && !unix.include?("|\r\n")
|
184
|
+
assert unix.include?("|\n") && !unix.include?("|\r\n"), unix
|
185
185
|
|
186
186
|
windows = binread(OUTPUT_DIR+'/line_endings_windows.txt')
|
187
|
-
assert windows.include?("|\r\n") && !windows.include?("|\n")
|
187
|
+
assert windows.include?("|\r\n") && !windows.include?("|\n"), windows
|
188
188
|
|
189
189
|
mixed = binread(OUTPUT_DIR+'/line_endings_mixed.txt')
|
190
|
-
assert mixed.include?("|\r\n") && mixed.include?("|\n")
|
190
|
+
assert mixed.include?("|\r\n") && mixed.include?("|\n"), mixed
|
191
191
|
end
|
192
192
|
|
193
193
|
def test_ws
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rgen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Thiede
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -16,7 +16,7 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.6.0
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: 1.6.8.1
|
@@ -26,17 +26,31 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 1.6.0
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 1.6.8.1
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rake
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '12.0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '12.0'
|
33
47
|
- !ruby/object:Gem::Dependency
|
34
48
|
name: minitest
|
35
49
|
requirement: !ruby/object:Gem::Requirement
|
36
50
|
requirements:
|
37
51
|
- - "~>"
|
38
52
|
- !ruby/object:Gem::Version
|
39
|
-
version: '5.
|
53
|
+
version: '5.0'
|
40
54
|
- - ">="
|
41
55
|
- !ruby/object:Gem::Version
|
42
56
|
version: 5.10.1
|
@@ -46,14 +60,28 @@ dependencies:
|
|
46
60
|
requirements:
|
47
61
|
- - "~>"
|
48
62
|
- !ruby/object:Gem::Version
|
49
|
-
version: '5.
|
63
|
+
version: '5.0'
|
50
64
|
- - ">="
|
51
65
|
- !ruby/object:Gem::Version
|
52
66
|
version: 5.10.1
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: minitest-fail-fast
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 0.1.0
|
74
|
+
type: :development
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - "~>"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 0.1.0
|
53
81
|
description: RGen is a framework for Model Driven Software Development (MDSD) in Ruby.
|
54
82
|
This means that it helps you build Metamodels, instantiate Models, modify and transform
|
55
83
|
Models and finally generate arbitrary textual content from it.
|
56
|
-
email:
|
84
|
+
email:
|
57
85
|
executables: []
|
58
86
|
extensions: []
|
59
87
|
extra_rdoc_files:
|
@@ -63,6 +91,7 @@ extra_rdoc_files:
|
|
63
91
|
files:
|
64
92
|
- CHANGELOG
|
65
93
|
- MIT-LICENSE
|
94
|
+
- Project.yaml
|
66
95
|
- README.rdoc
|
67
96
|
- Rakefile
|
68
97
|
- lib/ea_support/ea_support.rb
|
@@ -84,6 +113,7 @@ files:
|
|
84
113
|
- lib/rgen/ecore/ecore_builder_methods.rb
|
85
114
|
- lib/rgen/ecore/ecore_ext.rb
|
86
115
|
- lib/rgen/ecore/ecore_interface.rb
|
116
|
+
- lib/rgen/ecore/ecore_to_json.rb
|
87
117
|
- lib/rgen/ecore/ecore_to_ruby.rb
|
88
118
|
- lib/rgen/ecore/ruby_to_ecore.rb
|
89
119
|
- lib/rgen/environment.rb
|
@@ -247,7 +277,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
247
277
|
- !ruby/object:Gem::Version
|
248
278
|
version: '0'
|
249
279
|
requirements: []
|
250
|
-
rubyforge_project:
|
280
|
+
rubyforge_project:
|
251
281
|
rubygems_version: 2.5.2
|
252
282
|
signing_key:
|
253
283
|
specification_version: 4
|