archruby 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -0
  3. data/README.md +1 -1
  4. data/Rakefile +46 -0
  5. data/TODO.rtf +20 -0
  6. data/architecture.yml +51 -0
  7. data/archruby.gemspec +3 -0
  8. data/bin/archruby +1 -0
  9. data/lib/archruby.rb +14 -2
  10. data/lib/archruby/architecture/architecture.rb +6 -6
  11. data/lib/archruby/architecture/config_definition.rb +13 -13
  12. data/lib/archruby/architecture/constraint_break.rb +1 -1
  13. data/lib/archruby/architecture/dependency.rb +3 -1
  14. data/lib/archruby/architecture/file_content.rb +2 -2
  15. data/lib/archruby/architecture/module_definition.rb +33 -20
  16. data/lib/archruby/architecture/parser.rb +25 -11
  17. data/lib/archruby/architecture/type_inference_checker.rb +29 -13
  18. data/lib/archruby/presenters/dsm.rb +163 -0
  19. data/lib/archruby/presenters/dsm/cell_dsm.rb +17 -0
  20. data/lib/archruby/presenters/dsm/dsm_css.css +77 -0
  21. data/lib/archruby/presenters/graph.rb +12 -9
  22. data/lib/archruby/ruby/parser.rb +131 -125
  23. data/lib/archruby/ruby/type_inference/dependency_organizer.rb +53 -0
  24. data/lib/archruby/ruby/type_inference/ruby/class_dependency.rb +22 -0
  25. data/lib/archruby/ruby/type_inference/ruby/internal_method_invocation.rb +20 -0
  26. data/lib/archruby/ruby/type_inference/ruby/method_definition.rb +20 -0
  27. data/lib/archruby/ruby/type_inference/ruby/parser_for_typeinference.rb +537 -0
  28. data/lib/archruby/ruby/type_inference/ruby/process_method_arguments.rb +155 -0
  29. data/lib/archruby/ruby/type_inference/ruby/process_method_body.rb +427 -0
  30. data/lib/archruby/ruby/type_inference/ruby/process_method_params.rb +276 -0
  31. data/lib/archruby/ruby/type_inference/type_inference_checker.rb +126 -0
  32. data/lib/archruby/version.rb +1 -1
  33. data/spec/architecture/file_content_spec.rb +2 -1
  34. data/spec/architecture/module_definition_spec.rb +9 -9
  35. data/spec/dummy_app/lib/teste_class.rb +6 -0
  36. data/spec/ruby/type_inference/dependency_organizer_spec.rb +20 -0
  37. data/spec/ruby/type_inference/fixtures/homebrew_bottles_class.rb +139 -0
  38. data/spec/ruby/type_inference/fixtures/homebrew_brew_teste.rb +1323 -0
  39. data/spec/ruby/type_inference/fixtures/rails_action_view_class_teste.rb +89 -0
  40. data/spec/ruby/type_inference/fixtures/rails_active_record_class.rb +99 -0
  41. data/spec/ruby/type_inference/fixtures/rails_teste_active_record.rb +55 -0
  42. data/spec/ruby/type_inference/fixtures/teste2.rb +16 -0
  43. data/spec/ruby/type_inference/fixtures/teste_class_and_args.rb +49 -0
  44. data/spec/ruby/type_inference/fixtures/teste_class_and_args2.rb +11 -0
  45. data/spec/ruby/type_inference/parser_for_typeinference_spec.rb +69 -0
  46. data/spec/ruby/type_inference/type_inference_checker_spec.rb +47 -0
  47. metadata +84 -3
@@ -6,10 +6,11 @@ module Archruby
6
6
 
7
7
  class Parser < SexpInterpreter
8
8
  attr_reader :dependencies, :classes, :classes_and_dependencies,
9
- :type_inference, :method_calls
9
+ :type_inference, :method_calls, :type_propagation_parser
10
10
 
11
- def initialize content
11
+ def initialize(content)
12
12
  super()
13
+ #a = Archruby::Presenters::Graph.new
13
14
  @content = content
14
15
  @dependencies = []
15
16
  @classes = []
@@ -18,21 +19,23 @@ module Archruby
18
19
  @module_names = []
19
20
  @complete_class_name = []
20
21
  @var_propagation = Archruby::Ruby::VarPropagation.new
22
+ @type_propagation_parser = Archruby::Ruby::TypeInference::Ruby::ParserForTypeinference.new
21
23
  @type_inference = []
22
24
  @method_calls = []
23
25
  parse
24
26
  end
25
27
 
26
28
  def parse
27
- process ruby_parser.parse @content
29
+ process ruby_parser.parse(@content)
30
+ @type_propagation_parser.parse(@content)
28
31
  end
