rubyjs 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +128 -0
- data/Rakefile +9 -0
- data/bin/rubyjs +140 -0
- data/examples/ex1/Rakefile +7 -0
- data/examples/ex1/ex1.js +771 -0
- data/examples/ex1/ex1.rb +42 -0
- data/examples/ex1/index.html +7 -0
- data/examples/hw/Rakefile +9 -0
- data/examples/hw/hw.js +635 -0
- data/examples/hw/hw.rb +7 -0
- data/examples/hw/index.html +7 -0
- data/patches/parse_tree.rb.diff +34 -0
- data/rubyjs.gemspec +24 -0
- data/src/rubyjs.rb +4 -0
- data/src/rubyjs/code_generator.rb +474 -0
- data/src/rubyjs/compiler.rb +2007 -0
- data/src/rubyjs/debug_name_generator.rb +75 -0
- data/src/rubyjs/encoder.rb +171 -0
- data/src/rubyjs/eval_into.rb +59 -0
- data/src/rubyjs/lib/core.rb +1008 -0
- data/src/rubyjs/lib/json.rb +101 -0
- data/src/rubyjs/model.rb +287 -0
- data/src/rubyjs/name_generator.rb +71 -0
- data/src/rwt/AbsolutePanel.rb +161 -0
- data/src/rwt/DOM.Konqueror.rb +89 -0
- data/src/rwt/DOM.Opera.rb +65 -0
- data/src/rwt/DOM.rb +1044 -0
- data/src/rwt/Event.Opera.rb +35 -0
- data/src/rwt/Event.rb +429 -0
- data/src/rwt/HTTPRequest.IE6.rb +5 -0
- data/src/rwt/HTTPRequest.rb +74 -0
- data/src/rwt/Label.rb +164 -0
- data/src/rwt/Panel.rb +90 -0
- data/src/rwt/RootPanel.rb +16 -0
- data/src/rwt/UIObject.rb +495 -0
- data/src/rwt/Widget.rb +193 -0
- data/src/rwt/ported-from/AbsolutePanel.java +158 -0
- data/src/rwt/ported-from/DOM.java +571 -0
- data/src/rwt/ported-from/DOMImpl.java +426 -0
- data/src/rwt/ported-from/DOMImplOpera.java +82 -0
- data/src/rwt/ported-from/DOMImplStandard.java +234 -0
- data/src/rwt/ported-from/HTTPRequest.java +81 -0
- data/src/rwt/ported-from/HTTPRequestImpl.java +103 -0
- data/src/rwt/ported-from/Label.java +163 -0
- data/src/rwt/ported-from/Panel.java +99 -0
- data/src/rwt/ported-from/UIObject.java +614 -0
- data/src/rwt/ported-from/Widget.java +221 -0
- data/test/benchmark/bm_call_conv1.js +16 -0
- data/test/benchmark/bm_call_conv2.js +14 -0
- data/test/benchmark/bm_var_acc1.js +13 -0
- data/test/benchmark/bm_var_acc2.js +11 -0
- data/test/benchmark/bm_vm1_block.js +15 -0
- data/test/benchmark/bm_vm1_block.rb +15 -0
- data/test/benchmark/bm_vm1_const.js +13 -0
- data/test/benchmark/bm_vm1_const.rb +13 -0
- data/test/benchmark/bm_vm1_ensure.js +17 -0
- data/test/benchmark/bm_vm1_ensure.rb +15 -0
- data/test/benchmark/common.js +4 -0
- data/test/benchmark/common.rb +5 -0
- data/test/benchmark/params.yaml +7 -0
- data/test/browser.test.html +4059 -0
- data/test/browser.test.js +3225 -0
- data/test/common.Browser.rb +13 -0
- data/test/common.rb +8 -0
- data/test/gen_browser_test_suite.rb +129 -0
- data/test/gen_test_suite.rb +41 -0
- data/test/run_benchs.rb +58 -0
- data/test/run_tests.rb +22 -0
- data/test/test_args.rb +24 -0
- data/test/test_array.rb +26 -0
- data/test/test_case.rb +35 -0
- data/test/test_class.rb +55 -0
- data/test/test_eql.rb +9 -0
- data/test/test_exception.rb +61 -0
- data/test/test_expr.rb +12 -0
- data/test/test_hash.rb +29 -0
- data/test/test_if.rb +28 -0
- data/test/test_inspect.rb +10 -0
- data/test/test_lebewesen.rb +39 -0
- data/test/test_massign.rb +66 -0
- data/test/test_new.rb +12 -0
- data/test/test_range.rb +53 -0
- data/test/test_regexp.rb +22 -0
- data/test/test_send.rb +65 -0
- data/test/test_simple_output.rb +5 -0
- data/test/test_splat.rb +21 -0
- data/test/test_string.rb +51 -0
- data/test/test_yield.rb +152 -0
- data/utils/js/Makefile +9 -0
- data/utils/js/RunScript.class +0 -0
- data/utils/js/RunScript.java +73 -0
- data/utils/js/js.jar +0 -0
- data/utils/js/run.sh +3 -0
- data/utils/jsc/Makefile +7 -0
- data/utils/jsc/README +3 -0
- data/utils/jsc/RunScript.c +93 -0
- data/utils/jsc/run.sh +15 -0
- data/utils/yuicompressor/README +1 -0
- data/utils/yuicompressor/yuicompressor-2.2.5.jar +0 -0
- data/vendor/ParseTree-1.7.1-patched/History.txt +217 -0
- data/vendor/ParseTree-1.7.1-patched/Manifest.txt +22 -0
- data/vendor/ParseTree-1.7.1-patched/README.txt +110 -0
- data/vendor/ParseTree-1.7.1-patched/Rakefile +41 -0
- data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_abc +89 -0
- data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_audit +28 -0
- data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_deps +62 -0
- data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_show +49 -0
- data/vendor/ParseTree-1.7.1-patched/demo/printer.rb +20 -0
- data/vendor/ParseTree-1.7.1-patched/lib/composite_sexp_processor.rb +49 -0
- data/vendor/ParseTree-1.7.1-patched/lib/parse_tree.rb +1013 -0
- data/vendor/ParseTree-1.7.1-patched/lib/sexp.rb +235 -0
- data/vendor/ParseTree-1.7.1-patched/lib/sexp_processor.rb +330 -0
- data/vendor/ParseTree-1.7.1-patched/lib/unique.rb +15 -0
- data/vendor/ParseTree-1.7.1-patched/test/pt_testcase.rb +1221 -0
- data/vendor/ParseTree-1.7.1-patched/test/something.rb +53 -0
- data/vendor/ParseTree-1.7.1-patched/test/test_all.rb +13 -0
- data/vendor/ParseTree-1.7.1-patched/test/test_composite_sexp_processor.rb +69 -0
- data/vendor/ParseTree-1.7.1-patched/test/test_parse_tree.rb +216 -0
- data/vendor/ParseTree-1.7.1-patched/test/test_sexp.rb +291 -0
- data/vendor/ParseTree-1.7.1-patched/test/test_sexp_processor.rb +244 -0
- data/vendor/ParseTree-1.7.1-patched/validate.sh +31 -0
- data/vendor/ParseTree-1.7.1/History.txt +217 -0
- data/vendor/ParseTree-1.7.1/Manifest.txt +22 -0
- data/vendor/ParseTree-1.7.1/README.txt +110 -0
- data/vendor/ParseTree-1.7.1/Rakefile +41 -0
- data/vendor/ParseTree-1.7.1/bin/parse_tree_abc +89 -0
- data/vendor/ParseTree-1.7.1/bin/parse_tree_audit +28 -0
- data/vendor/ParseTree-1.7.1/bin/parse_tree_deps +62 -0
- data/vendor/ParseTree-1.7.1/bin/parse_tree_show +49 -0
- data/vendor/ParseTree-1.7.1/demo/printer.rb +20 -0
- data/vendor/ParseTree-1.7.1/lib/composite_sexp_processor.rb +49 -0
- data/vendor/ParseTree-1.7.1/lib/parse_tree.rb +1004 -0
- data/vendor/ParseTree-1.7.1/lib/sexp.rb +235 -0
- data/vendor/ParseTree-1.7.1/lib/sexp_processor.rb +330 -0
- data/vendor/ParseTree-1.7.1/lib/unique.rb +15 -0
- data/vendor/ParseTree-1.7.1/test/pt_testcase.rb +1221 -0
- data/vendor/ParseTree-1.7.1/test/something.rb +53 -0
- data/vendor/ParseTree-1.7.1/test/test_all.rb +13 -0
- data/vendor/ParseTree-1.7.1/test/test_composite_sexp_processor.rb +69 -0
- data/vendor/ParseTree-1.7.1/test/test_parse_tree.rb +216 -0
- data/vendor/ParseTree-1.7.1/test/test_sexp.rb +291 -0
- data/vendor/ParseTree-1.7.1/test/test_sexp_processor.rb +244 -0
- data/vendor/ParseTree-1.7.1/validate.sh +31 -0
- metadata +230 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
bin/parse_tree_abc
|
6
|
+
bin/parse_tree_audit
|
7
|
+
bin/parse_tree_deps
|
8
|
+
bin/parse_tree_show
|
9
|
+
demo/printer.rb
|
10
|
+
lib/composite_sexp_processor.rb
|
11
|
+
lib/parse_tree.rb
|
12
|
+
lib/sexp.rb
|
13
|
+
lib/sexp_processor.rb
|
14
|
+
lib/unique.rb
|
15
|
+
test/pt_testcase.rb
|
16
|
+
test/something.rb
|
17
|
+
test/test_all.rb
|
18
|
+
test/test_composite_sexp_processor.rb
|
19
|
+
test/test_parse_tree.rb
|
20
|
+
test/test_sexp.rb
|
21
|
+
test/test_sexp_processor.rb
|
22
|
+
validate.sh
|
@@ -0,0 +1,110 @@
|
|
1
|
+
ParseTree
|
2
|
+
http://rubyforge.org/projects/parsetree/
|
3
|
+
http://www.zenspider.com/ZSS/Products/ParseTree/
|
4
|
+
support@zenspider.com
|
5
|
+
|
6
|
+
** DESCRIPTION:
|
7
|
+
|
8
|
+
ParseTree is a C extension (using RubyInline) that extracts the parse
|
9
|
+
tree for an entire class or a specific method and returns it as a
|
10
|
+
s-expression (aka sexp) using ruby's arrays, strings, symbols, and
|
11
|
+
integers.
|
12
|
+
|
13
|
+
As an example:
|
14
|
+
|
15
|
+
def conditional1(arg1)
|
16
|
+
if arg1 == 0 then
|
17
|
+
return 1
|
18
|
+
end
|
19
|
+
return 0
|
20
|
+
end
|
21
|
+
|
22
|
+
becomes:
|
23
|
+
|
24
|
+
[:defn,
|
25
|
+
:conditional1,
|
26
|
+
[:scope,
|
27
|
+
[:block,
|
28
|
+
[:args, :arg1],
|
29
|
+
[:if,
|
30
|
+
[:call, [:lvar, :arg1], :==, [:array, [:lit, 0]]],
|
31
|
+
[:return, [:lit, 1]],
|
32
|
+
nil],
|
33
|
+
[:return, [:lit, 0]]]]]
|
34
|
+
|
35
|
+
** FEATURES/PROBLEMS:
|
36
|
+
|
37
|
+
+ Uses RubyInline, so it just drops in.
|
38
|
+
+ Includes SexpProcessor and CompositeSexpProcessor.
|
39
|
+
+ Allows you to write very clean filters.
|
40
|
+
+ Includes parse_tree_show, which lets you quickly snoop code.
|
41
|
+
+ echo "1+1" | parse_tree_show -f for quick snippet output.
|
42
|
+
+ Includes parse_tree_abc, which lets you get abc metrics on code.
|
43
|
+
+ abc metrics = numbers of assignments, branches, and calls.
|
44
|
+
+ whitespace independent metric for method complexity.
|
45
|
+
+ Includes parse_tree_deps, which shows you basic class level dependencies.
|
46
|
+
+ Only works on methods in classes/modules, not arbitrary code.
|
47
|
+
+ Does not work on the core classes, as they are not ruby (yet).
|
48
|
+
|
49
|
+
** SYNOPSYS:
|
50
|
+
|
51
|
+
sexp_array = ParseTree.new.parse_tree(klass)
|
52
|
+
|
53
|
+
or:
|
54
|
+
|
55
|
+
class MyProcessor < SexpProcessor
|
56
|
+
def initialize
|
57
|
+
super
|
58
|
+
self.strict = false
|
59
|
+
end
|
60
|
+
def process_lit(exp)
|
61
|
+
val = exp.shift
|
62
|
+
return val
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
or:
|
67
|
+
|
68
|
+
% ./parse_tree_show myfile.rb
|
69
|
+
|
70
|
+
or:
|
71
|
+
|
72
|
+
% echo "1+1" | ./parse_tree_show -f
|
73
|
+
|
74
|
+
or:
|
75
|
+
|
76
|
+
% ./parse_tree_abc myfile.rb
|
77
|
+
|
78
|
+
** REQUIREMENTS:
|
79
|
+
|
80
|
+
+ RubyInline 3 or better.
|
81
|
+
|
82
|
+
** INSTALL:
|
83
|
+
|
84
|
+
+ sudo rake install
|
85
|
+
+ or: sudo gem install ParseTree
|
86
|
+
|
87
|
+
** LICENSE:
|
88
|
+
|
89
|
+
(The MIT License)
|
90
|
+
|
91
|
+
Copyright (c) 2001-2004 Ryan Davis, Zen Spider Software
|
92
|
+
|
93
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
94
|
+
a copy of this software and associated documentation files (the
|
95
|
+
"Software"), to deal in the Software without restriction, including
|
96
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
97
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
98
|
+
permit persons to whom the Software is furnished to do so, subject to
|
99
|
+
the following conditions:
|
100
|
+
|
101
|
+
The above copyright notice and this permission notice shall be
|
102
|
+
included in all copies or substantial portions of the Software.
|
103
|
+
|
104
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
105
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
106
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
107
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
108
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
109
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
110
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
|
6
|
+
$: << "../../RubyInline/dev"
|
7
|
+
require './lib/parse_tree.rb'
|
8
|
+
|
9
|
+
Hoe.new("ParseTree", ParseTree::VERSION) do |p|
|
10
|
+
p.rubyforge_name = "parsetree"
|
11
|
+
p.summary = "Extract and enumerate ruby parse trees."
|
12
|
+
p.description = p.paragraphs_of("README.txt", 2).join("\n\n")
|
13
|
+
p.changes = p.paragraphs_of("History.txt", 1).join("\n\n")
|
14
|
+
p.clean_globs << File.expand_path("~/.ruby_inline")
|
15
|
+
p.extra_deps << ['RubyInline', '>= 3.2.0']
|
16
|
+
p.spec_extras[:require_paths] = proc { |paths| paths << 'test' }
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'Run against ruby 1.9 (from a multiruby install) with -d.'
|
20
|
+
task :test19 do
|
21
|
+
sh "~/.multiruby/install/1_9/bin/ruby -d #{Hoe::RUBY_FLAGS} test/test_all.rb #{Hoe::FILTER}"
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Run in gdb'
|
25
|
+
task :debug do
|
26
|
+
puts "RUN: r -d #{Hoe::RUBY_FLAGS} test/test_all.rb #{Hoe::FILTER}"
|
27
|
+
sh "gdb ~/.multiruby/install/19/bin/ruby"
|
28
|
+
end
|
29
|
+
|
30
|
+
desc 'Run a very basic demo'
|
31
|
+
task :demo do
|
32
|
+
sh "echo 1+1 | ruby #{Hoe::RUBY_FLAGS} ./bin/parse_tree_show -f"
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Show what tests are not sorted'
|
36
|
+
task :sort do
|
37
|
+
sh "pgrep '^ \\\"(\\w+)' test/pt_testcase.rb | cut -f 2 -d\\\" > x"
|
38
|
+
sh "sort x > y"
|
39
|
+
sh "diff x y"
|
40
|
+
sh "rm -f x y"
|
41
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
#!/usr/local/bin/ruby -ws
|
2
|
+
|
3
|
+
# ABC metric
|
4
|
+
#
|
5
|
+
# Assignments, Branches, and Calls
|
6
|
+
#
|
7
|
+
# A simple way to measure the complexity of a function or method.
|
8
|
+
|
9
|
+
if defined? $I and String === $I then
|
10
|
+
$I.split(/:/).each do |dir|
|
11
|
+
$: << dir
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
PARSE_TREE_ABC=true
|
16
|
+
|
17
|
+
begin require 'rubygems' rescue LoadError end
|
18
|
+
require 'sexp'
|
19
|
+
require 'parse_tree'
|
20
|
+
require 'sexp_processor'
|
21
|
+
|
22
|
+
old_classes = []
|
23
|
+
ObjectSpace.each_object(Module) do |klass|
|
24
|
+
old_classes << klass
|
25
|
+
end
|
26
|
+
|
27
|
+
ARGV.each do |name|
|
28
|
+
begin
|
29
|
+
require name
|
30
|
+
rescue NameError => err
|
31
|
+
$stderr.puts "ERROR requiring #{name}. Perhaps you need to add some -I's?\n\n#{err}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
new_classes = []
|
36
|
+
ObjectSpace.each_object(Module) do |klass|
|
37
|
+
new_classes << klass
|
38
|
+
end
|
39
|
+
|
40
|
+
score = {}
|
41
|
+
|
42
|
+
new_classes -= old_classes
|
43
|
+
|
44
|
+
klasses = Sexp.from_array(ParseTree.new.parse_tree(*new_classes))
|
45
|
+
klasses.each do |klass|
|
46
|
+
klass.shift # :class
|
47
|
+
klassname = klass.shift
|
48
|
+
klass.shift # superclass
|
49
|
+
methods = klass
|
50
|
+
|
51
|
+
methods.each do |defn|
|
52
|
+
a=b=c=0
|
53
|
+
defn.shift
|
54
|
+
methodname = defn.shift
|
55
|
+
tokens = defn.structure.flatten
|
56
|
+
tokens.each do |token|
|
57
|
+
case token
|
58
|
+
when :attrasgn, :attrset, :dasgn_curr, :iasgn, :lasgn, :masgn then
|
59
|
+
a += 1
|
60
|
+
when :and, :case, :else, :if, :iter, :or, :rescue, :until, :when, :while then
|
61
|
+
b += 1
|
62
|
+
when :call, :fcall, :super, :vcall, :yield then
|
63
|
+
c += 1
|
64
|
+
when :args, :argscat, :array, :begin, :block, :block_arg, :block_pass, :bool, :cfunc, :colon2, :const, :cvar, :defined, :defn, :dregx, :dstr, :dvar, :dxstr, :ensure, :false, :fbody, :gvar, :hash, :ivar, :lit, :long, :lvar, :match2, :match3, :nil, :not, :nth_ref, :return, :scope, :self, :splat, :str, :to_ary, :true, :unknown, :value, :void, :zarray, :zarray, :zclass, :zsuper then
|
65
|
+
# ignore
|
66
|
+
else
|
67
|
+
puts "unhandled token #{token.inspect}" if $VERBOSE
|
68
|
+
end
|
69
|
+
end
|
70
|
+
key = ["#{klassname}.#{methodname}", a, b, c]
|
71
|
+
val = Math.sqrt(a*a+b*b+c*c)
|
72
|
+
score[key] = val
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
puts "|ABC| = Math.sqrt(assignments^2 + branches^2 + calls^2)"
|
77
|
+
puts
|
78
|
+
count = 1
|
79
|
+
ta = tb = tc = tval = 0
|
80
|
+
score.sort_by { |k,v| v }.reverse.each do |key,val|
|
81
|
+
name, a, b, c = *key
|
82
|
+
ta += a
|
83
|
+
tb += b
|
84
|
+
tc += c
|
85
|
+
tval += val
|
86
|
+
printf "%3d) %-50s = %2d + %2d + %2d = %6.2f\n", count, name, a, b, c, val
|
87
|
+
count += 1
|
88
|
+
end rescue nil
|
89
|
+
printf "%3d) %-50s = %2d + %2d + %2d = %6.2f\n", count, "Total", ta, tb, tc, tval
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
require 'parse_tree'
|
4
|
+
|
5
|
+
all_nodes = ParseTree::NODE_NAMES
|
6
|
+
|
7
|
+
ARGV.each do |processor|
|
8
|
+
require processor
|
9
|
+
end
|
10
|
+
|
11
|
+
ObjectSpace.each_object(Class) do |klass|
|
12
|
+
if klass < SexpProcessor then
|
13
|
+
|
14
|
+
processor = klass.new
|
15
|
+
processors = klass.public_instance_methods(true).grep(/process_/)
|
16
|
+
|
17
|
+
if processor.strict then
|
18
|
+
puts "#{klass.name}:"
|
19
|
+
puts
|
20
|
+
|
21
|
+
# TODO: check unsupported against supported
|
22
|
+
processors = processors.map { |m| m[8..-1].intern } + processor.unsupported
|
23
|
+
unsupported = all_nodes - processors
|
24
|
+
p unsupported.sort_by { |sym| sym.to_s }
|
25
|
+
puts
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/usr/local/bin/ruby -ws
|
2
|
+
|
3
|
+
old_classes = []; new_classes = []
|
4
|
+
|
5
|
+
ObjectSpace.each_object(Module) { |klass| old_classes << klass } if defined? $a
|
6
|
+
|
7
|
+
require 'pp'
|
8
|
+
|
9
|
+
begin require 'rubygems' rescue LoadError end
|
10
|
+
require 'parse_tree'
|
11
|
+
require 'sexp_processor'
|
12
|
+
|
13
|
+
ObjectSpace.each_object(Module) { |klass| old_classes << klass } unless defined? $a
|
14
|
+
|
15
|
+
class DependencyAnalyzer < SexpProcessor
|
16
|
+
|
17
|
+
attr_reader :dependencies
|
18
|
+
attr_accessor :current_class
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
super
|
22
|
+
self.auto_shift_type = true
|
23
|
+
@dependencies = Hash.new { |h,k| h[k] = [] }
|
24
|
+
@current_method = nil
|
25
|
+
@current_class = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.process(*klasses)
|
29
|
+
analyzer = self.new
|
30
|
+
klasses.each do |start_klass|
|
31
|
+
analyzer.current_class = start_klass
|
32
|
+
analyzer.process(ParseTree.new.parse_tree(start_klass))
|
33
|
+
end
|
34
|
+
|
35
|
+
deps = analyzer.dependencies
|
36
|
+
deps.keys.sort_by {|k| k.to_s}.each do |dep_to|
|
37
|
+
dep_from = deps[dep_to]
|
38
|
+
puts "#{dep_to}: #{dep_from.uniq.sort.join(", ")}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def process_defn(exp)
|
43
|
+
name = exp.shift
|
44
|
+
@current_method = name
|
45
|
+
return s(:defn, name, process(exp.shift), process(exp.shift))
|
46
|
+
end
|
47
|
+
|
48
|
+
def process_const(exp)
|
49
|
+
name = exp.shift
|
50
|
+
const = (defined?($c) ? @current_class.name : "#{@current_class}.#{@current_method}")
|
51
|
+
is_class = ! (Object.const_get(name) rescue nil).nil?
|
52
|
+
@dependencies[name] << const if is_class
|
53
|
+
return s(:const, name)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if __FILE__ == $0 then
|
58
|
+
ARGV.each { |name| require name }
|
59
|
+
ObjectSpace.each_object(Module) { |klass| new_classes << klass }
|
60
|
+
new_classes.delete DependencyAnalyzer unless defined? $a
|
61
|
+
DependencyAnalyzer.process(*(new_classes - old_classes))
|
62
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/local/bin/ruby -ws
|
2
|
+
|
3
|
+
require 'pp'
|
4
|
+
begin require 'rubygems' rescue LoadError end
|
5
|
+
require 'parse_tree'
|
6
|
+
|
7
|
+
def discover_new_classes_from
|
8
|
+
old_classes = []
|
9
|
+
ObjectSpace.each_object(Module) do |klass|
|
10
|
+
old_classes << klass
|
11
|
+
end
|
12
|
+
|
13
|
+
yield
|
14
|
+
|
15
|
+
new_classes = []
|
16
|
+
ObjectSpace.each_object(Module) do |klass|
|
17
|
+
new_classes << klass
|
18
|
+
end
|
19
|
+
|
20
|
+
new_classes -= old_classes
|
21
|
+
new_classes = [ eval($c) ] if defined? $c
|
22
|
+
new_classes
|
23
|
+
end
|
24
|
+
|
25
|
+
$f = false unless defined? $f
|
26
|
+
|
27
|
+
new_classes = discover_new_classes_from do
|
28
|
+
ARGV.unshift "-" if ARGV.empty?
|
29
|
+
ARGV.each do |name|
|
30
|
+
if name == "-" then
|
31
|
+
code = $stdin.read
|
32
|
+
code = "class Example; def example; #{code}; end; end" if $f
|
33
|
+
eval code unless code.nil?
|
34
|
+
else
|
35
|
+
require name
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
result = ParseTree.new.parse_tree(*new_classes)
|
41
|
+
|
42
|
+
result = result[0][3][2][1][2..-1] if $f
|
43
|
+
|
44
|
+
unless defined? $q then
|
45
|
+
pp result
|
46
|
+
else
|
47
|
+
p result
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
require 'rubygems'
|
3
|
+
require 'sexp_processor'
|
4
|
+
|
5
|
+
class QuickPrinter < SexpProcessor
|
6
|
+
def initialize
|
7
|
+
super
|
8
|
+
self.strict = false
|
9
|
+
self.auto_shift_type = true
|
10
|
+
end
|
11
|
+
def process_defn(exp)
|
12
|
+
name = exp.shift
|
13
|
+
args = process exp.shift
|
14
|
+
body = process exp.shift
|
15
|
+
puts " def #{name}"
|
16
|
+
return s(:defn, name, args, body)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
QuickPrinter.new.process(*ParseTree.new.parse_tree(QuickPrinter))
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'sexp_processor'
|
2
|
+
|
3
|
+
##
|
4
|
+
# Implements the Composite pattern on SexpProcessor. Need we say more?
|
5
|
+
#
|
6
|
+
# Yeah... probably. Implements a SexpProcessor of SexpProcessors so
|
7
|
+
# you can easily chain multiple to each other. At some stage we plan
|
8
|
+
# on having all of them run +process+ and but only ever output
|
9
|
+
# something when +generate+ is called, allowing for deferred final
|
10
|
+
# processing.
|
11
|
+
|
12
|
+
class CompositeSexpProcessor < SexpProcessor
|
13
|
+
|
14
|
+
##
|
15
|
+
# The list o' processors to run.
|
16
|
+
|
17
|
+
attr_reader :processors
|
18
|
+
|
19
|
+
def initialize # :nodoc:
|
20
|
+
super
|
21
|
+
@processors = []
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Add a +processor+ to the list of processors to run.
|
26
|
+
|
27
|
+
def <<(processor)
|
28
|
+
raise ArgumentError, "Can only add sexp processors" unless
|
29
|
+
SexpProcessor === processor
|
30
|
+
@processors << processor
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Run +exp+ through all of the processors, returning the final
|
35
|
+
# result.
|
36
|
+
|
37
|
+
def process(exp)
|
38
|
+
@processors.each do |processor|
|
39
|
+
exp = processor.process(exp)
|
40
|
+
end
|
41
|
+
exp
|
42
|
+
end
|
43
|
+
|
44
|
+
def on_error_in(node_type, &block)
|
45
|
+
@processors.each do |processor|
|
46
|
+
processor.on_error_in(node_type, &block)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|