rdg 0.0.2 → 0.1.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +2 -2
  5. data/Gemfile +1 -1
  6. data/RELEASES.md +10 -0
  7. data/TODO.md +68 -0
  8. data/bin/ast +5 -4
  9. data/bin/cfg +5 -4
  10. data/lib/rdg/analysis/analyser.rb +30 -0
  11. data/lib/rdg/analysis/composite.rb +23 -0
  12. data/lib/rdg/analysis/context.rb +17 -0
  13. data/lib/rdg/analysis/equivalences.rb +25 -0
  14. data/lib/rdg/analysis/propagater.rb +51 -0
  15. data/lib/rdg/analysis/registry.rb +35 -0
  16. data/lib/rdg/cfg.rb +12 -41
  17. data/lib/rdg/control/begin.rb +6 -4
  18. data/lib/rdg/control/break.rb +19 -0
  19. data/lib/rdg/control/case.rb +25 -0
  20. data/lib/rdg/control/{while.rb → conditional_loop.rb} +8 -7
  21. data/lib/rdg/control/def.rb +21 -7
  22. data/lib/rdg/control/ensure.rb +30 -0
  23. data/lib/rdg/control/for.rb +29 -0
  24. data/lib/rdg/control/handler.rb +25 -0
  25. data/lib/rdg/control/if.rb +7 -6
  26. data/lib/rdg/control/jump.rb +33 -0
  27. data/lib/rdg/control/jump_to_start.rb +11 -0
  28. data/lib/rdg/control/next.rb +9 -0
  29. data/lib/rdg/control/none.rb +5 -3
  30. data/lib/rdg/control/redo.rb +9 -0
  31. data/lib/rdg/control/rescue.rb +31 -0
  32. data/lib/rdg/control/rescue_body.rb +29 -0
  33. data/lib/rdg/control/retry.rb +13 -0
  34. data/lib/rdg/control/return.rb +5 -6
  35. data/lib/rdg/control/when.rb +27 -0
  36. data/lib/rdg/graph/bidirected_adjacency_graph.rb +19 -0
  37. data/lib/rdg/graph/rgl/allow_duplicates.rb +45 -0
  38. data/lib/rdg/tree/ast.rb +15 -4
  39. data/lib/rdg/version.rb +1 -1
  40. data/rdg.gemspec +3 -2
  41. data/spec/integration/cfg/conditionals/case_spec.rb +66 -0
  42. data/spec/integration/cfg/{if_spec.rb → conditionals/if_spec.rb} +24 -9
  43. data/spec/integration/cfg/conditionals/unless_spec.rb +53 -0
  44. data/spec/integration/cfg/exceptions_spec.rb +131 -0
  45. data/spec/integration/cfg/loops/loop_control_spec.rb +90 -0
  46. data/spec/integration/cfg/loops/loop_spec.rb +70 -0
  47. data/spec/integration/cfg/sequence_spec.rb +7 -1
  48. data/spec/support/doubles/fake_ast.rb +15 -0
  49. data/spec/support/matchers/flow_between_matcher.rb +1 -1
  50. data/spec/unit/analysis/composite_spec.rb +47 -0
  51. data/spec/unit/analysis/equivalences_spec.rb +29 -0
  52. data/spec/unit/{control/analyser_spec.rb → analysis/propagater_spec.rb} +23 -12
  53. data/spec/unit/analysis/registry_spec.rb +61 -0
  54. data/spec/unit/control/begin_spec.rb +3 -6
  55. data/spec/unit/control/break_spec.rb +26 -0
  56. data/spec/unit/control/case_spec.rb +66 -0
  57. data/spec/unit/control/conditional_loop_spec.rb +22 -0
  58. data/spec/unit/control/ensure_spec.rb +33 -0
  59. data/spec/unit/control/for_spec.rb +26 -0
  60. data/spec/unit/control/handler_spec.rb +27 -0
  61. data/spec/unit/control/if_spec.rb +26 -18
  62. data/spec/unit/control/jump_spec.rb +43 -0
  63. data/spec/unit/control/jump_to_start_spec.rb +22 -0
  64. data/spec/unit/control/rescue_body_spec.rb +26 -0
  65. data/spec/unit/control/rescue_spec.rb +62 -0
  66. data/spec/unit/control/return_spec.rb +1 -10
  67. data/spec/unit/control/when_spec.rb +59 -0
  68. data/spec/unit/graph/bidirected_adjacency_graph_spec.rb +49 -0
  69. metadata +91 -18
  70. data/lib/rdg/control/analyser.rb +0 -44
  71. data/spec/integration/cfg/methods_spec.rb +0 -39
  72. data/spec/unit/control/def_spec.rb +0 -28
  73. data/spec/unit/control/while_spec.rb +0 -25
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Louis Rose
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-04 00:00:00.000000000 Z
11
+ date: 2015-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.2.0.2
19
+ version: 2.2.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.2.0.2
26
+ version: 2.2.2.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rgl
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,20 +38,34 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.5.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: require_all
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.3.2
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.3.2
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: 1.8.0
61
+ version: 1.9.0
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: 1.8.0
68
+ version: 1.9.0
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -121,38 +135,79 @@ files:
121
135
  - ".gitignore"