29
32
 
30
- def process_block exp
33
+ def process_block(exp)
31
34
  _, *args = exp
32
- args.map! {|sub_tree| process sub_tree}
35
+ args.map! {|sub_tree| process(sub_tree)}
33
36
  end
34
37
 
35
- def process_class exp
38
+ def process_class(exp)
36
39
  _, class_name, *args = exp
37
40
  if class_name.class == Symbol
38
41
  if !@module_names.empty?
@@ -42,17 +45,17 @@ module Archruby
42
45
  end
43
46
  else
44
47
  # cai aqui quando a definicao é algo do tipo: class Teste::De end
45
- get_complete_class_name class_name
48
+ get_complete_class_name(class_name)
46
49
  @classes << @complete_class_name.join("::")
47
50
  @complete_class_name = []
48
51
  end
49
- args.map! {|sub_tree| process sub_tree}
52
+ args.map! {|sub_tree| process(sub_tree)}
50
53
  end
51
54
 
52
- def get_complete_class_name exp
55
+ def get_complete_class_name(exp)
53
56
  if exp[0] == :const
54
57
  _, const_name = exp
55
- @complete_class_name.unshift const_name
58
+ @complete_class_name.unshift(const_name)
56
59
  return
57
60
  else
58
61
  _, first_part, last_constant_part = exp
@@ -61,53 +64,57 @@ module Archruby
61
64
  end
62
65
  end
63
66
 
64
- def process_const exp
67
+ def process_const(exp)
65
68
  _, const_name = exp
66
69
  if !@full_class_path.empty?
67
70
  const_name = build_full_name(const_name)
68
71
  end
69
- add_dependency const_name
70
- build_class_dependency const_name, exp.line
72
+ add_dependency(const_name)
73
+ build_class_dependency(const_name, exp.line)
71
74
  end
72
75
 
73
- def build_full_name const_name
74
- @full_class_path.unshift const_name
76
+ def build_full_name(const_name)
77
+ @full_class_path.unshift(const_name)
75
78
  full_class_path = @full_class_path.join('::')
76
79
  @full_class_path = []
77
80
  full_class_path
78
81
  end
79
82
 
80
- def build_class_dependency const_name, line_number
83
+ def build_class_dependency(const_name, line_number)
81
84
  return if @classes.empty?
82
85
  class_name = @classes.last
83
86
  @classes_and_dependencies[class_name] = [] if @classes_and_dependencies[class_name].nil?
84
87
  @classes_and_dependencies[class_name] << Archruby::Architecture::Dependency.new(const_name, line_number)
85
88
  end
86
89
 
87
- def add_dependency const_name
90
+ def process_for(exp)
91
+
92
+ end
93
+
94
+ def add_dependency(const_name)
88
95
  @dependencies << const_name.to_s if !@dependencies.include?(const_name.to_s)
89
96
  end
90
97
 
91
- def process_colon3 exp
98
+ def process_colon3(exp)
92
99
  _, constant_name = exp
93
100
  const_name = build_full_name("::#{constant_name}")
94
- add_dependency const_name
95
- build_class_dependency const_name, exp.line
101
+ add_dependency(const_name)
102
+ build_class_dependency(const_name, exp.line)
96
103
  end
97
104
 
98
- def process_call exp
105
+ def process_call(exp)
99
106
  _, receiver, method_name, *args = exp
100
- process receiver
107
+ process(receiver)
101
108
  if receiver && (receiver[0] == :const || receiver[0] == :colon2)
102
109
  if @variables
103
- @var_propagation.push @variables.last, exp.line, @dependencies.last
110
+ @var_propagation.push(@variables.last, exp.line, @dependencies.last)
104
111
  end
105
112
  end
106
113
  build_type_inference(receiver, method_name, args, exp.line)
107
114
  args.map! {|sub_tree| process sub_tree}
108
115
  end
109
116
 
110
- def build_call_history receiver, method_name, params_name
117
+ def build_call_history(receiver, method_name, params_name)
111
118
  @method_calls << {
112
119
  :class => @classes.last,
113
120
  :method => @current_method_name,
@@ -115,10 +122,10 @@ module Archruby
115
122
  :class_call => receiver,
116
123
  :method_call => method_name,
117
124
  :method_call_params => params_name
118
- }
125
+ }
119
126
  end
120
127
 
121
- def build_type_inference receiver, method_name, params, line_num
128
+ def build_type_inference(receiver, method_name, params, line_num)
122
129
  if !@local_types.nil? && receiver && receiver[0] == :lvar
123
130
  receiver = @local_types[receiver[1]]
