ruby_traverser 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +27 -253
- data/TODO.txt +12 -0
- data/VERSION +1 -1
- data/lib/config/api.rb +11 -0
- data/lib/config/has_ext.rb +44 -0
- data/lib/{traversal → config}/misc.rb +4 -4
- data/lib/config/mixin.rb +15 -0
- data/lib/{traversal → config}/module.rb +1 -1
- data/lib/{traversal → config}/patch.rb +4 -4
- data/lib/manipulation/api.rb +30 -0
- data/lib/manipulation/delete/api.rb +10 -0
- data/lib/manipulation/helpers.rb +30 -0
- data/lib/manipulation/insert/api.rb +57 -0
- data/lib/manipulation/position.rb +44 -0
- data/lib/{mutate/replacer.rb → manipulation/update/api.rb} +25 -14
- data/lib/query/api.rb +7 -0
- data/lib/query/find.rb +73 -0
- data/lib/rails/api.rb +13 -0
- data/lib/rails/{api_wrapper.rb → gemfile.rb} +1 -1
- data/lib/ruby_traverser.rb +1 -3
- data/ruby_traverser.gemspec +21 -12
- data/test/mutate/delete_test.rb +25 -0
- data/test/mutate/mutate_class_test.rb +7 -7
- data/test/mutate/mutate_test.rb +18 -17
- data/test/traversal/gemfile_test.rb +6 -6
- metadata +23 -14
- data/lib/mutate/api.rb +0 -124
- data/lib/traversal/api/finders.rb +0 -41
- data/lib/traversal/api/inside.rb +0 -36
- data/lib/traversal/api/traversal.rb +0 -20
- data/lib/traversal/mixin.rb +0 -50
@@ -14,15 +14,15 @@ end}
|
|
14
14
|
|
15
15
|
def_code = Ripper::RubyBuilder.build(def_src)
|
16
16
|
code = Ripper::RubyBuilder.build(src)
|
17
|
-
code.
|
17
|
+
code.inside(:class, 'Monty', :superclass => 'Abc::Blip') do |b|
|
18
18
|
assert_equal Ruby::Class, b.class
|
19
|
-
gem_abc = b.
|
20
|
-
blip = b.
|
21
|
-
gem_123 = gem_abc.
|
22
|
-
gem_123.
|
23
|
-
my_def = b.
|
19
|
+
gem_abc = b.insert(:after, "gem 'abc'")
|
20
|
+
blip = b.insert(:after,"blip")
|
21
|
+
gem_123 = gem_abc.insert(:after,"gem '123'")
|
22
|
+
gem_123.insert_comment(:after, "hello")
|
23
|
+
my_def = b.insert(:after, def_src)
|
24
24
|
|
25
|
-
b.
|
25
|
+
b.insert(:before, "gem '789'")
|
26
26
|
puts b.to_ruby
|
27
27
|
end
|
28
28
|
end
|
data/test/mutate/mutate_test.rb
CHANGED
@@ -14,10 +14,11 @@ end
|
|
14
14
|
|
15
15
|
code = Ripper::RubyBuilder.build(src)
|
16
16
|
|
17
|
-
code.
|
18
|
-
|
17
|
+
code.find(:block, 'group', :args => [:test]) do |b|
|
18
|
+
puts "BLOCK"
|
19
|
+
call_node = b.find(:call, 'gem', :args => ['ripper', {:src => 'github'}])
|
19
20
|
assert_equal Ruby::Call, call_node.class
|
20
|
-
b.
|
21
|
+
b.insert(:after, "gem 'abc'")
|
21
22
|
puts "mutated block:"
|
22
23
|
puts b.to_ruby
|
23
24
|
end
|
@@ -31,11 +32,10 @@ end
|
|
31
32
|
}
|
32
33
|
|
33
34
|
code = Ripper::RubyBuilder.build(src)
|
34
|
-
code.
|
35
|
-
call_node =
|
36
|
-
|
37
|
-
|
38
|
-
puts b.to_ruby
|
35
|
+
code.find(:block, 'group', :args => [:test]) do
|
36
|
+
call_node = find(:call, 'gem', :args => ['ripper'])
|
37
|
+
call_node.update(:select => {:arg => :src}, :with_code => "{:src => 'unknown'}")
|
38
|
+
puts to_ruby
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -47,10 +47,10 @@ end
|
|
47
47
|
}
|
48
48
|
|
49
49
|
code = Ripper::RubyBuilder.build(src)
|
50
|
-
code.
|
51
|
-
call_node = b.
|
50
|
+
code.inside(:block, 'group', :args => [:test]) do |b|
|
51
|
+
call_node = b.find(:call, 'gem', :args => ['ripper'])
|
52
52
|
assert_equal Ruby::Call, call_node.class
|
53
|
-
call_node.
|
53
|
+
call_node.update(:select => {:arg => {:src => 'blip'}} , :with_code => "{:src => 'unknown'}")
|
54
54
|
puts b.to_ruby
|
55
55
|
end
|
56
56
|
end
|
@@ -64,12 +64,13 @@ end
|
|
64
64
|
|
65
65
|
code = Ripper::RubyBuilder.build(src)
|
66
66
|
|
67
|
-
code.
|
67
|
+
code.find(:def, 'hello_world', :params => ['a']) do |b|
|
68
|
+
puts "HELLO"
|
68
69
|
# call_node = b.find_call('gem', :args => ['ripper', {:src => 'github'}], :verbose => true)
|
69
|
-
|
70
|
-
assert_equal Ruby::Assignment,
|
70
|
+
ass_node = b.find(:assignment, 'my_var')
|
71
|
+
assert_equal Ruby::Assignment, ass_node.class
|
71
72
|
|
72
|
-
|
73
|
+
ass_node.update(:value => "3")
|
73
74
|
puts b.to_ruby
|
74
75
|
end
|
75
76
|
end
|
@@ -80,9 +81,9 @@ end
|
|
80
81
|
end
|
81
82
|
}
|
82
83
|
code = Ripper::RubyBuilder.build(src)
|
83
|
-
code.
|
84
|
+
code.find(:class, 'Monty', :superclass => 'Abc::Blip') do |b|
|
84
85
|
assert_equal Ruby::Class, b.class
|
85
|
-
b.
|
86
|
+
b.insert(:after, "gem 'abc'")
|
86
87
|
puts b.to_ruby
|
87
88
|
end
|
88
89
|
end
|
@@ -52,9 +52,9 @@ class TraversalTest < Test::Unit::TestCase
|
|
52
52
|
|
53
53
|
code = Ripper::RubyBuilder.build(src)
|
54
54
|
code.inside_def('hello_world', :params => ['a']) do |b|
|
55
|
-
|
56
|
-
assert_equal Ruby::Variable,
|
57
|
-
puts
|
55
|
+
var_node = b.find(:variable, 'my_var')
|
56
|
+
assert_equal Ruby::Variable, var_node.class
|
57
|
+
puts var_node.to_ruby
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -67,9 +67,9 @@ class TraversalTest < Test::Unit::TestCase
|
|
67
67
|
|
68
68
|
code = Ripper::RubyBuilder.build(src)
|
69
69
|
code.inside_def('hello_world', :params => ['a']) do |b|
|
70
|
-
|
71
|
-
assert_equal Ruby::Assignment,
|
72
|
-
puts
|
70
|
+
ass_node = b.find_assignment('my_var')
|
71
|
+
assert_equal Ruby::Assignment, ass_node.class
|
72
|
+
puts ass_node.to_ruby
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Kristian Mandrup
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-04-
|
17
|
+
date: 2010-04-28 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -59,22 +59,30 @@ files:
|
|
59
59
|
- LICENSE
|
60
60
|
- README.markdown
|
61
61
|
- Rakefile
|
62
|
+
- TODO.txt
|
62
63
|
- VERSION
|
63
|
-
- lib/
|
64
|
-
- lib/
|
65
|
-
- lib/
|
64
|
+
- lib/config/api.rb
|
65
|
+
- lib/config/has_ext.rb
|
66
|
+
- lib/config/misc.rb
|
67
|
+
- lib/config/mixin.rb
|
68
|
+
- lib/config/module.rb
|
69
|
+
- lib/config/patch.rb
|
70
|
+
- lib/manipulation/api.rb
|
71
|
+
- lib/manipulation/delete/api.rb
|
72
|
+
- lib/manipulation/helpers.rb
|
73
|
+
- lib/manipulation/insert/api.rb
|
74
|
+
- lib/manipulation/position.rb
|
75
|
+
- lib/manipulation/update/api.rb
|
76
|
+
- lib/query/api.rb
|
77
|
+
- lib/query/find.rb
|
78
|
+
- lib/rails/api.rb
|
79
|
+
- lib/rails/gemfile.rb
|
66
80
|
- lib/ruby_traverser.rb
|
67
|
-
- lib/traversal/api/finders.rb
|
68
|
-
- lib/traversal/api/inside.rb
|
69
|
-
- lib/traversal/api/traversal.rb
|
70
|
-
- lib/traversal/misc.rb
|
71
|
-
- lib/traversal/mixin.rb
|
72
|
-
- lib/traversal/module.rb
|
73
|
-
- lib/traversal/patch.rb
|
74
81
|
- ruby_traverser.gemspec
|
75
82
|
- spec/ruby_traverser_spec.rb
|
76
83
|
- spec/spec.opts
|
77
84
|
- spec/spec_helper.rb
|
85
|
+
- test/mutate/delete_test.rb
|
78
86
|
- test/mutate/mutate_class_test.rb
|
79
87
|
- test/mutate/mutate_test.rb
|
80
88
|
- test/rails_api/gemfile_api.rb
|
@@ -114,6 +122,7 @@ summary: traverse and mutate ruby code using a nice DSL
|
|
114
122
|
test_files:
|
115
123
|
- spec/ruby_traverser_spec.rb
|
116
124
|
- spec/spec_helper.rb
|
125
|
+
- test/mutate/delete_test.rb
|
117
126
|
- test/mutate/mutate_class_test.rb
|
118
127
|
- test/mutate/mutate_test.rb
|
119
128
|
- test/rails_api/gemfile_api.rb
|
data/lib/mutate/api.rb
DELETED
@@ -1,124 +0,0 @@
|
|
1
|
-
require 'mutate/replacer'
|
2
|
-
|
3
|
-
class String
|
4
|
-
# Returns an indented string, all lines of string will be indented with count of chars
|
5
|
-
def indent(char, count)
|
6
|
-
(char * count) + gsub(/(\n+)/) { $1 + (char * count) }
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
|
11
|
-
module RubyAPI
|
12
|
-
module Mutator
|
13
|
-
include Replacer
|
14
|
-
|
15
|
-
def append_code(code)
|
16
|
-
return append_code_simple(code) if !elemental?
|
17
|
-
obj = object
|
18
|
-
indentation = obj.last_indent
|
19
|
-
code = "\n#{code}\n".indent(' ', indentation)
|
20
|
-
ruby_code = Ripper::RubyBuilder.build(code)
|
21
|
-
inject_code = ruby_code.elements[0]
|
22
|
-
obj.get_elements << inject_code
|
23
|
-
inject_code
|
24
|
-
end
|
25
|
-
|
26
|
-
def append_code_simple(code)
|
27
|
-
indentation = position.col
|
28
|
-
code = "\n#{code}\n".indent(' ', indentation)
|
29
|
-
ruby_code = Ripper::RubyBuilder.build(code)
|
30
|
-
inject_code = ruby_code.elements[0]
|
31
|
-
index = parent.find_index(self)
|
32
|
-
parent.get_elements.insert(index+1, inject_code)
|
33
|
-
inject_code
|
34
|
-
end
|
35
|
-
|
36
|
-
def find_index(obj)
|
37
|
-
get_elements.each_with_index do |elem, i|
|
38
|
-
if elem == obj
|
39
|
-
return i
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def prepend_code(code)
|
45
|
-
obj = object
|
46
|
-
indentation = obj.first_indent
|
47
|
-
code = "\n#{code}\n".indent(' ', indentation)
|
48
|
-
ruby_code = Ripper::RubyBuilder.build(code)
|
49
|
-
inject_code = ruby_code.elements[0]
|
50
|
-
obj.get_elements.insert(0, inject_code)
|
51
|
-
obj
|
52
|
-
end
|
53
|
-
|
54
|
-
|
55
|
-
def append_comment(text)
|
56
|
-
append_code("# #{text}")
|
57
|
-
end
|
58
|
-
|
59
|
-
def elemental?
|
60
|
-
respond_to?(:body) || respond_to?(:elements)
|
61
|
-
end
|
62
|
-
|
63
|
-
def get_elements
|
64
|
-
case self
|
65
|
-
when Ruby::Class
|
66
|
-
body.elements
|
67
|
-
else
|
68
|
-
elements
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
|
73
|
-
protected
|
74
|
-
|
75
|
-
def last_indent
|
76
|
-
case self
|
77
|
-
when Ruby::Block, Ruby::Class
|
78
|
-
last_position(get_elements)
|
79
|
-
else
|
80
|
-
puts "unknown: #{obj.class}"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def last_position(elements)
|
85
|
-
last_element = elements.last
|
86
|
-
return position.col
|
87
|
-
return position.col if simple_pos?(last_element)
|
88
|
-
return last_element.identifier.position.col if elements && elements.size > 0
|
89
|
-
inside_indent
|
90
|
-
end
|
91
|
-
|
92
|
-
def simple_pos?(elem)
|
93
|
-
[Ruby::Token, Ruby::Variable].include?(elem.class)
|
94
|
-
end
|
95
|
-
|
96
|
-
def first_indent
|
97
|
-
case self
|
98
|
-
when Ruby::Block, Ruby::Class
|
99
|
-
first_position(get_elements)
|
100
|
-
else
|
101
|
-
puts "unknown: #{obj.class}"
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def first_position(elements)
|
106
|
-
first_element = elements.first
|
107
|
-
return position.col if simple_pos?(first_element)
|
108
|
-
return first_element.identifier.position.col if elements && elements.size > 0
|
109
|
-
inside_indent
|
110
|
-
end
|
111
|
-
|
112
|
-
def object
|
113
|
-
self.respond_to?(:block) ? self.block : self
|
114
|
-
end
|
115
|
-
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
module Ruby
|
120
|
-
class Node
|
121
|
-
include RubyAPI::Mutator
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
|
-
module RubyAPI
|
4
|
-
module Finders
|
5
|
-
def find_module(name)
|
6
|
-
get_obj.select(Ruby::Module, :identifier => name).first
|
7
|
-
end
|
8
|
-
|
9
|
-
def find_class(name, options = {})
|
10
|
-
options.merge!(:identifier => name)
|
11
|
-
get_obj.select(Ruby::Class, options).first
|
12
|
-
end
|
13
|
-
|
14
|
-
def find_variable(name, options = {})
|
15
|
-
options.merge!(:token => name)
|
16
|
-
get_obj.select(Ruby::Variable, options).first
|
17
|
-
end
|
18
|
-
|
19
|
-
def find_assignment(name, options = {})
|
20
|
-
options.merge!(:left_token => name)
|
21
|
-
get_obj.select(Ruby::Assignment, options).first
|
22
|
-
end
|
23
|
-
|
24
|
-
def find_call(name, options = {})
|
25
|
-
options.merge!(:identifier => name)
|
26
|
-
get_obj.select(Ruby::Call, options).first
|
27
|
-
end
|
28
|
-
|
29
|
-
def find_block(name, options = {})
|
30
|
-
options.merge!(:identifier => name)
|
31
|
-
options.merge!(:block => true) if !options.has_key?(:block_params)
|
32
|
-
get_obj.select(Ruby::Call, options).first
|
33
|
-
end
|
34
|
-
|
35
|
-
|
36
|
-
def find_def(name, options = {})
|
37
|
-
options.merge!(:identifier => name)
|
38
|
-
get_obj.select(Ruby::Method, options).first
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
data/lib/traversal/api/inside.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
module RubyAPI
|
2
|
-
module Inside
|
3
|
-
def inside_block(name, options = {}, &block)
|
4
|
-
call_block(find_block(name, options), options, &block)
|
5
|
-
end
|
6
|
-
|
7
|
-
def inside_module(name, &block)
|
8
|
-
call_block(find_module(name), options, &block)
|
9
|
-
end
|
10
|
-
|
11
|
-
def inside_class(name, options = {}, &block)
|
12
|
-
call_block(find_class(name, options), options, &block)
|
13
|
-
end
|
14
|
-
|
15
|
-
def inside_def(name, options = {}, &block)
|
16
|
-
call_block(find_def(name, options), options, &block)
|
17
|
-
end
|
18
|
-
|
19
|
-
protected
|
20
|
-
|
21
|
-
def call_block(s, options, &block)
|
22
|
-
# inc_inside_indent
|
23
|
-
s.extend(options[:extend]) if options[:extend]
|
24
|
-
block.arity < 1 ? s.instance_eval(&block) : block.call(s)
|
25
|
-
end
|
26
|
-
|
27
|
-
def inside_indent
|
28
|
-
if self.class == Ruby::Class
|
29
|
-
pos = ldelim.position.col
|
30
|
-
return pos
|
31
|
-
end
|
32
|
-
2
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'traversal/api/finders'
|
2
|
-
require 'traversal/api/inside'
|
3
|
-
|
4
|
-
module RubyAPI
|
5
|
-
include Finders
|
6
|
-
include Inside
|
7
|
-
|
8
|
-
protected
|
9
|
-
|
10
|
-
def get_obj(options = {})
|
11
|
-
return self.block if self.class == Ruby::Method
|
12
|
-
self
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
module Ruby
|
17
|
-
class Node
|
18
|
-
include RubyAPI
|
19
|
-
end
|
20
|
-
end
|
data/lib/traversal/mixin.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
require 'traversal/module'
|
2
|
-
require 'traversal/misc'
|
3
|
-
require 'traversal/patch'
|
4
|
-
|
5
|
-
module Ruby
|
6
|
-
class Node
|
7
|
-
include Traversal::Module
|
8
|
-
include Traversal::Misc
|
9
|
-
include Traversal::Patch
|
10
|
-
|
11
|
-
def has_const?(value)
|
12
|
-
if respond_to?(:const)
|
13
|
-
if namespace?(value)
|
14
|
-
name = value.split('::').last
|
15
|
-
return self.const.identifier.token == name
|
16
|
-
end
|
17
|
-
end
|
18
|
-
false
|
19
|
-
end
|
20
|
-
|
21
|
-
def has_block?
|
22
|
-
respond_to? :block
|
23
|
-
end
|
24
|
-
|
25
|
-
def has_namespace?(value)
|
26
|
-
if respond_to?(:namespace)
|
27
|
-
return self.namespace.identifier.token == value
|
28
|
-
end
|
29
|
-
false
|
30
|
-
end
|
31
|
-
|
32
|
-
def has_identifier?(value)
|
33
|
-
if respond_to?(:identifier)
|
34
|
-
id = self.identifier
|
35
|
-
|
36
|
-
if namespace?(value)
|
37
|
-
return id.token.to_s == value.to_s if id.respond_to?(:token)
|
38
|
-
if id.respond_to?(:identifier)
|
39
|
-
name = value.split('::').last
|
40
|
-
return id.identifier.token == name
|
41
|
-
end
|
42
|
-
end
|
43
|
-
else
|
44
|
-
has_const?(value)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
|