122
136
  - ".rspec"
123
137
  - ".rubocop.yml"
138
+ - ".ruby-version"
124
139
  - ".travis.yml"
125
140
  - Gemfile
126
141
  - LICENSE.txt
127
142
  - README.md
143
+ - RELEASES.md
128
144
  - Rakefile
145
+ - TODO.md
129
146
  - bin/ast
130
147
  - bin/cfg
148
+ - lib/rdg/analysis/analyser.rb
149
+ - lib/rdg/analysis/composite.rb
150
+ - lib/rdg/analysis/context.rb
151
+ - lib/rdg/analysis/equivalences.rb
152
+ - lib/rdg/analysis/propagater.rb
153
+ - lib/rdg/analysis/registry.rb
131
154
  - lib/rdg/cfg.rb
132
- - lib/rdg/control/analyser.rb
133
155
  - lib/rdg/control/begin.rb
156
+ - lib/rdg/control/break.rb
157
+ - lib/rdg/control/case.rb
158
+ - lib/rdg/control/conditional_loop.rb
134
159
  - lib/rdg/control/def.rb
160
+ - lib/rdg/control/ensure.rb
161
+ - lib/rdg/control/for.rb
162
+ - lib/rdg/control/handler.rb
135
163
  - lib/rdg/control/if.rb
164
+ - lib/rdg/control/jump.rb
165
+ - lib/rdg/control/jump_to_start.rb
166
+ - lib/rdg/control/next.rb
136
167
  - lib/rdg/control/none.rb
168
+ - lib/rdg/control/redo.rb
169
+ - lib/rdg/control/rescue.rb
170
+ - lib/rdg/control/rescue_body.rb
171
+ - lib/rdg/control/retry.rb
137
172
  - lib/rdg/control/return.rb
138
- - lib/rdg/control/while.rb
173
+ - lib/rdg/control/when.rb
174
+ - lib/rdg/graph/bidirected_adjacency_graph.rb
175
+ - lib/rdg/graph/rgl/allow_duplicates.rb
139
176
  - lib/rdg/tree/ast.rb
140
177
  - lib/rdg/tree/rgl/post_order_iterator.rb
141
178
  - lib/rdg/tree/rgl/pre_order_iterator.rb
142
179
  - lib/rdg/version.rb
143
180
  - rdg.gemspec
144
- - spec/integration/cfg/if_spec.rb
145
- - spec/integration/cfg/methods_spec.rb
181
+ - spec/integration/cfg/conditionals/case_spec.rb
182
+ - spec/integration/cfg/conditionals/if_spec.rb
183
+ - spec/integration/cfg/conditionals/unless_spec.rb
184
+ - spec/integration/cfg/exceptions_spec.rb
185
+ - spec/integration/cfg/loops/loop_control_spec.rb
186
+ - spec/integration/cfg/loops/loop_spec.rb
146
187
  - spec/integration/cfg/sequence_spec.rb
147
188
  - spec/spec_helper.rb
189
+ - spec/support/doubles/fake_ast.rb
148
190
  - spec/support/matchers/contain_matcher.rb
149
191
  - spec/support/matchers/flow_between_matcher.rb