124
131
  params_name = []
@@ -151,28 +158,27 @@ module Archruby
151
158
  end
152
159
  end
153
160
 
154
- def extract_arguments arguments
161
+ def extract_arguments(arguments)
155
162
  _, *arg_vars = arguments
156
163
  if arg_vars[0].class == Symbol
157
164
  @current_arguments = arg_vars
158
165
  end
159
166
  end
160
167
 
161
- def process_defn exp
168
+ def process_defn(exp)
162
169
  @variables = []
163
170
  @local_types = {}
164
171
  _, method_name, method_arguments, *args = exp
165
172
  @current_method_name = method_name
166
173
  extract_arguments(method_arguments)
167
- process method_arguments
174
+ process(method_arguments)
168
175
  args.map! {|sub_tree| process sub_tree}
169
176
  @var_propagation.vars.each do |var|
170
177
  var = var[var.keys.first]
171
178
  if var[:type]
172
179
  var[:lines].shift
173
180
  var[:lines].each do |line_number|
174
-
175
- build_class_dependency var[:type], line_number
181
+ build_class_dependency(var[:type], line_number)
176
182
  end
177
183
  end
178
184
  end
@@ -182,185 +188,185 @@ module Archruby
182
188
  @current_arguments = nil
183
189
  end
184
190
 
185
- def process_lasgn exp
191
+ def process_lasgn(exp)
186
192
  _, variable_name, *args = exp
187
193
  const_access = args[0][0] == :call unless args[0].nil?
188
194
  @variables.push(variable_name) if @variables
189
- args.map! {|sub_tree| process sub_tree}
195
+ args.map!{ |sub_tree| process(sub_tree) }
190
196
  if @local_types.class == Hash && const_access
191
197
  @local_types[variable_name] = @dependencies.last
192
198
  end
193
199
  end
194
200
 
195
- def process_lit exp
201
+ def process_lit(exp)
196
202
  _, value = exp
197
203
  end
198
204
 
199
- def process_lvar exp
205
+ def process_lvar(exp)
200
206
  _, variable_name = exp
201
- @var_propagation.push variable_name, exp.line
207
+ @var_propagation.push(variable_name, exp.line)
202
208
  end
203
209
 
204
- def process_iter exp
210
+ def process_iter(exp)
205
211
  _, *args = exp
206
- args.map! {|sub_tree| process sub_tree}
212
+ args.map! {|sub_tree| next if sub_tree.class == Fixnum; process(sub_tree)}
207
213
  end
208
214
 
209
- def process_args exp
215
+ def process_args(exp)
210
216
  _, *args = exp
211
217
  args.map! do |sub_tree|
212
218
  process sub_tree if sub_tree.class != Symbol
213
219
  end
214
220
  end
215
221
 
216
- def process_nil exp
222
+ def process_nil(exp)
217
223
  _ = exp
218
224
  end
219
225
 
220
- def process_str exp
226
+ def process_str(exp)
221
227
  _, string = exp
222
228
  end
223
229
 
224
- def process_return exp
230
+ def process_return(exp)
225
231
  _, *args = exp
226
- args.map! {|sub_tree| process sub_tree}
232
+ args.map! {|sub_tree| process(sub_tree) }
227
233
  end
228
234
 
229
- def process_colon2 exp
235
+ def process_colon2(exp)
230
236
  _, first_part, last_part = exp
231
237
  @full_class_path.unshift(last_part)
232
- process first_part
238
+ process(first_part)
233
239
  end
234
240
 
235
- def process_hash exp
241
+ def process_hash(exp)
236
242
  _, *args = exp
237
- args.map! {|sub_tree| process sub_tree}
243
+ args.map! {|sub_tree| process(sub_tree)}
238
244
  end
239
245
 
240
246
  def process_iasgn exp
241
247
  _, variable_name, *args = exp
242
- args.map! {|sub_tree| process sub_tree}
248
+ args.map! {|sub_tree| process(sub_tree)}
243
249
  end
244
250
 
245
- def process_defs exp
251
+ def process_defs(exp)
246
252
  _, receiver, method_name, arguments, *args = exp
247
- process arguments
248
- args.map! {|sub_tree| process sub_tree}
253
+ process(arguments)
254
+ args.map! {|sub_tree| process(sub_tree)}
249
255
  end
250
256
 
251
- def process_attrasgn exp
257
+ def process_attrasgn(exp)
252
258
  _, object, method_call, *args = exp
253
- process object
254
- args.map! {|sub_tree| process sub_tree}
259
+ process(object)
260
+ args.map! {|sub_tree| process(sub_tree)}
255
261
  end
256
262
 
