ruby_traverser 0.1.1 → 0.2.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.
- 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
|
-
|