superchris-rubyjs 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/README +131 -0
  2. data/Rakefile +65 -0
  3. data/bin/rubyjs +144 -0
  4. data/rubyjs.gemspec +112 -0
  5. data/src/rubyjs.rb +3 -0
  6. data/src/rubyjs/code_generator.rb +474 -0
  7. data/src/rubyjs/compiler.rb +2061 -0
  8. data/src/rubyjs/debug_name_generator.rb +95 -0
  9. data/src/rubyjs/encoder.rb +171 -0
  10. data/src/rubyjs/eval_into.rb +59 -0
  11. data/src/rubyjs/lib/core.rb +1016 -0
  12. data/src/rubyjs/lib/dom_element.rb +66 -0
  13. data/src/rubyjs/lib/json.rb +101 -0
  14. data/src/rubyjs/lib/microunit.rb +188 -0
  15. data/src/rubyjs/model.rb +293 -0
  16. data/src/rubyjs/name_generator.rb +71 -0
  17. data/src/rwt/AbsolutePanel.rb +161 -0
  18. data/src/rwt/DOM.Konqueror.rb +89 -0
  19. data/src/rwt/DOM.Opera.rb +65 -0
  20. data/src/rwt/DOM.rb +1044 -0
  21. data/src/rwt/Event.Opera.rb +35 -0
  22. data/src/rwt/Event.rb +429 -0
  23. data/src/rwt/HTTPRequest.IE6.rb +5 -0
  24. data/src/rwt/HTTPRequest.rb +74 -0
  25. data/src/rwt/Label.rb +164 -0
  26. data/src/rwt/Panel.rb +90 -0
  27. data/src/rwt/RootPanel.rb +16 -0
  28. data/src/rwt/UIObject.rb +495 -0
  29. data/src/rwt/Widget.rb +193 -0
  30. data/src/rwt/ported-from/AbsolutePanel.java +158 -0
  31. data/src/rwt/ported-from/DOM.java +571 -0
  32. data/src/rwt/ported-from/DOMImpl.java +426 -0
  33. data/src/rwt/ported-from/DOMImplOpera.java +82 -0
  34. data/src/rwt/ported-from/DOMImplStandard.java +234 -0
  35. data/src/rwt/ported-from/HTTPRequest.java +81 -0
  36. data/src/rwt/ported-from/HTTPRequestImpl.java +103 -0
  37. data/src/rwt/ported-from/Label.java +163 -0
  38. data/src/rwt/ported-from/Panel.java +99 -0
  39. data/src/rwt/ported-from/UIObject.java +614 -0
  40. data/src/rwt/ported-from/Widget.java +221 -0
  41. data/test/benchmark/bm_vm1_block.rb +15 -0
  42. data/test/benchmark/bm_vm1_const.rb +13 -0
  43. data/test/benchmark/bm_vm1_ensure.rb +15 -0
  44. data/test/benchmark/common.rb +5 -0
  45. data/test/benchmark/params.yaml +7 -0
  46. data/test/common.Browser.rb +13 -0
  47. data/test/common.rb +8 -0
  48. data/test/gen_browser_test_suite.rb +129 -0
  49. data/test/gen_test_suite.rb +41 -0
  50. data/test/run_benchs.rb +58 -0
  51. data/test/run_tests.rb +22 -0
  52. data/test/test_args.rb +24 -0
  53. data/test/test_array.rb +22 -0
  54. data/test/test_case.rb +35 -0
  55. data/test/test_class.rb +55 -0
  56. data/test/test_eql.rb +9 -0
  57. data/test/test_exception.rb +61 -0
  58. data/test/test_expr.rb +12 -0
  59. data/test/test_hash.rb +29 -0
  60. data/test/test_hot_ruby.rb +146 -0
  61. data/test/test_if.rb +28 -0
  62. data/test/test_insertion_sort.rb +25 -0
  63. data/test/test_inspect.rb +10 -0
  64. data/test/test_lebewesen.rb +39 -0
  65. data/test/test_massign.rb +66 -0
  66. data/test/test_new.rb +12 -0
  67. data/test/test_range.rb +70 -0
  68. data/test/test_regexp.rb +22 -0
  69. data/test/test_send.rb +65 -0
  70. data/test/test_simple_output.rb +5 -0
  71. data/test/test_splat.rb +21 -0
  72. data/test/test_string.rb +51 -0
  73. data/test/test_test.rb +17 -0
  74. data/test/test_yield.rb +154 -0
  75. data/utils/js/Makefile +9 -0
  76. data/utils/js/RunScript.class +0 -0
  77. data/utils/js/RunScript.java +73 -0
  78. data/utils/js/js.jar +0 -0
  79. data/utils/js/run.sh +3 -0
  80. data/utils/jsc/Makefile +7 -0
  81. data/utils/jsc/README +3 -0
  82. data/utils/jsc/RunScript.c +93 -0
  83. data/utils/jsc/run.sh +15 -0
  84. data/utils/yuicompressor/README +1 -0
  85. data/utils/yuicompressor/yuicompressor-2.2.5.jar +0 -0
  86. metadata +157 -0