257
- def process_ivar exp
263
+ def process_ivar(exp)
258
264
  _, instance_variable_name = exp
259
265
  end
260
266
 
261
- def process_dstr exp
267
+ def process_dstr(exp)
262
268
  _, string, *args = exp
263
- args.map! {|sub_tree| process sub_tree}
269
+ args.map! {|sub_tree| process(sub_tree)}
264
270
  end
265
271
 
266
- def process_evstr exp
272
+ def process_evstr(exp)
267
273
  _, *args = exp
268
- args.map! {|sub_tree| process sub_tree}
274
+ args.map! {|sub_tree| process(sub_tree)}
269
275
  end
270
276
 
271
- def process_self exp
277
+ def process_self(exp)
272
278
  _ = exp
273
279
  end
274
280
 
275
- def process_masgn exp
281
+ def process_masgn(exp)
276
282
  _, *args = exp
277
- args.map! {|sub_tree| process sub_tree}
283
+ args.map! {|sub_tree| process(sub_tree)}
278
284
  end
279
285
 
280
- def process_array exp
286
+ def process_array(exp)
281
287
  _, *args = exp
282
- args.map! {|sub_tree| process sub_tree}
288
+ args.map! {|sub_tree| process(sub_tree)}
283
289
  end
284
290
 
285
- def process_cdecl exp
291
+ def process_cdecl(exp)
286
292
  _, constant_name = exp
287
293
  end
288
294
 
289
- def process_and exp
295
+ def process_and(exp)
290
296
  _, *args = exp
291
- args.map! {|sub_tree| process sub_tree}
297
+ args.map! {|sub_tree| process(sub_tree)}
292
298
  end
293
299
 
294
- def process_rescue exp
300
+ def process_rescue(exp)
295
301
  _, *args = exp
296
- args.map! {|sub_tree| process sub_tree}
302
+ args.map! {|sub_tree| process(sub_tree)}
297
303
  end
298
304
 
299
- def process_resbody exp
305
+ def process_resbody(exp)
300
306
  _, *args = exp
301
- args.map! {|sub_tree| process sub_tree}
307
+ args.map! {|sub_tree| process(sub_tree)}
302
308
  end
303
309
 
304
- def process_gvar exp
310
+ def process_gvar(exp)
305
311
  _, ruby_global_var_name = exp
306
312
  end
307
313
 
308
- def process_if exp
314
+ def process_if(exp)
309
315
  _, *args = exp
310
- args.map! {|sub_tree| process sub_tree}
316
+ args.map! {|sub_tree| process(sub_tree)}
311
317
  end
312
318
 
313
- def process_true exp
319
+ def process_true(exp)
314
320
  _ = exp
315
321
  end
316
322
 
317
- def process_false exp
323
+ def process_false(exp)
318
324
  _ = exp
319
325
  end
320
326
 
321
- def process_case exp
327
+ def process_case(exp)
322
328
  _, *args = exp
323
- args.map! {|sub_tree| process sub_tree}
329
+ args.map! {|sub_tree| process(sub_tree)}
324
330
  end
325
331
 
326
- def process_when exp
332
+ def process_when(exp)
327
333
  _, *args = exp
328
- args.map! {|sub_tree| process sub_tree}
334
+ args.map! {|sub_tree| process(sub_tree)}
329
335
  end
330
336
 
331
- def process_op_asgn1 exp
337
+ def process_op_asgn1(exp)
332
338
  _, variabe_rec, position_to_access, operator, *args = exp
333
- args.map! {|sub_tree| process sub_tree}
339
+ args.map! {|sub_tree| process(sub_tree)}
334
340
  end
335
341
 
336
- def process_arglist exp
342
+ def process_arglist(exp)
337
343
  _, *args = exp
338
- args.map! {|sub_tree| process sub_tree}
344
+ args.map! {|sub_tree| process(sub_tree)}
339
345
  end
340
346
 
341
- def process_block_pass exp
347
+ def process_block_pass(exp)
342
348
  _, *args = exp
343
- args.map! {|sub_tree| process sub_tree}
349
+ args.map! {|sub_tree| process(sub_tree)}
344
350
  end
345
351
 
346
- def process_or exp
352
+ def process_or(exp)
347
353
  _, *args = exp
348
- args.map! {|sub_tree| process sub_tree}
354
+ args.map! {|sub_tree| process(sub_tree)}
349
355
  end
350
356
 
351
- def process_sclass exp
357
+ def process_sclass(exp)
352
358
  _, *args = exp
353
359
  args.map! {|sub_tree| process sub_tree}
354
360
  end
355
361
 
356
- def process_next exp
362
+ def process_next(exp)
357
363
  _ = exp
