fastruby 0.0.16 → 0.0.17

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 (78) hide show
  1. data/CHANGELOG +17 -1
  2. data/Rakefile +1 -1
  3. data/ext/fastruby_base/fastruby_base.inl +81 -3
  4. data/lib/fastruby/fastruby_sexp.rb +21 -0
  5. data/lib/fastruby/getlocals.rb +2 -1
  6. data/lib/fastruby/object.rb +1 -1
  7. data/lib/fastruby/sexp_extension.rb +189 -0
  8. data/lib/fastruby/sexp_extension_edges.rb +210 -0
  9. data/lib/fastruby/translator/modules/block.rb +29 -22
  10. data/lib/fastruby/translator/modules/call.rb +211 -34
  11. data/lib/fastruby/translator/modules/defn.rb +64 -29
  12. data/lib/fastruby/translator/modules/exceptions.rb +1 -1
  13. data/lib/fastruby/translator/modules/flow.rb +93 -31
  14. data/lib/fastruby/translator/modules/iter.rb +277 -340
  15. data/lib/fastruby/translator/modules/literal.rb +97 -20
  16. data/lib/fastruby/translator/modules/logical.rb +40 -5
  17. data/lib/fastruby/translator/modules/method_group.rb +41 -19
  18. data/lib/fastruby/translator/modules/nonlocal.rb +74 -29
  19. data/lib/fastruby/translator/modules/variable.rb +151 -42
  20. data/lib/fastruby/translator/scope_mode_helper.rb +161 -0
  21. data/lib/fastruby/translator/translator.rb +389 -302
  22. data/lib/fastruby.rb +1 -1
  23. data/lib/fastruby.rb~ +36 -0
  24. data/spec/edges_helper.rb +91 -0
  25. data/spec/graph/base_spec.rb +35 -0
  26. data/spec/graph/path_spec.rb +48 -0
  27. data/spec/graph/vertex_spec.rb +58 -0
  28. data/spec/ruby/block/proc_as_block_spec.rb +214 -0
  29. data/spec/ruby/block/redo_spec.rb +133 -0
  30. data/spec/ruby/defn/single_function_spec.rb +50 -0
  31. data/spec/scope_mode/base_spec.rb +55 -0
  32. data/spec/scope_mode/block_spec.rb +105 -0
  33. data/spec/scope_mode/call_spec.rb +24 -0
  34. data/spec/scope_mode/exception_spec.rb +34 -0
  35. data/spec/scope_mode/flow_spec.rb +99 -0
  36. data/spec/scope_mode/optimization_spec.rb +130 -0
  37. data/spec/sexp2graph/base_spec.rb +36 -0
  38. data/spec/sexp2graph/exception_spec.rb +172 -0
  39. data/spec/sexp2graph/flow_spec.rb +67 -0
  40. data/spec/sexp2graph/logical_spec.rb +21 -0
  41. data/spec/sexp2graph/variable_spec.rb +26 -0
  42. metadata +110 -120
  43. data/lib/fastruby/self +0 -82
  44. data/lib/len +0 -280
  45. data/spec/block/proc_as_block_spec.rb +0 -111
  46. data/spec/block/redo_spec.rb +0 -67
  47. /data/spec/{base_spec.rb → ruby/base_spec.rb} +0 -0
  48. /data/spec/{block → ruby/block}/arguments_spec.rb +0 -0
  49. /data/spec/{block → ruby/block}/block_as_proc_spec.rb +0 -0
  50. /data/spec/{block → ruby/block}/break_spec.rb +0 -0
  51. /data/spec/{block → ruby/block}/callcc_spec.rb +0 -0
  52. /data/spec/{block → ruby/block}/lambda_spec.rb +0 -0
  53. /data/spec/{block → ruby/block}/next_spec.rb +0 -0
  54. /data/spec/{block → ruby/block}/proc_spec.rb +0 -0
  55. /data/spec/{block → ruby/block}/retry_spec.rb +0 -0
  56. /data/spec/{block_spec.rb → ruby/block_spec.rb} +0 -0
  57. /data/spec/{call → ruby/call}/base_call_spec.rb +0 -0
  58. /data/spec/{call → ruby/call}/multiple_args_spec.rb +0 -0
  59. /data/spec/{control_spec.rb → ruby/control_spec.rb} +0 -0
  60. /data/spec/{defn → ruby/defn}/default_args_spec.rb +0 -0
  61. /data/spec/{defn → ruby/defn}/multiple_args_spec.rb +0 -0
  62. /data/spec/{defn → ruby/defn}/replacement_spec.rb +0 -0
  63. /data/spec/{exception → ruby/exception}/base_spec.rb +0 -0
  64. /data/spec/{exception → ruby/exception}/ensure_spec.rb +0 -0
  65. /data/spec/{exception → ruby/exception}/exc_trap_spec.rb +0 -0
  66. /data/spec/{exception → ruby/exception}/internal_ex_spec.rb +0 -0
  67. /data/spec/{exception → ruby/exception}/syntaxis_spec.rb +0 -0
  68. /data/spec/{expression_spec.rb → ruby/expression_spec.rb} +0 -0
  69. /data/spec/{flow_control → ruby/flow_control}/case_spec.rb +0 -0
  70. /data/spec/{flow_control → ruby/flow_control}/for_spec.rb +0 -0
  71. /data/spec/{integrity_spec.rb → ruby/integrity_spec.rb} +0 -0
  72. /data/spec/{jump → ruby/jump}/next_spec.rb +0 -0
  73. /data/spec/{literal_spec.rb → ruby/literal_spec.rb} +0 -0
  74. /data/spec/{module_spec.rb → ruby/module_spec.rb} +0 -0
  75. /data/spec/{return_spec.rb → ruby/return_spec.rb} +0 -0
  76. /data/spec/{singleton_spec.rb → ruby/singleton_spec.rb} +0 -0
  77. /data/spec/{sugar_spec.rb → ruby/sugar_spec.rb} +0 -0
  78. /data/spec/{variable_spec.rb → ruby/variable_spec.rb} +0 -0