data/README ADDED
@@ -0,0 +1,131 @@
1
+ ------------------------------------
2
+ RubyJS - Ruby to Javascript Compiler
3
+ ------------------------------------
4
+
5
+ COPYRIGHT
6
+
7
+ Copyright (c) 2007, 2008 by Michael Neumann (mneumann@ntecs.de).
8
+ All rights reserved.
9
+
10
+ ABOUT
11
+
12
+ RubyJS translates Ruby code into Javascript code. NOTE that it executes
13
+ the Ruby code before it translates it into Javascript. This has the
14
+ advantage of being able to (mis-)use all of Ruby's meta-programming
15
+ tricks in the global scope (i.e. for defining classes and methods, NOT
16
+ within methods!).
17
+
18
+ REQUIREMENTS
19
+
20
+ * Ruby >= 1.8.6
21
+ * ParseTree >= 2.1.1
22
+
23
+ MAPPING
24
+
25
+ The mapping from Ruby objects (left) to Javascript values (right) are
26
+ given below.
27
+
28
+ true -> true (class Boolean)
29
+ false -> false (class Boolean)
30
+ nil -> nil (a special variable!)
31
+ 1, 1.2 -> Javascript Number (unboxed)
32
+ "String" -> immutable Javascript String (unboxed)
33
+ /regexp/ -> /regexp/ (unboxed)
34
+ [array] -> [array] (unboxed)
35
+ {hash} -> Javascript Hash object (unboxed, but indirect)
36
+ iterator -> function (unboxed)
37
+ 1..2 -> custom Range object
38
+
39
+ BUGS
40
+
41
+ --
42
+ Debug mode sometimes generates code that does not run!
43
+
44
+ --
45
+ Spidermonkey doesn't run all tests.
46
+
47
+ TODO
48
+
49
+ --
50
+ Issue a warning whenever a destructive Ruby string method like gsub!
51
+ is used. The reason behind this warning is that, due to efficience
52
+ reasons, Ruby strings (which are mutable) are mapped to immutable
53
+ Javascript strings.
54
+
55
+ --
56
+ Command-line switch that doesn't call methods for some operators.
57
+ Most important ones are "+", "-" and "/". This is of course an unsafe
58
+ operation as you could define a method "+" in your own class. For
59
+ heavy math operations, this of course increases performance a lot!
60
+
61
+ --
62
+ Command-line switch that removes unused methods. This is possible, as
63
+ we record the names of all (possibly) called methods. This of course
64
+ disables send() support. This switch has the potential to reduce the
65
+ size of the generated Javascript significantly (which also reduces
66
+ memory consumption on the client side). For this to work, we have to
67
+ generate a call chain, which method name calls which other method
68
+ names. This works only on method names, as we can't infer the used
69
+ classes.
70
+
71
+ --
72
+ Command-line switch that disables the generation of name-information
73
+ used by methods like send(), instance_variables(), methods() or
74
+ respond_to?(). This makes it hard to decompile the Javascript code
75
+ back to Ruby or assign meaningful names.
76
+
77
+ LIMITATIONS
78
+
79
+ --
80
+ Module's are mapped to Classes for now.
81
+
82
+ --
83
+ You can't inherit from core classes like Array, String, Regexp and so
84
+ on. It's easy to allow by adding one further indirection, e.g. in that
85
+ on object creation an attribute "m" is assigned, which contains a hash
86
+ of all methods of that object, and on method call use "obj.m.method".
87
+ As long as this limitation is no problem, I go the way via prototypes,
88
+ which should be slightly more efficient.
89
+
90
+ --
91
+ You are not allowed to redefine the classes name method:
92
+
93
+ class MyClass
94
+ def self.name
95
+ # NOT ALLOWED!!!
96
+ end
97
+ end
98
+
99
+ The same is true for other methods like ancestors, superclass,
100
+ instance_methods, methods. But you wouldn't do that anyways in Ruby,
101
+ so that's no big restriction!
102
+
103
+ --
104
+ Constant assignment inside methods is forbidden. This is due to
105
+ using static constant lookup. Constant assignment inside the class
106
+ scope or module scope is not affected, as this is executed by the
107
+ Ruby interpreter.
108
+ Constants are either inlined in the case it is a value type (Fixnum, Float)
109
+ or a reference is generated (i.e. a variable holding it's value + a name).
110
+ References are only generated on demand, i.e. only when a constant is
111
+ accessed.
112
+
113
+ --
114
+ +break+ inside of loops cannot have arguments in RubyJS:
115
+
116
+ # RubyJS
117
+ while true
118
+ break 1 # => CompileTime Error
119
+ end
120
+
121
+ This could be accomplished, by introducing a "return loop"
122
+ variable for each while loop, and setting this variable
123
+ in "break".
124
+
125
+ A loop break cannot occur as expression. This could be accomplished
126
+ by using a throw instead of break and surrounding the loop by a catch.
127
+
128
+ The same applies for +next+!
129
+
130
+ --
131
+ Methods can be called regardless of their privacy (private, protected)
@@ -0,0 +1,65 @@
1
+ require 'rubygems'
2
+ RUBYJS_BIN = File.join ".", "bin", "rubyjs"
3
+
4
+ task :gen_tests do
5
+ ruby "test/gen_browser_test_suite.rb"
6
+ end
7
+
8
+ task :run_tests do
9
+ ruby "test/run_tests.rb"
10
+ end
11
+
12
+ task :default => :gen_tests
13
+
14
+ rule ".js" => ".rb" do |t|
15
+ klass = t.source.pathmap("%n").
16
+ split(/_/).collect { |part| part.capitalize}.join
17
+ sh "#{RUBYJS_BIN} -O PrettyPrint -d -m #{klass} -o #{t.name} #{t.source}"
18
+ end
19
+
20
+ rule ".html" => ".js" do |t|
21
+ File.open(t.name, "w") do |file|
22
+ file.puts <<EOHTML
23
+ <html>
24
+ <head>
25
+ <title></title>
26
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
27
+
28
+
29
+
30
+ </head>
31
+ <body>
32
+
33
+ <script src="#{t.source.pathmap("%f")}"></script>
34
+ </body>
35
+ </html>
36
+ EOHTML
37
+ end
38
+ end
39
+
40
+ desc "Generate a rubyspec file that github won't complain about"
41
+ task :generate_gemspec do
42
+ files = Dir['**/*'].reject { |file|
43
+ file if [/^nbproject/, /^examples/, /~$/, /\.gem$/, /test\/.*.js/, /test\/.*.html/ ].detect { |exp| file =~ exp }
44
+ }.map {|entry| "'#{entry}'"}.join(", \n")
45
+ File.open("rubyjs.gemspec", "w") do |f|
46
+ f.puts <<EOF
47
+ spec = Gem::Specification.new do |s|
48
+ s.name = 'rubyjs'
49
+ s.version = '0.8.2'
50
+ s.summary = 'RubyJS is a Ruby to Javascript Compiler. This is a fork with some added features. Orignally by Michael Neumann'
51
+
52
+ s.files = [#{files}]
53
+ s.add_dependency('ParseTree', '>= 2.1.1')
54
+ s.required_ruby_version = ">= 1.8.6"
55
+
56
+ s.require_path = 'src'
57
+ s.bindir = 'bin'
58
+ s.executables = ['rubyjs']
59
+
60
+ s.author = "Chris Nelson"
61
+ s.email = "me@christophernelsonconsulting.com"
62
+ end
63
+ EOF
64
+ end
65
+ end
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'ostruct'
5
+ require 'rubygems'
6
+
7
+ options = OpenStruct.new
8
+ options.load_path = []
9
+ options.library = []
10
+ options.platform = []
11
+ options.outputs = []
12
+ options.main = nil
13
+ options.code = nil
14
+ options.append = ""
15
+ options.debug = false
16
+ options.opts = []
17
+
18
+ OPTS = %w(NoArgumentArityChecks NoMethodMissing OptimizeArithOps PrettyPrint)
19
+
20
+ def show_options
21
+ puts "Compiler Options:"
22
+ puts " --opt NoArgumentArityChecks:: Disable generation of arity checking code"
23
+ puts " --opt NoMethodMissing:: Disable method_missing functionality"
24
+ puts " --opt OptimizeArithOps:: Enable native +-*/ operators"
25
+ puts " --opt PrettyPrint:: Output more readable code"
26
+ end
27
+
28
+ opts = OptionParser.new do |opts|
29
+ opts.banner = "Usage: rubyjs [options] [file, [file, ...]]"
30
+ opts.on("-r", "--require LIBRARY",
31
+ "Require the LIBRARY before executing your script") do |lib|
32
+ options.library << lib
33
+ end
34
+ opts.on("-I", "--load-path DIRECTORY", "Specifies load path") do |lib|
35
+ options.load_path << lib
36
+ end
37
+ opts.on("-P", "--platform PLATFORM", "Specifies platform") do |plat|
38
+ options.platform << plat
39
+ end
40
+ opts.on("-m", "--main CLASSNAME", "Entry point") do |main|
41
+ raise "only one entry point allowed" if options.main
42
+ options.main = main
43
+ end
44
+ opts.on("-e", "--eval STRING", "Eval code") do |code|
45
+ raise "only one code allowed" if options.code
46
+ options.code = code
47
+ end
48
+ opts.on("-a", "--append JSCODE", "Append Javascript code") do |append|
49
+ options.append << append
50
+ options.append << "\n"
51
+ end
52
+ opts.on("-o", "--output FILE", "Filename to write output to") do |out|
53
+ options.outputs << out
54
+ end
55
+ opts.on("-O", "--opt OPTION", "Set a specific compiler option") do |out|
56
+ if OPTS.include?(out)
57
+ options.opts << out
58
+ else
59
+ puts "WRONG option"
60
+ show_options()
61
+ exit 1
62
+ end
63
+ end
64
+ opts.on("--show-options", "--show-options", "Show all compiler options") do |out|
65
+ show_options()
66
+ exit
67
+ end
68
+ opts.on("-d", "--debug", "Turn on debug mode") do |out|
69
+ options.debug = true
70
+ end
71
+ opts.on_tail("-h", "--help", "Show this message") do
72
+ puts opts
73
+ exit
74
+ end
75
+ end
76
+
77
+ args = ARGV.dup
78
+ opts.parse!(args)
79
+
80
+ # output to STDOUT by default
81
+ if options.outputs.empty?
82
+ options.outputs << "-"
83
+ end
84
+
85
+ if args.empty? and !options.code
86
+ puts opts
87
+ exit
88
+ end
89
+
90
+ src_dir = File.expand_path(File.join(File.dirname(__FILE__), "..", "src"))
91
+ options.load_path << src_dir
92
+ options.load_path << File.join(src_dir, "rubyjs", "lib")
93
+
94
+ $RUBYJS__LOAD_PATH = options.load_path.map {|i| File.expand_path(i)}
95
+ $RUBYJS__LOAD_PATH << "."
96
+ $RUBYJS__PLATFORM = options.platform
97
+ $RUBYJS = true # to distinguish between Ruby and RubyJS
98
+ $RUBYJS__DEBUG = options.debug
99
+ $RUBYJS__OPTS = options.opts
100
+
101
+ # load RubyJS
102
+ $LOAD_PATH.unshift(src_dir)
103
+ require 'rubyjs'
104
+
105
+ # process requires
106
+
107
+ eval_into(RubyJS::Environment) do |eval|
108
+ $RUBYJS__LOAD_PATH.unshift File.join(src_dir, "rubyjs", "lib")
109
+ require 'core'
110
+ $RUBYJS__LOAD_PATH.shift
111
+
112
+ options.library.each do |lib|
113
+ require lib
114
+ end
115
+
116
+ eval.call(options.code) if options.code
117
+
118
+ args.each do |file|
119
+ if file == '-'
120
+ eval.call(STDIN.read)
121
+ else
122
+ eval.call(File.read(file))
123
+ end
124
+ end
125
+ end
126
+
127
+ gen = CodeGenerator.new
128
+ str = ""
129
+ str << gen.generate()
130
+ if options.main
131
+ klass, method = options.main.split(".")
132
+ method ||= "main"
133
+ str << gen.encode("#<#{klass}>.#<m:#{method}>.apply(#<#{klass}>); ")
134
+ end
135
+ str << options.append
136
+
137
+ options.outputs.each do |outname|
138
+ if outname == "-"
139
+ STDOUT << str
140
+ STDOUT.flush
141
+ else
142
+ File.open(outname, 'w+') {|f| f << str }
143
+ end
144
+ end
@@ -0,0 +1,112 @@
1
+ spec = Gem::Specification.new do |s|
2
+ s.name = 'rubyjs'
3
+ s.version = '0.8.2'
4
+ s.summary = 'RubyJS is a Ruby to Javascript Compiler. This is a fork with some added features. Orignally by Michael Neumann'
5
+
6
+ s.files = ['README',
7
+ 'Rakefile',
8
+ 'bin',
9
+ 'bin/rubyjs',
10
+ 'rubyjs.gemspec',
11
+ 'src',
12
+ 'src/rubyjs.rb',
13
+ 'src/rubyjs',
14
+ 'src/rubyjs/code_generator.rb',
15
+ 'src/rubyjs/compiler.rb',
16
+ 'src/rubyjs/debug_name_generator.rb',
17
+ 'src/rubyjs/encoder.rb',
18
+ 'src/rubyjs/eval_into.rb',
19
+ 'src/rubyjs/lib',
20
+ 'src/rubyjs/lib/core.rb',
21
+ 'src/rubyjs/lib/json.rb',
22
+ 'src/rubyjs/lib/microunit.rb',
23
+ 'src/rubyjs/lib/dom_element.rb',
24
+ 'src/rubyjs/model.rb',
25
+ 'src/rubyjs/name_generator.rb',
26
+ 'src/rwt',
27
+ 'src/rwt/AbsolutePanel.rb',
28
+ 'src/rwt/DOM.Konqueror.rb',
29
+ 'src/rwt/DOM.Opera.rb',
30
+ 'src/rwt/DOM.rb',
31
+ 'src/rwt/Event.Opera.rb',
32
+ 'src/rwt/Event.rb',
33
+ 'src/rwt/HTTPRequest.IE6.rb',
34
+ 'src/rwt/HTTPRequest.rb',
35
+ 'src/rwt/Label.rb',
36
+ 'src/rwt/Panel.rb',
37
+ 'src/rwt/RootPanel.rb',
38
+ 'src/rwt/UIObject.rb',
39
+ 'src/rwt/Widget.rb',
40
+ 'src/rwt/ported-from',
41
+ 'src/rwt/ported-from/AbsolutePanel.java',
42
+ 'src/rwt/ported-from/DOM.java',
43
+ 'src/rwt/ported-from/DOMImpl.java',
44
+ 'src/rwt/ported-from/DOMImplOpera.java',
45
+ 'src/rwt/ported-from/DOMImplStandard.java',
46
+ 'src/rwt/ported-from/HTTPRequest.java',
47
+ 'src/rwt/ported-from/HTTPRequestImpl.java',
48
+ 'src/rwt/ported-from/Label.java',
49
+ 'src/rwt/ported-from/Panel.java',
50
+ 'src/rwt/ported-from/UIObject.java',
51
+ 'src/rwt/ported-from/Widget.java',
52
+ 'test',
53
+ 'test/benchmark',
54
+ 'test/benchmark/bm_vm1_block.rb',
55
+ 'test/benchmark/bm_vm1_const.rb',
56
+ 'test/benchmark/bm_vm1_ensure.rb',
57
+ 'test/benchmark/common.rb',
58
+ 'test/benchmark/params.yaml',
59
+ 'test/common.Browser.rb',
60
+ 'test/common.rb',
61
+ 'test/gen_browser_test_suite.rb',
62
+ 'test/gen_test_suite.rb',
63
+ 'test/run_benchs.rb',
64
+ 'test/run_tests.rb',
65
+ 'test/test_args.rb',
66
+ 'test/test_array.rb',
67
+ 'test/test_case.rb',
68
+ 'test/test_class.rb',
69
+ 'test/test_eql.rb',
70
+ 'test/test_exception.rb',
71
+ 'test/test_expr.rb',
72
+ 'test/test_hash.rb',
73
+ 'test/test_hot_ruby.rb',
74
+ 'test/test_if.rb',
75
+ 'test/test_insertion_sort.rb',
76
+ 'test/test_inspect.rb',
77
+ 'test/test_lebewesen.rb',
78
+ 'test/test_massign.rb',
79
+ 'test/test_new.rb',
80
+ 'test/test_range.rb',
81
+ 'test/test_regexp.rb',
82
+ 'test/test_send.rb',
83
+ 'test/test_simple_output.rb',
84
+ 'test/test_splat.rb',
85
+ 'test/test_string.rb',
86
+ 'test/test_yield.rb',
87
+ 'test/test_test.rb',
88
+ 'utils',
89
+ 'utils/js',
90
+ 'utils/js/Makefile',
91
+ 'utils/js/RunScript.class',
92
+ 'utils/js/RunScript.java',
93
+ 'utils/js/js.jar',
94
+ 'utils/js/run.sh',
95
+ 'utils/jsc',
96
+ 'utils/jsc/Makefile',
97
+ 'utils/jsc/README',
98
+ 'utils/jsc/RunScript.c',
99
+ 'utils/jsc/run.sh',
100
+ 'utils/yuicompressor',
101
+ 'utils/yuicompressor/README',
102
+ 'utils/yuicompressor/yuicompressor-2.2.5.jar']
103
+ s.add_dependency('ParseTree', '>= 2.1.1')
104
+ s.required_ruby_version = ">= 1.8.6"
105
+
106
+ s.require_path = 'src'
107
+ s.bindir = 'bin'
108
+ s.executables = ['rubyjs']
109
+
110
+ s.author = "Chris Nelson"
111
+ s.email = "me@christophernelsonconsulting.com"
112
+ end