358
364
  end
359
365
 
360
- def process_module exp
366
+ def process_module(exp)
361
367
  _, module_name, *args = exp
362
368
  if module_name.class == Symbol
363
- @module_names.push module_name.to_s
369
+ @module_names.push(module_name.to_s)
364
370
  @classes << @module_names.join('::')
365
371
  else
366
372
  get_complete_class_name(module_name)
@@ -368,98 +374,98 @@ module Archruby
368
374
  @module_names.push @complete_class_name.join('::')
369
375
  @complete_class_name = []
370
376
  end
371
- args.map! {|sub_tree| process sub_tree}
377
+ args.map! {|sub_tree| process(sub_tree)}
372
378
  @module_names.pop
373
379
  end
374
380
 
375
- def process_to_ary exp
381
+ def process_to_ary(exp)
376
382
  _, *args = exp
377
- args.map! {|sub_tree| process sub_tree}
383
+ args.map! {|sub_tree| process(sub_tree)}
378
384
  end
379
385
 
380
- def process_while exp
386
+ def process_while(exp)
381
387
  _, condition, *args = exp
382
388
  true_clause = args.pop
383
- args.map! {|sub_tree| process sub_tree}
389
+ args.map! {|sub_tree| process(sub_tree)}
384
390
  end
385
391
 
386
- def process_cvdecl exp
392
+ def process_cvdecl(exp)
387
393
  _, variable_name, *args = exp
388
- args.map! {|sub_tree| process sub_tree}
394
+ args.map! {|sub_tree| process(sub_tree)}
389
395
  end
390
396
 
391
- def process_cvar exp
397
+ def process_cvar(exp)
392
398
  _, variable_name = exp
393
399
  end
394
400
 
395
- def process_until exp
401
+ def process_until(exp)
396
402
  _, condition, *args = exp
397
403
  true_clause = args.pop
398
- args.map! {|sub_tree| process sub_tree}
404
+ args.map! {|sub_tree| process(sub_tree)}
399
405
  end
400
406
 
401
- def process_yield exp
407
+ def process_yield(exp)
402
408
  _, *body = exp
403
409
  if !body.empty?
404
- body.map! {|sub_tree| process sub_tree}
410
+ body.map! {|sub_tree| process(sub_tree)}
405
411
  end
406
412
  end
407
413
 
408
- def process_dot2 exp
414
+ def process_dot2(exp)
409
415
  _, first, second = exp
410
416
  end
411
417
 
412
- def process_zsuper exp
418
+ def process_zsuper(exp)
413
419
  _ = exp
414
420
  end
415
421
 
416
- def process_op_asgn_or exp
422
+ def process_op_asgn_or(exp)
417
423
  _, first, second = exp
418
- process first
419
- process second
424
+ process(first)
425
+ process(second)
420
426
  end
421
427
 
422
- def process_match3 exp
428
+ def process_match3(exp)
423
429
  _, regular_expression, *args = exp
424
- args.map! {|sub_tree| process sub_tree}
430
+ args.map! {|sub_tree| process(sub_tree)}
425
431
  end
426
432
 
427
- def process_break exp
433
+ def process_break(exp)
428
434
  _ = exp
429
435
  end
430
436
 
431
- def process_dregx exp
437
+ def process_dregx(exp)
432
438
  _, regex = exp
433
439
  end
434
440
 
435
- def process_super exp
441
+ def process_super(exp)
436
442
  _, args = exp
437
- process args
443
+ process(args)
438
444
  end
439
445
 
440
- def process_ensure exp
446
+ def process_ensure(exp)
441
447
  _, rescue_clause, *ensure_clause = exp
442
- process rescue_clause
443
- ensure_clause.map! {|sub_tree| process sub_tree}
448
+ process(rescue_clause)
449
+ ensure_clause.map! {|sub_tree| process(sub_tree)}
444
450
  end
445
451
 
446
- def process_op_asgn2 exp
452
+ def process_op_asgn2(exp)
447
453
  _, left_assign, variable, method, args = exp
448
- process left_assign
449
- process args
454
+ process(left_assign)
455
+ process(args)
450
456
  end
451
457
 
452
- def process_splat exp
458
+ def process_splat(exp)
453
459
  _, left_assign = exp
454
- process left_assign
460
+ process(left_assign)
455
461
  end
456
462
 
457
- def process_dxstr exp
463
+ def process_dxstr(exp)
458
464
  # shelling out
459
465
  _ = exp
460
466
  end
461
467
 
462
- def process_dot3 exp
468
+ def process_dot3(exp)
463
469
  _ = exp
464
470
  end
465
471