150
- - spec/unit/control/analyser_spec.rb
192
+ - spec/unit/analysis/composite_spec.rb
193
+ - spec/unit/analysis/equivalences_spec.rb
194
+ - spec/unit/analysis/propagater_spec.rb
195
+ - spec/unit/analysis/registry_spec.rb
151
196
  - spec/unit/control/begin_spec.rb
152
- - spec/unit/control/def_spec.rb
197
+ - spec/unit/control/break_spec.rb
198
+ - spec/unit/control/case_spec.rb
199
+ - spec/unit/control/conditional_loop_spec.rb
200
+ - spec/unit/control/ensure_spec.rb
201
+ - spec/unit/control/for_spec.rb
202
+ - spec/unit/control/handler_spec.rb
153
203
  - spec/unit/control/if_spec.rb
204
+ - spec/unit/control/jump_spec.rb
205
+ - spec/unit/control/jump_to_start_spec.rb
206
+ - spec/unit/control/rescue_body_spec.rb
207
+ - spec/unit/control/rescue_spec.rb
154
208
  - spec/unit/control/return_spec.rb
155
- - spec/unit/control/while_spec.rb
209
+ - spec/unit/control/when_spec.rb
210
+ - spec/unit/graph/bidirected_adjacency_graph_spec.rb
156
211
  - spec/unit/tree/ast_spec.rb
157
212
  - spec/unit/tree/rgl/post_order_iterator_spec.rb
158
213
  - spec/unit/tree/rgl/pre_order_iterator_spec.rb
@@ -181,18 +236,36 @@ signing_key:
181
236
  specification_version: 4
182
237
  summary: Dependency analysis for Ruby programs
183
238
  test_files:
184
- - spec/integration/cfg/if_spec.rb
185
- - spec/integration/cfg/methods_spec.rb
239
+ - spec/integration/cfg/conditionals/case_spec.rb
240
+ - spec/integration/cfg/conditionals/if_spec.rb
241
+ - spec/integration/cfg/conditionals/unless_spec.rb
242
+ - spec/integration/cfg/exceptions_spec.rb
243
+ - spec/integration/cfg/loops/loop_control_spec.rb
244
+ - spec/integration/cfg/loops/loop_spec.rb
186
245
  - spec/integration/cfg/sequence_spec.rb
187
246
  - spec/spec_helper.rb
247
+ - spec/support/doubles/fake_ast.rb
188
248
  - spec/support/matchers/contain_matcher.rb
189
249
  - spec/support/matchers/flow_between_matcher.rb
190
- - spec/unit/control/analyser_spec.rb
250
+ - spec/unit/analysis/composite_spec.rb
251
+ - spec/unit/analysis/equivalences_spec.rb
252
+ - spec/unit/analysis/propagater_spec.rb
253
+ - spec/unit/analysis/registry_spec.rb
191
254
  - spec/unit/control/begin_spec.rb
192
- - spec/unit/control/def_spec.rb
255
+ - spec/unit/control/break_spec.rb
256
+ - spec/unit/control/case_spec.rb
257
+ - spec/unit/control/conditional_loop_spec.rb
258
+ - spec/unit/control/ensure_spec.rb
259
+ - spec/unit/control/for_spec.rb
260
+ - spec/unit/control/handler_spec.rb
193
261
  - spec/unit/control/if_spec.rb
262
+ - spec/unit/control/jump_spec.rb
263
+ - spec/unit/control/jump_to_start_spec.rb
264
+ - spec/unit/control/rescue_body_spec.rb
265
+ - spec/unit/control/rescue_spec.rb
194
266
  - spec/unit/control/return_spec.rb
195
- - spec/unit/control/while_spec.rb
267
+ - spec/unit/control/when_spec.rb
268
+ - spec/unit/graph/bidirected_adjacency_graph_spec.rb
196
269
  - spec/unit/tree/ast_spec.rb
197
270
  - spec/unit/tree/rgl/post_order_iterator_spec.rb
198
271
  - spec/unit/tree/rgl/pre_order_iterator_spec.rb
