live_ast 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.rdoc +5 -1
- data/MANIFEST +2 -0
- data/devel/levitate.rb +53 -23
- data/lib/live_ast/base.rb +1 -0
- data/lib/live_ast/irb_spy.rb +74 -0
- data/lib/live_ast/linker.rb +13 -5
- data/lib/live_ast/version.rb +1 -1
- data/test/define_method_test.rb +29 -3
- data/test/irb_test.rb +38 -0
- metadata +7 -3
data/CHANGES.rdoc
CHANGED
data/MANIFEST
CHANGED
@@ -9,6 +9,7 @@ lib/live_ast/ast_load.rb
|
|
9
9
|
lib/live_ast/base.rb
|
10
10
|
lib/live_ast/error.rb
|
11
11
|
lib/live_ast/evaler.rb
|
12
|
+
lib/live_ast/irb_spy.rb
|
12
13
|
lib/live_ast/linker.rb
|
13
14
|
lib/live_ast/loader.rb
|
14
15
|
lib/live_ast/reader.rb
|
@@ -41,6 +42,7 @@ test/encoding_test/utf8bom_only.rb
|
|
41
42
|
test/error_test.rb
|
42
43
|
test/eval_test.rb
|
43
44
|
test/flush_cache_test.rb
|
45
|
+
test/irb_test.rb
|
44
46
|
test/lambda_test.rb
|
45
47
|
test/load_path_test.rb
|
46
48
|
test/load_test.rb
|
data/devel/levitate.rb
CHANGED
@@ -249,12 +249,12 @@ class Levitate
|
|
249
249
|
include AttrLazy
|
250
250
|
include Util
|
251
251
|
|
252
|
-
def initialize(
|
252
|
+
def initialize(gem_name)
|
253
253
|
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
254
254
|
|
255
255
|
require 'rubygems/package_task'
|
256
256
|
|
257
|
-
@
|
257
|
+
@gem_name = gem_name
|
258
258
|
|
259
259
|
yield self
|
260
260
|
|
@@ -269,24 +269,22 @@ class Levitate
|
|
269
269
|
alias_method :attribute, :attr_lazy_accessor
|
270
270
|
end
|
271
271
|
|
272
|
-
|
273
|
-
@project_name
|
274
|
-
end
|
272
|
+
attr_reader :gem_name
|
275
273
|
|
276
274
|
attribute :version_constant_name do
|
277
275
|
"VERSION"
|
278
276
|
end
|
279
277
|
|
280
278
|
attribute :camel_name do
|
281
|
-
to_camel_case(
|
279
|
+
to_camel_case(gem_name)
|
282
280
|
end
|
283
281
|
|
284
282
|
attribute :version do
|
285
283
|
catch :bail do
|
286
|
-
if File.file?(version_file = "./lib/#{
|
284
|
+
if File.file?(version_file = "./lib/#{gem_name}/version.rb")
|
287
285
|
require version_file
|
288
|
-
elsif File.file?("./lib/#{
|
289
|
-
require
|
286
|
+
elsif File.file?("./lib/#{gem_name}.rb")
|
287
|
+
require gem_name
|
290
288
|
else
|
291
289
|
throw :bail
|
292
290
|
end
|
@@ -337,7 +335,7 @@ class Levitate
|
|
337
335
|
|
338
336
|
[:gem, :tgz].each { |ext|
|
339
337
|
attribute ext do
|
340
|
-
"pkg/#{
|
338
|
+
"pkg/#{gem_name}-#{version}.#{ext}"
|
341
339
|
end
|
342
340
|
}
|
343
341
|
|
@@ -383,7 +381,7 @@ class Levitate
|
|
383
381
|
end
|
384
382
|
|
385
383
|
attribute :rdoc_title do
|
386
|
-
"#{
|
384
|
+
"#{gem_name}: #{summary}"
|
387
385
|
end
|
388
386
|
|
389
387
|
attribute :require_paths do
|
@@ -418,9 +416,7 @@ class Levitate
|
|
418
416
|
|
419
417
|
attribute :gemspec do
|
420
418
|
Gem::Specification.new do |g|
|
421
|
-
g.has_rdoc = true
|
422
419
|
%w[
|
423
|
-
name
|
424
420
|
authors
|
425
421
|
email
|
426
422
|
summary
|
@@ -430,18 +426,15 @@ class Levitate
|
|
430
426
|
rdoc_options
|
431
427
|
extra_rdoc_files
|
432
428
|
require_paths
|
433
|
-
].each
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
429
|
+
].each do |param|
|
430
|
+
t = send(param) and g.send("#{param}=", t)
|
431
|
+
end
|
432
|
+
g.name = gem_name
|
433
|
+
g.has_rdoc = true
|
439
434
|
g.homepage = url if url
|
440
|
-
|
441
435
|
dependencies.each { |dep|
|
442
436
|
g.add_dependency(*dep)
|
443
437
|
}
|
444
|
-
|
445
438
|
development_dependencies.each { |dep|
|
446
439
|
g.add_development_dependency(*dep)
|
447
440
|
}
|
@@ -495,7 +488,7 @@ class Levitate
|
|
495
488
|
}
|
496
489
|
|
497
490
|
attribute :url do
|
498
|
-
"http://#{github_user}.github.com/#{
|
491
|
+
"http://#{github_user}.github.com/#{gem_name}"
|
499
492
|
end
|
500
493
|
|
501
494
|
attribute :github_user do
|
@@ -737,6 +730,43 @@ class Levitate
|
|
737
730
|
end
|
738
731
|
end
|
739
732
|
|
733
|
+
def define_update_levitate
|
734
|
+
url = ENV["LEVITATE"] ||
|
735
|
+
"https://github.com/quix/levitate/raw/master/levitate.rb"
|
736
|
+
task :update_levitate do
|
737
|
+
if system "curl", "-s", "-o", __FILE__, url
|
738
|
+
if `git diff #{__FILE__}` == ""
|
739
|
+
puts "Already up-to-date."
|
740
|
+
else
|
741
|
+
git "commit", __FILE__, "-m", "updated levitate"
|
742
|
+
puts "Updated levitate."
|
743
|
+
end
|
744
|
+
else
|
745
|
+
raise "levitate download failed"
|
746
|
+
end
|
747
|
+
end
|
748
|
+
end
|
749
|
+
|
750
|
+
def define_changes
|
751
|
+
task :changes do
|
752
|
+
header = "\n\n== Version ____\n\n"
|
753
|
+
|
754
|
+
bullets = `git log --format=%s #{last_release}..HEAD`.lines.map { |line|
|
755
|
+
"* #{line}"
|
756
|
+
}.join.chomp
|
757
|
+
|
758
|
+
write_file(history_file) do
|
759
|
+
File.read(history_file).sub(/(?<=#{gem_name} Changes)/) {
|
760
|
+
header + bullets
|
761
|
+
}
|
762
|
+
end
|
763
|
+
end
|
764
|
+
end
|
765
|
+
|
766
|
+
def last_release
|
767
|
+
`git tag`.lines.select { |t| t.index(gem_name) == 0 }.last.chomp
|
768
|
+
end
|
769
|
+
|
740
770
|
def git(*args)
|
741
771
|
sh "git", *args
|
742
772
|
end
|
@@ -751,7 +781,7 @@ class Levitate
|
|
751
781
|
task :prerelease => [:clean, :check_directory, :ping, history_file]
|
752
782
|
|
753
783
|
task :finish_release do
|
754
|
-
git "tag", "#{
|
784
|
+
git "tag", "#{gem_name}-" + version.to_s
|
755
785
|
git "push", "--tags", "origin", "master"
|
756
786
|
sh "gem", "push", gem
|
757
787
|
end
|
data/lib/live_ast/base.rb
CHANGED
@@ -0,0 +1,74 @@
|
|
1
|
+
#
|
2
|
+
# Some hacks to get LiveAST working with IRB.
|
3
|
+
#
|
4
|
+
# (1) Because Readline::HISTORY is empty at startup, we count the
|
5
|
+
# lines of the history file in order to determine where the new
|
6
|
+
# history begins for this IRB session.
|
7
|
+
#
|
8
|
+
# (2) IRB::ReadlineInputMethod#gets discards empty input lines,
|
9
|
+
# causing Readline::HISTORY to be out of sync with the current line
|
10
|
+
# number, thereby fouling up source_location. We redefine #gets to
|
11
|
+
# keep empty lines.
|
12
|
+
#
|
13
|
+
|
14
|
+
module LiveAST
|
15
|
+
module IRBSpy
|
16
|
+
class << self
|
17
|
+
def code_at(line)
|
18
|
+
history = Readline::HISTORY.to_a
|
19
|
+
start = @history_start + line - 1
|
20
|
+
grow = 0
|
21
|
+
begin
|
22
|
+
code = history[start..(start + grow)].join("\n")
|
23
|
+
LiveAST.parser.new.parse(code) or raise "#{LiveAST.parser} error"
|
24
|
+
rescue
|
25
|
+
grow += 1
|
26
|
+
retry if start + grow < history.size
|
27
|
+
raise
|
28
|
+
end
|
29
|
+
code
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Find the starting point of history for this IRB session.
|
34
|
+
#
|
35
|
+
def find_history_start
|
36
|
+
if IRB.conf[:HISTORY_FILE]
|
37
|
+
# cut & paste from irb/ext/save-history.rb
|
38
|
+
if history_file = IRB.conf[:HISTORY_FILE]
|
39
|
+
history_file = File.expand_path(history_file)
|
40
|
+
end
|
41
|
+
history_file = IRB.rc_file("_history") unless history_file
|
42
|
+
|
43
|
+
if File.exist?(history_file)
|
44
|
+
File.readlines(history_file).size
|
45
|
+
else
|
46
|
+
0
|
47
|
+
end
|
48
|
+
else
|
49
|
+
0
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
@history_start = find_history_start
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# From irb/input-method.rb.
|
60
|
+
#
|
61
|
+
class IRB::ReadlineInputMethod
|
62
|
+
alias_method :live_ast_original_gets, :gets
|
63
|
+
def gets
|
64
|
+
Readline.input = @stdin
|
65
|
+
Readline.output = @stdout
|
66
|
+
if l = readline(@prompt, false)
|
67
|
+
HISTORY.push(l) #if !l.empty? # <---- only this line modified
|
68
|
+
@line[@line_no += 1] = l + "\n"
|
69
|
+
else
|
70
|
+
@eof = true
|
71
|
+
l
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/live_ast/linker.rb
CHANGED
@@ -81,11 +81,19 @@ module LiveAST
|
|
81
81
|
def fetch_from_cache(file, line)
|
82
82
|
cache = @caches[file]
|
83
83
|
if !cache and !file.index(REVISION_TOKEN)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
84
|
+
_, cache =
|
85
|
+
if defined?(IRB) and file == "(irb)"
|
86
|
+
unless defined? Readline::HISTORY
|
87
|
+
raise "LiveAST requires readline enabled in irb."
|
88
|
+
end
|
89
|
+
new_cache(IRBSpy.code_at(line), file, line, false)
|
90
|
+
else
|
91
|
+
#
|
92
|
+
# File was loaded by 'require'.
|
93
|
+
# Play catch-up: assume it has not changed in the meantime.
|
94
|
+
#
|
95
|
+
new_cache(Reader.read(file), file, 1, true)
|
96
|
+
end
|
89
97
|
end
|
90
98
|
cache.fetch_ast(line) if cache
|
91
99
|
end
|
data/lib/live_ast/version.rb
CHANGED
data/test/define_method_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative 'main'
|
2
2
|
|
3
3
|
class DefineMethodTest < RegularTest
|
4
|
-
|
4
|
+
WITH_BLOCKS = lambda do
|
5
5
|
class A
|
6
6
|
{
|
7
7
|
:f => :+,
|
@@ -26,8 +26,8 @@ class DefineMethodTest < RegularTest
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
30
|
-
|
29
|
+
def test_with_block
|
30
|
+
WITH_BLOCKS.call
|
31
31
|
|
32
32
|
assert_equal binop_define_method_with_var(:name, :+),
|
33
33
|
A.instance_method(:f).to_ast
|
@@ -38,4 +38,30 @@ class DefineMethodTest < RegularTest
|
|
38
38
|
assert_equal binop_define_method_with_var(:name, :-),
|
39
39
|
A.instance_method(:h).to_ast
|
40
40
|
end
|
41
|
+
|
42
|
+
WITH_PROCS = lambda do
|
43
|
+
class B
|
44
|
+
op = lambda { |x, y| x / y }
|
45
|
+
|
46
|
+
no_arg = proc { "B#f" }
|
47
|
+
|
48
|
+
define_method :g, &no_arg ; define_method :f, &op
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_via_block
|
53
|
+
WITH_PROCS.call
|
54
|
+
|
55
|
+
assert_equal binop_block(:lambda, :/),
|
56
|
+
B.instance_method(:f).to_ast
|
57
|
+
|
58
|
+
assert_equal binop_block(:lambda, :/),
|
59
|
+
B.new.method(:f).to_ast
|
60
|
+
|
61
|
+
assert_equal no_arg_block(:proc, "B#f"),
|
62
|
+
B.instance_method(:g).to_ast
|
63
|
+
|
64
|
+
assert_equal no_arg_block(:proc, "B#f"),
|
65
|
+
B.new.method(:g).to_ast
|
66
|
+
end
|
41
67
|
end
|
data/test/irb_test.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative 'main'
|
2
|
+
|
3
|
+
class IRBTest < RegularTest
|
4
|
+
def with_module(parent, child)
|
5
|
+
parent.const_set child, Module.new
|
6
|
+
begin
|
7
|
+
yield
|
8
|
+
ensure
|
9
|
+
parent.send :remove_const, child
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_readline_not_present
|
14
|
+
with_module(Object, :IRB) do
|
15
|
+
error = assert_raises RuntimeError do
|
16
|
+
LiveAST::Linker.fetch_from_cache("(irb)", 33)
|
17
|
+
end
|
18
|
+
assert_match(/readline enabled/, error.message)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_irb
|
23
|
+
with_module(Object, :IRB) do
|
24
|
+
with_module(Object, :Readline) do
|
25
|
+
with_module(Readline, :HISTORY) do
|
26
|
+
with_module(LiveAST, :IRBSpy) do
|
27
|
+
LiveAST::IRBSpy.class_eval do
|
28
|
+
def self.code_at(line)
|
29
|
+
"def f ; end"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
LiveAST::Linker.fetch_from_cache("(irb)", 1)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: live_ast
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.6.
|
5
|
+
version: 0.6.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- James M. Lawrence
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-03-01 00:00:00 -05:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -44,6 +44,7 @@ files:
|
|
44
44
|
- lib/live_ast/base.rb
|
45
45
|
- lib/live_ast/error.rb
|
46
46
|
- lib/live_ast/evaler.rb
|
47
|
+
- lib/live_ast/irb_spy.rb
|
47
48
|
- lib/live_ast/linker.rb
|
48
49
|
- lib/live_ast/loader.rb
|
49
50
|
- lib/live_ast/reader.rb
|
@@ -76,6 +77,7 @@ files:
|
|
76
77
|
- test/error_test.rb
|
77
78
|
- test/eval_test.rb
|
78
79
|
- test/flush_cache_test.rb
|
80
|
+
- test/irb_test.rb
|
79
81
|
- test/lambda_test.rb
|
80
82
|
- test/load_path_test.rb
|
81
83
|
- test/load_test.rb
|
@@ -109,6 +111,8 @@ rdoc_options:
|
|
109
111
|
- --exclude
|
110
112
|
- lib/live_ast/evaler.rb
|
111
113
|
- --exclude
|
114
|
+
- lib/live_ast/irb_spy.rb
|
115
|
+
- --exclude
|
112
116
|
- lib/live_ast/linker.rb
|
113
117
|
- --exclude
|
114
118
|
- lib/live_ast/loader.rb
|
@@ -138,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
142
|
requirements: []
|
139
143
|
|
140
144
|
rubyforge_project:
|
141
|
-
rubygems_version: 1.5.
|
145
|
+
rubygems_version: 1.5.3
|
142
146
|
signing_key:
|
143
147
|
specification_version: 3
|
144
148
|
summary: A pure Ruby library for obtaining live abstract syntax trees of methods and procs.
|