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 CHANGED
@@ -1,5 +1,9 @@
1
1
 
2
- = LiveAST ChangeLog
2
+ = live_ast Changes
3
+
4
+ == Version 0.6.1
5
+
6
+ * enable usage inside irb
3
7
 
4
8
  == Version 0.6.0
5
9
 
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(project_name)
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
- @project_name = project_name
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
- attribute :name do
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(name)
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/#{name}/version.rb")
284
+ if File.file?(version_file = "./lib/#{gem_name}/version.rb")
287
285
  require version_file
288
- elsif File.file?("./lib/#{name}.rb")
289
- require name
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/#{name}-#{version}.#{ext}"
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
- "#{name}: #{summary}"
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 { |param|
434
- value = send(param) and (
435
- g.send("#{param}=", value)
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/#{name}"
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", "#{name}-" + version.to_s
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
@@ -5,6 +5,7 @@ require 'live_ast/evaler'
5
5
  require 'live_ast/linker'
6
6
  require 'live_ast/loader'
7
7
  require 'live_ast/error'
8
+ require 'live_ast/irb_spy' if defined?(IRB) && defined?(Readline::HISTORY)
8
9
 
9
10
  module LiveAST
10
11
  NATIVE_EVAL = Kernel.method(:eval) #:nodoc:
@@ -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
@@ -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
- # File was loaded by 'require'.
86
- # Play catch-up: assume it has not changed in the meantime.
87
- #
88
- _, cache = new_cache(Reader.read(file), file, 1, true)
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
@@ -1,3 +1,3 @@
1
1
  module LiveAST
2
- VERSION = "0.6.0"
2
+ VERSION = "0.6.1"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  require_relative 'main'
2
2
 
3
3
  class DefineMethodTest < RegularTest
4
- DEFINE = lambda do
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 test_define_method
30
- DEFINE.call
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.0
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-02-26 00:00:00 -05:00
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.2
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.