@@ -0,0 +1,55 @@
1
+ require "fastruby"
2
+ require "sexp"
3
+ require "ruby_parser"
4
+ require "fastruby/translator/scope_mode_helper"
5
+
6
+ $parser = RubyParser.new
7
+
8
+ describe FastRuby::ScopeModeHelper, "scope mode helper" do
9
+ it "method with only ONE call and read after call should return :dag scope mode" do
10
+ FastRuby::ScopeModeHelper.get_scope_mode(
11
+ $parser.parse "def foo(a,b,c)
12
+ a+b
13
+ c
14
+ end"
15
+ ).should be == :dag
16
+ end
17
+
18
+ it "method with only ONE call and self read after call should return :dag scope mode" do
19
+ FastRuby::ScopeModeHelper.get_scope_mode(
20
+ $parser.parse "def foo(a,b,c)
21
+ a+b
22
+ self
23
+ end"
24
+ ).should be == :dag
25
+ end
26
+
27
+ it "method with only ONE call and yield after call should return :dag scope mode" do
28
+ FastRuby::ScopeModeHelper.get_scope_mode(
29
+ $parser.parse "def foo(a,b,c)
30
+ a+b
31
+ yield
32
+ end"
33
+ ).should be == :dag
34
+ end
35
+
36
+ it "method with only ONE call and local call after call should return :dag scope mode" do
37
+ FastRuby::ScopeModeHelper.get_scope_mode(
38
+ $parser.parse "def foo(a,b,c)
39
+ a+b
40
+ foo
41
+ end"
42
+ ).should be == :dag
43
+ end
44
+
45
+ it "method call AFTER read inside while should return :dag scope" do
46
+ FastRuby::ScopeModeHelper.get_scope_mode(
47
+ $parser.parse "def foo(a,b)
48
+ while (true)
49
+ a=b
50
+ a+b
51
+ end
52
+ end"
53
+ ).should be == :dag
54
+ end
55
+ end
@@ -0,0 +1,105 @@
1
+ require "fastruby"
2
+ require "sexp"
3
+ require "ruby_parser"
4
+ require "fastruby/translator/scope_mode_helper"
5
+
6
+ $parser = RubyParser.new
7
+
8
+ describe FastRuby::ScopeModeHelper, "scope mode helper" do
9
+ it "iter call with block accessing locals should return dag" do
10
+ FastRuby::ScopeModeHelper.get_scope_mode(
11
+ $parser.parse "def foo(a)
12
+ bar do
13
+ a
14
+ end
15
+ end"
16
+ ).should be == :dag
17
+ end
18
+
19
+ it "iter call with block doing yield should return dag" do
20
+ FastRuby::ScopeModeHelper.get_scope_mode(
21
+ $parser.parse "def foo(a)
22
+ bar do
23
+ yield
24
+ end
25
+ end"
26
+ ).should be == :dag
27
+ end
28
+
29
+ it "iter call with block with arguments should return dag" do
30
+ FastRuby::ScopeModeHelper.get_scope_mode(
31
+ $parser.parse "def foo(a)
32
+ bar do |x|
33
+ end
34
+ end"
35
+ ).should be == :dag
36
+ end
37
+
38
+ it "iter call with block writing local variable should return dag" do
39
+ FastRuby::ScopeModeHelper.get_scope_mode(
40
+ $parser.parse "def foo(a)
41
+ bar do
42
+ a = 87
43
+ end
44
+ end"
45
+ ).should be == :dag
46
+ end
47
+
48
+ it "two iter call, one empty and the second with yield should return dag" do
49
+ FastRuby::ScopeModeHelper.get_scope_mode(
50
+ $parser.parse "def foo(a)
51
+ bar do
52
+ end
53
+
54
+ bar do
55
+ yield
56
+ end
57
+ end"
58
+ ).should be == :dag
59
+ end
60
+
61
+ it "lambda with yield must return :dag" do
62
+ FastRuby::ScopeModeHelper.get_scope_mode(
63
+ $parser.parse " def foo
64
+ lambda {
65
+ yield
66
+ }
67
+ end
68
+ "
69
+ ).should be == :dag
70
+ end
71
+
72
+ it "method with return from inside block return :dag" do
73
+ FastRuby::ScopeModeHelper.get_scope_mode(
74
+ $parser.parse " def bar
75
+ foo do
76
+ return 9
77
+ end
78
+ end
79
+ "
80
+ ).should be == :dag
81
+ end
82
+
83
+ it "method with self from inside block return :dag" do
84
+ FastRuby::ScopeModeHelper.get_scope_mode(
85
+ $parser.parse " def bar
86
+ foo do
87
+ self
88
+ end
89
+ end
90
+ "
91
+ ).should be == :dag
92
+ end
93
+
94
+ it "local call from inside block should return :dag" do
95
+ FastRuby::ScopeModeHelper.get_scope_mode(
96
+ $parser.parse " def bar
97
+ foo do
98
+ print
99
+ end
100
+ end
101
+ "
102
+ ).should be == :dag
103
+ end
104
+
105
+ end
@@ -0,0 +1,24 @@
1
+ require "fastruby"
2
+ require "sexp"
3
+ require "ruby_parser"
4
+ require "fastruby/translator/scope_mode_helper"
5
+
6
+ $parser = RubyParser.new
7
+
8
+ describe FastRuby::ScopeModeHelper, "scope mode helper" do
9
+ it "method with two nested calls refering local vars should return :dag scope mode" do
10
+ FastRuby::ScopeModeHelper.get_scope_mode(
11
+ $parser.parse "def foo(a,b,c)
12
+ a+b+c
13
+ end"
14
+ ).should be == :dag
15
+ end
16
+
17
+ it "method with two nested calls refering local vars should return :dag scope mode" do
18
+ FastRuby::ScopeModeHelper.get_scope_mode(
19
+ $parser.parse "def foo(a,b,c)
20
+ a.foo(b){}.foo(c){}
21
+ end"
22
+ ).should be == :dag
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ require "fastruby"
2
+ require "sexp"
3
+ require "ruby_parser"
4
+ require "fastruby/translator/scope_mode_helper"
5
+
6
+ $parser = RubyParser.new
7
+
8
+ describe FastRuby::ScopeModeHelper, "scope mode helper" do
9
+ it "method with read on begin body, call on rescue body and retry should return :dag scope mode" do
10
+ FastRuby::ScopeModeHelper.get_scope_mode(
11
+ $parser.parse "def foo(a,b,c)
12
+ begin
13
+ b
14
+ rescue
15
+ a.foo
16
+ retry
17
+ end
18
+ end"
19
+ ).should be == :dag
20
+ end
21
+
22
+ it "method with read on begin body and retry should return :dag scope mode" do
23
+ FastRuby::ScopeModeHelper.get_scope_mode(
24
+ $parser.parse "def foo(a,b,c)
25
+ begin
26
+ nil.bar(b)
27
+ rescue
28
+ retry
29
+ end
30
+ end"
31
+ ).should be == :dag
32
+ end
33
+
34
+ end
@@ -0,0 +1,99 @@
1
+ require "fastruby"
2
+ require "sexp"
3
+ require "ruby_parser"
4
+ require "fastruby/translator/scope_mode_helper"
5
+
6
+ $parser = RubyParser.new
7
+
8
+ describe FastRuby::ScopeModeHelper, "scope mode helper" do
9
+ it "possible read on if after call should return :dag scope mode" do
10
+ FastRuby::ScopeModeHelper.get_scope_mode(
11
+ $parser.parse "def foo(a,b,c)
12
+ if (a > 0)
13
+ c
14
+ end
15
+ end"
16
+ ).should be == :dag
17
+ end
18
+
19
+ it "possible read on case after call should return :dag scope mode" do
20
+ FastRuby::ScopeModeHelper.get_scope_mode(
21
+ $parser.parse "def foo(a,b,c)
22
+ case (a > 0)
23
+ when 0
24
+ c
25
+ end
26
+ end"
27
+ ).should be == :dag
28
+ end
29
+
30
+ it "possible read on case (on enum) after call should return :dag scope mode" do
31
+ FastRuby::ScopeModeHelper.get_scope_mode(
32
+ $parser.parse "def foo(a,b,c)
33
+ case (a > 0)
34
+ when c
35
+ 0
36
+ end
37
+ end"
38
+ ).should be == :dag
39
+ end
40
+
41
+ it "for with local read and call should return :dag scope mode" do
42
+ FastRuby::ScopeModeHelper.get_scope_mode(
43
+ $parser.parse "def foo(a,b,c)
44
+ for a in b
45
+ foo
46
+ c
47
+ end
48
+ end"
49
+ ).should be == :dag
50
+ end
51
+
52
+ it "empty for with local read should return :dag scope mode (because for is a iter call to each with one argument)" do
53
+ FastRuby::ScopeModeHelper.get_scope_mode(
54
+ $parser.parse "def foo(a,b,c)
55
+ for a in b
56
+ end
57
+ end"
58
+ ).should be == :dag
59
+ end
60
+
61
+ it "case with a when should act as call and local read after case when should return :dag" do
62
+ FastRuby::ScopeModeHelper.get_scope_mode(
63
+ $parser.parse "def foo(a,b,c)
64
+ case b
65
+ when c
66
+ end
67
+ a
68
+ end"
69
+ ).should be == :dag
70
+ end
71
+
72
+ it "case with a when should act as call and local read after case when should return :dag" do
73
+ FastRuby::ScopeModeHelper.get_scope_mode(
74
+ $parser.parse "def foo(a,b,c)
75
+ case b
76
+ when c
77
+ a
78
+ else
79
+ c
80
+ end
81
+ end"
82
+ ).should be == :dag
83
+ end
84
+
85
+ it "case with two call (when) after read should return :dag scope" do
86
+ FastRuby::ScopeModeHelper.get_scope_mode(
87
+ $parser.parse "def foo(a,b,c)
88
+ case a
89
+ when b # call to a.===(b)
90
+ 43
91
+ when c # read of variable c
92
+ 439
93
+ end
94
+ end"
95
+ ).should be == :dag
96
+ end
97
+
98
+
99
+ end
@@ -0,0 +1,130 @@
1
+ require "fastruby"
2
+ require "sexp"
3
+ require "ruby_parser"
4
+ require "fastruby/translator/scope_mode_helper"
5
+
6
+ $parser = RubyParser.new
7
+
8
+ describe FastRuby::ScopeModeHelper, "scope mode helper" do
9
+ it "empty method should return :linear scope mode" do
10
+ FastRuby::ScopeModeHelper.get_scope_mode(
11
+ $parser.parse "def foo(); end"
12
+ ).should be == :linear
13
+ end
14
+
15
+ it "method without calls should return :linear scope mode" do
16
+ FastRuby::ScopeModeHelper.get_scope_mode(
17
+ $parser.parse "def foo(a,b,c)
18
+ a
19
+ end"
20
+ ).should be == :linear
21
+ end
22
+
23
+ it "method with only ONE call should return :linear scope mode" do
24
+ FastRuby::ScopeModeHelper.get_scope_mode(
25
+ $parser.parse "def foo(a,b)
26
+ a+b
27
+ end"
28
+ ).should be == :linear
29
+ end
30
+
31
+ it "method call AFTER read should return :linear scope" do
32
+ FastRuby::ScopeModeHelper.get_scope_mode(
33
+ $parser.parse "def foo(a,b)
34
+ a=b
35
+ a+b
36
+ end"
37
+ ).should be == :linear
38
+ end
39
+
40
+ it "empty if should return :linear scope mode" do
41
+ FastRuby::ScopeModeHelper.get_scope_mode(
42
+ $parser.parse "def foo(a,b,c)
43
+ if (a)
44
+ end
45
+ end"
46
+ ).should be == :linear
47
+ end
48
+ it "iter call with empty block should return linear" do
49
+ FastRuby::ScopeModeHelper.get_scope_mode(
50
+ $parser.parse "def foo
51
+ bar do
52
+ end
53
+ end"
54
+ ).should be == :linear
55
+ end
56
+
57
+ it "return of simple call should return :linear" do
58
+ FastRuby::ScopeModeHelper.get_scope_mode(
59
+ $parser.parse "def foo(a,b)
60
+ return a+b
61
+ end"
62
+ ).should be == :linear
63
+ end
64
+
65
+ it "call on if body and read on condition should return :linear (no read after call risk)" do
66
+ FastRuby::ScopeModeHelper.get_scope_mode(
67
+ $parser.parse "def foo(a,b)
68
+ if a
69
+ b.foo
70
+ end
71
+ end"
72
+ ).should be == :linear
73
+ end
74
+
75
+ it "call on if body and read on else body should return :linear (no read after call risk)" do
76
+ FastRuby::ScopeModeHelper.get_scope_mode(
77
+ $parser.parse "def foo(a,b)
78
+ if true
79
+ b
80
+ else
81
+ b.foo
82
+ end
83
+ end"
84
+ ).should be == :linear
85
+ end
86
+
87
+ it "method with read on begin body should return :linear scope mode" do
88
+ FastRuby::ScopeModeHelper.get_scope_mode(
89
+ $parser.parse "def foo(a,b,c)
90
+ begin
91
+ nil.bar(b)
92
+ rescue
93
+ end
94
+ end"
95
+ ).should be == :linear
96
+ end
97
+
98
+ it "method with read on begin body and call on rescue body should return :linear scope mode" do
99
+ FastRuby::ScopeModeHelper.get_scope_mode(
100
+ $parser.parse "def foo(a,b,c)
101
+ begin
102
+ b
103
+ rescue
104
+ a.foo
105
+ end
106
+ end"
107
+ ).should be == :linear
108
+ end
109
+
110
+ it "case with call (when) after read should return :linear scope" do
111
+ FastRuby::ScopeModeHelper.get_scope_mode(
112
+ $parser.parse "def foo(a,b,c)
113
+ case a
114
+ when b
115
+ 43
116
+ end
117
+ end"
118
+ ).should be == :linear
119
+ end
120
+
121
+ it "read of variable AFTER write without call between them should return :linear scope" do
122
+ FastRuby::ScopeModeHelper.get_scope_mode(
123
+ $parser.parse "def foo(a,b)
124
+ a+b
125
+ c=55
126
+ c
127
+ end"
128
+ ).should be == :linear
129
+ end
130
+ end
@@ -0,0 +1,36 @@
1
+ require "fastruby"
2
+ require "fastruby/sexp_extension"
3
+ require "sexp"
4
+ require "ruby_parser"
5
+ require "edges_helper"
6
+
7
+ describe FastRuby::FastRubySexp, "FastRubySexp" do
8
+ include EdgesHelper
9
+
10
+ it "should have edges" do
11
+ FastRuby::FastRubySexp.parse("def foo; end").should respond_to(:edges)
12
+ end
13
+
14
+ assert_graph_defn("should have two edges for empty method","def foo; end",2) do |sexp, edges|
15
+ {sexp.find_tree(:block) => sexp.find_tree(:scope), sexp.find_tree(:nil) => sexp.find_tree(:block)}
16
+ end
17
+
18
+ assert_graph_defn("should have two edges for method returning literal 1","def foo; 0; end",2) do |sexp, edges|
19
+ {sexp.find_tree(:block) => sexp.find_tree(:scope), sexp.find_tree(:lit) => sexp.find_tree(:block)}
20
+ end
21
+
22
+ assert_graph_defn("should have three edges for method invoking method a and then literal 1","def foo; a; 1; end",3) do |sexp, edges|
23
+ {:a => sexp.find_tree(:lit),
24
+ sexp.find_tree(:lit) => sexp.find_tree(:block),
25
+ sexp.find_tree(:block) => sexp.find_tree(:scope) }
26
+ end
27
+
28
+ assert_graph("should have three edges for method invoking method with two arguments","x.foo(y,z)",3) do |sexp,edges|
29
+ {:y => :z, :x => :y, :z => sexp}
30
+ end
31
+
32
+ assert_graph_defn("should connect edges on block","def foo(x); x.bar; x1.foo(y,z); end") do |sexp,edges|
33
+ block_tree = sexp.find_tree(:block)
34
+ { block_tree[1] => :x1}
35
+ end
36
+ end
@@ -0,0 +1,172 @@
1
+ require "fastruby"
2
+ require "fastruby/sexp_extension"
3
+ require "sexp"
4
+ require "ruby_parser"
5
+ require "edges_helper"
6
+
7
+ describe FastRuby::FastRubySexp, "FastRubySexp" do
8
+ include EdgesHelper
9
+
10
+ assert_graph_defn("should have edges for rescue","
11
+ def foo
12
+ begin
13
+ b
14
+ rescue
15
+ a
16
+ retry
17
+ end
18
+ end") do |sexp, edges|
19
+
20
+ {sexp.find_tree(:rescue)[1] => [:a,sexp.find_tree(:rescue)],
21
+ :a => sexp.find_tree(:retry),
22
+ sexp.find_tree(:retry) => :b
23
+ }
24
+ end
25
+
26
+ assert_graph_defn("should have edges for rescue","
27
+ def foo
28
+ begin
29
+ b
30
+ rescue
31
+ end
32
+ end") do |sexp, edges|
33
+
34
+ {sexp.find_tree(:rescue)[1] => [sexp.find_tree(:rescue)]}
35
+ end
36
+
37
+ assert_graph_defn("should enter the rescue in the body","
38
+ def foo
39
+ a
40
+ begin
41
+ b
42
+ rescue
43
+ c
44
+ end
45
+ end") do |sexp, edges|
46
+
47
+ {:a => :b,
48
+ sexp.find_tree(:rescue)[1] => sexp.find_tree(:rescue),
49
+ sexp.find_tree(:rescue) => sexp.find_tree(:block),
50
+ :b => :c,
51
+ :b => sexp.find_tree(:rescue)
52
+ }
53
+ end
54
+
55
+ assert_graph_defn("multiple calls on rescue may raise and go to rescue","
56
+ def foo
57
+ begin
58
+ a
59
+ b
60
+ c
61
+ rescue
62
+ d
63
+ end
64
+ end") do |sexp, edges|
65
+
66
+ {:a => :d, :b => :d, :c => [:d, sexp.find_tree(:rescue)[1] ],
67
+ sexp.find_tree(:rescue)[1] => sexp.find_tree(:rescue) }
68
+ end
69
+
70
+ assert_graph_defn("multiple calls on ensure may raise and go to rescue","
71
+ def foo
72
+ begin
73
+ a
74
+ b
75
+ c
76
+ ensure
77
+ d
78
+ end
79
+ end") do |sexp, edges|
80
+
81
+ {:a => :d, :b => :d, :c => :d, sexp.find_tree(:ensure)[2] => sexp.find_tree(:ensure) }
82
+ end
83
+
84
+ assert_graph_defn("should enter the ensure in the body","
85
+ def foo
86
+ a
87
+ begin
88
+ b
89
+ ensure
90
+ c
91
+ end
92
+ end") do |sexp, edges|
93
+
94
+ {:a => :b,
95
+ :b => :c}
96
+ end
97
+
98
+
99
+ assert_graph_defn("should link declaration of exceptions on rescue","
100
+ def foo
101
+ begin
102
+ a
103
+ rescue b => c
104
+ d
105
+ end
106
+ end") do |sexp, edges|
107
+
108
+ {:a => :b,
109
+ :b => sexp.find_tree(:gvar),
110
+ sexp.find_tree(:gvar) => sexp.find_tree(:lasgn),
111
+ sexp.find_tree(:lasgn) => :d
112
+ }
113
+ end
114
+
115
+ assert_graph_defn("should link multiple declaration of exceptions on rescue","
116
+ def foo
117
+ begin
118
+ a
119
+ rescue b, d => e
120
+ f
121
+ end
122
+ end") do |sexp, edges|
123
+
124
+ array_tree = sexp.find_tree(:array)
125
+
126
+ {:a => :b,
127
+ :b => [sexp.find_tree(:gvar), :d],
128
+ sexp.find_tree(:gvar) => sexp.find_tree(:lasgn),
129
+ sexp.find_tree(:lasgn) => :f,
130
+ :d => sexp.find_tree(:gvar)
131
+ }
132
+ end
133
+
134
+ assert_graph_defn("should link trees on rescue without execution body","
135
+ def foo
136
+ begin
137
+ rescue Exception
138
+ return a
139
+ end
140
+ end") do |sexp,edges|
141
+ {}
142
+
143
+ end
144
+
145
+ assert_graph_defn("should link trees on rescue without execution body and else","
146
+ def foo
147
+ begin
148
+ rescue Exception
149
+ return a
150
+ else
151
+ return b
152
+ end
153
+ end") do |sexp,edges|
154
+ {}
155
+
156
+ end
157
+
158
+ assert_graph_defn("should link call previous to rescue when execution body of rescue is empty","
159
+ def foo
160
+ z
161
+ begin
162
+ rescue Exception
163
+ return a
164
+ else
165
+ return b
166
+ end
167
+ end") do |sexp,edges|
168
+ {:z => sexp.find_tree(:rescue) }
169
+
170
+ end
171
+
172
+ end