live_ast 0.7.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,11 @@
1
1
 
2
2
  = live_ast Changes
3
3
 
4
+ == Version 0.7.3
5
+
6
+ * live_ast/full now available for jruby (via boc gem)
7
+ * fix instance_eval with BasicObject instance
8
+
4
9
  == Version 0.7.2
5
10
 
6
11
  * fix old find&replace accident with boc; rubyspec test now enabled by default
@@ -123,9 +123,9 @@ parser plug-in, if one is found.
123
123
 
124
124
  An essential feature of <code>require 'live_ast'</code> is that it is
125
125
  implemented in pure ruby. However since pure ruby is not powerful
126
- enough to replace +eval+, one must use +ast_eval+ instead of +eval+
127
- for AST-accessible objects. +ast_eval+ has the same semantics as
128
- +eval+ except that the binding argument is required.
126
+ enough to replace +eval+, in this case +ast_eval+ must be used instead
127
+ of +eval+ for AST-accessible objects. +ast_eval+ has the same
128
+ semantics as +eval+ except that the binding argument is required.
129
129
 
130
130
  require 'live_ast'
131
131
 
@@ -136,8 +136,8 @@ for AST-accessible objects. +ast_eval+ has the same semantics as
136
136
  == Full Integration
137
137
 
138
138
  In order for LiveAST to be transparent to the user, +eval+ must be
