live_ast 0.7.2 → 0.7.3

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.
@@ -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