archruby 0.2.0 → 0.3.0

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.
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
@@ -0,0 +1,155 @@
1
+ module Archruby
2
+ module Ruby
3
+ module TypeInference
4
+ module Ruby
5
+
6
+ class ProcessMethodArguments < SexpInterpreter
7
+ def initialize(ast)
8
+ super()
9
+ @ast = ast
10
+ @params = {}
11
+ @current_dependency_class = []
12
+ @current_dependency_class_name = nil
13
+ end
14
+
15
+ def parse
16
+ process(@ast)
17
+ @params
18
+ end
19
+
20
+ def process_args(exp)
21
+ _, *args = exp
22
+ if !args.empty?
23
+ if args.first.class == Symbol
24
+ @params[args.first] ||= Set.new
25
+ else
26
+ args.map! {|sub_tree| process(sub_tree) if sub_tree.class == Sexp}
27
+ end
28
+ end
29
+ end
30
+
31
+ def process_lasgn(exp)
32
+ _, variable_name, *args = exp
33
+ @params[variable_name] ||= Set.new
34
+ args.map! {|sub_tree| process(sub_tree)}
35
+ @params[variable_name].add(@current_dependency_class_name)
36
+ @current_dependency_class_name = nil
37
+ end
38
+
39
+ def process_lit(exp)
40
+ _, value = exp
41
+ end
42
+
43
+ def process_call(exp)
44
+ _, receiver, method_name, *args = exp
45
+ process(receiver)
46
+ args.map! { |subtree| process(subtree) }
47
+ end
48
+
49
+ def process_const(exp)
50
+ _, const_name = exp
51
+ if !@current_dependency_class.empty?
52
+ @current_dependency_class_name = build_full_name(const_name)
53
+ else
54
+ @current_dependency_class_name = const_name.to_s
55
+ end
56
+ end
57
+
58
+ def process_colon2(exp)
59
+ _, first_part, last_part = exp
60
+ @current_dependency_class.unshift(last_part)
61
+ process(first_part)
62
+ end
63
+
64
+ def process_colon3(exp)
65
+ _, constant_name = exp
66
+ @current_dependency_class_name = build_full_name("::#{constant_name}")
67
+ end
68
+
69
+ def build_full_name(const_name)
70
+ @current_dependency_class.unshift(const_name)
71
+ full_class_path = @current_dependency_class.join('::')
72
+ @current_dependency_class = []
73
+ full_class_path
74
+ end
75
+
76
+ def process_hash(exp)
77
+ _, key, value = exp
78
+ process(key)
79
+ process(value)
80
+ end
81
+
82
+ def process_if(exp)
83
+ _, *args = exp
84
+ args.map! {|sub_tree| process(sub_tree) if sub_tree.class == Sexp }
85
+ end
86
+
87
+ def process_kwarg(exp)
88
+ _, *args = exp
89
+ args.map! { |subtree| process(subtree) if subtree.class == Sexp}
90
+ end
91
+
92
+ def process_array(exp)
93
+ _, *args = exp
94
+ args.map! {|sub_tree| process(sub_tree)}
95
+ end
96
+
97
+ def process_ivar(exp)
98
+ _, var_name, *args = exp
99
+ args.map! {|sub_tree| process(sub_tree)}
100
+ end
101
+
102
+ def process_iter(exp)
103
+ _, first_part, second_part, *body = exp
104
+ process(first_part)
105
+ body.map! {|sub_tree| process(sub_tree)}
106
+ end
107
+
108
+ def process_cvasgn(exp)
109
+ _, class_var_name, *value = exp
110
+ value.map! {|sub_tree| process(sub_tree)}
111
+ end
112
+
113
+ def process_masgn(exp)
114
+ _, *args = exp
115
+ args.map! {|sub_tree| process(sub_tree) if sub_tree.class == Sexp}
116
+ end
117
+
118
+ def process_or(exp)
119
+ _, left_side, right_side = exp
120
+ process(left_side)
121
+ process(right_side)
122
+ end
123
+
124
+ def process_lvar(exp)
125
+ end
126
+
127
+ def process_cvar(exp)
128
+ # class variable
129
+ end
130
+
131
+ def process_true(exp)
132
+ end
133
+
134
+ def process_nil(exp)
135
+ end
136
+
137
+ def process_str(exp)
138
+ end
139
+
140
+ def process_false(exp)
141
+ end
142
+
143
+ def process_self(exp)
144
+ end
145
+
146
+ def process_gvar(exp)
147
+ #global variables
148
+ end
149
+
150
+ end
151
+
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,427 @@
1
+ module Archruby
2
+ module Ruby
3
+ module TypeInference
4
+ module Ruby
5
+
6
+ class ProcessMethodBody < SexpInterpreter
7
+ def initialize(ast, local_scope)
8
+ super()
9
+ @ast = ast
10
+ @params = {}
11
+ @current_dependency_class = []
12
+ @current_dependency_class_name = nil
13
+ @method_calls = []
14
+ @local_scope = local_scope
15
+ end
16
+
17
+ def parse
18
+ #binding.pry
19
+ @ast.map! {|sub_tree| process(sub_tree)}
20
+ @method_calls
21
+ end
22
+
23
+ def process_call(exp)
24
+ _, receiver, method_name, *params = exp
25
+ if receiver && receiver[0] == :lvar && receiver[1].class == Symbol
26
+ type = @local_scope.var_type(receiver[1])
27
+ parsed_params = ProcessMethodParams.new(params, @local_scope).parse
28
+ add_method_call(type, method_name, parsed_params)
29
+ elsif !receiver.nil?
30
+ process(receiver)
31
+ parsed_params = nil
32
+ if check_if_has_params(params)
33
+ parsed_params = ProcessMethodParams.new(params, @local_scope).parse
34
+ end
35
+ add_method_call(@current_dependency_class_name, method_name, parsed_params)
36
+ #@current_dependency_class_name = nil
37
+ end
38
+ end
39
+
40
+ def process_defs(exp)
41
+ #estudar esse caso -> acontece no rails em activemodel
42
+ end
43
+
44
+ def check_if_has_params(params)
45
+ has_local_params = false
46
+ params.each do |param|
47
+ if param[0] == :lvar
48
+ has_local_params = @local_scope.has_formal_parameter(param[1]) || @local_scope.has_local_params(param[1])
49
+ end
50
+ end
51
+ has_local_params
52
+ end
53
+
54
+ def add_method_call(class_name, method_name, params=nil)
55
+ @method_calls << InternalMethodInvocation.new(class_name, method_name, params)
56
+ end
57
+
58
+ def process_lasgn(exp)
59
+ _, variable_name, *args = exp
60
+ args.map! { |subtree| process(subtree) }
61
+ if @current_dependency_class_name
62
+ @local_scope.add_variable(variable_name, @current_dependency_class_name)
63
+ end
64
+ @current_dependency_class_name = nil
65
+ end
66
+
67
+ def process_const(exp)
68
+ _, const_name = exp
69
+ if !@current_dependency_class.empty?
70
+ @current_dependency_class_name = build_full_name(const_name)
71
+ else
72
+ @current_dependency_class_name = const_name.to_s
73
+ end
74
+ end
75
+
76
+ def process_colon3(exp)
77
+ _, constant_name = exp
78
+ @current_dependency_class_name = build_full_name("::#{constant_name}")
79
+ end
80
+
81
+ def process_colon2(exp)
82
+ _, first_part, last_part = exp
83
+ @current_dependency_class.unshift(last_part)
84
+ process(first_part)
85
+ end
86
+
87
+ def build_full_name(const_name)
88
+ @current_dependency_class.unshift(const_name)
89
+ full_class_path = @current_dependency_class.join('::')
90
+ @current_dependency_class = []
91
+ full_class_path
92
+ end
93
+
94
+ def process_attrasgn(exp)
95
+ _, receiver, method_name, value = exp
96
+ process(receiver)
97
+ process(value)
98
+ end
99
+
100
+ def process_iasgn(exp)
101
+ _, instance_varialbe_name, *value = exp
102
+ value.map! { |subtree| process(subtree) }
103
+ end
104
+
105
+ def process_op_asgn1(exp)
106
+ process(exp.last)
107
+ end
108
+
109
+ def process_match3(exp)
110
+ _, left_side, right_side = exp
111
+ process(left_side)
112
+ process(right_side)
113
+ end
114
+
115
+ def process_op_asgn2(exp)
116
+ _, receiver, method, met, last = exp
117
+ process(receiver)
118
+ process(last)
119
+ end
120
+
121
+ def process_iter(exp)
122
+ _, first_part, second_part, *body = exp
123
+ process(first_part)
124
+ body.map! {|sub_tree| process(sub_tree)}
125
+ end
126
+
127
+ def process_if(exp)
128
+ _, condition, true_body, else_body = exp
129
+ process(condition)
130
+ process(true_body)
131
+ process(else_body)
132
+ end
133
+
134
+ def process_dsym(exp)
135
+ _, str, *args = exp
136
+ args.map! {|sub_tree| process(sub_tree)}
137
+ end
138
+
139
+ def process_block(exp)
140
+ _, *args = exp
141
+ args.map! { |subtree| process(subtree) }
142
+ end
143
+
144
+ def process_hash(exp)
145
+ _, key, value = exp
146
+ process(key)
147
+ process(value)
148
+ end
149
+
150
+ def process_super(exp)
151
+ _, *args = exp
152
+ args.map! {|sub_tree| process(sub_tree)}
153
+ end
154
+
155
+ def process_rescue(exp)
156
+ _, normal, *rescue_body = exp
157
+ process(normal)
158
+ rescue_body.map! {|sub_tree| process(sub_tree)}
159
+ end
160
+
161
+ def process_return(exp)
162
+ _, *value = exp
163
+ value.map! {|sub_tree| process(sub_tree)}
164
+ end
165
+
166
+ def process_resbody(exp)
167
+ _, class_to_rescue, *body = exp
168
+ process(class_to_rescue)
169
+ body.map! {|sub_tree| process(sub_tree)}
170
+ end
171
+
172
+ def process_array(exp)
173
+ _, *args = exp
174
+ args.map! {|sub_tree| process(sub_tree)}
175
+ end
176
+
177
+ def process_and(exp)
178
+ _, left_side, right_side = exp
179
+ process(left_side)
180
+ process(right_side)
181
+ end
182
+
183
+ def process_or(exp)
184
+ _, left_side, right_side = exp
185
+ process(left_side)
186
+ process(right_side)
187
+ end
188
+
189
+ def process_dstr(exp)
190
+ _, start, *args = exp
191
+ args.map! {|sub_tree| process(sub_tree)}
192
+ end
193
+
194
+ def process_dregx_once(exp)
195
+ _, start, *args = exp
196
+ args.map! {|sub_tree| process(sub_tree)}
197
+ end
198
+
199
+ def process_evstr(exp)
200
+ _, *args = exp
201
+ args.map! {|sub_tree| process(sub_tree)}
202
+ end
203
+
204
+ def process_dstr(exp)
205
+ _, init, *args = exp
206
+ args.map! {|sub_tree| process(sub_tree)}
207
+ end
208
+
209
+ def process_dxstr(exp)
210
+ _, str, *args = exp
211
+ args.map! {|sub_tree| process(sub_tree)}
212
+ end
213
+
214
+ def process_ivar(exp)
215
+ _, var_name, *args = exp
216
+ args.map! {|sub_tree| process(sub_tree)}
217
+ end
218
+
219
+ def process_match2(exp)
220
+ _, rec, *args = exp
221
+ args.map! {|sub_tree| process(sub_tree)}
222
+ end
223
+
224
+ def process_match3(exp)
225
+ _, first, second = exp
226
+ process(first)
227
+ process(second)
228
+ end
229
+
230
+ def process_svalue(exp)
231
+ _, *args = exp
232
+ args.map! {|sub_tree| process(sub_tree)}
233
+ end
234
+
235
+ def process_op_asgn_or(exp)
236
+ _, *args = exp
237
+ args.map! {|sub_tree| process(sub_tree)}
238
+ end
239
+
240
+ def process_op_asgn_and(exp)
241
+ _, *args = exp
242
+ args.map! {|sub_tree| process(sub_tree)}
243
+ end
244
+
245
+ def process_ensure(exp)
246
+ _, *args = exp
247
+ args.map! {|sub_tree| process(sub_tree)}
248
+ end
249
+
250
+ def process_while(exp)
251
+ _, condition, body = exp
252
+ process(condition)
253
+ process(body)
254
+ end
255
+
256
+ def process_until(exp)
257
+ _, condition, body, *args = exp
258
+ process(condition)
259
+ process(body)
260
+ end
261
+
262
+ def process_yield(exp)
263
+ _, *args = exp
264
+ args.map! {|sub_tree| process(sub_tree)}
265
+ end
266
+
267
+ def process_splat(exp)
268
+ _, *args = exp
269
+ args.map! {|sub_tree| process(sub_tree)}
270
+ end
271
+
272
+ def process_case(exp)
273
+ _, condition, when_part, ensure_part = exp
274
+ process(condition)
275
+ process(when_part)
276
+ process(ensure_part)
277
+ end
278
+
279
+ def process_for(exp)
280
+ _, x, y, body = exp
281
+ process(x)
282
+ process(y)
283
+ process(body)
284
+ end
285
+
286
+ def process_when(exp)
287
+ _, condition, body = exp
288
+ process(condition)
289
+ process(body)
290
+ end
291
+
292
+ def process_rescue(exp)
293
+ _, body, rescbody = exp
294
+ process(body)
295
+ process(rescbody)
296
+ end
297
+
298
+ def process_cvasgn(exp)
299
+ _, class_var_name, *value = exp
300
+ value.map! {|sub_tree| process(sub_tree)}
301
+ end
302
+
303
+ def process_dot3(exp)
304
+ _, left, right = exp
305
+ process(left)
306
+ process(right)
307
+ end
308
+
309
+ def process_dot2(exp)
310
+ _, left, right = exp
311
+ process(left)
312
+ process(right)
313
+ end
314
+
315
+ def process_block_pass(exp)
316
+ _, *args = exp
317
+ args.map! {|sub_tree| process(sub_tree)}
318
+ end
319
+
320
+ def process_retry(exp)
321
+ end
322
+
323
+ def process_dregx(exp)
324
+ _, str, *args = exp
325
+ args.map! {|sub_tree| process(sub_tree) if sub_tree.class == Sexp}
326
+ end
327
+
328
+ def process_defn(exp)
329
+ #estudar esse caso para ver se vamos quer pegar isso
330
+ end
331
+
332
+ def process_masgn(exp)
333
+ _, *args = exp
334
+ args.map! {|sub_tree| process(sub_tree)}
335
+ end
336
+
337
+ def process_redo(exp)
338
+ end
339
+
340
+ def process_to_ary(exp)
341
+ _, *args = exp
342
+ args.map! {|sub_tree| process(sub_tree)}
343
+ end
344
+
345
+ def process_gasgn(exp)
346
+ _, global_var_name, *value = exp
347
+ value.map! {|sub_tree| process(sub_tree)}
348
+ end
349
+
350
+ def process_sclass(exp)
351
+ _, singleton_class, *body = exp
352
+ body.map! {|sub_tree| process(sub_tree)}
353
+ end
354
+
355
+ def process_not(exp)
356
+ _, *args = exp
357
+ args.map! {|sub_tree| process(sub_tree)}
358
+ end
359
+
360
+ def process_defined(exp)
361
+ _, *args = exp
362
+ args.map! {|sub_tree| process(sub_tree)}
363
+ end
364
+
365
+ def process_cvdecl(exp)
366
+ _, instance_classvar_name, *value = exp
367
+ value.map! {|sub_tree| process(sub_tree)}
368
+ end
369
+
370
+ def process_back_ref(exp)
371
+ end
372
+
373
+ def process_cvar(exp)
374
+ # class variable
375
+ end
376
+
377
+ def process_alias(exp)
378
+ end
379
+
380
+ def process_begin(exp)
381
+ end
382
+
383
+ def process_self(exp)
384
+ end
385
+
386
+ def process_xstr(exp)
387
+ end
388
+
389
+ def process_nth_ref(exp)
390
+ end
391
+
392
+ def process_break(exp)
393
+ end
394
+
395
+ def process_next(exp)
396
+ end
397
+
398
+ def process_str(exp)
399
+ end
400
+
401
+ def process_gvar(exp)
402
+ end
403
+
404
+ def process_nil(exp)
405
+ end
406
+
407
+ def process_zsuper(exp)
408
+ end
409
+
410
+ def process_lit(exp)
411
+ end
412
+
413
+ def process_lvar(exp)
414
+ end
415
+
416
+ def process_true(exp)
417
+ end
418
+
419
+ def process_false(exp)
420
+ end
421
+
422
+ end
423
+
424
+ end
425
+ end
426
+ end
427
+ end