139
- replaced. This requires the +boc+ gem (http://quix.github.com/boc)
140
- which at present only targets MRI 1.9.2 (other platforms are planned).
139
+ replaced. This is accomplished with the help of the +boc+ gem
140
+ (http://quix.github.com/boc).
141
141
 
142
142
  To replace +eval+,
143
143
 
@@ -150,8 +150,8 @@ and then
150
150
  The new AST-electrified +eval+, +instance_eval+, +module_eval+,
151
151
  +class_eval+, and <code>Binding#eval</code> all pass RubySpec
152
152
  (http://rubyspec.org) with the minor exception of backtraces sometimes
153
- not matching that of the original +eval+. See the "Backtraces" section
154
- below for details.
153
+ not matching that of the original +eval+ (see the "Backtraces" section
154
+ below for details).
155
155
 
156
156
  require 'live_ast/full'
157
157
 
@@ -160,7 +160,7 @@ below for details.
160
160
  # => s(:iter, s(:call, nil, :lambda, s(:arglist)), nil, s(:str, "dynamic1"))
161
161
 
162
162
  Since LiveAST itself is pure ruby, any new platforms supported by
163
- +boc+ will automatically work with <code>live_ast/full</code>.
163
+ +boc+ should work with <code>live_ast/full</code>.
164
164
 
165
165
  == Limitations
166
166
 
data/Rakefile CHANGED
@@ -7,6 +7,7 @@ Levitate.new "live_ast" do |s|
7
7
  s.camel_name = "LiveAST"
8
8
  s.required_ruby_version = ">= 1.9.2"
9
9
  s.dependencies << ["live_ast_ruby_parser", ">= 0.6.0"]
10
+ s.rdoc_title = "LiveAST: Live Abstract Syntax Trees"
10
11
  s.rdoc_files = %w[
11
12
  lib/live_ast/ast_eval.rb
12
13
  lib/live_ast/base.rb
@@ -1,231 +1,33 @@
1
1
 
2
2
  class Levitate
3
- class Installer
4
- def initialize
5
- require 'fileutils'
6
- require 'rbconfig'
7
- require 'find'
8
-
9
- rb_root = RbConfig::CONFIG["sitelibdir"]
10
- @spec = []
11
-
12
- Find.find "lib" do |source|
13
- next if source == "lib"
14
- next unless File.directory?(source) || File.extname(source) == ".rb"
15
- dest = File.join(rb_root, source.sub(%r!\Alib/!, ""))
16
- @spec << { :source => source, :dest => dest }
17
- end
18
- end
19
-
20
- def install
21
- @spec.each do |entry|
22
- source, dest = entry.values_at(:source, :dest)
23
- if File.directory?(source)
24
- unless File.directory?(dest)
25
- puts "mkdir #{dest}"
26
- FileUtils.mkdir(dest)
27
- end
28
- else
29
- puts "install #{source} --> #{dest}"
30
- FileUtils.install(source, dest)
31
- end
32
- end
33
- end
34
-
35
- def uninstall
36
- @spec.reverse.each do |entry|
37
- source, dest = entry.values_at(:source, :dest)
38
- if File.directory?(source)
39
- if File.directory?(dest)
40
- puts "rmdir #{dest}"
41
- FileUtils.rmdir(dest)
42
- end
43
- else
44
- if File.file?(dest)
45
- puts "rm #{dest}"
46
- FileUtils.rm(dest)
47
- end
48
- end
49
- end
50
- end
51
- end
52
-
53
- module AttrLazy
54
- def attr_lazy(name, &block)
55
- AttrLazy.define_reader(class << self ; self ; end, name, &block)
56
- end
57
-
58
- def attr_lazy_accessor(name, &block)
59
- attr_lazy(name, &block)
60
- AttrLazy.define_writer(class << self ; self ; end, name, &block)
61
- end
62
-
63
- class << self
64
- def included(mod)
65
- (class << mod ; self ; end).class_eval do
66
- def attr_lazy(name, &block)
67
- AttrLazy.define_reader(self, name, &block)
68
- end
69
-
70
- def attr_lazy_accessor(name, &block)
71
- attr_lazy(name, &block)
72
- AttrLazy.define_writer(self, name, &block)
73
- end
74
- end
75
- end
3
+ def initialize(gem_name)
4
+ @gem_name = gem_name
76
5
 
77
- def define_evaluated_reader(instance, name, value)
78
- (class << instance ; self ; end).class_eval do
79
- remove_method name rescue nil
80
- define_method name do
81
- value
82
- end
83
- end
84
- end
6
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
85
7
 
86
- def define_reader(klass, name, &block)
87
- klass.class_eval do
88
- remove_method name rescue nil
89
- define_method name do
90
- value = instance_eval(&block)
91
- AttrLazy.define_evaluated_reader(self, name, value)
92
- value
93
- end
94
- end
95
- end
8
+ yield self
96
9
 
97
- def define_writer(klass, name, &block)
98
- klass.class_eval do
99
- writer = "#{name}="
100
- remove_method writer rescue nil
101
- define_method writer do |value|
102
- AttrLazy.define_evaluated_reader(self, name, value)
103
- value
104
- end
105
- end
10
+ self.class.instance_methods(false).each do |name|
11
+ if name.to_s =~ %r!\Adefine_!
12
+ send(name)
106
13
  end
107
14
  end
108
15
  end
109
16
 
110
- module Ruby
111
- module_function
112
-
113
- def executable
114
- require 'rbconfig'
115
-
116
- name = File.join(
117
- RbConfig::CONFIG["bindir"],
118
- RbConfig::CONFIG["RUBY_INSTALL_NAME"]
119
- )
17
+ attr_reader :gem_name
120
18
 
121
- if RbConfig::CONFIG["host"] =~ %r!(mswin|cygwin|mingw)! and
122
- File.basename(name) !~ %r!\.(exe|com|bat|cmd)\Z!i
123
- name + RbConfig::CONFIG["EXEEXT"]
19
+ def self.attribute(name, &block)
20
+ var = :"@#{name}"
21
+ define_method name do
22
+ if instance_variable_defined?(var)
23
+ instance_variable_get(var)
124
24
  else
125
- name
126
- end
127
- end
128
-
129
- def run(*args)
130
- cmd = [executable, *args]
131
- unless system(*cmd)
132
- cmd_str = cmd.map { |t| "'#{t}'" }.join(", ")
133
- raise "system(#{cmd_str}) failed with status #{$?.exitstatus}"
134
- end
135
- end
136
-
137
- def run_code_and_capture(code)
138
- IO.popen(%{"#{executable}"}, "r+") { |pipe|
139
- pipe.print(code)
140
- pipe.flush
141
- pipe.close_write
142
- pipe.read
143
- }
144
- end
145
-
146
- def run_file_and_capture(file)
147
- unless File.file? file
148
- raise "file does not exist: `#{file}'"
149
- end
150
- IO.popen(%{"#{executable}" "#{file}"}, "r") { |pipe|
151
- pipe.read
152
- }
153
- end
154
-
155
- def with_warnings(value = true)
156
- previous = $VERBOSE
157
- $VERBOSE = value
158
- begin
159
- yield
160
- ensure
161
- $VERBOSE = previous
25
+ instance_variable_set(var, instance_eval(&block))
162
26
  end
163
27
  end
164
-
165
- def no_warnings(&block)
166
- with_warnings(nil, &block)
167
- end
28
+ attr_writer name
168
29
  end
169
30
 
170
- module Util
171
- module_function
172
-
173
- def run_ruby_on_each(*files)
174
- files.each { |file|
175
- Ruby.run("-w", file)
176
- }
177
- end
178
-
179
- def to_camel_case(str)
180
- str.split('_').map { |t| t.capitalize }.join
181
- end
182
-
183
- def write_file(file)
184
- contents = yield
185
- File.open(file, "wb") { |out|
186
- out.print(contents)
187
- }
188
- contents
189
- end
190
-
191
- def instance_exec2(obj, *args, &block)
192
- method_name = ["_", obj.object_id, "_", Thread.current.object_id].join
193
- (class << obj ; self ; end).class_eval do
194
- define_method method_name, &block
195
- begin
196
- obj.send(method_name, *args)
197
- ensure
198
- remove_method method_name
199
- end
200
- end
201
- end
202
- end
203
-
204
- include AttrLazy
205
- include Util
206
-
207
- def initialize(gem_name)
208
- $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
209
-
210
- require 'rubygems/package_task'
211
-
212
- @gem_name = gem_name
213
-
214
- yield self
215
-
216
- self.class.instance_methods(false).select { |t|
217
- t.to_s =~ %r!\Adefine_!
218
- }.sort.each { |method_name|
219
- send(method_name)
220
- }
221
- end
222
-
223
- class << self
224
- alias_method :attribute, :attr_lazy_accessor
225
- end
226
-
227
- attr_reader :gem_name
228
-
229
31
  attribute :version_constant_name do
230
32
  "VERSION"
231
33
  end
@@ -288,16 +90,10 @@ class Levitate
288
90
  "spec.html"
289
91
  end
290
92
 
291
- attr_lazy :spec_output do
93
+ attribute :spec_output do
292
94
  "#{spec_output_dir}/#{spec_output_file}"
293
95
  end
294
96
 
295
- [:gem, :tgz].each { |ext|
296
- attribute ext do
297
- "pkg/#{gem_name}-#{version}.#{ext}"
298
- end
299
- }
300
-
301
97
  attribute :rcov_options do
302
98
  # workaround for the default rspec task
303
99
  Dir["*"].select { |f| File.directory? f }.inject(Array.new) { |acc, dir|
@@ -309,14 +105,6 @@ class Levitate
309
105
  } + ["--text-report"]
310
106
  end
311
107
 
312
- attribute :readme_file do
313
- "README.rdoc"
314
- end
315
-
316
- attribute :manifest_file do
317
- "MANIFEST"
318
- end
319
-
320
108
  attribute :generated_files do
321
109
  []
322
110
  end
@@ -326,17 +114,9 @@ class Levitate
326
114
  end
327
115
 
328
116
  attribute :files do
329
- if File.file? manifest_file
330
- File.read(manifest_file).split("\n")
331
- elsif source_control?
117
+ if source_control?
332
118
  IO.popen("git ls-files") { |pipe| pipe.read.split "\n" }
333
- end.to_a + [manifest_file] + generated_files
334
- end
335
-
336
- def files_in_require_paths
337
- require_paths.inject([]) { |acc, dir|
338
- acc + Dir.glob("#{dir}/**/*.rb")
339
- }
119
+ end.to_a + generated_files
340
120
  end
341
121
 
342
122
  attribute :rdoc_files do
@@ -380,8 +160,6 @@ class Levitate
380
160
  attribute :gemspec do
381
161
  Gem::Specification.new do |g|
382
162
  %w[
383
- authors
384
- email
385
163
  summary
386
164
  version
387
165
  description
@@ -390,7 +168,6 @@ class Levitate
390
168
  extra_rdoc_files
391
169
  require_paths
392
170
  required_ruby_version
393
- extensions
394
171
  ].each do |param|
395
172
  t = send(param) and g.send("#{param}=", t)
396
173
  end
@@ -403,6 +180,8 @@ class Levitate
403
180
  development_dependencies.each { |dep|
404
181
  g.add_development_dependency(*dep)
405
182
  }
183
+ g.authors = developers.map { |d| d[0] }
184
+ g.email = developers.map { |d| d[1] }
406
185
  extra_gemspec.call(g)
407
186
  end
408
187
  end
@@ -467,14 +246,6 @@ class Levitate
467
246
  nil
468
247
  end
469
248
 
470
- def authors
471
- developers.map { |d| d[0] }
472
- end
473
-
474
- def email
475
- developers.map { |d| d[1] }
476
- end
477
-
478
249
  attribute :dependencies do
479
250
  []
480
251
  end
@@ -487,17 +258,18 @@ class Levitate
487
258
  []
488
259
  end
489
260
 
490
- attribute :extensions do
491
- ["ext/#{gem_name}/extconf.rb"].select { |f| File.file? f }
261
+ attribute :remote_levitate do
262
+ url = ENV["LEVITATE"] ||
263
+ "https://github.com/quix/levitate/raw/master/levitate.rb"
264
+ IO.popen("curl -s #{url}") { |f| f.read }
492
265
  end
493
-
494
- attribute :so_file do
495
- unless extensions.empty?
496
- require 'rbconfig'
497
- "lib/" + gem_name + "." + RbConfig::CONFIG["DLEXT"]
498
- end
266
+
267
+ attribute :local_levitate do
268
+ File.open(__FILE__, "rb") { |f| f.read }
499
269
  end
500
270
 
271
+ #### tasks
272
+
501
273
  def define_clean
502
274
  require 'rake/clean'
503
275
  task :clean do
@@ -507,10 +279,8 @@ class Levitate
507
279
 
508
280
  def define_package
509
281
  if source_control?
510
- task manifest_file do
511
- create_manifest
512
- end
513
- CLEAN.add manifest_file
282
+ require 'rubygems/package_task'
283
+
514
284
  task :package => :clean
515
285
  Gem::PackageTask.new(gemspec).define
516
286
  end
@@ -518,7 +288,7 @@ class Levitate
518
288
 
519
289
  def define_spec
520
290
  unless spec_files.empty?
521
- Ruby.no_warnings {
291
+ no_warnings {
522
292
  require 'spec/rake/spectask'
523
293
  }
524
294
 
@@ -550,7 +320,7 @@ class Levitate
550
320
 
551
321
  desc "run specs individually"
552
322
  task :spec_deps do
553
- run_ruby_on_each(*spec_files)
323
+ run_each_file(*spec_files)
554
324
  end
555
325
 
556
326
  task :prerelease => [:spec, :spec_deps]
@@ -606,7 +376,7 @@ class Levitate
606
376
 
607
377
  desc "run tests individually"
608
378
  task :test_deps do
609
- run_ruby_on_each(*test_files)
379
+ run_each_file(*test_files)
610
380
  end
611
381
 
612
382
  task :prerelease => [:test, :test_deps]
@@ -619,7 +389,7 @@ class Levitate
619
389
  def define_doc
620
390
  desc "run rdoc"
621
391
  task :doc => :clean_doc do
622
- Kernel.send :gem, 'rdoc' rescue nil
392
+ gem 'rdoc' rescue nil
623
393
  require 'rdoc/rdoc'
624
394
  args = (
625
395
  gemspec.rdoc_options +
@@ -648,6 +418,7 @@ class Levitate
648
418
  if source_control?
649
419
  desc "publish docs"
650
420
  task :publish => [:clean, :check_directory, :doc] do
421
+ current_branch = `git branch`[/^\* (\S+)$/, 1] or raise "??? branch"
651
422
  if rubyforge_info
652
423
  user, project = rubyforge_info
653
424
  Dir.chdir(doc_dir) do
@@ -666,6 +437,7 @@ class Levitate
666
437
  FileUtils.rmdir "doc"
667
438
  git "add", "."
668
439
  git "commit", "-m", "generated by rdoc"
440
+ git "checkout", current_branch
669
441
  git "push", "-f", "origin", "gh-pages"
670
442
  end
671
443
  end
@@ -681,22 +453,6 @@ class Levitate
681
453
  task :uninstall do
682
454
  Installer.new.uninstall
683
455
  end
684
-
685
- if so_file
686
- dest = File.join(RbConfig::CONFIG["sitearchdir"], File.basename(so_file))
687
-
688
- task :install => so_file do
689
- puts "install #{so_file} --> #{dest}"
690
- FileUtils.install(so_file, dest)
691
- end
692
-
693
- task :uninstall do
694
- if File.file?(dest)
695
- puts "rm #{dest}"
696
- FileUtils.rm(dest)
697
- end
698
- end
699
- end
700
456
  end
701
457
 
702
458
  def define_check_directory
@@ -710,7 +466,10 @@ class Levitate
710
466
  def define_ping
711
467
  task :ping do
712
468
  require 'rbconfig'
713
- %w[github.com].each { |server|
469
+ [
470
+ "github.com",
471
+ ("rubyforge.org" if rubyforge_info),
472
+ ].compact.each do |server|
714
473
  cmd = "ping " + (
715
474
  if RbConfig::CONFIG["host"] =~ %r!darwin!
716
475
  "-c2 #{server}"
@@ -721,23 +480,26 @@ class Levitate
721
480
  unless `#{cmd}` =~ %r!0% packet loss!
722
481
  raise "No ping for #{server}"
723
482
  end
724
- }
483
+ end
484
+ end
485
+ end
486
+
487
+ def define_check_levitate
488
+ task :check_levitate do
489
+ unless local_levitate == remote_levitate
490
+ raise "levitate is out of date"
491
+ end
725
492
  end
726
493
  end
727
494
 
728
495
  def define_update_levitate
729
- url = ENV["LEVITATE"] ||
730
- "https://github.com/quix/levitate/raw/master/levitate.rb"
731
496
  task :update_levitate do
732
- if system "curl", "-s", "-o", __FILE__, url
733
- if `git diff #{__FILE__}` == ""
734
- puts "Already up-to-date."
735
- else
736
- git "commit", __FILE__, "-m", "updated levitate"
737
- puts "Updated levitate."
738
- end
497
+ if local_levitate == remote_levitate
498
+ puts "Already up-to-date."
739
499
  else
740
- raise "levitate download failed"
500
+ File.open(__FILE__, "w") { |f| f.print(remote_levitate) }
501
+ git "commit", __FILE__, "-m", "update levitate"
502
+ puts "Updated levitate."
741
503
  end
742
504
  end
743
505
  end
@@ -762,30 +524,22 @@ class Levitate
762
524
  end
763
525
  end
764
526
 
765
- def last_release
766
- `git tag`.lines.select { |t| t.index(gem_name) == 0 }.last.chomp
767
- end
768
-
769
- def git(*args)
770
- sh "git", *args
771
- end
772
-
773
- def create_manifest
774
- write_file(manifest_file) {
775
- files.sort.join("\n")
776
- }
777
- end
778
-
779
527
  def define_release
780
- task :prerelease => [:clean, :check_directory, :ping, history_file]
528
+ task :prerelease => [
529
+ :clean,
530
+ :check_directory,
531
+ :check_levitate,
532
+ :ping,
533
+ history_file
534
+ ]
781
535
 
782
536
  task :finish_release do
783
537
  git "tag", "#{gem_name}-" + version.to_s
784
538
  git "push", "--tags", "origin", "master"
785
- sh "gem", "push", gem
539
+ sh "gem", "push", "pkg/#{gem_name}-#{version}.gem"
786
540
  end
787
541
 
788
- task :release => [:prerelease, :package, :finish_release]
542
+ task :release => [:prerelease, :package, :finish_release, :publish]
789
543
  end
790
544
 
791
545
  def define_debug_gem
@@ -794,34 +548,22 @@ class Levitate
794
548
  end
795
549
  end
796
550
 
797
- def define_extension
798
- if so_file and (source_control? or !File.file?(so_file))
799
- require 'rbconfig'
800
- require 'rake/extensiontask'
801
-
802
- Rake::ExtensionTask.new gem_name, gemspec do |ext|
803
- ext.cross_compile = true
804
- ext.cross_platform = 'i386-mswin32'
805
- ext.cross_compiling do |gemspec|
806
- gemspec.post_install_message =
807
- "U got dat binary versionation of this gemination!"
808
- end
809
- end
551
+ #### helpers
810
552
 
811
- if Rake::Task[so_file].needed?
812
- task :test => so_file
813
- end
553
+ def files_in_require_paths
554
+ require_paths.inject([]) { |acc, dir|
555
+ acc + Dir.glob("#{dir}/**/*.rb")
556
+ }
557
+ end
814
558
 
815
- task :cross_native_gem do
816
- Rake::Task[:gem].reenable
817
- Rake.application.top_level_tasks.replace %w[cross native gem]
818
- Rake.application.top_level
819
- end
559
+ def last_release
560
+ `git tag`.lines.select { |t| t.index(gem_name) == 0 }.last.chomp
561
+ end
820
562
 
821
- task :gem => :cross_native_gem
822
- end
563
+ def git(*args)
564
+ sh "git", *args
823
565
  end
824
-
566
+
825
567
  def open_browser(*files)
826
568
  sh(*([browser].flatten + files))
827
569
  end
@@ -830,7 +572,7 @@ class Levitate
830
572
  task_names.each { |task_name|
831
573
  Rake::Task[task_name].actions.map! { |action|
832
574
  lambda { |*args|
833
- Ruby.no_warnings {
575
+ no_warnings {
834
576
  action.call(*args)
835
577
  }
836
578
  }
@@ -846,10 +588,110 @@ class Levitate
846
588
  File.directory? ".git"
847
589
  end
848
590
 
849
- class << self
850
- include Util
591
+ #### utility for instance and class
592
+
593
+ module Util
594
+ def ruby_bin
595
+ require 'rbconfig'
596
+
597
+ name = File.join(
598
+ RbConfig::CONFIG["bindir"],
599
+ RbConfig::CONFIG["RUBY_INSTALL_NAME"]
600
+ )
601
+
602
+ if RbConfig::CONFIG["host"] =~ %r!(mswin|cygwin|mingw)! and
603
+ File.basename(name) !~ %r!\.(exe|com|bat|cmd)\Z!i
604
+ name + RbConfig::CONFIG["EXEEXT"]
605
+ else
606
+ name
607
+ end
608
+ end
609
+
610
+ def ruby_command
611
+ [ruby_bin] + Levitate.ruby_opts.to_a
612
+ end
613
+
614
+ def ruby_command_string
615
+ ruby_command.join(" ")
616
+ end
617
+
618
+ def run(*args)
619
+ cmd = ruby_command + args
620
+ unless system(*cmd)
621
+ cmd_str = cmd.map { |t| "'#{t}'" }.join(", ")
622
+ raise "system(#{cmd_str}) failed with status #{$?.exitstatus}"
623
+ end
624
+ end
625
+
626
+ def run_each_file(*files)
627
+ files.each { |file|
628
+ run("-w", file)
629
+ }
630
+ end
851
631
 
852
- # From minitest, part of the Ruby source; by Ryan Davis.
632
+ def run_code_and_capture(code)
633
+ IO.popen(ruby_command_string, "r+") { |pipe|
634
+ pipe.print(code)
635
+ pipe.flush
636
+ pipe.close_write
637
+ pipe.read
638
+ }
639
+ end
640
+
641
+ def run_file_and_capture(file)
642
+ unless File.file? file
643
+ raise "file does not exist: `#{file}'"
644
+ end
645
+ IO.popen(ruby_command_string + " " + file, "r") { |pipe|
646
+ pipe.read
647
+ }
648
+ end
649
+
650
+ def with_warnings(value = true)
651
+ previous = $VERBOSE
652
+ $VERBOSE = value
653
+ begin
654
+ yield
655
+ ensure
656
+ $VERBOSE = previous
657
+ end
658
+ end
659
+
660
+ def no_warnings(&block)
661
+ with_warnings(nil, &block)
662
+ end
663
+
664
+ def to_camel_case(str)
665
+ str.split('_').map { |t| t.capitalize }.join
666
+ end
667
+
668
+ def write_file(file)
669
+ contents = yield
670
+ File.open(file, "wb") { |out|
671
+ out.print(contents)
672
+ }
673
+ contents
674
+ end
675
+
676
+ def instance_exec2(obj, *args, &block)
677
+ method_name = ["_", obj.object_id, "_", Thread.current.object_id].join
678
+ (class << obj ; self ; end).class_eval do
679
+ define_method method_name, &block
680
+ begin
681
+ obj.send(method_name, *args)
682
+ ensure
683
+ remove_method method_name
684
+ end
685
+ end
686
+ end
687
+ end
688
+ extend Util
689
+ include Util
690
+
691
+ #### public helpers for testing
692
+
693
+ class << self
694
+ # From 'minitest' by Ryan Davis.
853
695
  def capture_io
854
696
  require 'stringio'
855
697
 
@@ -884,7 +726,7 @@ class Levitate
884
726
  Tempfile.open("run-rdoc-code") { |temp_file|
885
727
  temp_file.print(final_code)
886
728
  temp_file.close
887
- actual = Ruby.run_file_and_capture(temp_file.path).chomp
729
+ actual = run_file_and_capture(temp_file.path).chomp
888
730
  }
889
731
 
890
732
  instance_exec2(instance, expected, actual, index, &block)
@@ -954,5 +796,57 @@ class Levitate
954
796
  end
955
797
  Object.const_set("Test#{file}".gsub(".", ""), klass)
956
798
  end
799
+
800
+ def ruby_opts
801
+ @ruby_opts ||= []
802
+ end
803
+ attr_writer :ruby_opts
804
+ end
805
+
806
+ #### raw install, bypass gems
807
+
808
+ class Installer
809
+ def initialize
810
+ require 'fileutils'
811
+ require 'rbconfig'
812
+ require 'find'
813
+
814
+ @fu = FileUtils::Verbose
815
+ @spec = []
816
+
817
+ rb_root = RbConfig::CONFIG["sitelibdir"]
818
+
819
+ Find.find "lib" do |source|
820
+ next if source == "lib"
821
+ next unless File.directory?(source) || File.extname(source) == ".rb"
822
+ dest = File.join(rb_root, source.sub(%r!\Alib/!, ""))
823
+ @spec << [source, dest]
824
+ end
825
+ end
826
+
827
+ def install
828
+ @spec.each do |source, dest|
829
+ if File.directory?(source)
830
+ @fu.mkdir(dest) unless File.directory?(dest)
831
+ else
832
+ @fu.install(source, dest)
833
+ end
834
+ end
835
+ end
836
+
837
+ def uninstall
838
+ @spec.reverse.each do |source, dest|
839
+ if File.directory?(source)
840
+ @fu.rmdir(dest) if File.directory?(dest)
841
+ else
842
+ @fu.rm(dest) if File.file?(dest)
843
+ end
844
+ end
845
+ end
957
846
  end
958
847
  end
848
+
849
+ lambda do
850
+ config = File.join(File.dirname(__FILE__), "levitate_config.rb")
851
+ require config if File.file? config
852
+ end.call
@@ -0,0 +1,4 @@
1
+
2
+ if RUBY_ENGINE == "jruby"
3
+ Levitate.ruby_opts = %w[--1.9 -J-Djruby.astInspector.enabled=false]
4
+ end
@@ -4,6 +4,27 @@ require 'boc'
4
4
  module LiveAST
5
5
  module ReplaceEval
6
6
  class << self
7
+ def module_or_instance_eval(which, remote_self, bind, args)
8
+ handle_args(args)
9
+
10
+ cache[:remote_self] = remote_self
11
+ cache[:args] = args
12
+
13
+ code = %{
14
+ ::LiveAST::ReplaceEval.cache[:remote_self].
15
+ live_ast_original_#{which}_eval %{
16
+ ::LiveAST.eval(
17
+ ::LiveAST::ReplaceEval.cache[:args][0],
18
+ ::Kernel.binding,
19
+ *::LiveAST::ReplaceEval.cache[:args][1..-1])
20
+ }
21
+ }
22
+
23
+ live_ast_original_eval(code, bind)
24
+ ensure
25
+ cache.clear
26
+ end
27
+
7
28
  def cache
8
29
  Thread.current[:_live_ast_arg_cache] ||= {}
9
30
  end
@@ -22,27 +43,6 @@ module LiveAST
22
43
 
23
44
  args[1] = Common.arg_to_str(args[1]) if args[1]
24
45
  end
25
-
26
- def module_or_instance_eval(which, remote_self, bind, args)
27
- handle_args(args)
28
- begin
29
- cache[:remote_self] = remote_self
30
- cache[:args] = args
31
-
32
- code = %{
33
- ::LiveAST::ReplaceEval.cache[:remote_self].
34
- live_ast_original_#{which}_eval %{
35
- ::LiveAST.eval(
36
- ::LiveAST::ReplaceEval.cache[:args][0],
37
- binding,
38
- *::LiveAST::ReplaceEval.cache[:args][1..-1])
39
- }
40
- }
41
- live_ast_original_eval(code, bind)
42
- ensure
43
- cache.clear
44
- end
45
- end
46
46
  end
47
47
  end
48
48
 
@@ -50,7 +50,25 @@ module LiveAST
50
50
  parser
51
51
  end
52
52
 
53
+ # squelch alias warnings
54
+ prev_verbose = $VERBOSE
55
+ $VERBOSE = nil
56
+
53
57
  module Kernel
58
+ class << self
59
+ alias_method :live_ast_original_singleton_eval, :eval
60
+
61
+ def eval(*args)
62
+ LiveAST::Common.check_arity(args, 1..4)
63
+ LiveAST.eval(
64
+ "::Kernel.live_ast_original_instance_eval do;" << args[0] << ";end",
65
+ args[1] || Boc.value,
66
+ *LiveAST::Common.location_for_eval(*args[1..3]))
67
+ end
68
+
69
+ Boc.enable self, :eval
70
+ end
71
+
54
72
  private
55
73
 
56
74
  alias_method :live_ast_original_eval, :eval
@@ -63,17 +81,7 @@ module Kernel
63
81
  *LiveAST::Common.location_for_eval(*args[1..3]))
64
82
  end
65
83
 
66
- class << self
67
- alias_method :live_ast_original_singleton_eval, :eval
68
-
69
- def eval(*args)
70
- LiveAST::Common.check_arity(args, 1..4)
71
- LiveAST.eval(
72
- "::Kernel.live_ast_original_instance_eval do;" << args[0] << ";end",
73
- args[1] || Boc.value,
74
- *LiveAST::Common.location_for_eval(*args[1..3]))
75
- end
76
- end
84
+ Boc.enable self, :eval
77
85
  end
78
86
 
79
87
  class Binding
@@ -95,6 +103,8 @@ class BasicObject
95
103
  module_or_instance_eval(:instance, self, ::Boc.value, args)
96
104
  end
97
105
  end
106
+
107
+ ::Boc.enable_basic_object self, :instance_eval
98
108
  end
99
109
 
100
110
  class Module
@@ -108,14 +118,12 @@ class Module
108
118
  module_or_instance_eval(:module, self, Boc.value, args)
109
119
  end
110
120
  end
111
- end
112
121
 
113
- Boc.enable Kernel, :eval
114
- Boc.enable Kernel.singleton_class, :eval
115
- Boc.enable Module, :module_eval
116
- Boc.enable_basic_object BasicObject, :instance_eval
122
+ Boc.enable self, :module_eval
117
123
 
118
- class Module
119
124
  remove_method :class_eval
120
125
  alias_method :class_eval, :module_eval
121
126
  end
127
+
128
+ # unsquelch alias warnings
129
+ $VERBOSE = prev_verbose
@@ -1,3 +1,3 @@
1
1
  module LiveAST
2
- VERSION = "0.7.2"
2
+ VERSION = "0.7.3"
3
3
  end
@@ -16,9 +16,10 @@ class AllEncodingTest < RegularTest
16
16
  ]]
17
17
 
18
18
  ENC_TESTS.each_pair do |abbr, name|
19
- require_relative "encoding_test/#{abbr}"
20
-
21
19
  define_method "test_#{abbr}" do
20
+ require_relative "encoding_test/#{abbr}"
21
+ self.class.class_eval { include EncodingTest }
22
+
22
23
  str = send("#{abbr}_string")
23
24
  assert_equal name, str.encoding.to_s
24
25
 
@@ -32,8 +33,6 @@ class AllEncodingTest < RegularTest
32
33
  end
33
34
  end
34
35
 
35
- include EncodingTest
36
-
37
36
  def test_bad
38
37
  orig = assert_raises ArgumentError do
39
38
  live_ast_original_load "./test/encoding_test/bad.rb"
@@ -69,10 +69,7 @@ class BaseTest < JLMiniTest
69
69
  DATA_DIR = File.expand_path(File.dirname(__FILE__) + "/data")
70
70
 
71
71
  def self.stdlib_has_source?
72
- case RUBY_ENGINE
73
- when "ruby" # MRI; possibly others; not jruby
74
- true
75
- end
72
+ RUBY_ENGINE != "jruby"
76
73
  end
77
74
 
78
75
  def temp_file(basename = nil)
@@ -2,7 +2,8 @@ require_relative 'main'
2
2
  require_relative '../devel/levitate'
3
3
 
4
4
  if LiveAST.parser::Test.respond_to?(:unified_sexp?) and
5
- LiveAST.parser::Test.unified_sexp?
5
+ LiveAST.parser::Test.unified_sexp? and
6
+ RUBY_ENGINE != "jruby" then # jruby takes about a minute
6
7
  sections = [
7
8
  "Synopsis",
8
9
  "+to_ruby+",
@@ -373,4 +373,29 @@ class ZZY_ReplaceEvalTest < ReplaceEvalTest
373
373
 
374
374
  assert_equal expected, [file, line]
375
375
  end
376
+
377
+ DEFINE_BO_TEST = lambda do
378
+ class BasicObject
379
+ Kernel.eval("1 + 1")
380
+ end
381
+ end
382
+
383
+ def test_basic_object
384
+ ::BasicObject.new.instance_eval %{
385
+ t = 33
386
+ ::ZZY_ReplaceEvalTest::RESULT[:bo_test] = t + 44
387
+ }
388
+ assert_equal 77, RESULT[:bo_test]
389
+ end
390
+
391
+ class Z
392
+ def initialize
393
+ @t = 99
394
+ end
395
+ end
396
+
397
+ def test_instance_variables
398
+ assert_equal 99, Z.new.instance_eval{ @t }
399
+ assert_equal 99, Z.new.instance_eval("@t")
400
+ end
376
401
  end
@@ -4,7 +4,7 @@ require_relative '../devel/levitate'
4
4
  class RubygemsTest < RegularTest
5
5
  def test_rubygems
6
6
  lib = File.expand_path(File.dirname(__FILE__) + "/../lib")
7
- result = Levitate::Ruby.run_code_and_capture %{
7
+ result = Levitate.run_code_and_capture %{
8
8
  $LOAD_PATH.unshift '#{lib}'
9
9
  require 'live_ast/full'
10
10
  LiveAST.parser::Test
@@ -1,12 +1,10 @@
1
1
  require_relative 'main'
2
2
  require_relative '../devel/levitate'
3
3
 
4
- class ZZZ_RubySpecTest < ReplaceEvalTest
5
- def setup
6
- super
7
- puts "\n==== rubyspec"
8
- end
9
-
4
+ #
5
+ # Tests against rubyspec branch which discards '|ast@' tokens
6
+ #
7
+ class ZZZ_RubySpecTest < RegularTest
10
8
  FILES = [
11
9
  'core/basicobject/instance_eval_spec.rb',
12
10
  'core/binding/eval_spec.rb',
@@ -15,13 +13,27 @@ class ZZZ_RubySpecTest < ReplaceEvalTest
15
13
  'core/module/class_eval_spec.rb',
16
14
  'core/module/module_eval_spec.rb',
17
15
  ]
16
+
17
+ def setup
18
+ super
19
+ puts "\n==== rubyspec"
20
+ end
21
+
22
+ FILES.each do |file|
23
+ mname = "test_" + file.gsub("/", "_").chop!.chop!.chop!
24
+ define_method mname do
25
+ Dir.chdir ENV["LIVE_AST_RUBYSPEC_HOME"] do
26
+ cmd =
27
+ ["mspec", "-t", Levitate.ruby_bin] +
28
+
29
+ (["-T"]*Levitate.ruby_opts.size).
30
+ zip(Levitate.ruby_opts).
31
+ flatten +
32
+
33
+ [file]
18
34
 
19
- def test_rubyspec
20
- Dir.chdir(ENV["RUBYSPEC_HOME"] || "../rubyspec") do
21
- FILES.each do |file|
22
- cmd = %w[mspec -I../live_ast/lib -t] + [Levitate::Ruby.executable, file]
23
35
  assert system(*cmd)
24
36
  end
25
37
  end
26
38
  end
27
- end if [ENV["USER"], ENV["USERNAME"]].include? "jlawrence"
39
+ end if ENV["LIVE_AST_RUBYSPEC_HOME"]
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: live_ast
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.7.2
5
+ version: 0.7.3
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-03-16 00:00:00 -04:00
13
+ date: 2011-03-21 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -39,6 +39,7 @@ files:
39
39
  - README.rdoc
40
40
  - Rakefile
41
41
  - devel/levitate.rb
42
+ - devel/levitate_config.rb
42
43
  - lib/live_ast.rb
43
44
  - lib/live_ast/ast_eval.rb
44
45
  - lib/live_ast/ast_load.rb
@@ -100,7 +101,6 @@ files:
100
101
  - test/to_ast_feature_test.rb
101
102
  - test/to_ruby_feature_test.rb
102
103
  - test/to_ruby_test.rb
103
- - MANIFEST
104
104
  has_rdoc: true
105
105
  homepage: http://quix.github.com/live_ast
106
106
  licenses: []
@@ -110,7 +110,7 @@ rdoc_options:
110
110
  - --main
111
111
  - README.rdoc
112
112
  - --title
113
- - "live_ast: Live abstract syntax trees of methods and procs"
113
+ - "LiveAST: Live Abstract Syntax Trees"
114
114
  - --exclude
115
115
  - lib/live_ast/ast_load.rb
116
116
  - --exclude
data/MANIFEST DELETED
@@ -1,66 +0,0 @@
1
- CHANGES.rdoc
2
- MANIFEST
3
- README.rdoc
4
- Rakefile
5
- devel/levitate.rb
6
- lib/live_ast.rb
7
- lib/live_ast/ast_eval.rb
8
- lib/live_ast/ast_load.rb
9
- lib/live_ast/base.rb
10
- lib/live_ast/common.rb
11
- lib/live_ast/error.rb
12
- lib/live_ast/evaler.rb
13
- lib/live_ast/full.rb
14
- lib/live_ast/irb_spy.rb
15
- lib/live_ast/linker.rb
16
- lib/live_ast/loader.rb
17
- lib/live_ast/reader.rb
18
- lib/live_ast/replace_eval.rb
19
- lib/live_ast/replace_load.rb
20
- lib/live_ast/replace_raise.rb
21
- lib/live_ast/to_ast.rb
22
- lib/live_ast/to_ruby.rb
23
- lib/live_ast/version.rb
24
- test/ast_eval_feature_test.rb
25
- test/ast_load_feature_test.rb
26
- test/attr_test.rb
27
- test/backtrace_test.rb
28
- test/covert_define_method_test.rb
29
- test/def_test.rb
30
- test/define_method_test.rb
31
- test/define_singleton_method_test.rb
32
- test/encoding_test.rb
33
- test/encoding_test/bad.rb
34
- test/encoding_test/cp932.rb
35
- test/encoding_test/default.rb
36
- test/encoding_test/eucjp.rb
37
- test/encoding_test/koi8.rb
38
- test/encoding_test/koi8_shebang.rb
39
- test/encoding_test/koi8_with_utf8bom.rb
40
- test/encoding_test/usascii.rb
41
- test/encoding_test/usascii_with_utf8bom.rb
42
- test/encoding_test/utf8.rb
43
- test/encoding_test/utf8bom.rb
44
- test/encoding_test/utf8bom_only.rb
45
- test/error_test.rb
46
- test/eval_test.rb
47
- test/flush_cache_test.rb
48
- test/irb_test.rb
49
- test/lambda_test.rb
50
- test/load_path_test.rb
51
- test/load_test.rb
52
- test/main.rb
53
- test/nested_test.rb
54
- test/noninvasive_test.rb
55
- test/readme_test.rb
56
- test/recursive_eval_test.rb
57
- test/redefine_method_test.rb
58
- test/reload_test.rb
59
- test/replace_eval_test.rb
60
- test/rubygems_test.rb
61
- test/rubyspec_test.rb
62
- test/stdlib_test.rb
63
- test/thread_test.rb
64
- test/to_ast_feature_test.rb
65
- test/to_ruby_feature_test.rb
66
- test/to_ruby_test.rb