@@ -1,44 +0,0 @@
1
- module RDG
2
- module Control
3
- class Analyser
4
- def initialize(ast_node, graph, state)
5
- @ast_node, @graph, @state = ast_node, graph, state
6
- end
7
-
8
- def analyse
9
- add_internal_flow_edges
10
- propogate_incoming_flow
11
- propogate_outgoing_flow
12
- remove_non_flow_vertices
13
- end
14
-
15
- private
16
-
17
- def children
18
- @ast_node.children
19
- end
20
-
21
- def add_internal_flow_edges
22
- internal_flow_edges.each { |s, t| @graph.add_edge(s, t) }
23
- end
24
-
25
- def propogate_incoming_flow
26
- @graph.each_predecessor(@ast_node) do |predecessor|
27
- @graph.remove_edge(predecessor, @ast_node)
28
- start_nodes.each { |n| @graph.add_edge(predecessor, n) }
29
- end
30
- end
31
-
32
- def propogate_outgoing_flow
33
- @graph.each_successor(@ast_node) do |successor|
34
- @graph.remove_edge(@ast_node, successor)
35
- end_nodes.each { |n| @graph.add_edge(n, successor) }
36
- end
37
- end
38
-
39
- def remove_non_flow_vertices
40
- @graph.remove_vertex(@ast_node)
41
- end
42
- end
43
- end
44
- end
@@ -1,39 +0,0 @@
1
- require "rdg/cfg"
2
-
3
- module RDG
4
- describe CFG do
5
- context "for a simple method" do
6
- it "should show control flowing from the method name to the body" do
7
- cfg = CFG.from_source("def foo; a = 1; a = 2; end")
8
- name, first, _ = cfg.vertices
9
-
10
- expect(cfg.vertices.size).to eq(3)
11
- expect(cfg.has_edge?(name, first)).to be_truthy
12
- end
13
- end
14
-
15
- context "for a method containing an early return" do
16
- before(:all) do
17
- @cfg = CFG.from_source("def foo; a = 1; if a == 2; return; end; a = 2; end")
18
- @name, @first, _, _, @ret = @cfg.vertices
19
- end
20
-
21
- it "should show control flowing from the method name to the body" do
22
- expect(@cfg.has_edge?(@name, @first)).to be_truthy
23
- end
24
-
25
- it "should not show control flowing from return to successor" do
26
- expect(@cfg.has_edge?(@ret, @second)).to be_falsey
27
- end
28
- end
29
-
30
- context "return from no method" do
31
- it "should do nothing" do
32
- cfg = CFG.from_source("return")
33
-
34
- puts cfg.vertices
35
- expect(cfg.vertices.empty?).to be_truthy
36
- end
37
- end
38
- end
39
- end
@@ -1,28 +0,0 @@
1
- require "rdg/control/def"
2
-
3
- module RDG
4
- module Control
5
- describe Def do
6
- let(:state) { Hash.new }
7
- let(:graph) { spy("graph") }
8
- subject do
9
- ast = double("ast")
10
- allow(ast).to receive(:children) { [:name, :args, :body] }
11
- Def.new(ast, graph, state)
12
- end
13
-
14
- it "should have control flow from name to body" do
15
- subject.analyse
16
-
17
- expect(graph).to have_received(:add_edge).with(:name, :body)
18
- expect(graph).to have_received(:add_edge).once
19
- end
20
-
21
- it "should have updated state with name node" do
22
- subject.analyse
23
-
24
- expect(state[:current_method]).to eq(:name)
25
- end
26
- end
27
- end
28
- end
@@ -1,25 +0,0 @@
1
- require "rdg/control/while"
2
-
3
- module RDG
4
- module Control
5
- describe While do
6
- subject do
7
- ast = double("ast")
8
- allow(ast).to receive(:children) { [:predicate, :body] }
9
- While.new(ast, nil, nil)
10
- end
11
-
12
- it "should have control flow start at the predicate" do
13
- expect(subject.start_nodes).to eq([:predicate])
14
- end
15
-
16
- it "should have control flow end at the body" do
17
- expect(subject.end_nodes).to eq([:body])
18
- end
19
-
20
- it "should have control flow edges between predicate and body, and vice-versa" do
21
- expect(subject.internal_flow_edges).to eq([[:predicate, :body], [:body, :predicate]])
22
- end
23
- end
24
- end
25
- end