codemodels-ruby 0.1.5-java
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/Gemfile +3 -0
- data/README.md +6 -0
- data/Rakefile +13 -0
- data/codemodels-ruby.gemspec +33 -0
- data/lib/codemodels/ruby.rb +12 -0
- data/lib/codemodels/ruby/code.rb +14 -0
- data/lib/codemodels/ruby/info_extraction.rb +100 -0
- data/lib/codemodels/ruby/language.rb +17 -0
- data/lib/codemodels/ruby/metamodel.rb +481 -0
- data/lib/codemodels/ruby/model_building.rb +36 -0
- data/lib/codemodels/ruby/parser.rb +809 -0
- data/lib/codemodels/ruby/query.rb +25 -0
- data/lib/jars/com.google.collect_1.0.0.v201105210816.jar +0 -0
- data/lib/jars/com.google.inject_2.0.0.v201105231817.jar +0 -0
- data/lib/jars/com.ibm.icu_4.4.2.v20110208.jar +0 -0
- data/lib/jars/org.apache.commons.lang_2.4.0.v201005080502.jar +0 -0
- data/lib/jars/org.apache.commons.logging_1.1.1.jar +0 -0
- data/lib/jars/org.apache.log4j_1.2.16.jar +0 -0
- data/lib/jars/org.eclipse.core.runtime.compatibility_3.2.100.v20100505.jar +0 -0
- data/lib/jars/org.eclipse.core.runtime_3.7.0.v20110110.jar +0 -0
- data/test/data/012_add_comments_permissions.rb +14 -0
- data/test/data/darcs_adapter.rb +242 -0
- data/test/data/example_of_complex_class.rb +157 -0
- data/test/data/issues_helper_test.rb +271 -0
- data/test/data/status_test.rb +14 -0
- data/test/data/user_custom_field.rb +23 -0
- data/test/helper.rb +87 -0
- data/test/test_assignments.rb +14 -0
- data/test/test_blocks.rb +102 -0
- data/test/test_constants.rb +14 -0
- data/test/test_exception_handling.rb +35 -0
- data/test/test_info.rb +52 -0
- data/test/test_logic.rb +61 -0
- data/test/test_metamodel.rb +70 -0
- data/test/test_modules_and_classes.rb +81 -0
- data/test/test_not_variable_assignements.rb +75 -0
- data/test/test_operations.rb +440 -0
- data/test/test_parsing_complex.rb +49 -0
- data/test/test_parsing_literals.rb +92 -0
- data/test/test_statements.rb +169 -0
- data/test/test_terms_extraction.rb +240 -0
- data/test/test_values_extraction.rb +102 -0
- data/test/test_variables.rb +81 -0
- metadata +272 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.platform = 'java'
|
7
|
+
s.name = 'codemodels-ruby'
|
8
|
+
s.version = '0.1.5'
|
9
|
+
s.date = '2013-09-03'
|
10
|
+
s.summary = "Plugin of codemodels to build models from Ruby code."
|
11
|
+
s.description = "Plugin of codemodels to build models from Ruby code. See http://github.com/ftomassetti/codemodels."
|
12
|
+
s.authors = ["Federico Tomassetti"]
|
13
|
+
s.email = 'f.tomassetti@gmail.com'
|
14
|
+
s.homepage = 'http://federico-tomassetti.it'
|
15
|
+
s.license = "APACHE 2"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split($/)
|
18
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency('json')
|
23
|
+
s.add_dependency('emf_jruby')
|
24
|
+
s.add_dependency('jruby-parser', '=0.5.0')
|
25
|
+
s.add_dependency('codemodels')
|
26
|
+
s.add_dependency('codemodels-java')
|
27
|
+
s.add_dependency('rgen')
|
28
|
+
|
29
|
+
s.add_development_dependency "bundler", "~> 1.3"
|
30
|
+
s.add_development_dependency "rake"
|
31
|
+
s.add_development_dependency "rubygems-tasks"
|
32
|
+
s.add_development_dependency "simplecov"
|
33
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
curr_dir = File.dirname(__FILE__)
|
2
|
+
Dir[curr_dir+"/jars/*.jar"].each do |jar|
|
3
|
+
require jar
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'codemodels/ruby/metamodel'
|
7
|
+
require 'codemodels/ruby/query'
|
8
|
+
require 'codemodels/ruby/parser'
|
9
|
+
require 'codemodels/ruby/model_building'
|
10
|
+
require 'codemodels/ruby/info_extraction'
|
11
|
+
require 'codemodels/ruby/code'
|
12
|
+
require 'codemodels/ruby/language'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module CodeModels
|
2
|
+
module Ruby
|
3
|
+
|
4
|
+
def self.to_code(node)
|
5
|
+
on = node.original_node
|
6
|
+
sw = java.io.StringWriter.new
|
7
|
+
rwv = org.jrubyparser.rewriter.ReWriteVisitor.new(sw,'')
|
8
|
+
cbw = org.jrubyparser.rewriter.ClassBodyWriter.new(rwv,on)
|
9
|
+
cbw.write
|
10
|
+
sw.to_string
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'codemodels-java'
|
2
|
+
|
3
|
+
module CodeModels
|
4
|
+
module Ruby
|
5
|
+
|
6
|
+
module InfoExtraction
|
7
|
+
|
8
|
+
def self.is_id_str(s)
|
9
|
+
(not s.index /[^A-Za-z0-9_!?=]/) && (s.index /[A-Za-z]/)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.id_to_words(id)
|
13
|
+
return [''] if id==''
|
14
|
+
while id.start_with?'_' # otherwise _ciao => ['','ciao']
|
15
|
+
id = id[1..-1]
|
16
|
+
end
|
17
|
+
|
18
|
+
number_index = id.index /[0-9]/
|
19
|
+
if number_index
|
20
|
+
if number_index==0
|
21
|
+
words_before = []
|
22
|
+
else
|
23
|
+
id_before = id[0..number_index-1]
|
24
|
+
words_before = id_to_words(id_before)
|
25
|
+
end
|
26
|
+
|
27
|
+
id_from = id[number_index..-1]
|
28
|
+
has_other_after = id_from.index /[^0-9]/
|
29
|
+
if has_other_after
|
30
|
+
number_word = id_from[0..has_other_after-1]
|
31
|
+
id_after = id_from[has_other_after..-1]
|
32
|
+
words_after = id_to_words(id_after)
|
33
|
+
else
|
34
|
+
number_word = id_from
|
35
|
+
words_after = []
|
36
|
+
end
|
37
|
+
words = words_before
|
38
|
+
words = words + id.split(/[_!?=]/)
|
39
|
+
words = words + words_after
|
40
|
+
words
|
41
|
+
else
|
42
|
+
id.split /[_!?=]/
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class RubySpecificInfoExtractionLogic
|
47
|
+
|
48
|
+
def terms_containing_value?(value)
|
49
|
+
res = ::CodeModels::Java::InfoExtraction.is_camel_case_str(value) || CodeModels::Ruby::InfoExtraction.is_id_str(value)
|
50
|
+
#puts "Contains terms? '#{value}' : #{res} #{::CodeModels::Java::InfoExtraction.is_camel_case_str(value)} #{CodeModels::Ruby::InfoExtraction.is_id_str(value)}"
|
51
|
+
res
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_words(value)
|
55
|
+
if ::CodeModels::Java::InfoExtraction.is_camel_case_str(value)
|
56
|
+
res = ::CodeModels::Java::InfoExtraction.camel_to_words(value)
|
57
|
+
res.each {|v| raise "Camel case to words produced a nil" if v==nil}
|
58
|
+
raise "No words found using the camel case to words" if res.count==0
|
59
|
+
else
|
60
|
+
res = CodeModels::Ruby::InfoExtraction.id_to_words(value)
|
61
|
+
res.each {|v| raise "Id to words produced a nil" if v==nil}
|
62
|
+
raise "No words found using the id to words on '#{value}'" if res.count==0
|
63
|
+
end
|
64
|
+
res
|
65
|
+
end
|
66
|
+
|
67
|
+
def concat(a,b)
|
68
|
+
# if both the words are capitalized then do not insert the
|
69
|
+
# underscore
|
70
|
+
#if (a.capitalize==a) && (b.capitalize==b)
|
71
|
+
# return a+b
|
72
|
+
#end
|
73
|
+
|
74
|
+
# I use the underscore also for MyIdentifier so that I match
|
75
|
+
# my_identifier
|
76
|
+
|
77
|
+
a+'_'+b
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.terms_map(model_node,context=nil)
|
82
|
+
CodeModels::InfoExtraction.terms_map(RubySpecificInfoExtractionLogic.new,model_node,context)
|
83
|
+
end
|
84
|
+
|
85
|
+
end # end of InfoExtraction
|
86
|
+
|
87
|
+
module RubyInfoExtractionFunctionalities
|
88
|
+
|
89
|
+
def terms_map(context=nil)
|
90
|
+
super(InfoExtraction::RubySpecificInfoExtractionLogic.new,context)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
class RubyNode
|
96
|
+
include RubyInfoExtractionFunctionalities
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'CodeModels'
|
2
|
+
|
3
|
+
module CodeModels
|
4
|
+
module Ruby
|
5
|
+
|
6
|
+
class RubyLanguage < Language
|
7
|
+
def initialize
|
8
|
+
super('Ruby')
|
9
|
+
@extensions << 'rb'
|
10
|
+
@parser = CodeModels::Ruby::Parser.new
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
CodeModels.register_language RubyLanguage.new
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,481 @@
|
|
1
|
+
require 'rgen/metamodel_builder'
|
2
|
+
|
3
|
+
module CodeModels
|
4
|
+
|
5
|
+
module Ruby
|
6
|
+
|
7
|
+
class RubyNode < RGen::MetamodelBuilder::MMBase
|
8
|
+
end
|
9
|
+
|
10
|
+
class Value < RubyNode
|
11
|
+
end
|
12
|
+
|
13
|
+
# later attrs like optional or default value could be added
|
14
|
+
class Argument < RubyNode
|
15
|
+
has_attr 'name', String
|
16
|
+
end
|
17
|
+
|
18
|
+
class SplittedArgument < Argument
|
19
|
+
has_many_attr 'names', String
|
20
|
+
end
|
21
|
+
|
22
|
+
class Statement < Value
|
23
|
+
end
|
24
|
+
|
25
|
+
class RegexMatcher < Value
|
26
|
+
contains_one_uni 'checked_value', Value
|
27
|
+
contains_one_uni 'regex', Value
|
28
|
+
end
|
29
|
+
|
30
|
+
class RegexTryer < Value
|
31
|
+
contains_one_uni 'checked_value', Value
|
32
|
+
contains_one_uni 'regex', Value
|
33
|
+
end
|
34
|
+
|
35
|
+
class Range < Value
|
36
|
+
contains_one_uni 'lower', Value
|
37
|
+
contains_one_uni 'upper', Value
|
38
|
+
end
|
39
|
+
|
40
|
+
class IfStatement < Statement
|
41
|
+
contains_one_uni 'condition', Value
|
42
|
+
contains_one_uni 'then_body', Value
|
43
|
+
contains_one_uni 'else_body', Value
|
44
|
+
end
|
45
|
+
|
46
|
+
class IsDefined < Value
|
47
|
+
contains_one_uni 'value', Value
|
48
|
+
end
|
49
|
+
|
50
|
+
class RetryStatement < Statement
|
51
|
+
end
|
52
|
+
|
53
|
+
class Block < Value
|
54
|
+
contains_many_uni 'contents', Value
|
55
|
+
end
|
56
|
+
|
57
|
+
class AbstractCodeBlock < Value
|
58
|
+
end
|
59
|
+
|
60
|
+
class CodeBlock < AbstractCodeBlock
|
61
|
+
contains_one_uni 'body', Value
|
62
|
+
contains_many_uni 'args', Argument
|
63
|
+
end
|
64
|
+
|
65
|
+
class BlockReference < AbstractCodeBlock
|
66
|
+
contains_one_uni 'value', Value
|
67
|
+
end
|
68
|
+
|
69
|
+
class SuperCall < Statement
|
70
|
+
contains_many_uni 'args', Value
|
71
|
+
contains_one_uni 'block_arg', AbstractCodeBlock
|
72
|
+
end
|
73
|
+
|
74
|
+
class Call < Value
|
75
|
+
has_attr 'name', String
|
76
|
+
contains_many_uni 'args', Value
|
77
|
+
contains_one_uni 'block_arg', AbstractCodeBlock
|
78
|
+
contains_one_uni 'receiver', Value
|
79
|
+
|
80
|
+
module Methods
|
81
|
+
def inspect
|
82
|
+
"Call{name=#{name},args=#{args},receiver=#{receiver.class},implicit_receiver=#{implicit_receiver}}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
include Methods
|
87
|
+
end
|
88
|
+
|
89
|
+
class ExplicitReceiverCall < Call
|
90
|
+
end
|
91
|
+
|
92
|
+
class ImplicitReceiverCall < Call
|
93
|
+
end
|
94
|
+
|
95
|
+
class CallToSuper < Value
|
96
|
+
contains_many_uni 'args', Value
|
97
|
+
contains_one_uni 'block_arg', AbstractCodeBlock
|
98
|
+
end
|
99
|
+
|
100
|
+
class RescueClause < RubyNode
|
101
|
+
contains_one_uni 'body',Value
|
102
|
+
end
|
103
|
+
|
104
|
+
class FormalArgument < RubyNode
|
105
|
+
has_attr 'name',String
|
106
|
+
contains_one_uni 'default_value',Value
|
107
|
+
end
|
108
|
+
|
109
|
+
class Def < Value
|
110
|
+
has_attr 'name', String
|
111
|
+
contains_one_uni 'body', Value
|
112
|
+
contains_one_uni 'ensure_body', Value
|
113
|
+
contains_many_uni 'rescue_clauses',RescueClause
|
114
|
+
contains_many_uni 'formal_args', FormalArgument
|
115
|
+
end
|
116
|
+
|
117
|
+
class SelfDef < Def
|
118
|
+
end
|
119
|
+
|
120
|
+
class InstanceDef < Def
|
121
|
+
end
|
122
|
+
|
123
|
+
class Literal < Value
|
124
|
+
module Methods
|
125
|
+
|
126
|
+
def to_s
|
127
|
+
if respond_to? :value
|
128
|
+
value.to_s
|
129
|
+
else
|
130
|
+
super
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def inspect
|
135
|
+
"#{self.class}[#{to_s}]"
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
include Methods
|
141
|
+
end
|
142
|
+
|
143
|
+
class BooleanLiteral < Literal
|
144
|
+
has_attr 'value', Boolean
|
145
|
+
end
|
146
|
+
|
147
|
+
class IntLiteral < Literal
|
148
|
+
has_attr 'value', Integer
|
149
|
+
end
|
150
|
+
|
151
|
+
class FloatLiteral < Literal
|
152
|
+
has_attr 'value', Float
|
153
|
+
end
|
154
|
+
|
155
|
+
class RegExpLiteral < Literal
|
156
|
+
end
|
157
|
+
|
158
|
+
class StaticRegExpLiteral < RegExpLiteral
|
159
|
+
has_attr 'value', String
|
160
|
+
end
|
161
|
+
|
162
|
+
class DynamicRegExpLiteral < RegExpLiteral
|
163
|
+
contains_many_uni 'pieces', Value # only for dynamic strings
|
164
|
+
end
|
165
|
+
|
166
|
+
class NextStatement < Statement
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.bool(value)
|
170
|
+
BooleanLiteral.build(value)
|
171
|
+
end
|
172
|
+
|
173
|
+
def self.int(value)
|
174
|
+
IntLiteral.build(value)
|
175
|
+
end
|
176
|
+
|
177
|
+
class StringLiteral < Literal
|
178
|
+
end
|
179
|
+
|
180
|
+
class DynamicStringLiteral < StringLiteral
|
181
|
+
contains_many_uni 'pieces', Value # only for dynamic strings
|
182
|
+
end
|
183
|
+
|
184
|
+
class StaticStringLiteral < StringLiteral
|
185
|
+
has_attr 'value', String
|
186
|
+
end
|
187
|
+
|
188
|
+
class CmdLineStringLiteral < Literal
|
189
|
+
has_attr 'value', String
|
190
|
+
contains_many_uni 'pieces', Value # only for dynamic strings
|
191
|
+
end
|
192
|
+
|
193
|
+
class DynamicSymbol < Literal
|
194
|
+
#has_attr 'value', String
|
195
|
+
contains_many_uni 'pieces', Value
|
196
|
+
end
|
197
|
+
|
198
|
+
def self.string(value)
|
199
|
+
StaticStringLiteral.build(value)
|
200
|
+
end
|
201
|
+
|
202
|
+
class ConstantDecl < Value
|
203
|
+
has_attr 'name', String
|
204
|
+
contains_one_uni 'value', Value
|
205
|
+
end
|
206
|
+
|
207
|
+
class NilLiteral < Literal
|
208
|
+
end
|
209
|
+
|
210
|
+
class Self < Value
|
211
|
+
end
|
212
|
+
|
213
|
+
class GlobalScopeReference < Value
|
214
|
+
has_attr 'name', String
|
215
|
+
end
|
216
|
+
|
217
|
+
# for example the name of a method in an alias statement
|
218
|
+
class LiteralReference < Value
|
219
|
+
has_attr 'value', String
|
220
|
+
end
|
221
|
+
|
222
|
+
class Constant < Value
|
223
|
+
has_attr 'name', String
|
224
|
+
contains_one_uni 'container',Value
|
225
|
+
has_one 'top_container',Value, :derived => true
|
226
|
+
|
227
|
+
module Methods
|
228
|
+
def top_container_derived
|
229
|
+
return nil unless container
|
230
|
+
return container unless (container.respond_to?(:container) and container.container)
|
231
|
+
container.top_container
|
232
|
+
end
|
233
|
+
|
234
|
+
def to_s
|
235
|
+
return "#{name}" unless container
|
236
|
+
"#{container}::#{name}"
|
237
|
+
end
|
238
|
+
|
239
|
+
def inspect
|
240
|
+
'Constant{'+self.to_s+'}'
|
241
|
+
end
|
242
|
+
end
|
243
|
+
include Methods
|
244
|
+
end
|
245
|
+
|
246
|
+
def self.constant(first_part,*other_parts)
|
247
|
+
cont = Constant.build(first_part)
|
248
|
+
|
249
|
+
return cont if other_parts.count == 0
|
250
|
+
|
251
|
+
new_first_part, *new_other_parts = other_parts
|
252
|
+
|
253
|
+
internal_constant = constant(new_first_part, *new_other_parts)
|
254
|
+
if internal_constant.container
|
255
|
+
internal_constant.top_container.container = cont
|
256
|
+
else
|
257
|
+
internal_constant.container = cont
|
258
|
+
end
|
259
|
+
|
260
|
+
internal_constant
|
261
|
+
end
|
262
|
+
|
263
|
+
class ModuleDecl < Value
|
264
|
+
contains_one_uni 'defname', Constant
|
265
|
+
contains_many_uni 'contents', Value
|
266
|
+
end
|
267
|
+
|
268
|
+
class ClassDecl < Value
|
269
|
+
contains_one_uni 'defname', Constant
|
270
|
+
contains_one_uni 'super_class',Value
|
271
|
+
contains_many_uni 'contents', Value
|
272
|
+
end
|
273
|
+
|
274
|
+
class SingletonClassDecl < Value
|
275
|
+
contains_one_uni 'object', Value
|
276
|
+
contains_many_uni 'contents', Value
|
277
|
+
end
|
278
|
+
|
279
|
+
class Symbol < Literal
|
280
|
+
has_attr 'name', String
|
281
|
+
end
|
282
|
+
|
283
|
+
class Assignment < Value
|
284
|
+
contains_one_uni 'value', Value
|
285
|
+
end
|
286
|
+
|
287
|
+
class VarAssignment < Assignment
|
288
|
+
has_attr 'name_assigned', String
|
289
|
+
end
|
290
|
+
|
291
|
+
class LocalVarAssignment < VarAssignment
|
292
|
+
end
|
293
|
+
|
294
|
+
class GlobalVarAssignment < VarAssignment
|
295
|
+
end
|
296
|
+
|
297
|
+
class InstanceVarAssignment < VarAssignment
|
298
|
+
end
|
299
|
+
|
300
|
+
class ClassVarAssignment < VarAssignment
|
301
|
+
end
|
302
|
+
|
303
|
+
class BlockVarAssignment < VarAssignment
|
304
|
+
end
|
305
|
+
|
306
|
+
class OperatorAssignment < Value
|
307
|
+
contains_one_uni 'container', Value
|
308
|
+
has_attr 'element_name', String
|
309
|
+
contains_one_uni 'value', Value
|
310
|
+
has_attr 'operator_name', String
|
311
|
+
end
|
312
|
+
|
313
|
+
class VarAccess < Value
|
314
|
+
has_attr 'name', String
|
315
|
+
|
316
|
+
module Methods
|
317
|
+
def to_s
|
318
|
+
name
|
319
|
+
end
|
320
|
+
|
321
|
+
def inspect
|
322
|
+
"#{self.class}{#{self.to_s}}"
|
323
|
+
end
|
324
|
+
end
|
325
|
+
include Methods
|
326
|
+
end
|
327
|
+
|
328
|
+
class LocalVarAccess < VarAccess
|
329
|
+
end
|
330
|
+
|
331
|
+
class BlockVarAccess < VarAccess
|
332
|
+
end
|
333
|
+
|
334
|
+
def self.localvarac(name)
|
335
|
+
lva = LocalVarAccess.new
|
336
|
+
lva.name = name
|
337
|
+
lva
|
338
|
+
end
|
339
|
+
|
340
|
+
class GlobalVarAccess < VarAccess
|
341
|
+
end
|
342
|
+
|
343
|
+
class InstanceVarAccess < VarAccess
|
344
|
+
end
|
345
|
+
|
346
|
+
class ClassVarAccess < VarAccess
|
347
|
+
end
|
348
|
+
|
349
|
+
class HashPair < RubyNode
|
350
|
+
contains_one_uni 'key', Value
|
351
|
+
contains_one_uni 'value', Value
|
352
|
+
end
|
353
|
+
|
354
|
+
class HashLiteral < Literal
|
355
|
+
contains_many_uni 'pairs', HashPair
|
356
|
+
end
|
357
|
+
|
358
|
+
class ArrayLiteral < Literal
|
359
|
+
contains_many_uni 'values', Value
|
360
|
+
end
|
361
|
+
|
362
|
+
class AliasStatement < Statement
|
363
|
+
contains_one_uni 'old_name',Value
|
364
|
+
contains_one_uni 'new_name',Value
|
365
|
+
end
|
366
|
+
|
367
|
+
class UndefStatement < Statement
|
368
|
+
contains_one_uni 'name', Value
|
369
|
+
end
|
370
|
+
|
371
|
+
class WhenClause < RubyNode
|
372
|
+
contains_one_uni 'condition',Value
|
373
|
+
contains_one_uni 'body',Value
|
374
|
+
end
|
375
|
+
|
376
|
+
class CaseStatement < Statement
|
377
|
+
contains_many_uni 'when_clauses', WhenClause
|
378
|
+
contains_one_uni 'else_body', Value
|
379
|
+
end
|
380
|
+
|
381
|
+
class WhileStatement < Statement
|
382
|
+
contains_one_uni 'condition', Value
|
383
|
+
contains_one_uni 'body', Value
|
384
|
+
#has_attr 'type', Symbol
|
385
|
+
end
|
386
|
+
|
387
|
+
class ForStatement < Statement
|
388
|
+
contains_one_uni 'collection', Value
|
389
|
+
contains_one_uni 'iterator', Value
|
390
|
+
contains_one_uni 'body', Value
|
391
|
+
end
|
392
|
+
|
393
|
+
class UntilStatement < Statement
|
394
|
+
contains_one_uni 'condition', Value
|
395
|
+
contains_one_uni 'body', Value
|
396
|
+
#has_attr 'type', Symbol
|
397
|
+
end
|
398
|
+
|
399
|
+
class BreakStatement < Statement
|
400
|
+
end
|
401
|
+
|
402
|
+
class RescueStatement < Statement
|
403
|
+
contains_one_uni 'body', Value
|
404
|
+
contains_one_uni 'value', Value
|
405
|
+
end
|
406
|
+
|
407
|
+
class BackReference < Value
|
408
|
+
end
|
409
|
+
|
410
|
+
class NthGroupReference < Value
|
411
|
+
has_attr 'n', Integer
|
412
|
+
end
|
413
|
+
|
414
|
+
class YieldStatement < Statement
|
415
|
+
end
|
416
|
+
|
417
|
+
class BeginEndBlock < Value
|
418
|
+
contains_one_uni 'body',Value
|
419
|
+
contains_many_uni 'rescue_clauses',RescueClause
|
420
|
+
contains_one_uni 'ensure_body', Value
|
421
|
+
end
|
422
|
+
|
423
|
+
class UnaryOperation < Value
|
424
|
+
contains_one_uni 'value',Value
|
425
|
+
has_attr 'operator_name', String
|
426
|
+
end
|
427
|
+
|
428
|
+
class Splat < Value
|
429
|
+
contains_one_uni 'splatted', Value
|
430
|
+
end
|
431
|
+
|
432
|
+
def self.splat(v)
|
433
|
+
s = Splat.new
|
434
|
+
s.splatted = v
|
435
|
+
s
|
436
|
+
end
|
437
|
+
|
438
|
+
# ex a[1] = 2
|
439
|
+
class ElementAssignment < Assignment
|
440
|
+
contains_one_uni 'container',Value
|
441
|
+
contains_one_uni 'element',Value
|
442
|
+
end
|
443
|
+
|
444
|
+
# ex a[1] += 2
|
445
|
+
class ElementOperationAssignment < Value
|
446
|
+
contains_one_uni 'container',Value
|
447
|
+
contains_one_uni 'element',Value
|
448
|
+
contains_one_uni 'value',Value
|
449
|
+
has_attr 'operator',String
|
450
|
+
end
|
451
|
+
|
452
|
+
class MultipleAssignment < Value
|
453
|
+
contains_many_uni 'assignments',VarAssignment
|
454
|
+
contains_many_uni 'values',Value
|
455
|
+
end
|
456
|
+
|
457
|
+
class Return < Statement
|
458
|
+
contains_one_uni 'value',Value
|
459
|
+
end
|
460
|
+
|
461
|
+
class BinaryOperator < Value
|
462
|
+
contains_one_uni 'left',Value
|
463
|
+
contains_one_uni 'right',Value
|
464
|
+
end
|
465
|
+
|
466
|
+
class AndOperator < BinaryOperator
|
467
|
+
#has_attr 'word_form', Boolean # true for 'and', false for '&&'
|
468
|
+
end
|
469
|
+
|
470
|
+
class OrOperator < BinaryOperator
|
471
|
+
#has_attr 'word_form', Boolean # true for 'or', false for '||'
|
472
|
+
end
|
473
|
+
|
474
|
+
class OrAssignment < Value # ||=
|
475
|
+
contains_one_uni 'assigned',Value
|
476
|
+
contains_one_uni 'value', Value
|
477
|
+
end
|
478
|
+
|
479
|
+
end
|
480
|
+
|
481
|
+
end
|