mvz-live_ast 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.rdoc +14 -0
- data/Rakefile +48 -9
- data/devel/levitate.rb +5 -674
- data/lib/live_ast/common.rb +22 -21
- data/lib/live_ast/error.rb +2 -2
- data/lib/live_ast/irb_spy.rb +4 -6
- data/lib/live_ast/linker.rb +7 -7
- data/lib/live_ast/loader.rb +6 -6
- data/lib/live_ast/reader.rb +2 -2
- data/lib/live_ast/replace_eval.rb +27 -31
- data/lib/live_ast/replace_load.rb +1 -1
- data/lib/live_ast/ruby_parser.rb +24 -22
- data/lib/live_ast/ruby_parser/test.rb +183 -179
- data/lib/live_ast/ruby_parser/unparser.rb +10 -6
- data/lib/live_ast/to_ast.rb +1 -1
- data/lib/live_ast/version.rb +1 -1
- data/test/ast_eval/ast_eval_test.rb +11 -0
- data/test/ast_load/ast_load_test.rb +45 -0
- data/test/backtrace_test.rb +29 -28
- data/test/{noninvasive_test.rb → base/noninvasive_test.rb} +7 -5
- data/test/base/reload_test.rb +41 -0
- data/test/covert_define_method_test.rb +1 -1
- data/test/define_method_test.rb +5 -5
- data/test/encoding_test.rb +5 -5
- data/test/error_test.rb +6 -6
- data/test/eval_test.rb +7 -7
- data/test/flush_cache_test.rb +6 -6
- data/test/full/ast_reload_test.rb +39 -0
- data/test/{replace_eval_test.rb → full/replace_eval_test.rb} +31 -12
- data/test/irb_test.rb +1 -1
- data/test/lambda_test.rb +7 -0
- data/test/load_path_test.rb +12 -12
- data/test/load_test.rb +35 -35
- data/test/main.rb +19 -27
- data/test/nested_test.rb +1 -1
- data/test/readme_test.rb +1 -3
- data/test/recursive_eval_test.rb +2 -3
- data/test/redefine_method_test.rb +2 -2
- data/test/rubygems_test.rb +1 -1
- data/test/rubyspec_test.rb +3 -3
- data/test/stdlib_test.rb +1 -1
- data/test/thread_test.rb +1 -2
- data/test/to_ast/to_ast_feature_test.rb +11 -0
- data/test/to_ruby/to_ruby_feature_test.rb +11 -0
- data/test/{to_ruby_test.rb → to_ruby/to_ruby_test.rb} +2 -2
- metadata +93 -91
- data/test/ast_eval_feature_test.rb +0 -11
- data/test/ast_load_feature_test.rb +0 -11
- data/test/reload_test.rb +0 -105
- data/test/to_ast_feature_test.rb +0 -15
- data/test/to_ruby_feature_test.rb +0 -15
@@ -3,11 +3,15 @@ require 'ruby2ruby'
|
|
3
3
|
#
|
4
4
|
# Used by +to_ruby+ in LiveAST.
|
5
5
|
#
|
6
|
-
module LiveAST
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
module LiveAST
|
7
|
+
class RubyParser
|
8
|
+
module Unparser
|
9
|
+
#
|
10
|
+
# Return a ruby source string which reflects the given AST.
|
11
|
+
#
|
12
|
+
def self.unparse(sexp)
|
13
|
+
::Ruby2Ruby.new.process(sexp)
|
14
|
+
end
|
15
|
+
end
|
12
16
|
end
|
13
17
|
end
|
data/lib/live_ast/to_ast.rb
CHANGED
data/lib/live_ast/version.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'main'
|
2
|
+
|
3
|
+
require 'live_ast/ast_load'
|
4
|
+
|
5
|
+
class AstLoadTest < BaseTest
|
6
|
+
include FileUtils
|
7
|
+
|
8
|
+
def test_defines_ast_load
|
9
|
+
assert private_methods.include?(:ast_load)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_reloading
|
13
|
+
noninvasive_ast_reload
|
14
|
+
end
|
15
|
+
|
16
|
+
def noninvasive_ast_reload
|
17
|
+
code_1 = %{
|
18
|
+
class AstLoadTest::B
|
19
|
+
def f
|
20
|
+
"first B#f"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
}
|
24
|
+
|
25
|
+
code_2 = %{
|
26
|
+
class AstLoadTest::B
|
27
|
+
def f
|
28
|
+
"second B#f"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
}
|
32
|
+
|
33
|
+
temp_file code_1 do |file|
|
34
|
+
load file
|
35
|
+
|
36
|
+
LiveAST.ast(B.instance_method(:f))
|
37
|
+
|
38
|
+
write_file file, code_2
|
39
|
+
ast_load file
|
40
|
+
|
41
|
+
assert_equal no_arg_def(:f, "second B#f"),
|
42
|
+
LiveAST.ast(B.instance_method(:f))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/test/backtrace_test.rb
CHANGED
@@ -8,22 +8,22 @@ define_unsorted_test_case "BacktraceTest", RegularTest do
|
|
8
8
|
3.times do
|
9
9
|
orig = exception_backtrace do
|
10
10
|
eval %{
|
11
|
-
|
11
|
+
|
12
12
|
raise
|
13
|
-
|
14
|
-
|
13
|
+
|
14
|
+
|
15
15
|
}, binding, "somewhere", 1000
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
live = exception_backtrace do
|
19
19
|
ast_eval %{
|
20
|
-
|
20
|
+
|
21
21
|
raise
|
22
|
-
|
23
|
-
|
22
|
+
|
23
|
+
|
24
24
|
}, binding, "somewhere", 1000
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
assert_equal orig.first, live.first
|
28
28
|
assert_match(/somewhere:1002/, live.first)
|
29
29
|
end
|
@@ -33,19 +33,19 @@ define_unsorted_test_case "BacktraceTest", RegularTest do
|
|
33
33
|
3.times do
|
34
34
|
orig = exception_backtrace do
|
35
35
|
eval %{
|
36
|
-
|
36
|
+
|
37
37
|
|
38
38
|
raise
|
39
|
-
|
39
|
+
|
40
40
|
}, binding, __FILE__, (__LINE__ + 9)
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
live = exception_backtrace do
|
44
44
|
ast_eval %{
|
45
|
-
|
45
|
+
|
46
46
|
|
47
47
|
raise
|
48
|
-
|
48
|
+
|
49
49
|
}, binding
|
50
50
|
end
|
51
51
|
|
@@ -59,19 +59,19 @@ define_unsorted_test_case "BacktraceTest", RegularTest do
|
|
59
59
|
3.times do
|
60
60
|
orig = exception_backtrace do
|
61
61
|
eval %{
|
62
|
-
|
62
|
+
|
63
63
|
|
64
64
|
raise
|
65
|
-
|
65
|
+
|
66
66
|
}, binding, __FILE__, (__LINE__ + 9)
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
live = exception_backtrace do
|
70
70
|
ast_eval %{
|
71
|
-
|
71
|
+
|
72
72
|
|
73
73
|
raise
|
74
|
-
|
74
|
+
|
75
75
|
}, binding, __FILE__, __LINE__
|
76
76
|
end
|
77
77
|
|
@@ -85,19 +85,19 @@ define_unsorted_test_case "BacktraceTest", RegularTest do
|
|
85
85
|
3.times do
|
86
86
|
orig = exception_backtrace do
|
87
87
|
eval %{
|
88
|
-
|
88
|
+
|
89
89
|
|
90
90
|
raise
|
91
|
-
|
91
|
+
|
92
92
|
}, binding, __FILE__
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
live = exception_backtrace do
|
96
96
|
ast_eval %{
|
97
|
-
|
97
|
+
|
98
98
|
|
99
99
|
raise
|
100
|
-
|
100
|
+
|
101
101
|
}, binding, __FILE__
|
102
102
|
end
|
103
103
|
|
@@ -106,7 +106,7 @@ define_unsorted_test_case "BacktraceTest", RegularTest do
|
|
106
106
|
assert_match(/#{here}/, live.first)
|
107
107
|
end
|
108
108
|
end
|
109
|
-
|
109
|
+
|
110
110
|
def test_raise_after_eval
|
111
111
|
raise_after_eval("raise", false)
|
112
112
|
raise_after_eval("1/0", false)
|
@@ -125,7 +125,7 @@ define_unsorted_test_case "BacktraceTest", RegularTest do
|
|
125
125
|
|
126
126
|
|
127
127
|
}, binding, "somewhere", 1000
|
128
|
-
|
128
|
+
|
129
129
|
live = ast_eval %{
|
130
130
|
|
131
131
|
lambda { #{code} }
|
@@ -147,11 +147,12 @@ define_unsorted_test_case "BacktraceTest", RegularTest do
|
|
147
147
|
end
|
148
148
|
end
|
149
149
|
end
|
150
|
-
|
150
|
+
|
151
151
|
def test_tokens_stripped
|
152
|
-
exception_backtrace do
|
152
|
+
lines = exception_backtrace do
|
153
153
|
ast_eval %{ ast_eval %{ ast_eval %{raise}, binding }, binding }, binding
|
154
|
-
end
|
154
|
+
end
|
155
|
+
lines.each do |line|
|
155
156
|
assert_nil line.index(LiveAST::Linker::REVISION_TOKEN)
|
156
157
|
end
|
157
158
|
end
|
@@ -1,15 +1,17 @@
|
|
1
|
-
|
1
|
+
require 'main'
|
2
2
|
|
3
|
-
class
|
3
|
+
class NoninvasiveTest < BaseTest
|
4
4
|
def test_no_clutter
|
5
5
|
[Method, UnboundMethod, Proc].each do |klass|
|
6
6
|
assert !klass.instance_methods.include?(:to_ast)
|
7
7
|
assert !klass.instance_methods.include?(:to_ruby)
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
assert !respond_to?(:ast_eval)
|
11
|
+
assert !private_methods.include?(:ast_eval)
|
11
12
|
assert !Kernel.respond_to?(:ast_eval)
|
12
13
|
assert !respond_to?(:ast_load)
|
14
|
+
assert !private_methods.include?(:ast_load)
|
13
15
|
assert !Kernel.respond_to?(:ast_load)
|
14
16
|
end
|
15
17
|
|
@@ -30,14 +32,14 @@ class AAA_NoninvasiveTest < BaseTest
|
|
30
32
|
end
|
31
33
|
|
32
34
|
def test_lambda
|
33
|
-
a = lambda { |x, y| x
|
35
|
+
a = lambda { |x, y| x**y }
|
34
36
|
|
35
37
|
assert_equal binop_block(:lambda, :**), LiveAST.ast(a)
|
36
38
|
end
|
37
39
|
|
38
40
|
def test_ast_eval
|
39
41
|
code = %{ lambda { |x, y| x / y } }
|
40
|
-
|
42
|
+
|
41
43
|
expected = binop_block(:lambda, :/)
|
42
44
|
result = LiveAST.ast(LiveAST.eval(code, binding))
|
43
45
|
assert_equal expected, result
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'main'
|
2
|
+
|
3
|
+
class ReloadTest < BaseTest
|
4
|
+
include FileUtils
|
5
|
+
|
6
|
+
def test_reloading
|
7
|
+
raw_reload
|
8
|
+
end
|
9
|
+
|
10
|
+
def raw_reload
|
11
|
+
code_1 = %{
|
12
|
+
class ReloadTest::A
|
13
|
+
def f
|
14
|
+
"first A#f"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
}
|
18
|
+
|
19
|
+
code_2 = %{
|
20
|
+
class ReloadTest::A
|
21
|
+
def f
|
22
|
+
"second A#f"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
}
|
26
|
+
|
27
|
+
temp_file code_1 do |file|
|
28
|
+
load file
|
29
|
+
|
30
|
+
LiveAST.ast(A.instance_method(:f))
|
31
|
+
|
32
|
+
write_file file, code_2
|
33
|
+
load file
|
34
|
+
|
35
|
+
# forced a raw-reload inconsistency -- verify bogus
|
36
|
+
|
37
|
+
assert_equal no_arg_def(:f, "first A#f"),
|
38
|
+
LiveAST.ast(A.instance_method(:f))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/test/define_method_test.rb
CHANGED
@@ -4,9 +4,9 @@ class DefineMethodTest < RegularTest
|
|
4
4
|
WITH_BLOCKS = lambda do
|
5
5
|
class A
|
6
6
|
{
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
7
|
+
f: :+,
|
8
|
+
g: :*,
|
9
|
+
h: :-,
|
10
10
|
}.each_pair do |name, op|
|
11
11
|
case op
|
12
12
|
when :+
|
@@ -42,10 +42,10 @@ class DefineMethodTest < RegularTest
|
|
42
42
|
WITH_PROCS = lambda do
|
43
43
|
class B
|
44
44
|
op = lambda { |x, y| x / y }
|
45
|
-
|
45
|
+
|
46
46
|
no_arg = proc { "B#f" }
|
47
47
|
|
48
|
-
define_method :g, &no_arg
|
48
|
+
define_method :g, &no_arg; define_method :f, &op
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
data/test/encoding_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative 'main'
|
2
2
|
|
3
3
|
class AllEncodingTest < RegularTest
|
4
|
-
ENC_TESTS = Hash[*%w
|
4
|
+
ENC_TESTS = Hash[*%w(
|
5
5
|
default US-ASCII
|
6
6
|
usascii US-ASCII
|
7
7
|
utf8 UTF-8
|
@@ -17,7 +17,7 @@ class AllEncodingTest < RegularTest
|
|
17
17
|
eucjp EUC-JP
|
18
18
|
koi8 KOI8-R
|
19
19
|
koi8_shebang KOI8-R
|
20
|
-
]
|
20
|
+
)]
|
21
21
|
|
22
22
|
if RUBY_VERSION < '2.0.0'
|
23
23
|
ENC_TESTS['default'] = 'US-ASCII'
|
@@ -35,9 +35,9 @@ class AllEncodingTest < RegularTest
|
|
35
35
|
|
36
36
|
ast = EncodingTest.instance_method("#{abbr}_string").to_ast
|
37
37
|
assert_equal "UTF-8", no_arg_def_return(ast).encoding.to_s
|
38
|
-
|
38
|
+
|
39
39
|
LiveAST.load "./test/encoding_test/#{abbr}.rb"
|
40
|
-
|
40
|
+
|
41
41
|
ast = EncodingTest.instance_method("#{abbr}_string").to_ast
|
42
42
|
assert_equal "UTF-8", no_arg_def_return(ast).encoding.to_s
|
43
43
|
end
|
@@ -51,7 +51,7 @@ class AllEncodingTest < RegularTest
|
|
51
51
|
LiveAST.load "./test/encoding_test/bad.rb"
|
52
52
|
end
|
53
53
|
# inconsistent punctuation from Ruby
|
54
|
-
re =
|
54
|
+
re = /\Aunknown encoding name\s*[-:]\s*feynman-diagram\Z/
|
55
55
|
assert_match re, orig.message
|
56
56
|
assert_match re, live.message
|
57
57
|
end
|
data/test/error_test.rb
CHANGED
@@ -2,9 +2,9 @@ require_relative 'main'
|
|
2
2
|
|
3
3
|
class ErrorTest < RegularTest
|
4
4
|
def test_multiple_lambda_same_line
|
5
|
-
a = lambda {
|
5
|
+
a = lambda {}; b = lambda {}
|
6
6
|
ignore(b)
|
7
|
-
|
7
|
+
|
8
8
|
assert_raises LiveAST::MultipleDefinitionsOnSameLineError do
|
9
9
|
a.to_ast
|
10
10
|
end
|
@@ -12,7 +12,7 @@ class ErrorTest < RegularTest
|
|
12
12
|
|
13
13
|
DEFINE_A = lambda do
|
14
14
|
class A
|
15
|
-
def f
|
15
|
+
def f; end; def g; end
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -72,7 +72,7 @@ class ErrorTest < RegularTest
|
|
72
72
|
ast_eval("lambda { }", binding)
|
73
73
|
eval("lambda { }")
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
def test_reload_with_raw_eval_2
|
77
77
|
c = ast_eval %{
|
78
78
|
Class.new do
|
@@ -89,12 +89,12 @@ class ErrorTest < RegularTest
|
|
89
89
|
}
|
90
90
|
nil
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
assert_raises LiveAST::RawEvalError do
|
94
94
|
c.instance_method(:f).to_ast
|
95
95
|
end
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
def test_bad_binding
|
99
99
|
orig = assert_raises TypeError do
|
100
100
|
eval("", "bogus")
|
data/test/eval_test.rb
CHANGED
@@ -98,10 +98,10 @@ class EvalTest < RegularTest
|
|
98
98
|
assert_equal "#{self.class}::C", C.name
|
99
99
|
assert_equal C, C.instance_method(:g).owner
|
100
100
|
|
101
|
-
assert_equal binop_define_method(:g, :+),
|
101
|
+
assert_equal binop_define_method(:g, :+),
|
102
102
|
C.instance_method(:g).to_ast
|
103
103
|
|
104
|
-
assert_equal binop_define_method(:g, :+),
|
104
|
+
assert_equal binop_define_method(:g, :+),
|
105
105
|
C.new.method(:g).to_ast
|
106
106
|
end
|
107
107
|
|
@@ -164,7 +164,7 @@ class EvalTest < RegularTest
|
|
164
164
|
assert_equal binop_define_method(:g, :/),
|
165
165
|
klass.new.method(:g).to_ast
|
166
166
|
end
|
167
|
-
|
167
|
+
|
168
168
|
DEFINE_GH = lambda do
|
169
169
|
ast_eval %{
|
170
170
|
class G
|
@@ -172,7 +172,7 @@ class EvalTest < RegularTest
|
|
172
172
|
"G#f"
|
173
173
|
end
|
174
174
|
end
|
175
|
-
|
175
|
+
|
176
176
|
class H
|
177
177
|
def g
|
178
178
|
"H#g"
|
@@ -180,7 +180,7 @@ class EvalTest < RegularTest
|
|
180
180
|
end
|
181
181
|
}, binding
|
182
182
|
end
|
183
|
-
|
183
|
+
|
184
184
|
def test_reuse_string
|
185
185
|
DEFINE_GH.call
|
186
186
|
assert_equal "#{self.class}::G", G.name
|
@@ -191,7 +191,7 @@ class EvalTest < RegularTest
|
|
191
191
|
|
192
192
|
assert_equal no_arg_def(:f, "G#f"),
|
193
193
|
G.new.method(:f).to_ast
|
194
|
-
|
194
|
+
|
195
195
|
assert_equal no_arg_def(:g, "H#g"),
|
196
196
|
H.instance_method(:g).to_ast
|
197
197
|
|
@@ -258,7 +258,7 @@ class EvalTest < RegularTest
|
|
258
258
|
# sanity check
|
259
259
|
assert_not_equal binop_block(:lambda, :+), a.to_ast
|
260
260
|
end
|
261
|
-
|
261
|
+
|
262
262
|
# from rubyspec
|
263
263
|
def test_to_str_on_file
|
264
264
|
file = MiniTest::Mock.new
|