live_ast_ruby_parser 0.5.0
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.
- data/CHANGES.rdoc +10 -0
- data/MANIFEST +8 -0
- data/README.rdoc +47 -0
- data/Rakefile +17 -0
- data/devel/jumpstart.rb +901 -0
- data/lib/live_ast_ruby_parser.rb +60 -0
- data/lib/live_ast_ruby_parser/test_forms.rb +118 -0
- data/lib/live_ast_ruby_parser/unparser.rb +15 -0
- metadata +88 -0
data/CHANGES.rdoc
ADDED
data/MANIFEST
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
|
2
|
+
= live_ast_ruby_parser
|
3
|
+
|
4
|
+
== Summary
|
5
|
+
|
6
|
+
This is the default RubyParser-based parser used by LiveAST.
|
7
|
+
|
8
|
+
== Description
|
9
|
+
|
10
|
+
The nested TestForms module enables testing with the LiveAST test
|
11
|
+
suite. The Unparser module is used by +to_ruby+.
|
12
|
+
|
13
|
+
== Links
|
14
|
+
|
15
|
+
* Home: http://quix.github.com/live_ast_ruby_parser
|
16
|
+
* Feature Requests, Bug Reports: http://github.com/quix/live_ast_ruby_parser/issues
|
17
|
+
* Manual Download: http://github.com/quix/live_ast_ruby_parser/archives/master
|
18
|
+
* Repository: http://github.com/quix/live_ast_ruby_parser
|
19
|
+
|
20
|
+
== Author
|
21
|
+
|
22
|
+
* James M. Lawrence < quixoticsycophant@gmail.com >
|
23
|
+
|
24
|
+
== License
|
25
|
+
|
26
|
+
Copyright (c) 2011 James M. Lawrence. All rights reserved.
|
27
|
+
|
28
|
+
Permission is hereby granted, free of charge, to any person
|
29
|
+
obtaining a copy of this software and associated documentation files
|
30
|
+
(the "Software"), to deal in the Software without restriction,
|
31
|
+
including without limitation the rights to use, copy, modify, merge,
|
32
|
+
publish, distribute, sublicense, and/or sell copies of the Software,
|
33
|
+
and to permit persons to whom the Software is furnished to do so,
|
34
|
+
subject to the following conditions:
|
35
|
+
|
36
|
+
The above copyright notice and this permission notice shall be
|
37
|
+
included in all copies or substantial portions of the Software.
|
38
|
+
|
39
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
40
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
41
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
42
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
43
|
+
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
44
|
+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
45
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
46
|
+
SOFTWARE.
|
47
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'devel/jumpstart'
|
2
|
+
|
3
|
+
Jumpstart.new "live_ast_ruby_parser" do |s|
|
4
|
+
s.developers << ["James M. Lawrence", "quixoticsycophant@gmail.com"]
|
5
|
+
s.github_user = "quix"
|
6
|
+
s.version = "0.5.0"
|
7
|
+
|
8
|
+
# my code compensates for a ruby_parser bug; make this equal for now
|
9
|
+
s.dependencies << ["ruby_parser", "= 2.0.6"]
|
10
|
+
|
11
|
+
s.dependencies << ["ruby2ruby"]
|
12
|
+
end
|
13
|
+
|
14
|
+
# testing done inside live_ast
|
15
|
+
task :test do
|
16
|
+
end
|
17
|
+
|
data/devel/jumpstart.rb
ADDED
@@ -0,0 +1,901 @@
|
|
1
|
+
|
2
|
+
class Jumpstart
|
3
|
+
class Installer
|
4
|
+
def initialize
|
5
|
+
require 'fileutils'
|
6
|
+
require 'rbconfig'
|
7
|
+
require 'find'
|
8
|
+
dest_root = RbConfig::CONFIG["sitelibdir"]
|
9
|
+
sources = []
|
10
|
+
Find.find("./lib") { |source|
|
11
|
+
if install_file?(source)
|
12
|
+
sources << source
|
13
|
+
end
|
14
|
+
}
|
15
|
+
@spec = sources.inject(Array.new) { |acc, source|
|
16
|
+
if source == "./lib"
|
17
|
+
acc
|
18
|
+
else
|
19
|
+
dest = File.join(dest_root, source.sub(%r!\A\./lib!, ""))
|
20
|
+
|
21
|
+
install = lambda {
|
22
|
+
if File.directory?(source)
|
23
|
+
unless File.directory?(dest)
|
24
|
+
puts "mkdir #{dest}"
|
25
|
+
FileUtils.mkdir(dest)
|
26
|
+
end
|
27
|
+
else
|
28
|
+
puts "install #{source} --> #{dest}"
|
29
|
+
FileUtils.install(source, dest)
|
30
|
+
end
|
31
|
+
}
|
32
|
+
|
33
|
+
uninstall = lambda {
|
34
|
+
if File.directory?(source)
|
35
|
+
if File.directory?(dest)
|
36
|
+
puts "rmdir #{dest}"
|
37
|
+
FileUtils.rmdir(dest)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
if File.file?(dest)
|
41
|
+
puts "rm #{dest}"
|
42
|
+
FileUtils.rm(dest)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
}
|
46
|
+
|
47
|
+
acc << {
|
48
|
+
:source => source,
|
49
|
+
:dest => dest,
|
50
|
+
:install => install,
|
51
|
+
:uninstall => uninstall,
|
52
|
+
}
|
53
|
+
end
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def install_file?(source)
|
58
|
+
File.directory?(source) or
|
59
|
+
(File.file?(source) and File.extname(source) == ".rb")
|
60
|
+
end
|
61
|
+
|
62
|
+
def install
|
63
|
+
@spec.each { |entry|
|
64
|
+
entry[:install].call
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def uninstall
|
69
|
+
@spec.reverse.each { |entry|
|
70
|
+
entry[:uninstall].call
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
def run(args = ARGV)
|
75
|
+
if args.empty?
|
76
|
+
install
|
77
|
+
elsif args.size == 1 and args.first == "--uninstall"
|
78
|
+
uninstall
|
79
|
+
else
|
80
|
+
raise "unrecognized arguments: #{args.inspect}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
module AttrLazy
|
86
|
+
def attr_lazy(name, &block)
|
87
|
+
AttrLazy.define_reader(class << self ; self ; end, name, &block)
|
88
|
+
end
|
89
|
+
|
90
|
+
def attr_lazy_accessor(name, &block)
|
91
|
+
attr_lazy(name, &block)
|
92
|
+
AttrLazy.define_writer(class << self ; self ; end, name, &block)
|
93
|
+
end
|
94
|
+
|
95
|
+
class << self
|
96
|
+
def included(mod)
|
97
|
+
(class << mod ; self ; end).class_eval do
|
98
|
+
def attr_lazy(name, &block)
|
99
|
+
AttrLazy.define_reader(self, name, &block)
|
100
|
+
end
|
101
|
+
|
102
|
+
def attr_lazy_accessor(name, &block)
|
103
|
+
attr_lazy(name, &block)
|
104
|
+
AttrLazy.define_writer(self, name, &block)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def define_evaluated_reader(instance, name, value)
|
110
|
+
(class << instance ; self ; end).class_eval do
|
111
|
+
remove_method name rescue nil
|
112
|
+
define_method name do
|
113
|
+
value
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def define_reader(klass, name, &block)
|
119
|
+
klass.class_eval do
|
120
|
+
remove_method name rescue nil
|
121
|
+
define_method name do
|
122
|
+
value = instance_eval(&block)
|
123
|
+
AttrLazy.define_evaluated_reader(self, name, value)
|
124
|
+
value
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def define_writer(klass, name, &block)
|
130
|
+
klass.class_eval do
|
131
|
+
writer = "#{name}="
|
132
|
+
remove_method writer rescue nil
|
133
|
+
define_method writer do |value|
|
134
|
+
AttrLazy.define_evaluated_reader(self, name, value)
|
135
|
+
value
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
module Ruby
|
143
|
+
module_function
|
144
|
+
|
145
|
+
def executable
|
146
|
+
require 'rbconfig'
|
147
|
+
|
148
|
+
name = File.join(
|
149
|
+
RbConfig::CONFIG["bindir"],
|
150
|
+
RbConfig::CONFIG["RUBY_INSTALL_NAME"]
|
151
|
+
)
|
152
|
+
|
153
|
+
if RbConfig::CONFIG["host"] =~ %r!(mswin|cygwin|mingw)! and
|
154
|
+
File.basename(name) !~ %r!\.(exe|com|bat|cmd)\Z!i
|
155
|
+
name + RbConfig::CONFIG["EXEEXT"]
|
156
|
+
else
|
157
|
+
name
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def run(*args)
|
162
|
+
cmd = [executable, *args]
|
163
|
+
unless system(*cmd)
|
164
|
+
cmd_str = cmd.map { |t| "'#{t}'" }.join(", ")
|
165
|
+
raise "system(#{cmd_str}) failed with status #{$?.exitstatus}"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def run_code_and_capture(code)
|
170
|
+
IO.popen(%{"#{executable}"}, "r+") { |pipe|
|
171
|
+
pipe.print(code)
|
172
|
+
pipe.flush
|
173
|
+
pipe.close_write
|
174
|
+
pipe.read
|
175
|
+
}
|
176
|
+
end
|
177
|
+
|
178
|
+
def run_file_and_capture(file)
|
179
|
+
unless File.file? file
|
180
|
+
raise "file does not exist: `#{file}'"
|
181
|
+
end
|
182
|
+
IO.popen(%{"#{executable}" "#{file}"}, "r") { |pipe|
|
183
|
+
pipe.read
|
184
|
+
}
|
185
|
+
end
|
186
|
+
|
187
|
+
def with_warnings(value = true)
|
188
|
+
previous = $VERBOSE
|
189
|
+
$VERBOSE = value
|
190
|
+
begin
|
191
|
+
yield
|
192
|
+
ensure
|
193
|
+
$VERBOSE = previous
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def no_warnings(&block)
|
198
|
+
with_warnings(nil, &block)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
module Util
|
203
|
+
module_function
|
204
|
+
|
205
|
+
def run_ruby_on_each(*files)
|
206
|
+
files.each { |file|
|
207
|
+
Ruby.run("-w", file)
|
208
|
+
}
|
209
|
+
end
|
210
|
+
|
211
|
+
def to_camel_case(str)
|
212
|
+
str.split('_').map { |t| t.capitalize }.join
|
213
|
+
end
|
214
|
+
|
215
|
+
def write_file(file)
|
216
|
+
contents = yield
|
217
|
+
File.open(file, "wb") { |out|
|
218
|
+
out.print(contents)
|
219
|
+
}
|
220
|
+
contents
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
module InstanceEvalWithArgs
|
225
|
+
module_function
|
226
|
+
|
227
|
+
def with_temp_method(instance, method_name, method_block)
|
228
|
+
(class << instance ; self ; end).class_eval do
|
229
|
+
define_method(method_name, &method_block)
|
230
|
+
begin
|
231
|
+
yield method_name
|
232
|
+
ensure
|
233
|
+
remove_method(method_name)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def call_temp_method(instance, method_name, *args, &method_block)
|
239
|
+
with_temp_method(instance, method_name, method_block) {
|
240
|
+
instance.send(method_name, *args)
|
241
|
+
}
|
242
|
+
end
|
243
|
+
|
244
|
+
def instance_eval_with_args(instance, *args, &block)
|
245
|
+
call_temp_method(instance, :__temp_method, *args, &block)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
include AttrLazy
|
250
|
+
include Util
|
251
|
+
|
252
|
+
def initialize(project_name)
|
253
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
254
|
+
|
255
|
+
require 'rubygems/package_task'
|
256
|
+
|
257
|
+
@project_name = project_name
|
258
|
+
|
259
|
+
yield self
|
260
|
+
|
261
|
+
self.class.instance_methods(false).select { |t|
|
262
|
+
t.to_s =~ %r!\Adefine_!
|
263
|
+
}.sort.each { |method_name|
|
264
|
+
send(method_name)
|
265
|
+
}
|
266
|
+
end
|
267
|
+
|
268
|
+
class << self
|
269
|
+
alias_method :attribute, :attr_lazy_accessor
|
270
|
+
end
|
271
|
+
|
272
|
+
attribute :name do
|
273
|
+
@project_name
|
274
|
+
end
|
275
|
+
|
276
|
+
attribute :version_constant_name do
|
277
|
+
"VERSION"
|
278
|
+
end
|
279
|
+
|
280
|
+
attribute :camel_name do
|
281
|
+
to_camel_case(name)
|
282
|
+
end
|
283
|
+
|
284
|
+
attribute :version do
|
285
|
+
catch :bail do
|
286
|
+
if File.file?(version_file = "./lib/#{name}/version.rb")
|
287
|
+
require version_file
|
288
|
+
elsif File.file?("./lib/#{name}.rb")
|
289
|
+
require name
|
290
|
+
else
|
291
|
+
throw :bail
|
292
|
+
end
|
293
|
+
mod = Kernel.const_get(camel_name)
|
294
|
+
constants = mod.constants.map { |t| t.to_sym }
|
295
|
+
unless constants.include?(version_constant_name.to_sym)
|
296
|
+
throw :bail
|
297
|
+
end
|
298
|
+
mod.const_get(version_constant_name)
|
299
|
+
end or "0.0.0"
|
300
|
+
end
|
301
|
+
|
302
|
+
attribute :readme_file do
|
303
|
+
"README.rdoc"
|
304
|
+
end
|
305
|
+
|
306
|
+
attribute :history_file do
|
307
|
+
"CHANGES.rdoc"
|
308
|
+
end
|
309
|
+
|
310
|
+
attribute :doc_dir do
|
311
|
+
"doc"
|
312
|
+
end
|
313
|
+
|
314
|
+
attribute :spec_files do
|
315
|
+
Dir["./spec/*_{spec,example}.rb"]
|
316
|
+
end
|
317
|
+
|
318
|
+
attribute :test_files do
|
319
|
+
(Dir["./test/test_*.rb"] + Dir["./test/*_test.rb"]).uniq
|
320
|
+
end
|
321
|
+
|
322
|
+
attribute :cov_dir do
|
323
|
+
"coverage"
|
324
|
+
end
|
325
|
+
|
326
|
+
attribute :spec_output_dir do
|
327
|
+
"rspec_output"
|
328
|
+
end
|
329
|
+
|
330
|
+
attribute :spec_output_file do
|
331
|
+
"spec.html"
|
332
|
+
end
|
333
|
+
|
334
|
+
attr_lazy :spec_output do
|
335
|
+
"#{spec_output_dir}/#{spec_output_file}"
|
336
|
+
end
|
337
|
+
|
338
|
+
[:gem, :tgz].each { |ext|
|
339
|
+
attribute ext do
|
340
|
+
"pkg/#{name}-#{version}.#{ext}"
|
341
|
+
end
|
342
|
+
}
|
343
|
+
|
344
|
+
attribute :rcov_options do
|
345
|
+
# workaround for the default rspec task
|
346
|
+
Dir["*"].select { |f| File.directory? f }.inject(Array.new) { |acc, dir|
|
347
|
+
if dir == "lib"
|
348
|
+
acc
|
349
|
+
else
|
350
|
+
acc + ["--exclude", dir + "/"]
|
351
|
+
end
|
352
|
+
} + ["--text-report"]
|
353
|
+
end
|
354
|
+
|
355
|
+
attribute :readme_file do
|
356
|
+
"README.rdoc"
|
357
|
+
end
|
358
|
+
|
359
|
+
attribute :manifest_file do
|
360
|
+
"MANIFEST"
|
361
|
+
end
|
362
|
+
|
363
|
+
attribute :generated_files do
|
364
|
+
[]
|
365
|
+
end
|
366
|
+
|
367
|
+
attribute :files do
|
368
|
+
if File.file? manifest_file
|
369
|
+
File.read(manifest_file).split("\n")
|
370
|
+
elsif source_control?
|
371
|
+
IO.popen("git ls-files") { |pipe| pipe.read.split "\n" }
|
372
|
+
end.to_a + [manifest_file] + generated_files
|
373
|
+
end
|
374
|
+
|
375
|
+
def files_in_require_paths
|
376
|
+
require_paths.inject([]) { |acc, dir|
|
377
|
+
acc + Dir.glob("#{dir}/**/*.rb")
|
378
|
+
}
|
379
|
+
end
|
380
|
+
|
381
|
+
attribute :rdoc_files do
|
382
|
+
files_in_require_paths
|
383
|
+
end
|
384
|
+
|
385
|
+
attribute :rdoc_title do
|
386
|
+
"#{name}: #{summary}"
|
387
|
+
end
|
388
|
+
|
389
|
+
attribute :require_paths do
|
390
|
+
["lib"]
|
391
|
+
end
|
392
|
+
|
393
|
+
attribute :rdoc_options do
|
394
|
+
if File.file?(readme_file)
|
395
|
+
["--main", readme_file]
|
396
|
+
else
|
397
|
+
[]
|
398
|
+
end + [
|
399
|
+
"--title", rdoc_title,
|
400
|
+
] + (files_in_require_paths - rdoc_files).inject(Array.new) {
|
401
|
+
|acc, file|
|
402
|
+
acc + ["--exclude", file]
|
403
|
+
}
|
404
|
+
end
|
405
|
+
|
406
|
+
attribute :extra_rdoc_files do
|
407
|
+
File.file?(readme_file) ? [readme_file] : []
|
408
|
+
end
|
409
|
+
|
410
|
+
attribute :browser do
|
411
|
+
require 'rbconfig'
|
412
|
+
if RbConfig::CONFIG["host"] =~ %r!darwin!
|
413
|
+
"open"
|
414
|
+
else
|
415
|
+
"firefox"
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
attribute :gemspec do
|
420
|
+
Gem::Specification.new do |g|
|
421
|
+
g.has_rdoc = true
|
422
|
+
%w[
|
423
|
+
name
|
424
|
+
authors
|
425
|
+
email
|
426
|
+
summary
|
427
|
+
version
|
428
|
+
description
|
429
|
+
files
|
430
|
+
rdoc_options
|
431
|
+
extra_rdoc_files
|
432
|
+
require_paths
|
433
|
+
].each { |param|
|
434
|
+
value = send(param) and (
|
435
|
+
g.send("#{param}=", value)
|
436
|
+
)
|
437
|
+
}
|
438
|
+
|
439
|
+
g.homepage = url if url
|
440
|
+
|
441
|
+
dependencies.each { |dep|
|
442
|
+
g.add_dependency(*dep)
|
443
|
+
}
|
444
|
+
|
445
|
+
development_dependencies.each { |dep|
|
446
|
+
g.add_development_dependency(*dep)
|
447
|
+
}
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
attribute :readme_contents do
|
452
|
+
File.read(readme_file) rescue "FIXME: readme_file"
|
453
|
+
end
|
454
|
+
|
455
|
+
attribute :sections do
|
456
|
+
begin
|
457
|
+
data = readme_contents.split(%r!^==\s*(.*?)\s*$!)
|
458
|
+
pairs = data[1..-1].each_slice(2).map { |section, contents|
|
459
|
+
[section.downcase, contents.strip]
|
460
|
+
}
|
461
|
+
Hash[*pairs.flatten]
|
462
|
+
rescue
|
463
|
+
nil
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
attribute :description_section do
|
468
|
+
"description"
|
469
|
+
end
|
470
|
+
|
471
|
+
attribute :summary_section do
|
472
|
+
"summary"
|
473
|
+
end
|
474
|
+
|
475
|
+
attribute :description_sentences do
|
476
|
+
1
|
477
|
+
end
|
478
|
+
|
479
|
+
attribute :summary_sentences do
|
480
|
+
1
|
481
|
+
end
|
482
|
+
|
483
|
+
[:summary, :description].each { |section|
|
484
|
+
attribute section do
|
485
|
+
begin
|
486
|
+
sections[send("#{section}_section")].
|
487
|
+
gsub("\n", " ").
|
488
|
+
split(%r!\.\s*!m).
|
489
|
+
first(send("#{section}_sentences")).
|
490
|
+
join(". ") << "."
|
491
|
+
rescue
|
492
|
+
"FIXME: #{section}"
|
493
|
+
end
|
494
|
+
end
|
495
|
+
}
|
496
|
+
|
497
|
+
attribute :url do
|
498
|
+
"http://#{github_user}.github.com/#{name}"
|
499
|
+
end
|
500
|
+
|
501
|
+
attribute :github_user do
|
502
|
+
raise "github_user not set"
|
503
|
+
end
|
504
|
+
|
505
|
+
attribute :rubyforge_info do
|
506
|
+
nil
|
507
|
+
end
|
508
|
+
|
509
|
+
attribute :authors do
|
510
|
+
developers.map { |d| d[0] }
|
511
|
+
end
|
512
|
+
|
513
|
+
attribute :email do
|
514
|
+
developers.map { |d| d[1] }
|
515
|
+
end
|
516
|
+
|
517
|
+
attribute :dependencies do
|
518
|
+
[]
|
519
|
+
end
|
520
|
+
|
521
|
+
attribute :development_dependencies do
|
522
|
+
[]
|
523
|
+
end
|
524
|
+
|
525
|
+
attribute :developers do
|
526
|
+
[]
|
527
|
+
end
|
528
|
+
|
529
|
+
def define_clean
|
530
|
+
require 'rake/clean'
|
531
|
+
task :clean do
|
532
|
+
Rake::Task[:clobber].invoke
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
def define_package
|
537
|
+
if source_control?
|
538
|
+
task manifest_file do
|
539
|
+
create_manifest
|
540
|
+
end
|
541
|
+
CLEAN.add manifest_file
|
542
|
+
task :package => :clean
|
543
|
+
Gem::PackageTask.new(gemspec).define
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
def define_spec
|
548
|
+
unless spec_files.empty?
|
549
|
+
Ruby.no_warnings {
|
550
|
+
require 'spec/rake/spectask'
|
551
|
+
}
|
552
|
+
|
553
|
+
desc "run specs"
|
554
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
555
|
+
t.spec_files = spec_files
|
556
|
+
end
|
557
|
+
|
558
|
+
desc "run specs with text output"
|
559
|
+
Spec::Rake::SpecTask.new('text_spec') do |t|
|
560
|
+
t.spec_files = spec_files
|
561
|
+
t.spec_opts = ['-fs']
|
562
|
+
end
|
563
|
+
|
564
|
+
desc "run specs with html output"
|
565
|
+
Spec::Rake::SpecTask.new('full_spec') do |t|
|
566
|
+
t.spec_files = spec_files
|
567
|
+
t.rcov = true
|
568
|
+
t.rcov_opts = rcov_options
|
569
|
+
t.spec_opts = ["-fh:#{spec_output}"]
|
570
|
+
end
|
571
|
+
|
572
|
+
suppress_task_warnings :spec, :full_spec, :text_spec
|
573
|
+
|
574
|
+
desc "run full_spec then open browser"
|
575
|
+
task :show_spec => :full_spec do
|
576
|
+
open_browser(spec_output, cov_dir + "/index.html")
|
577
|
+
end
|
578
|
+
|
579
|
+
desc "run specs individually"
|
580
|
+
task :spec_deps do
|
581
|
+
run_ruby_on_each(*spec_files)
|
582
|
+
end
|
583
|
+
|
584
|
+
task :prerelease => [:spec, :spec_deps]
|
585
|
+
task :default => :spec
|
586
|
+
|
587
|
+
CLEAN.add spec_output_dir
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
def define_test
|
592
|
+
unless test_files.empty?
|
593
|
+
desc "run tests"
|
594
|
+
task :test do
|
595
|
+
test_files.each { |file| require file }
|
596
|
+
|
597
|
+
# if we use at_exit hook instead, it won't run before :release
|
598
|
+
MiniTest::Unit.new.run ARGV
|
599
|
+
end
|
600
|
+
|
601
|
+
desc "run tests with coverage"
|
602
|
+
if ruby_18?
|
603
|
+
task :full_test do
|
604
|
+
verbose(false) {
|
605
|
+
sh("rcov", "-o", cov_dir, "--text-report",
|
606
|
+
*(test_files + rcov_options)
|
607
|
+
)
|
608
|
+
}
|
609
|
+
end
|
610
|
+
else
|
611
|
+
task :full_test do
|
612
|
+
rm_rf cov_dir
|
613
|
+
require 'simplecov'
|
614
|
+
SimpleCov.start do
|
615
|
+
add_filter "test/"
|
616
|
+
add_filter "devel/"
|
617
|
+
end
|
618
|
+
Rake::Task[:test].invoke
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
622
|
+
desc "run full_test then open browser"
|
623
|
+
task :show_test => :full_test do
|
624
|
+
show = lambda { open_browser(cov_dir + "/index.html") }
|
625
|
+
if ruby_18?
|
626
|
+
show.call
|
627
|
+
else
|
628
|
+
SimpleCov.at_exit do
|
629
|
+
SimpleCov.result.format!
|
630
|
+
show.call
|
631
|
+
end
|
632
|
+
end
|
633
|
+
end
|
634
|
+
|
635
|
+
desc "run tests individually"
|
636
|
+
task :test_deps do
|
637
|
+
run_ruby_on_each(*test_files)
|
638
|
+
end
|
639
|
+
|
640
|
+
task :prerelease => [:test, :test_deps]
|
641
|
+
task :default => :test
|
642
|
+
|
643
|
+
CLEAN.add cov_dir
|
644
|
+
end
|
645
|
+
end
|
646
|
+
|
647
|
+
def define_doc
|
648
|
+
desc "run rdoc"
|
649
|
+
task :doc => :clean_doc do
|
650
|
+
Kernel.send :gem, 'rdoc' rescue nil
|
651
|
+
require 'rdoc/rdoc'
|
652
|
+
args = (
|
653
|
+
gemspec.rdoc_options +
|
654
|
+
gemspec.require_paths.clone +
|
655
|
+
gemspec.extra_rdoc_files +
|
656
|
+
["-o", doc_dir]
|
657
|
+
).flatten.map { |t| t.to_s }
|
658
|
+
RDoc::RDoc.new.document args
|
659
|
+
end
|
660
|
+
|
661
|
+
task :clean_doc do
|
662
|
+
# normally rm_rf, but mimic rake/clean output
|
663
|
+
rm_r(doc_dir) rescue nil
|
664
|
+
end
|
665
|
+
|
666
|
+
desc "run rdoc then open browser"
|
667
|
+
task :show_doc => :doc do
|
668
|
+
open_browser(doc_dir + "/index.html")
|
669
|
+
end
|
670
|
+
|
671
|
+
task :rdoc => :doc
|
672
|
+
task :clean => :clean_doc
|
673
|
+
end
|
674
|
+
|
675
|
+
def define_publish
|
676
|
+
if source_control?
|
677
|
+
desc "publish docs"
|
678
|
+
task :publish => [:clean, :check_directory, :doc] do
|
679
|
+
if rubyforge_info
|
680
|
+
user, project = rubyforge_info
|
681
|
+
Dir.chdir(doc_dir) do
|
682
|
+
sh "scp", "-r",
|
683
|
+
".",
|
684
|
+
"#{user}@rubyforge.org:/var/www/gforge-projects/#{project}"
|
685
|
+
end
|
686
|
+
end
|
687
|
+
git "branch", "-D", "gh-pages"
|
688
|
+
git "checkout", "--orphan", "gh-pages"
|
689
|
+
FileUtils.rm ".git/index"
|
690
|
+
git "clean", "-fdx", "-e", "doc"
|
691
|
+
Dir["doc/*"].each { |path|
|
692
|
+
FileUtils.mv path, "."
|
693
|
+
}
|
694
|
+
FileUtils.rmdir "doc"
|
695
|
+
git "add", "."
|
696
|
+
git "commit", "-m", "generated by rdoc"
|
697
|
+
git "push", "-f", "origin", "gh-pages"
|
698
|
+
end
|
699
|
+
end
|
700
|
+
end
|
701
|
+
|
702
|
+
def define_install
|
703
|
+
desc "direct install (no gem)"
|
704
|
+
task :install do
|
705
|
+
Installer.new.run([])
|
706
|
+
end
|
707
|
+
|
708
|
+
desc "direct uninstall (no gem)"
|
709
|
+
task :uninstall do
|
710
|
+
Installer.new.run(["--uninstall"])
|
711
|
+
end
|
712
|
+
end
|
713
|
+
|
714
|
+
def define_check_directory
|
715
|
+
task :check_directory do
|
716
|
+
unless `git status` =~ %r!nothing to commit \(working directory clean\)!
|
717
|
+
raise "directory not clean"
|
718
|
+
end
|
719
|
+
end
|
720
|
+
end
|
721
|
+
|
722
|
+
def define_ping
|
723
|
+
task :ping do
|
724
|
+
require 'rbconfig'
|
725
|
+
%w[github.com].each { |server|
|
726
|
+
cmd = "ping " + (
|
727
|
+
if RbConfig::CONFIG["host"] =~ %r!darwin!
|
728
|
+
"-c2 #{server}"
|
729
|
+
else
|
730
|
+
"#{server} 2 2"
|
731
|
+
end
|
732
|
+
)
|
733
|
+
unless `#{cmd}` =~ %r!0% packet loss!
|
734
|
+
raise "No ping for #{server}"
|
735
|
+
end
|
736
|
+
}
|
737
|
+
end
|
738
|
+
end
|
739
|
+
|
740
|
+
def git(*args)
|
741
|
+
sh "git", *args
|
742
|
+
end
|
743
|
+
|
744
|
+
def create_manifest
|
745
|
+
write_file(manifest_file) {
|
746
|
+
files.sort.join("\n")
|
747
|
+
}
|
748
|
+
end
|
749
|
+
|
750
|
+
def define_release
|
751
|
+
task :prerelease => [:clean, :check_directory, :ping, history_file]
|
752
|
+
|
753
|
+
task :finish_release do
|
754
|
+
git "tag", "#{name}-" + version.to_s
|
755
|
+
git "push", "--tags", "origin", "master"
|
756
|
+
sh "gem", "push", gem
|
757
|
+
end
|
758
|
+
|
759
|
+
task :release => [:prerelease, :package, :finish_release]
|
760
|
+
end
|
761
|
+
|
762
|
+
def define_debug_gem
|
763
|
+
task :debug_gem do
|
764
|
+
puts gemspec.to_ruby
|
765
|
+
end
|
766
|
+
end
|
767
|
+
|
768
|
+
def open_browser(*files)
|
769
|
+
sh(*([browser].flatten + files))
|
770
|
+
end
|
771
|
+
|
772
|
+
def suppress_task_warnings(*task_names)
|
773
|
+
task_names.each { |task_name|
|
774
|
+
Rake::Task[task_name].actions.map! { |action|
|
775
|
+
lambda { |*args|
|
776
|
+
Ruby.no_warnings {
|
777
|
+
action.call(*args)
|
778
|
+
}
|
779
|
+
}
|
780
|
+
}
|
781
|
+
}
|
782
|
+
end
|
783
|
+
|
784
|
+
def ruby_18?
|
785
|
+
RUBY_VERSION =~ %r!\A1\.8!
|
786
|
+
end
|
787
|
+
|
788
|
+
def source_control?
|
789
|
+
File.directory? ".git"
|
790
|
+
end
|
791
|
+
|
792
|
+
class << self
|
793
|
+
include Util
|
794
|
+
include InstanceEvalWithArgs
|
795
|
+
|
796
|
+
# From minitest, part of the Ruby source; by Ryan Davis.
|
797
|
+
def capture_io
|
798
|
+
require 'stringio'
|
799
|
+
|
800
|
+
orig_stdout, orig_stderr = $stdout, $stderr
|
801
|
+
captured_stdout, captured_stderr = StringIO.new, StringIO.new
|
802
|
+
$stdout, $stderr = captured_stdout, captured_stderr
|
803
|
+
|
804
|
+
yield
|
805
|
+
|
806
|
+
return captured_stdout.string, captured_stderr.string
|
807
|
+
ensure
|
808
|
+
$stdout = orig_stdout
|
809
|
+
$stderr = orig_stderr
|
810
|
+
end
|
811
|
+
|
812
|
+
def run_doc_code(code, expected, index, instance, &block)
|
813
|
+
lib = File.expand_path(File.dirname(__FILE__) + "/../lib")
|
814
|
+
header = %{
|
815
|
+
$LOAD_PATH.unshift "#{lib}"
|
816
|
+
begin
|
817
|
+
}
|
818
|
+
footer = %{
|
819
|
+
rescue Exception => __jumpstart_exception
|
820
|
+
puts "raises \#{__jumpstart_exception.class}"
|
821
|
+
end
|
822
|
+
}
|
823
|
+
final_code = header + code + footer
|
824
|
+
|
825
|
+
# Sometimes code is required to be inside a file.
|
826
|
+
actual = nil
|
827
|
+
require 'tempfile'
|
828
|
+
Tempfile.open("run-rdoc-code") { |temp_file|
|
829
|
+
temp_file.print(final_code)
|
830
|
+
temp_file.close
|
831
|
+
actual = Ruby.run_file_and_capture(temp_file.path).chomp
|
832
|
+
}
|
833
|
+
|
834
|
+
instance_eval_with_args(instance, expected, actual, index, &block)
|
835
|
+
end
|
836
|
+
|
837
|
+
def run_doc_section(file, section, instance, &block)
|
838
|
+
contents = File.read(file)
|
839
|
+
re = %r!^=+[ \t]#{Regexp.quote(section)}.*?\n(.*?)^=!m
|
840
|
+
if section_contents = contents[re, 1]
|
841
|
+
index = 0
|
842
|
+
section_contents.scan(%r!^( \S.*?)(?=(^\S|\Z))!m) { |indented, unused|
|
843
|
+
code_sections = indented.split(%r!^ \#\#\#\# output:\s*$!)
|
844
|
+
code, expected = (
|
845
|
+
case code_sections.size
|
846
|
+
when 1
|
847
|
+
[indented, indented.scan(%r!\# => (.*?)\n!).flatten.join("\n")]
|
848
|
+
when 2
|
849
|
+
code_sections
|
850
|
+
else
|
851
|
+
raise "parse error"
|
852
|
+
end
|
853
|
+
)
|
854
|
+
run_doc_code(code, expected, index, instance, &block)
|
855
|
+
index += 1
|
856
|
+
}
|
857
|
+
else
|
858
|
+
raise "couldn't find section `#{section}' of `#{file}'"
|
859
|
+
end
|
860
|
+
end
|
861
|
+
|
862
|
+
def doc_to_spec(file, *sections, &block)
|
863
|
+
jump = self
|
864
|
+
describe file do
|
865
|
+
sections.each { |section|
|
866
|
+
describe "section `#{section}'" do
|
867
|
+
it "should run as claimed" do
|
868
|
+
if block
|
869
|
+
jump.run_doc_section(file, section, self, &block)
|
870
|
+
else
|
871
|
+
jump.run_doc_section(file, section, self) {
|
872
|
+
|expected, actual, index|
|
873
|
+
actual.should == expected
|
874
|
+
}
|
875
|
+
end
|
876
|
+
end
|
877
|
+
end
|
878
|
+
}
|
879
|
+
end
|
880
|
+
end
|
881
|
+
|
882
|
+
def doc_to_test(file, *sections, &block)
|
883
|
+
jump = self
|
884
|
+
klass = Class.new MiniTest::Unit::TestCase do
|
885
|
+
sections.each { |section|
|
886
|
+
define_method "test_#{file}_#{section}" do
|
887
|
+
if block
|
888
|
+
jump.run_doc_section(file, section, self, &block)
|
889
|
+
else
|
890
|
+
jump.run_doc_section(file, section, self) {
|
891
|
+
|expected, actual, index|
|
892
|
+
assert_equal expected, actual
|
893
|
+
}
|
894
|
+
end
|
895
|
+
end
|
896
|
+
}
|
897
|
+
end
|
898
|
+
Object.const_set("Test#{file}".gsub(".", ""), klass)
|
899
|
+
end
|
900
|
+
end
|
901
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'ruby_parser'
|
2
|
+
require 'sexp_processor'
|
3
|
+
|
4
|
+
class LiveASTRubyParser < SexpProcessor
|
5
|
+
#
|
6
|
+
# Whether this is Ryan Davis' unified sexp format.
|
7
|
+
#
|
8
|
+
def self.unified?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
#
|
13
|
+
# Returns a line --> sexp hash where sexp corresponds to the
|
14
|
+
# method or block defined at the given line.
|
15
|
+
#
|
16
|
+
def parse(source)
|
17
|
+
@defs = {}
|
18
|
+
process RubyParser.new.parse(source)
|
19
|
+
@defs
|
20
|
+
end
|
21
|
+
|
22
|
+
def process_defn(sexp)
|
23
|
+
result = Sexp.new
|
24
|
+
result << sexp.shift
|
25
|
+
result << sexp.shift
|
26
|
+
result << process(sexp.shift)
|
27
|
+
result << process(sexp.shift)
|
28
|
+
|
29
|
+
store_sexp(result, sexp.line)
|
30
|
+
s()
|
31
|
+
end
|
32
|
+
|
33
|
+
def process_iter(sexp)
|
34
|
+
line = sexp[1].line
|
35
|
+
|
36
|
+
result = Sexp.new
|
37
|
+
result << sexp.shift
|
38
|
+
result << process(sexp.shift)
|
39
|
+
result << process(sexp.shift)
|
40
|
+
result << process(sexp.shift)
|
41
|
+
|
42
|
+
#
|
43
|
+
# ruby_parser bug: a method without args attached to a
|
44
|
+
# multi-line block reports the wrong line. workaround.
|
45
|
+
#
|
46
|
+
if result[1][3].size == 1
|
47
|
+
line = sexp.line
|
48
|
+
end
|
49
|
+
|
50
|
+
store_sexp(result, line)
|
51
|
+
s()
|
52
|
+
end
|
53
|
+
|
54
|
+
def store_sexp(sexp, line)
|
55
|
+
@defs[line] = @defs.has_key?(line) ? :multiple : sexp
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
LiveASTRubyParser.autoload :Unparser, 'live_ast_ruby_parser/unparser'
|
60
|
+
LiveASTRubyParser.autoload :TestForms, 'live_ast_ruby_parser/test_forms'
|
@@ -0,0 +1,118 @@
|
|
1
|
+
|
2
|
+
# For testing with LiveAST.
|
3
|
+
module LiveASTRubyParser::TestForms
|
4
|
+
#
|
5
|
+
# no_arg_def(:f, "A#f") returns the ast of
|
6
|
+
#
|
7
|
+
# def f
|
8
|
+
# "A#f"
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
def no_arg_def(name, ret)
|
12
|
+
s(:defn, name, s(:args), s(:scope, s(:block, s(:str, ret))))
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# no_arg_def_return(no_arg_def(:f, "A#f")) == "A#f"
|
17
|
+
#
|
18
|
+
def no_arg_def_return(ast)
|
19
|
+
ast[3][1][1][1]
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# binop_def(:f, :+) returns the ast of
|
24
|
+
#
|
25
|
+
# def f(x, y)
|
26
|
+
# x + y
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
def binop_def(name, op)
|
30
|
+
s(:defn,
|
31
|
+
name,
|
32
|
+
s(:args, :x, :y),
|
33
|
+
s(:scope,
|
34
|
+
s(:block, s(:call, s(:lvar, :x), op, s(:arglist, s(:lvar, :y))))))
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# binop_define_method(:f, :*) returns the ast of
|
39
|
+
#
|
40
|
+
# define_method :f do |x, y|
|
41
|
+
# x * y
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# binop_define_method(:f, :-, :my_def) returns the ast of
|
45
|
+
#
|
46
|
+
# my_def :f do |x, y|
|
47
|
+
# x - y
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
def binop_define_method(name, op, using = :define_method)
|
51
|
+
s(:iter,
|
52
|
+
s(:call, nil, using, s(:arglist, s(:lit, name))),
|
53
|
+
s(:masgn, s(:array, s(:lasgn, :x), s(:lasgn, :y))),
|
54
|
+
s(:call, s(:lvar, :x), op, s(:arglist, s(:lvar, :y))))
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
# binop_define_method_with_var(:method_name, :/) returns the ast of
|
59
|
+
#
|
60
|
+
# define_method method_name do |x, y|
|
61
|
+
# x / y
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
def binop_define_method_with_var(var_name, op)
|
65
|
+
s(:iter,
|
66
|
+
s(:call, nil, :define_method, s(:arglist, s(:lvar, var_name))),
|
67
|
+
s(:masgn, s(:array, s(:lasgn, :x), s(:lasgn, :y))),
|
68
|
+
s(:call, s(:lvar, :x), op, s(:arglist, s(:lvar, :y))))
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# binop_define_singleton_method(:f, :+, :a) returns the ast of
|
73
|
+
#
|
74
|
+
# a.define_singleton_method :f do |x, y|
|
75
|
+
# x + y
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
def binop_define_singleton_method(name, op, receiver)
|
79
|
+
s(:iter,
|
80
|
+
s(:call, s(:lvar, receiver), :define_singleton_method,
|
81
|
+
s(:arglist, s(:lit, name))),
|
82
|
+
s(:masgn, s(:array, s(:lasgn, :x), s(:lasgn, :y))),
|
83
|
+
s(:call, s(:lvar, :x), op, s(:arglist, s(:lvar, :y))))
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# no_arg_block(:foo, "bar") returns the ast of
|
88
|
+
#
|
89
|
+
# foo { "bar" }
|
90
|
+
#
|
91
|
+
def no_arg_block(name, ret)
|
92
|
+
s(:iter, s(:call, nil, name, s(:arglist)), nil, s(:str, ret))
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# binop_block(:foo, :+) returns the ast of
|
97
|
+
#
|
98
|
+
# foo { |x, y| x + y }
|
99
|
+
#
|
100
|
+
def binop_block(name, op)
|
101
|
+
s(:iter,
|
102
|
+
s(:call, nil, name, s(:arglist)),
|
103
|
+
s(:masgn, s(:array, s(:lasgn, :x), s(:lasgn, :y))),
|
104
|
+
s(:call, s(:lvar, :x), op, s(:arglist, s(:lvar, :y))))
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# binop_proc_new(:*) returns the ast of
|
109
|
+
#
|
110
|
+
# Proc.new { |x, y| x * y }
|
111
|
+
#
|
112
|
+
def binop_proc_new(op)
|
113
|
+
s(:iter,
|
114
|
+
s(:call, s(:const, :Proc), :new, s(:arglist)),
|
115
|
+
s(:masgn, s(:array, s(:lasgn, :x), s(:lasgn, :y))),
|
116
|
+
s(:call, s(:lvar, :x), op, s(:arglist, s(:lvar, :y))))
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'ruby2ruby'
|
2
|
+
|
3
|
+
module LiveASTRubyParser::Unparser
|
4
|
+
class << self
|
5
|
+
# Whether the unparsed code matches ruby2ruby output.
|
6
|
+
def ruby2ruby?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
|
10
|
+
# Return a ruby source string which reflects the given AST.
|
11
|
+
def unparse(sexp)
|
12
|
+
Ruby2Ruby.new.process(sexp)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: live_ast_ruby_parser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.5.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- James M. Lawrence
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-02-24 00:00:00 -05:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: ruby_parser
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - "="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 2.0.6
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ruby2ruby
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id002
|
38
|
+
description: The nested TestForms module enables testing with the LiveAST test suite.
|
39
|
+
email:
|
40
|
+
- quixoticsycophant@gmail.com
|
41
|
+
executables: []
|
42
|
+
|
43
|
+
extensions: []
|
44
|
+
|
45
|
+
extra_rdoc_files:
|
46
|
+
- README.rdoc
|
47
|
+
files:
|
48
|
+
- CHANGES.rdoc
|
49
|
+
- README.rdoc
|
50
|
+
- Rakefile
|
51
|
+
- devel/jumpstart.rb
|
52
|
+
- lib/live_ast_ruby_parser.rb
|
53
|
+
- lib/live_ast_ruby_parser/test_forms.rb
|
54
|
+
- lib/live_ast_ruby_parser/unparser.rb
|
55
|
+
- MANIFEST
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://quix.github.com/live_ast_ruby_parser
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options:
|
62
|
+
- --main
|
63
|
+
- README.rdoc
|
64
|
+
- --title
|
65
|
+
- "live_ast_ruby_parser: This is the default RubyParser-based parser used by LiveAST."
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "0"
|
80
|
+
requirements: []
|
81
|
+
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 1.5.2
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: This is the default RubyParser-based parser used by LiveAST.
|
87
|
+
test_files: []
|
88
|
+
|