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
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'CodeModels'
|
2
|
+
|
3
|
+
module CodeModels
|
4
|
+
|
5
|
+
module Ruby
|
6
|
+
|
7
|
+
def self.handle_models_in_dir(src,error_handler=nil,model_handler)
|
8
|
+
CodeModels::ModelBuilding.handle_models_in_dir(src,'rb',error_handler,model_handler) do |src|
|
9
|
+
root = Ruby.parse_file(src)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.handle_serialized_models_in_dir(src,error_handler=nil,model_handler)
|
14
|
+
CodeModels::ModelBuilding.handle_models_in_dir(src,'rb',error_handler,model_handler) do |src|
|
15
|
+
root = Ruby.parse_file(src)
|
16
|
+
CodeModels::Serialization.rgenobject_to_model(root)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.generate_models_in_dir(src,dest,model_ext='rb.lm',max_nesting=500,error_handler=nil)
|
21
|
+
CodeModels::ModelBuilding.generate_models_in_dir(src,dest,'rb',model_ext,max_nesting,error_handler) do |src|
|
22
|
+
root = Ruby.parse_file(src)
|
23
|
+
CodeModels::Serialization.rgenobject_to_model(root)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.generate_model_per_file(src,dest,model_ext='rb.lm',max_nesting=500,error_handler=nil)
|
28
|
+
CodeModels::ModelBuilding.generate_model_per_file(src,dest,max_nesting,error_handler) do |src|
|
29
|
+
root = Ruby.parse_file(src)
|
30
|
+
CodeModels::Serialization.rgenobject_to_model(root)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,809 @@
|
|
1
|
+
require 'jruby-parser'
|
2
|
+
require 'emf_jruby'
|
3
|
+
require 'codemodels/ruby/metamodel'
|
4
|
+
|
5
|
+
java_import org.jrubyparser.ast.Node
|
6
|
+
java_import org.jrubyparser.ast.ArrayNode
|
7
|
+
java_import org.jrubyparser.ast.ListNode
|
8
|
+
java_import org.jrubyparser.ast.BlockPassNode
|
9
|
+
java_import org.jrubyparser.ast.ArgsNode
|
10
|
+
java_import org.jrubyparser.ast.IterNode
|
11
|
+
java_import org.jrubyparser.ast.SymbolNode
|
12
|
+
java_import org.jrubyparser.ast.ArrayNode
|
13
|
+
|
14
|
+
java_import org.jrubyparser.util.StaticAnalyzerHelper
|
15
|
+
|
16
|
+
module CodeModels
|
17
|
+
|
18
|
+
module Ruby
|
19
|
+
|
20
|
+
module RawNodeAccessModule
|
21
|
+
attr_accessor :original_node
|
22
|
+
end
|
23
|
+
|
24
|
+
class << self
|
25
|
+
attr_accessor :skip_unknown_node
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.parse_file(path)
|
29
|
+
content = IO.read(path)
|
30
|
+
self.parse(content)
|
31
|
+
end
|
32
|
+
|
33
|
+
class ParsingError < Exception
|
34
|
+
attr_reader :node
|
35
|
+
|
36
|
+
def initialize(node,msg)
|
37
|
+
@node = node
|
38
|
+
@msg = msg
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_s
|
42
|
+
"#{@msg}, start line: #{@node.position.start_line}"
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
class UnknownNodeType < ParsingError
|
48
|
+
|
49
|
+
def initialize(node,where=nil)
|
50
|
+
super(node,"UnknownNodeType: type=#{node.node_type.name} , where: #{where}")
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.containment_pos(node)
|
56
|
+
container = node.eContainer
|
57
|
+
children = node.eContainer.send(node.eContainingFeature)
|
58
|
+
if children.respond_to?(:each)
|
59
|
+
children.each_with_index do |c,i|
|
60
|
+
return i if c==node
|
61
|
+
end
|
62
|
+
raise "Not found"
|
63
|
+
else
|
64
|
+
raise "Not found" unless children==node
|
65
|
+
0
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# node tree contains the original
|
70
|
+
# TO BE FIXED
|
71
|
+
def self.corresponding_node(model_element,node_tree)
|
72
|
+
return node_tree unless model_element.eContainer
|
73
|
+
corresponding_parent_node = corresponding_node(model_element.eContainer,node_tree)
|
74
|
+
containment_pos = containment_pos(model_element)
|
75
|
+
containing_feat = model_element.eContainingFeature
|
76
|
+
|
77
|
+
children = corresponding_parent_node.send(containing_feat)
|
78
|
+
if children.respond_to?(:each)
|
79
|
+
children[containment_pos]
|
80
|
+
else
|
81
|
+
children
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.assert_node_type(node,type)
|
86
|
+
raise ParsingError.new(node,"AssertionFailed: #{type} expected but #{node.node_type.name} found") unless node.node_type.name==type
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
def self.parse_code(code)
|
91
|
+
tree = JRubyParser.parse(code, {:version=>JRubyParser::Compat::RUBY2_0})
|
92
|
+
tree_to_model(tree)
|
93
|
+
end
|
94
|
+
|
95
|
+
# DEPRECATED
|
96
|
+
def self.parse(code)
|
97
|
+
parse_code(code)
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.node_tree_from_code(code)
|
101
|
+
JRubyParser.parse(code, {:version=>JRubyParser::Compat::RUBY2_0})
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.tree_to_model(tree)
|
105
|
+
unless tree.node_type.name=='ROOTNODE'
|
106
|
+
raise 'Root expected'
|
107
|
+
end
|
108
|
+
node_to_model tree.body
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.body_node_to_contents(body_node,container_node)
|
112
|
+
body = node_to_model(body_node)
|
113
|
+
if body
|
114
|
+
if body.is_a? Ruby::Block
|
115
|
+
body.contents.each do |el|
|
116
|
+
container_node.addContents(el)
|
117
|
+
end
|
118
|
+
else
|
119
|
+
container_node.addContents( body )
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.get_var_name_depending_on_parser_version(node,prefix_size=1)
|
125
|
+
if node.respond_to? :lexical_name # depends on the version...
|
126
|
+
return node.name
|
127
|
+
else
|
128
|
+
return node.name[prefix_size..-1]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.my_args_flattener(args_node)
|
133
|
+
if args_node.node_type.name=='ARGSPUSHNODE'
|
134
|
+
res = my_args_flattener(args_node.firstNode)
|
135
|
+
res << node_to_model(args_node.secondNode)
|
136
|
+
res
|
137
|
+
elsif args_node.node_type.name=='ARGSCATNODE'
|
138
|
+
res = my_args_flattener(args_node.firstNode)
|
139
|
+
if args_node.secondNode.is_a?(ArrayNode)
|
140
|
+
res.concat(my_args_flattener(args_node.secondNode))
|
141
|
+
else
|
142
|
+
res << Ruby.splat(node_to_model(args_node.secondNode))
|
143
|
+
end
|
144
|
+
res.class.class_eval do
|
145
|
+
include RawNodeAccessModule
|
146
|
+
end
|
147
|
+
res.original_node = args_node.secondNode
|
148
|
+
res
|
149
|
+
elsif args_node.is_a? ListNode
|
150
|
+
res = []
|
151
|
+
for i in 0..(args_node.size-1)
|
152
|
+
res << node_to_model(args_node.get i)
|
153
|
+
end
|
154
|
+
res
|
155
|
+
elsif args_node.node_type.name=='SPLATNODE'
|
156
|
+
res = []
|
157
|
+
res << node_to_model(args_node)
|
158
|
+
res
|
159
|
+
else
|
160
|
+
raise "Unknown: #{args_node.node_type.name} at #{args_node.position}, parent #{args_node.parent}"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def self.process_body(node,model)
|
165
|
+
if node.body==nil
|
166
|
+
model.body = nil
|
167
|
+
elsif node.body.node_type.name=='RESCUENODE'
|
168
|
+
rescue_node = node.body
|
169
|
+
model.body = node_to_model(rescue_node.body)
|
170
|
+
rescue_body_node = rescue_node.rescue
|
171
|
+
raise 'AssertionFailed' unless rescue_body_node.node_type.name=='RESCUEBODYNODE'
|
172
|
+
rescue_clause_model = Ruby::RescueClause.new
|
173
|
+
|
174
|
+
rescue_clause_model.class.class_eval do
|
175
|
+
include RawNodeAccessModule
|
176
|
+
end
|
177
|
+
rescue_clause_model.original_node = node
|
178
|
+
|
179
|
+
rescue_clause_model.body = node_to_model(rescue_body_node.body)
|
180
|
+
model.addRescue_clauses( rescue_clause_model )
|
181
|
+
elsif node.body.node_type.name=='ENSURENODE'
|
182
|
+
ensure_node = node.body
|
183
|
+
model.ensure_body = node_to_model(ensure_node.ensure)
|
184
|
+
model.body = node_to_model(ensure_node.body)
|
185
|
+
else
|
186
|
+
model.body = node_to_model(node.body,model)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def self.process_formal_args(node,model)
|
191
|
+
#puts "\nArgs are: #{node.args}"
|
192
|
+
|
193
|
+
args = []
|
194
|
+
args_node = node.args
|
195
|
+
populate_from_list(args,args_node.pre) if args_node.pre
|
196
|
+
populate_from_list(args,args_node.optional) if args_node.optional
|
197
|
+
populate_from_list(args,args_node.rest) if args_node.rest
|
198
|
+
populate_from_list(args,args_node.post) if args_node.post
|
199
|
+
#puts "\tCollected args: #{args}"
|
200
|
+
|
201
|
+
args.each do |a|
|
202
|
+
if a.is_a?(Argument)
|
203
|
+
fa = FormalArgument.new
|
204
|
+
fa.name = a.name
|
205
|
+
fa.class.class_eval do
|
206
|
+
include RawNodeAccessModule
|
207
|
+
end
|
208
|
+
fa.original_node = node
|
209
|
+
model.addFormal_args(fa)
|
210
|
+
elsif a.is_a?(FormalArgument)
|
211
|
+
if a.default_value.is_a? VarAssignment
|
212
|
+
a.default_value = a.default_value.value
|
213
|
+
end
|
214
|
+
model.addFormal_args(a)
|
215
|
+
else
|
216
|
+
raise "Unexpected #{a.class}"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
#puts "\tFormal args: #{model.formal_args}"
|
220
|
+
#model.formal_args = args_to_model(my_args_flattener(node.args))
|
221
|
+
end
|
222
|
+
|
223
|
+
def self.node_to_model(node,parent_model=nil)
|
224
|
+
return nil if node==nil
|
225
|
+
#puts "#{node} #{node.node_type.name}"
|
226
|
+
case node.node_type.name
|
227
|
+
when 'NEWLINENODE'
|
228
|
+
model = node_to_model node.next_node
|
229
|
+
|
230
|
+
##
|
231
|
+
## Literals
|
232
|
+
##
|
233
|
+
when 'FLOATNODE'
|
234
|
+
model = Ruby::FloatLiteral.new
|
235
|
+
model.value = node.value
|
236
|
+
model
|
237
|
+
when 'FIXNUMNODE'
|
238
|
+
model = Ruby::IntLiteral.new
|
239
|
+
model.value = node.value
|
240
|
+
model
|
241
|
+
when 'STRNODE'
|
242
|
+
model = Ruby::StaticStringLiteral.new
|
243
|
+
model.value = node.value
|
244
|
+
model
|
245
|
+
when 'DSTRNODE'
|
246
|
+
model = Ruby::DynamicStringLiteral.new
|
247
|
+
#model.value = node.value
|
248
|
+
for i in 0..(node.size-1)
|
249
|
+
model.addPieces( node_to_model(node.get i) )
|
250
|
+
end
|
251
|
+
model
|
252
|
+
when 'DXSTRNODE'
|
253
|
+
model = Ruby::CmdLineStringLiteral.new
|
254
|
+
for i in 0...node.size
|
255
|
+
model.addPieces( node_to_model(node.get i) )
|
256
|
+
end
|
257
|
+
model
|
258
|
+
when 'DSYMBOLNODE'
|
259
|
+
model = Ruby::DynamicSymbol.new
|
260
|
+
for i in 0...node.size
|
261
|
+
model.addPieces( node_to_model(node.get i) )
|
262
|
+
end
|
263
|
+
model
|
264
|
+
when 'DREGEXPNODE'
|
265
|
+
model = Ruby::DynamicRegExpLiteral.new
|
266
|
+
for i in 0...node.size
|
267
|
+
model.addPieces( node_to_model(node.get i) )
|
268
|
+
end
|
269
|
+
model
|
270
|
+
when 'NILNODE'
|
271
|
+
begin
|
272
|
+
implicit_nil = Java::OrgJrubyparserAst::NilImplicitNode
|
273
|
+
rescue
|
274
|
+
implicit_nil = nil # apparently the class was removed...
|
275
|
+
end
|
276
|
+
if implicit_nil && (node.is_a? Java::OrgJrubyparserAst::NilImplicitNode)
|
277
|
+
return nil
|
278
|
+
else
|
279
|
+
#puts "NIL for #{node}"
|
280
|
+
model = Ruby::NilLiteral.new
|
281
|
+
end
|
282
|
+
when 'FALSENODE'
|
283
|
+
model = Ruby::BooleanLiteral.new
|
284
|
+
model.value = false
|
285
|
+
model
|
286
|
+
when 'TRUENODE'
|
287
|
+
model = Ruby::BooleanLiteral.new
|
288
|
+
model.value = true
|
289
|
+
model
|
290
|
+
when 'REGEXPNODE'
|
291
|
+
model = Ruby::StaticRegExpLiteral.new
|
292
|
+
model.value = node.value
|
293
|
+
model
|
294
|
+
|
295
|
+
###
|
296
|
+
### Variable accesses
|
297
|
+
###
|
298
|
+
when 'LOCALVARNODE'
|
299
|
+
model = Ruby::LocalVarAccess.new
|
300
|
+
model.name = node.name
|
301
|
+
model
|
302
|
+
when 'DVARNODE'
|
303
|
+
model = Ruby::BlockVarAccess.new
|
304
|
+
model.name = node.name
|
305
|
+
model
|
306
|
+
when 'GLOBALVARNODE'
|
307
|
+
model = Ruby::GlobalVarAccess.new
|
308
|
+
model.name = get_var_name_depending_on_parser_version(node)
|
309
|
+
model
|
310
|
+
when 'CLASSVARNODE'
|
311
|
+
model = Ruby::ClassVarAccess.new
|
312
|
+
model.name = get_var_name_depending_on_parser_version(node,2)
|
313
|
+
model
|
314
|
+
when 'INSTVARNODE'
|
315
|
+
model = Ruby::InstanceVarAccess.build get_var_name_depending_on_parser_version(node)
|
316
|
+
|
317
|
+
###
|
318
|
+
### Variable Assignments
|
319
|
+
###
|
320
|
+
when 'LOCALASGNNODE'
|
321
|
+
model = Ruby::LocalVarAssignment.new
|
322
|
+
model.name_assigned = node.name
|
323
|
+
model.value = node_to_model(node.value)
|
324
|
+
model
|
325
|
+
when 'DASGNNODE'
|
326
|
+
model = Ruby::BlockVarAssignment.new
|
327
|
+
model.name_assigned = node.name
|
328
|
+
model.value = node_to_model(node.value)
|
329
|
+
model
|
330
|
+
when 'GLOBALASGNNODE'
|
331
|
+
model = Ruby::GlobalVarAssignment.new
|
332
|
+
model.name_assigned = get_var_name_depending_on_parser_version(node)
|
333
|
+
model.value = node_to_model(node.value)
|
334
|
+
model
|
335
|
+
when 'CLASSVARASGNNODE'
|
336
|
+
model = Ruby::ClassVarAssignment.new
|
337
|
+
model.name_assigned = get_var_name_depending_on_parser_version(node,2)
|
338
|
+
model.value = node_to_model(node.value)
|
339
|
+
model
|
340
|
+
when 'INSTASGNNODE'
|
341
|
+
model = Ruby::InstanceVarAssignment.new
|
342
|
+
model.name_assigned = get_var_name_depending_on_parser_version(node)
|
343
|
+
model.value = node_to_model(node.value)
|
344
|
+
model
|
345
|
+
|
346
|
+
###
|
347
|
+
### Other assignments
|
348
|
+
###
|
349
|
+
|
350
|
+
when 'OPELEMENTASGNNODE'
|
351
|
+
model = Ruby::ElementOperationAssignment.new
|
352
|
+
model.container = node_to_model(node.receiver)
|
353
|
+
model.element = node_to_model(node.args[0])
|
354
|
+
model.value = node_to_model(node.value)
|
355
|
+
model.operator = node.operator_name
|
356
|
+
model
|
357
|
+
when 'ATTRASSIGNNODE'
|
358
|
+
model = Ruby::ElementAssignment.new
|
359
|
+
model.container = node_to_model(node.receiver)
|
360
|
+
if node.args # apparently it can be null...
|
361
|
+
model.element = node_to_model(node.args[0])
|
362
|
+
model.value = node_to_model(node.args[1])
|
363
|
+
end
|
364
|
+
model
|
365
|
+
when 'OPASGNORNODE'
|
366
|
+
model = Ruby::OrAssignment.new
|
367
|
+
# assigned : from access to variable
|
368
|
+
# value : from Assignment to value
|
369
|
+
model.assigned = node_to_model(node.first)
|
370
|
+
model.value = node_to_model(node.second).value
|
371
|
+
model
|
372
|
+
when 'MULTIPLEASGNNODE'
|
373
|
+
# TODO consider asterisk
|
374
|
+
model = Ruby::MultipleAssignment.new
|
375
|
+
if node.pre
|
376
|
+
for i in 0..(node.pre.count-1)
|
377
|
+
model.addAssignments( node_to_model(node.pre.get(i)) )
|
378
|
+
end
|
379
|
+
end
|
380
|
+
values_model = node_to_model(node.value)
|
381
|
+
if values_model.respond_to? :values
|
382
|
+
values_model.values.each {|x| model.addValues(x) }
|
383
|
+
else
|
384
|
+
model.addValues( values_model )
|
385
|
+
end
|
386
|
+
# TODO consider rest and post!
|
387
|
+
model
|
388
|
+
when 'MULTIPLEASGN19NODE'
|
389
|
+
# TODO consider asterisk
|
390
|
+
model = Ruby::MultipleAssignment.new
|
391
|
+
if node.pre
|
392
|
+
for i in 0..(node.pre.count-1)
|
393
|
+
model.addAssignments( node_to_model(node.pre.get(i)) )
|
394
|
+
end
|
395
|
+
end
|
396
|
+
values_model = node_to_model(node.value)
|
397
|
+
if values_model.respond_to? :values
|
398
|
+
values_model.values.each {|x| model.addValues(x)}
|
399
|
+
else
|
400
|
+
model.addValues( values_model )
|
401
|
+
end
|
402
|
+
# TODO consider rest and post!
|
403
|
+
model
|
404
|
+
when 'OPASGNNODE'
|
405
|
+
model = Ruby::OperatorAssignment.new
|
406
|
+
model.value = node_to_model(node.valueNode)
|
407
|
+
model.container = node_to_model(node.receiverNode)
|
408
|
+
model.element_name = node.variable_name
|
409
|
+
model.operator_name = node.operator_name
|
410
|
+
model
|
411
|
+
|
412
|
+
###
|
413
|
+
### Constants
|
414
|
+
###
|
415
|
+
|
416
|
+
when 'CONSTDECLNODE'
|
417
|
+
model = Ruby::ConstantDecl.new
|
418
|
+
model.name = node.name
|
419
|
+
model.value = node_to_model(node.value)
|
420
|
+
model
|
421
|
+
|
422
|
+
###
|
423
|
+
### Statements
|
424
|
+
###
|
425
|
+
|
426
|
+
when 'ALIASNODE'
|
427
|
+
model = Ruby::AliasStatement.new
|
428
|
+
model.old_name = node_to_model(node.oldName)
|
429
|
+
model.new_name = node_to_model(node.newName)
|
430
|
+
model
|
431
|
+
when 'CASENODE'
|
432
|
+
model = Ruby::CaseStatement.new
|
433
|
+
for ci in 0..(node.cases.count-1)
|
434
|
+
c = node.cases[ci]
|
435
|
+
model.addWhen_clauses( node_to_model(c) )
|
436
|
+
end
|
437
|
+
model.else_body = node_to_model(node.else)
|
438
|
+
model
|
439
|
+
when 'WHENNODE'
|
440
|
+
model = Ruby::WhenClause.new
|
441
|
+
model.body = node_to_model(node.body)
|
442
|
+
model.condition = node_to_model(node.expression)
|
443
|
+
model
|
444
|
+
when 'UNDEFNODE'
|
445
|
+
model = Ruby::UndefStatement.new
|
446
|
+
model.name = node_to_model(node.name)
|
447
|
+
model
|
448
|
+
when 'WHILENODE'
|
449
|
+
model = Ruby::WhileStatement.new
|
450
|
+
model.body = node_to_model(node.body)
|
451
|
+
model.condition = node_to_model(node.condition)
|
452
|
+
model
|
453
|
+
when 'FORNODE'
|
454
|
+
model = Ruby::ForStatement.new
|
455
|
+
model.body = node_to_model(node.body)
|
456
|
+
model.collection = node_to_model(node.iter)
|
457
|
+
model.iterator = node_to_model(node.var)
|
458
|
+
model
|
459
|
+
when 'BREAKNODE'
|
460
|
+
model = Ruby::BreakStatement.new
|
461
|
+
when 'UNTILNODE'
|
462
|
+
model = Ruby::UntilStatement.new
|
463
|
+
model.body = node_to_model(node.body)
|
464
|
+
model.condition = node_to_model(node.condition)
|
465
|
+
model
|
466
|
+
when 'RESCUENODE'
|
467
|
+
model = Ruby::RescueStatement.new
|
468
|
+
model.body = node_to_model(node.body)
|
469
|
+
model.value = node_to_model(node.rescueNode.body)
|
470
|
+
model
|
471
|
+
|
472
|
+
###
|
473
|
+
### The rest
|
474
|
+
###
|
475
|
+
|
476
|
+
when 'NTHREFNODE'
|
477
|
+
model = Ruby::NthGroupReference.build(node.matchNumber)
|
478
|
+
when 'YIELDNODE'
|
479
|
+
model = Ruby::YieldStatement.new
|
480
|
+
when 'NEXTNODE'
|
481
|
+
model = Ruby::NextStatement.new
|
482
|
+
when 'COLON3NODE'
|
483
|
+
model = Ruby::GlobalScopeReference.new
|
484
|
+
model.name = node.name
|
485
|
+
model
|
486
|
+
when 'DOTNODE'
|
487
|
+
model = Ruby::Range.new
|
488
|
+
model.lower = node_to_model(node.beginNode)
|
489
|
+
model.upper = node_to_model(node.endNode)
|
490
|
+
model
|
491
|
+
when 'MATCH2NODE'
|
492
|
+
model = Ruby::RegexTryer.new
|
493
|
+
model.checked_value = node_to_model(node.value)
|
494
|
+
model.regex = node_to_model(node.receiver)
|
495
|
+
model
|
496
|
+
when 'MATCH3NODE'
|
497
|
+
model = Ruby::RegexMatcher.new
|
498
|
+
model.checked_value = node_to_model(node.value)
|
499
|
+
model.regex = node_to_model(node.receiver)
|
500
|
+
model
|
501
|
+
when 'LITERALNODE'
|
502
|
+
model = Ruby::LiteralReference.new
|
503
|
+
model.value = node.name
|
504
|
+
model
|
505
|
+
when 'SELFNODE'
|
506
|
+
model = Ruby::Self.new
|
507
|
+
model
|
508
|
+
when 'ZSUPERNODE'
|
509
|
+
model = Ruby::CallToSuper.new
|
510
|
+
if node.iter
|
511
|
+
model.block_arg = node_to_model(node.iter)
|
512
|
+
end
|
513
|
+
model
|
514
|
+
when 'SUPERNODE'
|
515
|
+
model = Ruby::SuperCall.new
|
516
|
+
|
517
|
+
if node.args.node_type.name == 'BLOCKPASSNODE'
|
518
|
+
model.block_arg = node_to_model(node.args)
|
519
|
+
args_to_process = node.args.args
|
520
|
+
else
|
521
|
+
args_to_process = node.args
|
522
|
+
end
|
523
|
+
|
524
|
+
if node.iter==nil and args_to_process.is_a?IterNode
|
525
|
+
model.block_arg = node_to_model(args_to_process)
|
526
|
+
# no args
|
527
|
+
else
|
528
|
+
model.block_arg = node_to_model(node.iter) if node.iter
|
529
|
+
model.args = my_args_flattener(args_to_process) if args_to_process
|
530
|
+
end
|
531
|
+
|
532
|
+
model
|
533
|
+
when 'CALLNODE'
|
534
|
+
model = Ruby::ExplicitReceiverCall.new
|
535
|
+
model.name = node.name
|
536
|
+
model.receiver = node_to_model node.receiver
|
537
|
+
|
538
|
+
if node.args.node_type.name == 'BLOCKPASSNODE'
|
539
|
+
model.block_arg = node_to_model(node.args)
|
540
|
+
args_to_process = node.args.args
|
541
|
+
else
|
542
|
+
args_to_process = node.args
|
543
|
+
end
|
544
|
+
|
545
|
+
if node.iter==nil and args_to_process.is_a?IterNode
|
546
|
+
model.block_arg = node_to_model(args_to_process)
|
547
|
+
# no args
|
548
|
+
else
|
549
|
+
model.block_arg = node_to_model(node.iter) if node.iter
|
550
|
+
model.args = my_args_flattener(args_to_process) if args_to_process
|
551
|
+
end
|
552
|
+
|
553
|
+
model
|
554
|
+
when 'VCALLNODE'
|
555
|
+
model = Ruby::ExplicitReceiverCall.new
|
556
|
+
model.name = node.name
|
557
|
+
model
|
558
|
+
when 'FCALLNODE'
|
559
|
+
model = Ruby::ImplicitReceiverCall.new
|
560
|
+
model.name = node.name
|
561
|
+
|
562
|
+
if node.args.node_type.name == 'BLOCKPASSNODE'
|
563
|
+
model.block_arg = node_to_model(node.args)
|
564
|
+
args_to_process = node.args.args
|
565
|
+
else
|
566
|
+
args_to_process = node.args
|
567
|
+
end
|
568
|
+
|
569
|
+
if node.iter==nil and args_to_process.is_a?IterNode
|
570
|
+
model.block_arg = node_to_model(args_to_process)
|
571
|
+
# no args
|
572
|
+
else
|
573
|
+
model.block_arg = node_to_model(node.iter) if node.iter
|
574
|
+
model.args = my_args_flattener(args_to_process) if args_to_process
|
575
|
+
end
|
576
|
+
|
577
|
+
model
|
578
|
+
when 'DEFNNODE'
|
579
|
+
model = Ruby::InstanceDef.new
|
580
|
+
model.name = node.name
|
581
|
+
process_formal_args(node,model)
|
582
|
+
process_body(node,model)
|
583
|
+
model
|
584
|
+
when 'DEFSNODE'
|
585
|
+
model = Ruby::SelfDef.new
|
586
|
+
model.name = node.name
|
587
|
+
process_formal_args(node,model)
|
588
|
+
process_body(node,model)
|
589
|
+
model
|
590
|
+
when 'BLOCKNODE'
|
591
|
+
model = Ruby::Block.new
|
592
|
+
for i in 0..(node.size-1)
|
593
|
+
content_at_i = node_to_model(node.get i)
|
594
|
+
#puts "Adding to contents #{content_at_i}"
|
595
|
+
model.addContents( content_at_i )
|
596
|
+
#puts "Contents #{model.contents.class}"
|
597
|
+
end
|
598
|
+
model
|
599
|
+
when 'BACKREFNODE'
|
600
|
+
model = Ruby::BackReference.new
|
601
|
+
when 'EVSTRNODE'
|
602
|
+
model = node_to_model(node.body)
|
603
|
+
when 'CLASSNODE'
|
604
|
+
model = Ruby::ClassDecl.new
|
605
|
+
model.defname = node_to_model(node.getCPath)
|
606
|
+
model.super_class = node_to_model(node.super)
|
607
|
+
body_node_to_contents(node.body_node,model)
|
608
|
+
model
|
609
|
+
when 'SCLASSNODE'
|
610
|
+
model = Ruby::SingletonClassDecl.new
|
611
|
+
model.object = node_to_model(node.receiver)
|
612
|
+
body_node_to_contents(node.body_node,model)
|
613
|
+
model
|
614
|
+
when 'MODULENODE'
|
615
|
+
model = Ruby::ModuleDecl.new
|
616
|
+
model.defname = node_to_model(node.getCPath)
|
617
|
+
body_node_to_contents(node.body_node,model)
|
618
|
+
model
|
619
|
+
when 'COLON2NODE'
|
620
|
+
model = Ruby::Constant.new
|
621
|
+
model.name = node.name
|
622
|
+
model.container = node_to_model(node.left_node)
|
623
|
+
model
|
624
|
+
when 'SYMBOLNODE'
|
625
|
+
model = Ruby::Symbol.new
|
626
|
+
model.name = node.name
|
627
|
+
model
|
628
|
+
when 'CONSTNODE'
|
629
|
+
model = Ruby::Constant.new
|
630
|
+
model.name = node.name
|
631
|
+
model
|
632
|
+
when 'IFNODE'
|
633
|
+
model = Ruby::IfStatement.new
|
634
|
+
model.condition = node_to_model(node.condition)
|
635
|
+
model.then_body = node_to_model(node.then_body)
|
636
|
+
model.else_body = node_to_model(node.else_body)
|
637
|
+
model
|
638
|
+
when 'HASHNODE'
|
639
|
+
model = Ruby::HashLiteral.new
|
640
|
+
count = node.get_list_node.count / 2
|
641
|
+
for i in 0..(count-1)
|
642
|
+
k_node = node.get_list_node[i*2]
|
643
|
+
k = node_to_model(k_node)
|
644
|
+
v_node = node.get_list_node[i*2 +1]
|
645
|
+
v = node_to_model(v_node)
|
646
|
+
pair = Ruby::HashPair.build key: k, value: v
|
647
|
+
model.addPairs(pair)
|
648
|
+
end
|
649
|
+
model
|
650
|
+
when 'DEFINEDNODE'
|
651
|
+
model = Ruby::IsDefined.new
|
652
|
+
model.value = node_to_model(node.expression)
|
653
|
+
model
|
654
|
+
when 'ARRAYNODE'
|
655
|
+
model = Ruby::ArrayLiteral.new
|
656
|
+
for i in 0..(node.count-1)
|
657
|
+
v_node = node[i]
|
658
|
+
v = node_to_model(v_node)
|
659
|
+
model.addValues(v)
|
660
|
+
end
|
661
|
+
model
|
662
|
+
when 'SPLATNODE'
|
663
|
+
model = Ruby::Splat.new
|
664
|
+
model.splatted = node_to_model(node.value)
|
665
|
+
model
|
666
|
+
when 'UNARYCALLNODE'
|
667
|
+
model = Ruby::UnaryOperation.new
|
668
|
+
model.value = node_to_model(node.receiver)
|
669
|
+
model.operator_name = node.lexical_name
|
670
|
+
model
|
671
|
+
when 'ZARRAYNODE'
|
672
|
+
model = Ruby::ArrayLiteral.new
|
673
|
+
when 'RETRYNODE'
|
674
|
+
model = Ruby::RetryStatement.new
|
675
|
+
when 'BEGINNODE'
|
676
|
+
model = Ruby::BeginEndBlock.new
|
677
|
+
process_body(node,model)
|
678
|
+
model
|
679
|
+
when 'RETURNNODE'
|
680
|
+
model = Ruby::Return.new
|
681
|
+
model.value = node_to_model(node.value)
|
682
|
+
model
|
683
|
+
when 'ANDNODE'
|
684
|
+
model = Ruby::AndOperator.new
|
685
|
+
model.left = node_to_model(node.first)
|
686
|
+
model.right = node_to_model(node.second)
|
687
|
+
model
|
688
|
+
when 'ORNODE'
|
689
|
+
model = Ruby::OrOperator.new
|
690
|
+
model.left = node_to_model(node.first)
|
691
|
+
model.right = node_to_model(node.second)
|
692
|
+
model
|
693
|
+
when 'ITERNODE'
|
694
|
+
model = Ruby::CodeBlock.new
|
695
|
+
model.args = clean_args(args_to_model(node.var))
|
696
|
+
model.body = node_to_model(node.body)
|
697
|
+
model
|
698
|
+
when 'ARGUMENTNODE'
|
699
|
+
model = Ruby::Argument.new
|
700
|
+
model.name = node.name
|
701
|
+
model
|
702
|
+
when 'RESTARG'
|
703
|
+
model = Ruby::Argument.new
|
704
|
+
model.name = node.name
|
705
|
+
model
|
706
|
+
when 'BLOCKPASSNODE'
|
707
|
+
model = Ruby::BlockReference.new
|
708
|
+
#raise ParsingError.new(node,"Unexpected something that is not a symbol but a #{node.body}") unless node.body.is_a? SymbolNode
|
709
|
+
model.value = node_to_model(node.body)
|
710
|
+
model
|
711
|
+
when 'ARGSCATNODE'
|
712
|
+
model = Ruby::ArrayLiteral.new
|
713
|
+
model.values = my_args_flattener(node)
|
714
|
+
model
|
715
|
+
when 'ARGSPUSHNODE'
|
716
|
+
model = Ruby::ArrayLiteral.new
|
717
|
+
model.values = my_args_flattener(node)
|
718
|
+
model
|
719
|
+
when 'OPTARGNODE'
|
720
|
+
model = Ruby::FormalArgument.new
|
721
|
+
model.name = node.name
|
722
|
+
model.default_value = node_to_model(node.value)
|
723
|
+
model
|
724
|
+
else
|
725
|
+
#n = node
|
726
|
+
#while n
|
727
|
+
# puts "> #{n}"
|
728
|
+
# n = n.parent
|
729
|
+
#end
|
730
|
+
unknown_node_type_found(node)
|
731
|
+
#raise "I don't know how to deal with #{node.node_type.name} (position: #{node.position})"
|
732
|
+
end
|
733
|
+
model.class.class_eval do
|
734
|
+
include RawNodeAccessModule
|
735
|
+
end
|
736
|
+
#puts "Setting variable for #{model} to #{node}" if model.is_a?(InstanceDef)
|
737
|
+
#model.instance_variable_set(:@original_node,node)
|
738
|
+
model.original_node = node
|
739
|
+
model
|
740
|
+
end
|
741
|
+
|
742
|
+
def self.unknown_node_type_found(node)
|
743
|
+
if Ruby.skip_unknown_node
|
744
|
+
puts "skipping #{node.node_type.name} at #{node.position}..."
|
745
|
+
else
|
746
|
+
raise UnknownNodeType.new(node)
|
747
|
+
end
|
748
|
+
end
|
749
|
+
|
750
|
+
def self.populate_from_list(array,list_node)
|
751
|
+
if list_node.respond_to? :size
|
752
|
+
for i in 0..(list_node.size-1)
|
753
|
+
array << node_to_model(list_node.get i)
|
754
|
+
end
|
755
|
+
else
|
756
|
+
array << node_to_model(list_node)
|
757
|
+
end
|
758
|
+
end
|
759
|
+
|
760
|
+
def self.clean_args(args)
|
761
|
+
for i in 0..(args.count-1)
|
762
|
+
if args[i].is_a? Ruby::MultipleAssignment
|
763
|
+
old = args[i]
|
764
|
+
args[i] = Ruby::SplittedArgument.new
|
765
|
+
old.assignments.each {|a| args[i].names = args[i].names << a.name_assigned}
|
766
|
+
end
|
767
|
+
end
|
768
|
+
args
|
769
|
+
end
|
770
|
+
|
771
|
+
def self.args_to_model(args_node)
|
772
|
+
args=[]
|
773
|
+
if args_node.is_a? ArrayNode
|
774
|
+
#puts "ARGS #{args_node} #{args_node.size} #{args_node.class}"
|
775
|
+
for i in 0..(args_node.size-1)
|
776
|
+
#puts "DEALING WITH #{i} #{args_node.get i} #{(args_node.get i).class}"
|
777
|
+
args << node_to_model(args_node.get i)
|
778
|
+
end
|
779
|
+
args
|
780
|
+
elsif args_node.is_a? ListNode
|
781
|
+
for i in 0..(args_node.size-1)
|
782
|
+
#puts "DEALING WITH #{i} #{args_node.get i} #{(args_node.get i).class}"
|
783
|
+
args << node_to_model(args_node.get i)
|
784
|
+
end
|
785
|
+
args
|
786
|
+
elsif args_node.is_a? ArgsNode
|
787
|
+
populate_from_list(args,args_node.pre) if args_node.pre
|
788
|
+
populate_from_list(args,args_node.optional) if args_node.optional
|
789
|
+
populate_from_list(args,args_node.rest) if args_node.rest
|
790
|
+
populate_from_list(args,args_node.post) if args_node.post
|
791
|
+
args
|
792
|
+
elsif args_node.is_a? Node
|
793
|
+
args << node_to_model(args_node)
|
794
|
+
args
|
795
|
+
else
|
796
|
+
raise UnknownNodeType.new(args_node,'in args')
|
797
|
+
end
|
798
|
+
end
|
799
|
+
|
800
|
+
class Parser < CodeModels::Parser
|
801
|
+
|
802
|
+
def parse_code(code)
|
803
|
+
CodeModels::Ruby.parse_code(code)
|
804
|
+
end
|
805
|
+
|
806
|
+
end
|
807
|
+
|
808
|
+
end
|
809
|
+
end
|