rubymm 0.1.0-java → 0.1.2-java
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rubymm.rb +1 -0
- data/lib/rubymm/metamodel.rb +189 -5
- data/lib/rubymm/parser.rb +174 -1
- data/lib/rubymm/query.rb +21 -0
- metadata +30 -37
data/lib/rubymm.rb
CHANGED
data/lib/rubymm/metamodel.rb
CHANGED
@@ -5,26 +5,210 @@ module RubyMM
|
|
5
5
|
class Value < RGen::MetamodelBuilder::MMBase
|
6
6
|
end
|
7
7
|
|
8
|
+
class Statement < Value
|
9
|
+
end
|
10
|
+
|
11
|
+
class IfStatement < Statement
|
12
|
+
contains_one_uni 'condition', Value
|
13
|
+
contains_many_uni 'body', Value
|
14
|
+
end
|
15
|
+
|
8
16
|
class Block < Value
|
9
|
-
|
17
|
+
contains_many_uni 'contents', Value
|
10
18
|
end
|
11
19
|
|
12
20
|
class Call < Value
|
13
21
|
has_attr 'name', String
|
14
|
-
|
15
|
-
|
22
|
+
contains_many_uni 'args', Value
|
23
|
+
contains_one_uni 'receiver', Value
|
24
|
+
has_attr 'implicit_receiver', Boolean
|
25
|
+
|
26
|
+
module Methods
|
27
|
+
def inspect
|
28
|
+
"Call{name=#{name},args=#{args},receiver=#{receiver.class},implicit_receiver=#{implicit_receiver}}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
include Methods
|
16
33
|
end
|
17
34
|
|
18
|
-
class Def <
|
35
|
+
class Def < Value
|
19
36
|
has_attr 'name', String
|
20
|
-
|
37
|
+
contains_one_uni 'body', Value
|
38
|
+
has_attr 'onself',Boolean
|
21
39
|
end
|
22
40
|
|
23
41
|
class Literal < Value
|
42
|
+
module Methods
|
43
|
+
|
44
|
+
def to_s
|
45
|
+
value.to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
def inspect
|
49
|
+
"#{self.class}[#{to_s}]"
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
include Methods
|
55
|
+
end
|
56
|
+
|
57
|
+
class BooleanLiteral < Literal
|
58
|
+
has_attr 'value', Boolean
|
24
59
|
end
|
25
60
|
|
26
61
|
class IntLiteral < Literal
|
27
62
|
has_attr 'value', Integer
|
28
63
|
end
|
29
64
|
|
65
|
+
def self.bool(value)
|
66
|
+
BooleanLiteral.build(value)
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.int(value)
|
70
|
+
IntLiteral.build(value)
|
71
|
+
end
|
72
|
+
|
73
|
+
class StringLiteral < Literal
|
74
|
+
has_attr 'value', String
|
75
|
+
has_attr 'dynamic', Boolean
|
76
|
+
contains_many_uni 'pieces', Value # only for dynamic strings
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.string(value)
|
80
|
+
StringLiteral.build(value)
|
81
|
+
end
|
82
|
+
|
83
|
+
class NilLiteral < Literal
|
84
|
+
end
|
85
|
+
|
86
|
+
class Constant < Value
|
87
|
+
has_attr 'name', String
|
88
|
+
contains_one_uni 'container',Constant
|
89
|
+
has_one 'top_container',Constant, :derived => true
|
90
|
+
|
91
|
+
module Methods
|
92
|
+
def top_container_derived
|
93
|
+
return nil unless container
|
94
|
+
return container if not container.container
|
95
|
+
container.top_container
|
96
|
+
end
|
97
|
+
|
98
|
+
def to_s
|
99
|
+
return "#{name}" unless container
|
100
|
+
"#{container}::#{name}"
|
101
|
+
end
|
102
|
+
|
103
|
+
def inspect
|
104
|
+
'Constant{'+self.to_s+'}'
|
105
|
+
end
|
106
|
+
end
|
107
|
+
include Methods
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.constant(first_part,*other_parts)
|
111
|
+
cont = Constant.build(first_part)
|
112
|
+
|
113
|
+
return cont if other_parts.count == 0
|
114
|
+
|
115
|
+
new_first_part, *new_other_parts = other_parts
|
116
|
+
|
117
|
+
internal_constant = constant(new_first_part, *new_other_parts)
|
118
|
+
if internal_constant.container
|
119
|
+
internal_constant.top_container.container = cont
|
120
|
+
else
|
121
|
+
internal_constant.container = cont
|
122
|
+
end
|
123
|
+
|
124
|
+
internal_constant
|
125
|
+
end
|
126
|
+
|
127
|
+
class ModuleDecl < Value
|
128
|
+
contains_one_uni 'defname', Constant
|
129
|
+
contains_many_uni 'contents', Value
|
130
|
+
end
|
131
|
+
|
132
|
+
class ClassDecl < Value
|
133
|
+
contains_one_uni 'defname', Constant
|
134
|
+
contains_one_uni 'super_class',Constant
|
135
|
+
contains_many_uni 'contents', Value
|
136
|
+
end
|
137
|
+
|
138
|
+
class Symbol < Value
|
139
|
+
has_attr 'name', String
|
140
|
+
end
|
141
|
+
|
142
|
+
class VarAssignement < Value
|
143
|
+
has_attr 'name_assigned', String
|
144
|
+
contains_one_uni 'value', Value
|
145
|
+
end
|
146
|
+
|
147
|
+
class LocalVarAssignment < VarAssignement
|
148
|
+
end
|
149
|
+
|
150
|
+
class GlobalVarAssignment < VarAssignement
|
151
|
+
end
|
152
|
+
|
153
|
+
class InstanceVarAssignement < VarAssignement
|
154
|
+
end
|
155
|
+
|
156
|
+
class VarAccess < Value
|
157
|
+
has_attr 'name', String
|
158
|
+
|
159
|
+
module Methods
|
160
|
+
def to_s
|
161
|
+
name
|
162
|
+
end
|
163
|
+
|
164
|
+
def inspect
|
165
|
+
"#{self.class}{#{self.to_s}}"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
include Methods
|
169
|
+
end
|
170
|
+
|
171
|
+
class LocalVarAccess < VarAccess
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.localvarac(name)
|
175
|
+
lva = LocalVarAccess.new
|
176
|
+
lva.name = name
|
177
|
+
lva
|
178
|
+
end
|
179
|
+
|
180
|
+
class GlobalVarAccess < VarAccess
|
181
|
+
end
|
182
|
+
|
183
|
+
class InstanceVarAccess < VarAccess
|
184
|
+
end
|
185
|
+
|
186
|
+
class HashPair < RGen::MetamodelBuilder::MMBase
|
187
|
+
contains_one_uni 'key', Value
|
188
|
+
contains_one_uni 'value', Value
|
189
|
+
end
|
190
|
+
|
191
|
+
class HashLiteral < Literal
|
192
|
+
contains_many_uni 'pairs', HashPair
|
193
|
+
end
|
194
|
+
|
195
|
+
class ArrayLiteral < Literal
|
196
|
+
contains_many_uni 'values', Value
|
197
|
+
end
|
198
|
+
|
199
|
+
class BeginRescue < Value
|
200
|
+
contains_one_uni 'body',Value
|
201
|
+
contains_one_uni 'rescue_body',Value
|
202
|
+
end
|
203
|
+
|
204
|
+
class ElementAssignement < Value
|
205
|
+
contains_one_uni 'array',Value
|
206
|
+
contains_one_uni 'element',Value
|
207
|
+
contains_one_uni 'value',Value
|
208
|
+
end
|
209
|
+
|
210
|
+
class Return < Statement
|
211
|
+
contains_one_uni 'value',Value
|
212
|
+
end
|
213
|
+
|
30
214
|
end
|
data/lib/rubymm/parser.rb
CHANGED
@@ -4,11 +4,18 @@ require 'java'
|
|
4
4
|
require 'emf_jruby'
|
5
5
|
|
6
6
|
java_import org.jrubyparser.ast.ArrayNode
|
7
|
+
java_import org.jrubyparser.ast.ListNode
|
7
8
|
|
8
9
|
module RubyMM
|
9
10
|
|
11
|
+
def self.parse_file(path)
|
12
|
+
content = IO.read(path)
|
13
|
+
self.parse(content)
|
14
|
+
end
|
15
|
+
|
10
16
|
def self.parse(code)
|
11
17
|
tree = JRubyParser.parse(code)
|
18
|
+
#puts "Code: #{code} Root: #{tree}"
|
12
19
|
tree_to_model(tree)
|
13
20
|
end
|
14
21
|
|
@@ -19,7 +26,22 @@ def self.tree_to_model(tree)
|
|
19
26
|
node_to_model tree.body
|
20
27
|
end
|
21
28
|
|
29
|
+
def self.body_node_to_contents(body_node,container_node)
|
30
|
+
body = node_to_model(body_node)
|
31
|
+
if body
|
32
|
+
if body.is_a? RubyMM::Block
|
33
|
+
body.contents.each do |el|
|
34
|
+
container_node.contents = container_node.contents << el
|
35
|
+
end
|
36
|
+
else
|
37
|
+
container_node.contents = container_node.contents << body
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
22
42
|
def self.node_to_model(node)
|
43
|
+
return nil if node==nil
|
44
|
+
#puts "#{node} #{node.node_type.name}"
|
23
45
|
case node.node_type.name
|
24
46
|
when 'NEWLINENODE'
|
25
47
|
node_to_model node.next_node
|
@@ -28,12 +50,33 @@ def self.node_to_model(node)
|
|
28
50
|
model.name = node.name
|
29
51
|
model.receiver = node_to_model node.receiver
|
30
52
|
model.args = args_to_model node.args
|
53
|
+
model.implicit_receiver = false
|
31
54
|
model
|
55
|
+
when 'VCALLNODE'
|
56
|
+
model = RubyMM::Call.new
|
57
|
+
model.name = node.name
|
58
|
+
#model.receiver = node_to_model node.receiver
|
59
|
+
#model.args = args_to_model node.args
|
60
|
+
model.implicit_receiver = false
|
61
|
+
model
|
62
|
+
when 'FCALLNODE'
|
63
|
+
model = RubyMM::Call.new
|
64
|
+
model.name = node.name
|
65
|
+
#model.receiver = node_to_model node.receiver
|
66
|
+
model.args = args_to_model node.args
|
67
|
+
model.implicit_receiver = true
|
68
|
+
model
|
32
69
|
when 'DEFNNODE'
|
33
70
|
model = RubyMM::Def.new
|
34
71
|
model.name = node.name
|
35
|
-
#puts "Body #{node_to_model node.body}"
|
36
72
|
model.body = node_to_model node.body
|
73
|
+
model.onself = false
|
74
|
+
model
|
75
|
+
when 'DEFSNODE'
|
76
|
+
model = RubyMM::Def.new
|
77
|
+
model.name = node.name
|
78
|
+
model.body = node_to_model node.body
|
79
|
+
model.onself = true
|
37
80
|
model
|
38
81
|
when 'BLOCKNODE'
|
39
82
|
model = RubyMM::Block.new
|
@@ -48,6 +91,130 @@ def self.node_to_model(node)
|
|
48
91
|
model = RubyMM::IntLiteral.new
|
49
92
|
model.value = node.value
|
50
93
|
model
|
94
|
+
when 'STRNODE'
|
95
|
+
model = RubyMM::StringLiteral.new
|
96
|
+
model.value = node.value
|
97
|
+
model.dynamic = false
|
98
|
+
model
|
99
|
+
when 'DSTRNODE'
|
100
|
+
model = RubyMM::StringLiteral.new
|
101
|
+
#model.value = node.value
|
102
|
+
model.dynamic = true
|
103
|
+
for i in 0..(node.size-1)
|
104
|
+
model.pieces = model.pieces << node_to_model(node.get i)
|
105
|
+
end
|
106
|
+
model
|
107
|
+
when 'EVSTRNODE'
|
108
|
+
node_to_model(node.body)
|
109
|
+
when 'CLASSNODE'
|
110
|
+
model = RubyMM::ClassDecl.new
|
111
|
+
model.defname = node_to_model(node.getCPath)
|
112
|
+
model.super_class = node_to_model(node.super)
|
113
|
+
body_node_to_contents(node.body_node,model)
|
114
|
+
model
|
115
|
+
when 'MODULENODE'
|
116
|
+
model = RubyMM::ModuleDecl.new
|
117
|
+
model.defname = node_to_model(node.getCPath)
|
118
|
+
body_node_to_contents(node.body_node,model)
|
119
|
+
model
|
120
|
+
when 'NILNODE'
|
121
|
+
if node.is_a? Java::OrgJrubyparserAst::NilImplicitNode
|
122
|
+
return nil
|
123
|
+
else
|
124
|
+
RubyMM::NilLiteral.new
|
125
|
+
end
|
126
|
+
when 'COLON2NODE'
|
127
|
+
model = RubyMM::Constant.new
|
128
|
+
model.name = node.name
|
129
|
+
model.container = node_to_model(node.left_node)
|
130
|
+
model
|
131
|
+
when 'SYMBOLNODE'
|
132
|
+
model = RubyMM::Symbol.new
|
133
|
+
model.name = node.name
|
134
|
+
model
|
135
|
+
when 'CONSTNODE'
|
136
|
+
model = RubyMM::Constant.new
|
137
|
+
model.name = node.name
|
138
|
+
model
|
139
|
+
when 'LOCALASGNNODE'
|
140
|
+
model = RubyMM::LocalVarAssignment.new
|
141
|
+
model.name_assigned = node.name
|
142
|
+
model.value = node_to_model(node.value)
|
143
|
+
model
|
144
|
+
when 'LOCALVARNODE'
|
145
|
+
model = RubyMM::LocalVarAccess.new
|
146
|
+
model.name = node.name
|
147
|
+
model
|
148
|
+
when 'FALSENODE'
|
149
|
+
model = RubyMM::BooleanLiteral.new
|
150
|
+
model.value = false
|
151
|
+
model
|
152
|
+
when 'TRUENODE'
|
153
|
+
model = RubyMM::BooleanLiteral.new
|
154
|
+
model.value = true
|
155
|
+
model
|
156
|
+
when 'IFNODE'
|
157
|
+
model = RubyMM::IfStatement.new
|
158
|
+
model
|
159
|
+
when 'GLOBALVARNODE'
|
160
|
+
model = RubyMM::GlobalVarAccess.new
|
161
|
+
model.name = node.name[1..-1]
|
162
|
+
model
|
163
|
+
when 'GLOBALASGNNODE'
|
164
|
+
model = RubyMM::GlobalVarAssignment.new
|
165
|
+
model.name_assigned = node.name[1..-1]
|
166
|
+
model.value = node_to_model(node.value)
|
167
|
+
model
|
168
|
+
when 'HASHNODE'
|
169
|
+
model = RubyMM::HashLiteral.new
|
170
|
+
count = node.get_list_node.count / 2
|
171
|
+
for i in 0..(count-1)
|
172
|
+
k_node = node.get_list_node[i*2]
|
173
|
+
k = node_to_model(k_node)
|
174
|
+
v_node = node.get_list_node[i*2 +1]
|
175
|
+
v = node_to_model(v_node)
|
176
|
+
pair = RubyMM::HashPair.build key: k, value: v
|
177
|
+
model.pairs = model.pairs << pair
|
178
|
+
end
|
179
|
+
model
|
180
|
+
when 'ARRAYNODE'
|
181
|
+
model = RubyMM::ArrayLiteral.new
|
182
|
+
for i in 0..(node.count-1)
|
183
|
+
v_node = node[i]
|
184
|
+
v = node_to_model(v_node)
|
185
|
+
model.values = model.values << v
|
186
|
+
end
|
187
|
+
model
|
188
|
+
when 'ZARRAYNODE'
|
189
|
+
RubyMM::ArrayLiteral.new
|
190
|
+
when 'BEGINNODE'
|
191
|
+
model = RubyMM::BeginRescue.new
|
192
|
+
rescue_node = node.body
|
193
|
+
raise 'AssertionFailed' unless rescue_node.node_type.name=='RESCUENODE'
|
194
|
+
model.body = node_to_model(rescue_node.body)
|
195
|
+
rescue_body_node = rescue_node.rescue
|
196
|
+
raise 'AssertionFailed' unless rescue_body_node.node_type.name=='RESCUEBODYNODE'
|
197
|
+
model.rescue_body = node_to_model(rescue_body_node.body)
|
198
|
+
model
|
199
|
+
when 'ATTRASSIGNNODE'
|
200
|
+
model = RubyMM::ElementAssignement.new
|
201
|
+
model.array = node_to_model(node.receiver)
|
202
|
+
model.element = node_to_model(node.args[0])
|
203
|
+
model.value = node_to_model(node.args[1])
|
204
|
+
model
|
205
|
+
when 'INSTASGNNODE'
|
206
|
+
model = RubyMM::InstanceVarAssignement.new
|
207
|
+
model.name_assigned = node.name[1..-1]
|
208
|
+
model.value = node_to_model(node.value)
|
209
|
+
model
|
210
|
+
when 'INSTVARNODE'
|
211
|
+
RubyMM::InstanceVarAccess.build node.name[1..-1]
|
212
|
+
when 'RETURNNODE'
|
213
|
+
model = RubyMM::Return.new
|
214
|
+
model.value = node_to_model(node.value)
|
215
|
+
model
|
216
|
+
when 'CONSTDECLNODE'
|
217
|
+
raise 'Const decl node: not implemented'
|
51
218
|
else
|
52
219
|
raise "I don't know how to deal with #{node.node_type.name}"
|
53
220
|
end
|
@@ -62,6 +229,12 @@ def self.args_to_model(args_node)
|
|
62
229
|
args << node_to_model(args_node.get i)
|
63
230
|
end
|
64
231
|
args
|
232
|
+
elsif args_node.is_a? ListNode
|
233
|
+
for i in 0..(args_node.size-1)
|
234
|
+
#puts "DEALING WITH #{i} #{args_node.get i} #{(args_node.get i).class}"
|
235
|
+
args << node_to_model(args_node.get i)
|
236
|
+
end
|
237
|
+
args
|
65
238
|
else
|
66
239
|
raise "I don't know how to deal with #{args_node.class}"
|
67
240
|
end
|
data/lib/rubymm/query.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module RubyMM
|
2
|
+
|
3
|
+
def self.is_call(node,name=nil,args=nil)
|
4
|
+
return false unless node.is_a? RubyMM::Call
|
5
|
+
return false if name and node.name!=name
|
6
|
+
if args
|
7
|
+
return false if args.count != node.args.count
|
8
|
+
for i in 0..(args.count-1)
|
9
|
+
return false unless args[i].eql?(node.args[i])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.is_def(node,name=nil)
|
16
|
+
return false unless node.is_a? RubyMM::Def
|
17
|
+
return false if name and node.name!=name
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
metadata
CHANGED
@@ -1,31 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubymm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
4
5
|
prerelease:
|
5
|
-
version: 0.1.0
|
6
6
|
platform: java
|
7
7
|
authors:
|
8
8
|
- Federico Tomassetti
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
12
|
+
date: 2013-08-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
16
16
|
version_requirements: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - '>='
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
21
|
-
MA==
|
20
|
+
version: '0'
|
22
21
|
none: false
|
23
22
|
requirement: !ruby/object:Gem::Requirement
|
24
23
|
requirements:
|
25
|
-
- -
|
24
|
+
- - '>='
|
26
25
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
28
|
-
MA==
|
26
|
+
version: '0'
|
29
27
|
none: false
|
30
28
|
prerelease: false
|
31
29
|
type: :runtime
|
@@ -33,17 +31,15 @@ dependencies:
|
|
33
31
|
name: emf_jruby
|
34
32
|
version_requirements: !ruby/object:Gem::Requirement
|
35
33
|
requirements:
|
36
|
-
- -
|
34
|
+
- - '>='
|
37
35
|
- !ruby/object:Gem::Version
|
38
|
-
version:
|
39
|
-
MA==
|
36
|
+
version: '0'
|
40
37
|
none: false
|
41
38
|
requirement: !ruby/object:Gem::Requirement
|
42
39
|
requirements:
|
43
|
-
- -
|
40
|
+
- - '>='
|
44
41
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
46
|
-
MA==
|
42
|
+
version: '0'
|
47
43
|
none: false
|
48
44
|
prerelease: false
|
49
45
|
type: :runtime
|
@@ -51,17 +47,15 @@ dependencies:
|
|
51
47
|
name: jruby-parser
|
52
48
|
version_requirements: !ruby/object:Gem::Requirement
|
53
49
|
requirements:
|
54
|
-
- -
|
50
|
+
- - '>='
|
55
51
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
57
|
-
MA==
|
52
|
+
version: '0'
|
58
53
|
none: false
|
59
54
|
requirement: !ruby/object:Gem::Requirement
|
60
55
|
requirements:
|
61
|
-
- -
|
56
|
+
- - '>='
|
62
57
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
64
|
-
MA==
|
58
|
+
version: '0'
|
65
59
|
none: false
|
66
60
|
prerelease: false
|
67
61
|
type: :runtime
|
@@ -71,17 +65,18 @@ executables: []
|
|
71
65
|
extensions: []
|
72
66
|
extra_rdoc_files: []
|
73
67
|
files:
|
74
|
-
-
|
75
|
-
-
|
76
|
-
-
|
77
|
-
-
|
78
|
-
-
|
79
|
-
-
|
80
|
-
-
|
81
|
-
-
|
82
|
-
-
|
83
|
-
-
|
84
|
-
-
|
68
|
+
- ./lib/rubymm.rb
|
69
|
+
- ./lib/rubymm/metamodel.rb
|
70
|
+
- ./lib/rubymm/query.rb
|
71
|
+
- ./lib/rubymm/parser.rb
|
72
|
+
- ./lib/jars/org.apache.commons.lang_2.4.0.v201005080502.jar
|
73
|
+
- ./lib/jars/com.google.collect_1.0.0.v201105210816.jar
|
74
|
+
- ./lib/jars/com.google.inject_2.0.0.v201105231817.jar
|
75
|
+
- ./lib/jars/org.eclipse.core.runtime_3.7.0.v20110110.jar
|
76
|
+
- ./lib/jars/org.apache.commons.logging_1.1.1.jar
|
77
|
+
- ./lib/jars/org.apache.log4j_1.2.16.jar
|
78
|
+
- ./lib/jars/org.eclipse.core.runtime.compatibility_3.2.100.v20100505.jar
|
79
|
+
- ./lib/jars/com.ibm.icu_4.4.2.v20110208.jar
|
85
80
|
homepage: http://federico-tomassetti.it
|
86
81
|
licenses: []
|
87
82
|
post_install_message:
|
@@ -90,17 +85,15 @@ require_paths:
|
|
90
85
|
- lib
|
91
86
|
required_ruby_version: !ruby/object:Gem::Requirement
|
92
87
|
requirements:
|
93
|
-
- -
|
88
|
+
- - '>='
|
94
89
|
- !ruby/object:Gem::Version
|
95
|
-
version:
|
96
|
-
MA==
|
90
|
+
version: '0'
|
97
91
|
none: false
|
98
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
93
|
requirements:
|
100
|
-
- -
|
94
|
+
- - '>='
|
101
95
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
103
|
-
MA==
|
96
|
+
version: '0'
|
104
97
|
none: false
|
105
98
|
requirements: []
|
106
99
|
rubyforge_project:
|