codemodels 0.2.3-java → 0.2.5-java
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.
- checksums.yaml +7 -0
- data/codemodels.gemspec +1 -0
- data/lib/codemodels/artifact.rb +108 -0
- data/lib/codemodels/comparison.rb +23 -0
- data/lib/codemodels/metamodel.rb +8 -0
- data/lib/codemodels/navigation.rb +25 -7
- data/lib/codemodels/parsing.rb +1 -1
- data/lib/codemodels/position.rb +156 -0
- data/lib/codemodels/serialization.rb +7 -7
- data/lib/codemodels/source_info.rb +56 -92
- data/lib/codemodels/version.rb +1 -1
- data/test/test_foreign_navigation.rb +24 -2
- data/test/test_metamodel.rb +1 -1
- data/test/test_rgen_ext.rb +6 -11
- data/test/test_source_info.rb +139 -0
- metadata +24 -24
- data/lib/codemodels/rgen_ext.rb +0 -133
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: db4711f37b0bf8dbdc6c9cc22e232312889dcd17
|
4
|
+
data.tar.gz: 55535f102297a1c548586fb5016f9b27abcb7198
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 60e734f24988aafcf5d07dc7524e74dfbc0010a37aab4ec32f38fa594afd4f60650eede7cd147c8bdede81e9dfb536ea4a5a00d81bd385950bd6a0b8216b9db4
|
7
|
+
data.tar.gz: 8bd823ea12998d2bfaa51da2352c256c29936c75349273b49d608c85c40a8f84efbdbf16824fe0e7154516321f616cb94c924f9e95358836bdaef8cfdd536f98
|
data/codemodels.gemspec
CHANGED
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'codemodels/position'
|
2
|
+
|
3
|
+
module CodeModels
|
4
|
+
|
5
|
+
class AbstractArtifact
|
6
|
+
|
7
|
+
def point_to_absolute(point)
|
8
|
+
offset = absolute_start
|
9
|
+
p = SourcePoint.new
|
10
|
+
p.line = point.line + offset.line - 1
|
11
|
+
p.column = point.column
|
12
|
+
p.column += offset.column-1 if point.line==1
|
13
|
+
p
|
14
|
+
end
|
15
|
+
|
16
|
+
def position_to_absolute(position)
|
17
|
+
pos = SourcePosition.new
|
18
|
+
pos.begin_point = point_to_absolute(position.begin_point)
|
19
|
+
pos.end_point = point_to_absolute(position.end_point)
|
20
|
+
pos
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
class EmbeddedArtifact < AbstractArtifact
|
26
|
+
attr_accessor :host_artifact
|
27
|
+
attr_accessor :position_in_host
|
28
|
+
|
29
|
+
def absolute_start
|
30
|
+
p = host_artifact.absolute_start
|
31
|
+
p.line += position_in_host.begin_point.line-1
|
32
|
+
if position_in_host.begin_point.line==1
|
33
|
+
# if I am on the first line of my "host", its column
|
34
|
+
# matters because there are not newlines to reset the column
|
35
|
+
# counter
|
36
|
+
p.column += position_in_host.begin_point.column-1
|
37
|
+
else
|
38
|
+
p.column = position_in_host.begin_point.column
|
39
|
+
end
|
40
|
+
p
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
"Embedded in (#{@host_artifact.to_s}) at #{position_in_host}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def final_host
|
48
|
+
host_artifact.final_host
|
49
|
+
end
|
50
|
+
|
51
|
+
def code
|
52
|
+
position_in_host.get_string(host_artifact.code)
|
53
|
+
end
|
54
|
+
|
55
|
+
def embedded?
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
def embedding_level
|
60
|
+
@host_artifact.embedding_level+1
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
class FileArtifact < AbstractArtifact
|
66
|
+
attr_reader :filename
|
67
|
+
attr_reader :code
|
68
|
+
|
69
|
+
def initialize(filename,code)
|
70
|
+
@filename = filename
|
71
|
+
@code = code
|
72
|
+
end
|
73
|
+
|
74
|
+
def absolute_start
|
75
|
+
sp = SourcePoint.new
|
76
|
+
sp.line = 1
|
77
|
+
sp.column = 1
|
78
|
+
sp
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_s
|
82
|
+
"File #{filename}"
|
83
|
+
end
|
84
|
+
|
85
|
+
def final_host
|
86
|
+
self
|
87
|
+
end
|
88
|
+
|
89
|
+
def embedded?
|
90
|
+
false
|
91
|
+
end
|
92
|
+
|
93
|
+
def embedding_level
|
94
|
+
0
|
95
|
+
end
|
96
|
+
|
97
|
+
def eql?(other)
|
98
|
+
return false unless other.is_a?(FileArtifact)
|
99
|
+
self.filename==other.filename && self.code==other.code
|
100
|
+
end
|
101
|
+
|
102
|
+
def ==(other)
|
103
|
+
self.eql?(other)
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module CodeModels
|
2
|
+
|
3
|
+
module ComparisonModule
|
4
|
+
|
5
|
+
def eql?(other)
|
6
|
+
return false unless RGen::Ext::Comparison::DeepComparator.eql?(self,other)
|
7
|
+
if self.respond_to?(:source) || other.respond_to?(:source)
|
8
|
+
return false if (self.source==nil) != (other.source==nil)
|
9
|
+
return true if self.source==nil
|
10
|
+
return false if (self.source.position==nil) != (other.source.position==nil)
|
11
|
+
return true if self.source.position==nil
|
12
|
+
return self.source.position(:absolute)==other.source.position(:absolute)
|
13
|
+
end
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
def ==(other)
|
18
|
+
eql? other
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/lib/codemodels/metamodel.rb
CHANGED
@@ -1,17 +1,25 @@
|
|
1
1
|
require 'rgen/metamodel_builder'
|
2
|
+
require 'rgen/ext'
|
2
3
|
require 'codemodels/source_info'
|
3
4
|
require 'codemodels/navigation'
|
4
5
|
require 'codemodels/info_extraction'
|
5
6
|
require 'codemodels/serialization'
|
7
|
+
require 'codemodels/comparison'
|
6
8
|
|
7
9
|
module CodeModels
|
8
10
|
|
9
11
|
# All AST nodes built with CodeModels should derive from this one
|
10
12
|
class CodeModelsAstNode < RGen::MetamodelBuilder::MMBase
|
13
|
+
|
14
|
+
class << self
|
15
|
+
include RGen::Ext::InstantiationExtensions
|
16
|
+
end
|
17
|
+
|
11
18
|
include SourceInfoExtensions
|
12
19
|
include ForeignAstExtensions
|
13
20
|
include HostPositionExtensions
|
14
21
|
include NavigationExtensions
|
22
|
+
include ComparisonModule
|
15
23
|
include InfoExtraction::InfoExtractionFunctionalities
|
16
24
|
include Serialization::SerializationFunctionalities
|
17
25
|
end
|
@@ -9,7 +9,7 @@ module NavigationExtensions
|
|
9
9
|
# Awful hack to forbid the same reference is visited twice when
|
10
10
|
# two references with the same name are found
|
11
11
|
already_used_references = []
|
12
|
-
ecore.eAllReferences.select {|r| r.containment}.each do |ref|
|
12
|
+
ecore.eAllReferences.sort_by{|r| r.name}.select {|r| r.containment}.each do |ref|
|
13
13
|
#raise "Too many features with name #{ref.name}. Count: #{features_by_name(ref.name).count}" if features_by_name(ref.name).count!=1
|
14
14
|
unless already_used_references.include?(ref.name)
|
15
15
|
res = self.send(ref.name.to_sym)
|
@@ -49,6 +49,14 @@ module NavigationExtensions
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
def values_map(flags=nil)
|
53
|
+
if flags.include?(:deep)
|
54
|
+
collect_values_with_count_subtree(flags[:also_foreign])
|
55
|
+
else
|
56
|
+
collect_values_with_count
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
52
60
|
def collect_values_with_count
|
53
61
|
values = Hash.new {|h,k| h[k]=0}
|
54
62
|
self.class.ecore.eAllAttributes.each do |a|
|
@@ -95,15 +103,21 @@ module NavigationExtensions
|
|
95
103
|
end
|
96
104
|
|
97
105
|
def container(flag=nil)
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
106
|
+
# a foreign child could have its own parent in the foreign ast, which is not part of the complexive AST
|
107
|
+
# the foreign parent has therefore the precedence.
|
108
|
+
also_foreign = (flag==:also_foreign)
|
109
|
+
if also_foreign && self.foreign_container
|
110
|
+
return self.foreign_container
|
102
111
|
else
|
103
|
-
|
112
|
+
return self.eContainer
|
104
113
|
end
|
105
114
|
end
|
106
115
|
|
116
|
+
def root(flag=nil)
|
117
|
+
return self unless self.container(flag)
|
118
|
+
self.container(flag).root(flag)
|
119
|
+
end
|
120
|
+
|
107
121
|
def all_children_also_foreign
|
108
122
|
all_children(:also_foreign)
|
109
123
|
end
|
@@ -113,7 +127,11 @@ module NavigationExtensions
|
|
113
127
|
end
|
114
128
|
|
115
129
|
def traverse_also_foreign(&block)
|
116
|
-
traverse(:also_foreign
|
130
|
+
traverse(:also_foreign,&block)
|
131
|
+
end
|
132
|
+
|
133
|
+
def container_also_foreign
|
134
|
+
container(:also_foreign)
|
117
135
|
end
|
118
136
|
|
119
137
|
end
|
data/lib/codemodels/parsing.rb
CHANGED
@@ -0,0 +1,156 @@
|
|
1
|
+
module CodeModels
|
2
|
+
|
3
|
+
class SourcePoint
|
4
|
+
include Comparable
|
5
|
+
|
6
|
+
attr_accessor :line, :column
|
7
|
+
|
8
|
+
def self.from_code_index(code,index)
|
9
|
+
l = line(code,index)
|
10
|
+
c = column(code,index)
|
11
|
+
SourcePoint.new(l,c)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(line=nil,column=nil)
|
15
|
+
self.line= line
|
16
|
+
self.column= column
|
17
|
+
end
|
18
|
+
|
19
|
+
def line=(v)
|
20
|
+
raise "Unvalid line #{v}" if v && v<1
|
21
|
+
@line = v
|
22
|
+
end
|
23
|
+
|
24
|
+
def column=(v)
|
25
|
+
# is valid only for newlines
|
26
|
+
raise "Unvalid column #{v}" if v && v<0
|
27
|
+
@column = v
|
28
|
+
end
|
29
|
+
|
30
|
+
def eql?(other)
|
31
|
+
other.line==line && other.column==column
|
32
|
+
end
|
33
|
+
|
34
|
+
def ==(other)
|
35
|
+
self.eql?(other)
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
"Line #{@line}, Col #{@column}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_absolute_index(s)
|
43
|
+
index = 0
|
44
|
+
lines = s.lines
|
45
|
+
(@line-1).times do
|
46
|
+
index+=lines.next.length
|
47
|
+
end
|
48
|
+
index+=@column
|
49
|
+
index-=1
|
50
|
+
index
|
51
|
+
|
52
|
+
# current_line = lines.next
|
53
|
+
# i=0
|
54
|
+
# c=0
|
55
|
+
# while c<@column
|
56
|
+
# c += current_line[i]=='\t' ? COLUMNS_FOR_TAB : 1
|
57
|
+
# i += 1
|
58
|
+
# end
|
59
|
+
|
60
|
+
# index+=c
|
61
|
+
# index-=1
|
62
|
+
# index
|
63
|
+
end
|
64
|
+
|
65
|
+
def <=>(other)
|
66
|
+
lc = self.line<=>other.line
|
67
|
+
if lc==0
|
68
|
+
self.column<=>other.column
|
69
|
+
else
|
70
|
+
lc
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def self.line(code,index)
|
77
|
+
piece = code[0..index]
|
78
|
+
return piece.lines.count+1 if code[index]=="\n"
|
79
|
+
piece.lines.count
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.column(code,index)
|
83
|
+
piece = code[0..index]
|
84
|
+
last_line = nil
|
85
|
+
piece.lines.each{|l| last_line=l}
|
86
|
+
return 0 if code[index]=="\n"
|
87
|
+
last_line.length
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class SourcePosition
|
92
|
+
attr_accessor :begin_point, :end_point
|
93
|
+
|
94
|
+
def self.from_code_indexes(code,begin_index,end_index)
|
95
|
+
SourcePosition.new(SourcePoint.from_code_index(code,begin_index),SourcePoint.from_code_index(code,end_index))
|
96
|
+
end
|
97
|
+
|
98
|
+
def initialize(begin_point=nil,end_point=nil)
|
99
|
+
@begin_point = begin_point
|
100
|
+
@end_point = end_point
|
101
|
+
end
|
102
|
+
|
103
|
+
def begin_line=(line)
|
104
|
+
@begin_point=SourcePoint.new unless @begin_point
|
105
|
+
@begin_point.line = line
|
106
|
+
end
|
107
|
+
|
108
|
+
def begin_column=(column)
|
109
|
+
@begin_point=SourcePoint.new unless @begin_point
|
110
|
+
@begin_point.column = column
|
111
|
+
end
|
112
|
+
|
113
|
+
def eql?(other)
|
114
|
+
return false unless other.respond_to?(:begin_point)
|
115
|
+
return false unless other.respond_to?(:end_point)
|
116
|
+
other.begin_point==begin_point && other.end_point==end_point
|
117
|
+
end
|
118
|
+
|
119
|
+
def ==(other)
|
120
|
+
self.eql?(other)
|
121
|
+
end
|
122
|
+
|
123
|
+
def to_s
|
124
|
+
"from #{@begin_point} to #{@end_point}"
|
125
|
+
end
|
126
|
+
|
127
|
+
def get_string(s)
|
128
|
+
as = @begin_point.to_absolute_index(s)
|
129
|
+
ae = @end_point.to_absolute_index(s)
|
130
|
+
s[as..ae]
|
131
|
+
end
|
132
|
+
|
133
|
+
def begin_line
|
134
|
+
@begin_point.line
|
135
|
+
end
|
136
|
+
|
137
|
+
def end_line
|
138
|
+
@end_point.line
|
139
|
+
end
|
140
|
+
|
141
|
+
def begin_column
|
142
|
+
@begin_point.column
|
143
|
+
end
|
144
|
+
|
145
|
+
def end_column
|
146
|
+
@end_point.column
|
147
|
+
end
|
148
|
+
|
149
|
+
def include?(other)
|
150
|
+
(self.begin_point <= other.begin_point) && (self.end_point >= other.end_point)
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# This code permit to transform
|
1
|
+
# This code permit to transform AstNode in Hash objects
|
2
2
|
# containing lists and single values
|
3
3
|
|
4
4
|
require 'json'
|
@@ -23,10 +23,10 @@ module SerializationFunctionalities
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
e_class = e_object.class.ecore
|
26
|
-
e_class.eAllAttributes.each do |a|
|
26
|
+
e_class.eAllAttributes.sort_by { |a| a.name }.each do |a|
|
27
27
|
jsonize_attr_value(map,a)
|
28
28
|
end
|
29
|
-
e_class.eAllReferences.each do |r|
|
29
|
+
e_class.eAllReferences.sort_by { |r| r.name }.each do |r|
|
30
30
|
id = jsonize_ref_value(map,r,adapters,serialization_memory)
|
31
31
|
end
|
32
32
|
if adapters.has_key? type
|
@@ -39,11 +39,11 @@ module SerializationFunctionalities
|
|
39
39
|
|
40
40
|
def source_info_to_json(source_info)
|
41
41
|
source_map = {}
|
42
|
-
if self.source.
|
43
|
-
source_map['
|
42
|
+
if self.source.begin_point
|
43
|
+
source_map['begin_point'] = {'line'=> self.source.begin_point.line, 'column'=>self.source.begin_point.column}
|
44
44
|
end
|
45
|
-
if self.source.
|
46
|
-
source_map['
|
45
|
+
if self.source.end_point
|
46
|
+
source_map['end_point'] = {'line'=> self.source.end_point.line, 'column'=>self.source.end_point.column}
|
47
47
|
end
|
48
48
|
source_map
|
49
49
|
end
|
@@ -1,130 +1,94 @@
|
|
1
1
|
require 'rgen/metamodel_builder'
|
2
2
|
require 'codemodels/language'
|
3
|
+
require 'codemodels/position'
|
4
|
+
require 'codemodels/artifact'
|
3
5
|
|
4
6
|
module CodeModels
|
5
7
|
|
6
|
-
class
|
7
|
-
|
8
|
-
|
9
|
-
offset = absolute_start
|
10
|
-
p = SourcePoint.new
|
11
|
-
p.line = point.line + offset.line - 1
|
12
|
-
p.column = point.column
|
13
|
-
p.column += offset.column-1 if point.line==1
|
14
|
-
p
|
15
|
-
end
|
16
|
-
|
17
|
-
def position_to_absolute(position)
|
18
|
-
pos = SourcePosition.new
|
19
|
-
pos.begin_point = point_to_absolute(position.begin_point)
|
20
|
-
pos.end_point = point_to_absolute(position.end_point)
|
21
|
-
pos
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
8
|
+
class SourceInfo
|
9
|
+
attr_accessor :artifact
|
10
|
+
attr_accessor :position
|
25
11
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
p.line += position_in_host.begin_point.line-1
|
33
|
-
if position_in_host.begin_point.line==1
|
34
|
-
# if I am on the first line of my "host", its column
|
35
|
-
# matters because there are not newlines to reset the column
|
36
|
-
# counter
|
37
|
-
p.column += position_in_host.begin_point.column-1
|
12
|
+
def artifact(scope=:relative)
|
13
|
+
case scope
|
14
|
+
when :relative
|
15
|
+
@artifact
|
16
|
+
when :absolute
|
17
|
+
@artifact.final_host
|
38
18
|
else
|
39
|
-
|
19
|
+
raise "unvalid scope"
|
40
20
|
end
|
41
|
-
p
|
42
21
|
end
|
43
22
|
|
44
|
-
|
45
|
-
|
46
|
-
class FileArtifact < AbstractArtifact
|
47
|
-
attr_accessor :filename
|
48
|
-
|
49
|
-
def absolute_start
|
50
|
-
sp = SourcePoint.new
|
51
|
-
sp.line = 1
|
52
|
-
sp.column = 1
|
53
|
-
sp
|
23
|
+
def code
|
24
|
+
position(:absolute).get_string(artifact.final_host.code)
|
54
25
|
end
|
55
|
-
end
|
56
|
-
|
57
|
-
class SourcePoint
|
58
|
-
attr_accessor :line, :column
|
59
26
|
|
60
|
-
def
|
61
|
-
|
62
|
-
@
|
27
|
+
def position=(value)
|
28
|
+
raise "Not assignable #{value} (#{value.class})" unless value.is_a?(SourcePosition)
|
29
|
+
@position = value
|
63
30
|
end
|
64
31
|
|
65
|
-
def
|
66
|
-
|
32
|
+
def begin_point=(data)
|
33
|
+
point = data_to_point(data)
|
34
|
+
@position = SourcePosition.new unless @position
|
35
|
+
@position.begin_point = point
|
67
36
|
end
|
68
37
|
|
69
|
-
def
|
70
|
-
|
38
|
+
def end_point=(data)
|
39
|
+
point = data_to_point(data)
|
40
|
+
@position = SourcePosition.new unless @position
|
41
|
+
@position.end_point = point
|
71
42
|
end
|
72
|
-
end
|
73
43
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
def initialize(begin_point=nil,end_point=nil)
|
78
|
-
@begin_point = begin_point
|
79
|
-
@end_point = end_point
|
44
|
+
def begin_line(flag=:relative)
|
45
|
+
position.begin_point.line
|
80
46
|
end
|
81
47
|
|
82
|
-
def
|
83
|
-
|
84
|
-
|
85
|
-
end
|
48
|
+
def end_line(flag=:relative)
|
49
|
+
position(flag).end_point.line
|
50
|
+
end
|
86
51
|
|
87
|
-
def begin_column
|
88
|
-
|
89
|
-
@begin_point.column = column
|
52
|
+
def begin_column(flag=:relative)
|
53
|
+
position(flag).begin_point.column
|
90
54
|
end
|
91
55
|
|
92
|
-
def
|
93
|
-
|
56
|
+
def end_column(flag=:relative)
|
57
|
+
position(flag).end_point.column
|
94
58
|
end
|
95
59
|
|
96
|
-
def
|
97
|
-
|
60
|
+
def begin_point(flag=:relative)
|
61
|
+
position(flag).begin_point
|
98
62
|
end
|
99
|
-
end
|
100
63
|
|
101
|
-
|
102
|
-
|
103
|
-
attr_accessor :position
|
104
|
-
|
105
|
-
def to_code
|
106
|
-
raise "Unimplemented"
|
64
|
+
def end_point(flag=:relative)
|
65
|
+
position(flag).end_point
|
107
66
|
end
|
108
67
|
|
109
|
-
def
|
110
|
-
|
111
|
-
|
112
|
-
|
68
|
+
def position(flag=:relative)
|
69
|
+
value = if flag==:relative
|
70
|
+
@position
|
71
|
+
elsif flag==:absolute
|
72
|
+
absolute_position
|
73
|
+
else
|
74
|
+
raise "unvalid value #{flag}"
|
75
|
+
end
|
76
|
+
raise "Returning not a position #{value} (#{value.class})" unless value.is_a?(SourcePosition)
|
77
|
+
value
|
113
78
|
end
|
114
79
|
|
115
|
-
def
|
116
|
-
|
117
|
-
@
|
118
|
-
@position.end_point = point
|
80
|
+
def absolute_position
|
81
|
+
raise "#{self} is not placed in any artifact" unless @artifact
|
82
|
+
@artifact.position_to_absolute(@position)
|
119
83
|
end
|
120
84
|
|
121
|
-
def
|
122
|
-
|
85
|
+
def embedded?
|
86
|
+
@artifact.embedded?
|
123
87
|
end
|
124
88
|
|
125
|
-
def
|
126
|
-
|
127
|
-
end
|
89
|
+
def embedding_level
|
90
|
+
@artifact.embedding_level
|
91
|
+
end
|
128
92
|
|
129
93
|
private
|
130
94
|
|
data/lib/codemodels/version.rb
CHANGED
@@ -60,12 +60,34 @@ def test_all_children_deep_also_foreign
|
|
60
60
|
assert_equal [], @c2.all_children_deep_also_foreign
|
61
61
|
end
|
62
62
|
|
63
|
-
def
|
63
|
+
def test_traverse_also_foreign
|
64
64
|
ids = []
|
65
|
-
|
65
|
+
@a1.traverse_also_foreign do |n|
|
66
66
|
ids << n.id
|
67
67
|
end
|
68
68
|
assert_equal ['a1','b4','b5','c1','b1','b2','b3','c2'],ids
|
69
69
|
end
|
70
70
|
|
71
|
+
def test_container_also_foreign
|
72
|
+
assert_equal nil,@a1.container_also_foreign
|
73
|
+
assert_equal @c1,@b1.container_also_foreign
|
74
|
+
assert_equal @b1,@b2.container_also_foreign
|
75
|
+
assert_equal @b1,@b3.container_also_foreign
|
76
|
+
assert_equal @a1,@b4.container_also_foreign
|
77
|
+
assert_equal @b4,@b5.container_also_foreign
|
78
|
+
assert_equal @a1,@c1.container_also_foreign
|
79
|
+
assert_equal @a1,@c2.container_also_foreign
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_root
|
83
|
+
assert_equal @a1,@a1.root(:also_foreign)
|
84
|
+
assert_equal @a1,@b1.root(:also_foreign)
|
85
|
+
assert_equal @a1,@b2.root(:also_foreign)
|
86
|
+
assert_equal @a1,@b3.root(:also_foreign)
|
87
|
+
assert_equal @a1,@b4.root(:also_foreign)
|
88
|
+
assert_equal @a1,@b5.root(:also_foreign)
|
89
|
+
assert_equal @a1,@c1.root(:also_foreign)
|
90
|
+
assert_equal @a1,@c2.root(:also_foreign)
|
91
|
+
end
|
92
|
+
|
71
93
|
end
|
data/test/test_metamodel.rb
CHANGED
data/test/test_rgen_ext.rb
CHANGED
@@ -107,23 +107,17 @@ def test_equal_wit_children
|
|
107
107
|
assert_equal false, d1==d2 # a child is different
|
108
108
|
end
|
109
109
|
|
110
|
-
def test_build_with_one_attribute
|
111
|
-
c = C.build(1)
|
112
|
-
assert_equal 1,c.id
|
113
|
-
end
|
114
|
-
|
115
110
|
class McWithTwoAttrs < RGen::MetamodelBuilder::MMBase
|
111
|
+
include ComparisonModule
|
112
|
+
class << self
|
113
|
+
include RGen::Ext::InstantiationExtensions
|
114
|
+
end
|
116
115
|
has_attr 'i',Integer
|
117
116
|
has_attr 's',String
|
118
117
|
end
|
119
118
|
|
120
|
-
def test_build_with_multiple_attributes
|
121
|
-
c = McWithTwoAttrs.build i: 27, s: 'Federico'
|
122
|
-
assert_equal 27,c.i
|
123
|
-
assert_equal 'Federico',c.s
|
124
|
-
end
|
125
|
-
|
126
119
|
class McWithNonContRef < RGen::MetamodelBuilder::MMBase
|
120
|
+
include ComparisonModule
|
127
121
|
has_one 'mcwta',McWithTwoAttrs
|
128
122
|
end
|
129
123
|
|
@@ -153,6 +147,7 @@ def test_equal_with_nil_ref
|
|
153
147
|
end
|
154
148
|
|
155
149
|
class McWithNonContRefMany < RGen::MetamodelBuilder::MMBase
|
150
|
+
include ComparisonModule
|
156
151
|
has_many 'mcwtas',McWithTwoAttrs
|
157
152
|
end
|
158
153
|
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestSourceInfo < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include CodeModels
|
6
|
+
|
7
|
+
def setup
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_source_point_from_code_index
|
12
|
+
code = "first line\nsecond line\nthird line\n"
|
13
|
+
|
14
|
+
# first line
|
15
|
+
assert_equal SourcePoint.new(1,1),SourcePoint.from_code_index(code,0)
|
16
|
+
assert_equal SourcePoint.new(1,2),SourcePoint.from_code_index(code,1)
|
17
|
+
assert_equal SourcePoint.new(1,3),SourcePoint.from_code_index(code,2)
|
18
|
+
assert_equal SourcePoint.new(1,9),SourcePoint.from_code_index(code,8)
|
19
|
+
assert_equal SourcePoint.new(1,10),SourcePoint.from_code_index(code,9)
|
20
|
+
|
21
|
+
# new line
|
22
|
+
assert_equal SourcePoint.new(2,0),SourcePoint.from_code_index(code,10)
|
23
|
+
|
24
|
+
# second line
|
25
|
+
assert_equal SourcePoint.new(2,1),SourcePoint.from_code_index(code,11)
|
26
|
+
assert_equal SourcePoint.new(2,2),SourcePoint.from_code_index(code,12)
|
27
|
+
assert_equal SourcePoint.new(2,10),SourcePoint.from_code_index(code,20)
|
28
|
+
assert_equal SourcePoint.new(2,11),SourcePoint.from_code_index(code,21)
|
29
|
+
|
30
|
+
# new line
|
31
|
+
assert_equal SourcePoint.new(3,0),SourcePoint.from_code_index(code,22)
|
32
|
+
|
33
|
+
# third line
|
34
|
+
assert_equal SourcePoint.new(3,1),SourcePoint.from_code_index(code,23)
|
35
|
+
assert_equal SourcePoint.new(3,10),SourcePoint.from_code_index(code,32)
|
36
|
+
|
37
|
+
# new line
|
38
|
+
assert_equal SourcePoint.new(4,0),SourcePoint.from_code_index(code,33)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_source_point_absolute_index
|
42
|
+
code = "first line\nsecond line\nthird line\n"
|
43
|
+
p1 = SourcePoint.new(1,1)
|
44
|
+
p2 = SourcePoint.new(1,5)
|
45
|
+
p3 = SourcePoint.new(1,10)
|
46
|
+
p4 = SourcePoint.new(2,6)
|
47
|
+
p5 = SourcePoint.new(2,2)
|
48
|
+
p7 = SourcePoint.new(3,1)
|
49
|
+
p8 = SourcePoint.new(3,10)
|
50
|
+
|
51
|
+
assert_equal 0,p1.to_absolute_index(code)
|
52
|
+
assert_equal 4,p2.to_absolute_index(code)
|
53
|
+
assert_equal 9,p3.to_absolute_index(code)
|
54
|
+
assert_equal 16,p4.to_absolute_index(code)
|
55
|
+
assert_equal 12,p5.to_absolute_index(code)
|
56
|
+
assert_equal 23,p7.to_absolute_index(code)
|
57
|
+
assert_equal 32,p8.to_absolute_index(code)
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_source_position_get_string
|
61
|
+
code = "first line\nsecond line\nthird line\n"
|
62
|
+
|
63
|
+
p1 = SourcePoint.new(1,1)
|
64
|
+
p2 = SourcePoint.new(1,5)
|
65
|
+
pos1 = SourcePosition.new(p1,p2)
|
66
|
+
assert_equal "first",pos1.get_string(code)
|
67
|
+
|
68
|
+
p3 = SourcePoint.new(1,10)
|
69
|
+
pos2 = SourcePosition.new(p1,p3)
|
70
|
+
assert_equal "first line",pos2.get_string(code)
|
71
|
+
|
72
|
+
p4 = SourcePoint.new(2,6)
|
73
|
+
pos3 = SourcePosition.new(p1,p4)
|
74
|
+
assert_equal "first line\nsecond",pos3.get_string(code)
|
75
|
+
|
76
|
+
p5 = SourcePoint.new(2,2)
|
77
|
+
p6 = SourcePoint.new(2,6)
|
78
|
+
pos4 = SourcePosition.new(p5,p6)
|
79
|
+
assert_equal "econd",pos4.get_string(code)
|
80
|
+
|
81
|
+
p7 = SourcePoint.new(3,1)
|
82
|
+
p8 = SourcePoint.new(3,10)
|
83
|
+
pos5 = SourcePosition.new(p7,p8)
|
84
|
+
assert_equal "third line",pos5.get_string(code)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_source_point_comparison
|
88
|
+
p1 = SourcePoint.new(1,1)
|
89
|
+
p2 = SourcePoint.new(1,1)
|
90
|
+
p3 = SourcePoint.new(1,3)
|
91
|
+
p4 = SourcePoint.new(2,1)
|
92
|
+
p5 = SourcePoint.new(2,6)
|
93
|
+
|
94
|
+
assert_equal 0,p1<=>p1
|
95
|
+
assert_equal 0,p1<=>p2
|
96
|
+
assert_equal -1,p1<=>p3
|
97
|
+
assert_equal -1,p1<=>p4
|
98
|
+
assert_equal -1,p1<=>p5
|
99
|
+
|
100
|
+
assert_equal 0,p2<=>p1
|
101
|
+
assert_equal 0,p2<=>p2
|
102
|
+
assert_equal -1,p2<=>p3
|
103
|
+
assert_equal -1,p2<=>p4
|
104
|
+
assert_equal -1,p2<=>p5
|
105
|
+
|
106
|
+
assert_equal 1,p3<=>p1
|
107
|
+
assert_equal 1,p3<=>p2
|
108
|
+
assert_equal 0,p3<=>p3
|
109
|
+
assert_equal -1,p3<=>p4
|
110
|
+
assert_equal -1,p3<=>p5
|
111
|
+
|
112
|
+
assert_equal 1,p4<=>p1
|
113
|
+
assert_equal 1,p4<=>p2
|
114
|
+
assert_equal 1,p4<=>p3
|
115
|
+
assert_equal 0,p4<=>p4
|
116
|
+
assert_equal -1,p4<=>p5
|
117
|
+
|
118
|
+
assert_equal 1,p5<=>p1
|
119
|
+
assert_equal 1,p5<=>p2
|
120
|
+
assert_equal 1,p5<=>p3
|
121
|
+
assert_equal 1,p5<=>p4
|
122
|
+
assert_equal 0,p5<=>p5
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_source_position_include
|
126
|
+
p1 = SourcePoint.new(1,1)
|
127
|
+
p2 = SourcePoint.new(1,1)
|
128
|
+
p3 = SourcePoint.new(1,3)
|
129
|
+
p4 = SourcePoint.new(2,1)
|
130
|
+
p5 = SourcePoint.new(2,6)
|
131
|
+
|
132
|
+
assert_equal true,SourcePosition.new(p1,p2).include?(SourcePosition.new(p2,p1))
|
133
|
+
assert_equal true,SourcePosition.new(p1,p5).include?(SourcePosition.new(p3,p4))
|
134
|
+
assert_equal true,SourcePosition.new(p3,p5).include?(SourcePosition.new(p4,SourcePoint.new(2,2)))
|
135
|
+
assert_equal false,SourcePosition.new(p3,p4).include?(SourcePosition.new(p4,p5))
|
136
|
+
assert_equal false,SourcePosition.new(p1,p4).include?(SourcePosition.new(p1,p5))
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: codemodels
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.2.3
|
4
|
+
version: 0.2.5
|
6
5
|
platform: java
|
7
6
|
authors:
|
8
7
|
- Federico Tomassetti
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-11-09 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: json
|
@@ -18,13 +17,11 @@ dependencies:
|
|
18
17
|
- - '>='
|
19
18
|
- !ruby/object:Gem::Version
|
20
19
|
version: '0'
|
21
|
-
none: false
|
22
20
|
requirement: !ruby/object:Gem::Requirement
|
23
21
|
requirements:
|
24
22
|
- - '>='
|
25
23
|
- !ruby/object:Gem::Version
|
26
24
|
version: '0'
|
27
|
-
none: false
|
28
25
|
prerelease: false
|
29
26
|
type: :runtime
|
30
27
|
- !ruby/object:Gem::Dependency
|
@@ -34,13 +31,25 @@ dependencies:
|
|
34
31
|
- - '>='
|
35
32
|
- !ruby/object:Gem::Version
|
36
33
|
version: '0'
|
37
|
-
none: false
|
38
34
|
requirement: !ruby/object:Gem::Requirement
|
39
35
|
requirements:
|
40
36
|
- - '>='
|
41
37
|
- !ruby/object:Gem::Version
|
42
38
|
version: '0'
|
43
|
-
|
39
|
+
prerelease: false
|
40
|
+
type: :runtime
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rgen_ext
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
44
53
|
prerelease: false
|
45
54
|
type: :runtime
|
46
55
|
- !ruby/object:Gem::Dependency
|
@@ -50,13 +59,11 @@ dependencies:
|
|
50
59
|
- - '='
|
51
60
|
- !ruby/object:Gem::Version
|
52
61
|
version: 1.3.5
|
53
|
-
none: false
|
54
62
|
requirement: !ruby/object:Gem::Requirement
|
55
63
|
requirements:
|
56
64
|
- - '='
|
57
65
|
- !ruby/object:Gem::Version
|
58
66
|
version: 1.3.5
|
59
|
-
none: false
|
60
67
|
prerelease: false
|
61
68
|
type: :development
|
62
69
|
- !ruby/object:Gem::Dependency
|
@@ -66,13 +73,11 @@ dependencies:
|
|
66
73
|
- - '>='
|
67
74
|
- !ruby/object:Gem::Version
|
68
75
|
version: '0'
|
69
|
-
none: false
|
70
76
|
requirement: !ruby/object:Gem::Requirement
|
71
77
|
requirements:
|
72
78
|
- - '>='
|
73
79
|
- !ruby/object:Gem::Version
|
74
80
|
version: '0'
|
75
|
-
none: false
|
76
81
|
prerelease: false
|
77
82
|
type: :development
|
78
83
|
- !ruby/object:Gem::Dependency
|
@@ -82,13 +87,11 @@ dependencies:
|
|
82
87
|
- - '>='
|
83
88
|
- !ruby/object:Gem::Version
|
84
89
|
version: '0'
|
85
|
-
none: false
|
86
90
|
requirement: !ruby/object:Gem::Requirement
|
87
91
|
requirements:
|
88
92
|
- - '>='
|
89
93
|
- !ruby/object:Gem::Version
|
90
94
|
version: '0'
|
91
|
-
none: false
|
92
95
|
prerelease: false
|
93
96
|
type: :development
|
94
97
|
description: Library to build models of code of different languages in a uniform way.
|
@@ -104,6 +107,8 @@ files:
|
|
104
107
|
- Rakefile
|
105
108
|
- codemodels.gemspec
|
106
109
|
- lib/codemodels.rb
|
110
|
+
- lib/codemodels/artifact.rb
|
111
|
+
- lib/codemodels/comparison.rb
|
107
112
|
- lib/codemodels/info_extraction.rb
|
108
113
|
- lib/codemodels/language.rb
|
109
114
|
- lib/codemodels/metamodel.rb
|
@@ -111,7 +116,7 @@ files:
|
|
111
116
|
- lib/codemodels/monkey_patching.rb
|
112
117
|
- lib/codemodels/navigation.rb
|
113
118
|
- lib/codemodels/parsing.rb
|
114
|
-
- lib/codemodels/
|
119
|
+
- lib/codemodels/position.rb
|
115
120
|
- lib/codemodels/serialization.rb
|
116
121
|
- lib/codemodels/source_info.rb
|
117
122
|
- lib/codemodels/version.rb
|
@@ -125,9 +130,11 @@ files:
|
|
125
130
|
- test/test_monkey_patching.rb
|
126
131
|
- test/test_rgen_ext.rb
|
127
132
|
- test/test_serialization.rb
|
133
|
+
- test/test_source_info.rb
|
128
134
|
homepage: https://github.com/ftomassetti/codemodels
|
129
135
|
licenses:
|
130
136
|
- Apache v2
|
137
|
+
metadata: {}
|
131
138
|
post_install_message:
|
132
139
|
rdoc_options: []
|
133
140
|
require_paths:
|
@@ -136,25 +143,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
136
143
|
requirements:
|
137
144
|
- - '>='
|
138
145
|
- !ruby/object:Gem::Version
|
139
|
-
segments:
|
140
|
-
- 0
|
141
|
-
hash: 2
|
142
146
|
version: '0'
|
143
|
-
none: false
|
144
147
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
148
|
requirements:
|
146
149
|
- - '>='
|
147
150
|
- !ruby/object:Gem::Version
|
148
|
-
segments:
|
149
|
-
- 0
|
150
|
-
hash: 2
|
151
151
|
version: '0'
|
152
|
-
none: false
|
153
152
|
requirements: []
|
154
153
|
rubyforge_project:
|
155
|
-
rubygems_version: 1.
|
154
|
+
rubygems_version: 2.1.9
|
156
155
|
signing_key:
|
157
|
-
specification_version:
|
156
|
+
specification_version: 4
|
158
157
|
summary: Library to build models of code
|
159
158
|
test_files:
|
160
159
|
- test/data/node_setCompleted.json
|
@@ -167,3 +166,4 @@ test_files:
|
|
167
166
|
- test/test_monkey_patching.rb
|
168
167
|
- test/test_rgen_ext.rb
|
169
168
|
- test/test_serialization.rb
|
169
|
+
- test/test_source_info.rb
|
data/lib/codemodels/rgen_ext.rb
DELETED
@@ -1,133 +0,0 @@
|
|
1
|
-
# Extensions to RGen objects
|
2
|
-
|
3
|
-
require 'rgen/metamodel_builder'
|
4
|
-
|
5
|
-
class RGen::MetamodelBuilder::MMBase
|
6
|
-
|
7
|
-
module ClassAddOn
|
8
|
-
|
9
|
-
def build(values={})
|
10
|
-
instance = self.new
|
11
|
-
if values.is_a? Hash
|
12
|
-
values.each do |k,v|
|
13
|
-
attribute = self.ecore.eAllAttributes.find {|x| x.name==k.to_s}
|
14
|
-
reference = self.ecore.eAllReferences.find {|x| x.name==k.to_s}
|
15
|
-
raise "UnexistingFeature #{k}" unless (attribute or reference)
|
16
|
-
setter = (k.to_s+'=').to_sym
|
17
|
-
instance.send setter, v
|
18
|
-
end
|
19
|
-
else
|
20
|
-
raise "SingleAttributeRequired" if self.ecore.eAllAttributes.count!=1
|
21
|
-
attribute = self.ecore.eAllAttributes[0]
|
22
|
-
set_attr(instance,attribute,values)
|
23
|
-
end
|
24
|
-
instance
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def set_attr(instance,attribute,value)
|
30
|
-
setter = (attribute.name+'=').to_sym
|
31
|
-
instance.send setter, value
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
module SingletonAddOn
|
36
|
-
|
37
|
-
# It does not check references, it is needed to avoid infinite recursion
|
38
|
-
def shallow_eql?(other)
|
39
|
-
return false if other==nil
|
40
|
-
return false unless self.class==other.class
|
41
|
-
self.class.ecore.eAllAttributes.each do |attrib|
|
42
|
-
raise "Attrib <nil> for class #{self.class.ecore.name}" unless attrib
|
43
|
-
self_value = self.get(attrib)
|
44
|
-
other_value = other.get(attrib)
|
45
|
-
return false unless self_value == other_value
|
46
|
-
end
|
47
|
-
true
|
48
|
-
end
|
49
|
-
|
50
|
-
def eql?(other)
|
51
|
-
# it should ignore relations which has as opposite a containement
|
52
|
-
return false unless self.shallow_eql?(other)
|
53
|
-
self.class.ecore.eAllReferences.each do |ref|
|
54
|
-
self_value = self.get(ref)
|
55
|
-
other_value = other.get(ref)
|
56
|
-
to_ignore = ref.getEOpposite and ref.getEOpposite.containment
|
57
|
-
unless to_ignore
|
58
|
-
if ref.containment
|
59
|
-
return false unless self_value == other_value
|
60
|
-
else
|
61
|
-
if (self_value.is_a? Array) or (other_value.is_a? Array)
|
62
|
-
return false unless self_value.count==other_value.count
|
63
|
-
for i in 0..(self_value.count-1)
|
64
|
-
unless self_value[i].shallow_eql?(other_value[i])
|
65
|
-
return false
|
66
|
-
end
|
67
|
-
end
|
68
|
-
else
|
69
|
-
if self_value==nil
|
70
|
-
return false unless other_value==nil
|
71
|
-
else
|
72
|
-
return false unless self_value.shallow_eql?(other_value)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
true
|
79
|
-
end
|
80
|
-
|
81
|
-
def ==(other)
|
82
|
-
eql? other
|
83
|
-
end
|
84
|
-
|
85
|
-
def get(attr_or_ref)
|
86
|
-
getter = (attr_or_ref.name).to_sym
|
87
|
-
send getter
|
88
|
-
end
|
89
|
-
|
90
|
-
def features_by_name(name)
|
91
|
-
features = []
|
92
|
-
ecore = self.class.ecore
|
93
|
-
ecore.eAllAttributes.select {|a| a.name==name}.each do |a|
|
94
|
-
features << a
|
95
|
-
end
|
96
|
-
ecore.eAllReferences.select {|r| r.name==name}.each do |r|
|
97
|
-
features << r
|
98
|
-
end
|
99
|
-
features
|
100
|
-
end
|
101
|
-
|
102
|
-
end
|
103
|
-
|
104
|
-
module FixingCollidingFeatureAddOn
|
105
|
-
def has_attr(role, target_class=nil, raw_props={}, &block)
|
106
|
-
raise "Role already used #{role}" if self.ecore.eAllAttributes.find {|a| a.name==role.to_s}
|
107
|
-
raise "Role already used #{role}" if self.ecore.eAllReferences.find {|r| r.name==role.to_s}
|
108
|
-
super(role,target_class,raw_props,block)
|
109
|
-
end
|
110
|
-
def has_many_attr(role, target_class=nil, raw_props={}, &block)
|
111
|
-
raise "Role already used #{role}" if self.ecore.eAllAttributes.find {|a| a.name==role.to_s}
|
112
|
-
raise "Role already used #{role}" if self.ecore.eAllReferences.find {|r| r.name==role.to_s}
|
113
|
-
super(role,target_class,raw_props,block)
|
114
|
-
end
|
115
|
-
def contains_many_uni(role, target_class=nil, raw_props={}, &block)
|
116
|
-
raise "Role already used #{role}" if self.ecore.eAllAttributes.find {|a| a.name==role.to_s}
|
117
|
-
raise "Role already used #{role}" if self.ecore.eAllReferences.find {|r| r.name==role.to_s}
|
118
|
-
super(role,target_class,raw_props,block)
|
119
|
-
end
|
120
|
-
def contains_one_uni(role, target_class=nil, raw_props={}, &block)
|
121
|
-
raise "Role already used #{role}" if self.ecore.eAllAttributes.find {|a| a.name==role.to_s}
|
122
|
-
raise "Role already used #{role}" if self.ecore.eAllReferences.find {|r| r.name==role.to_s}
|
123
|
-
super(role,target_class,raw_props,block)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
class << self
|
128
|
-
include ClassAddOn
|
129
|
-
end
|
130
|
-
|
131
|
-
include FixingCollidingFeatureAddOn
|
132
|
-
include SingletonAddOn
|
133
|
-
end
|