rubyjs 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. data/README +128 -0
  2. data/Rakefile +9 -0
  3. data/bin/rubyjs +140 -0
  4. data/examples/ex1/Rakefile +7 -0
  5. data/examples/ex1/ex1.js +771 -0
  6. data/examples/ex1/ex1.rb +42 -0
  7. data/examples/ex1/index.html +7 -0
  8. data/examples/hw/Rakefile +9 -0
  9. data/examples/hw/hw.js +635 -0
  10. data/examples/hw/hw.rb +7 -0
  11. data/examples/hw/index.html +7 -0
  12. data/patches/parse_tree.rb.diff +34 -0
  13. data/rubyjs.gemspec +24 -0
  14. data/src/rubyjs.rb +4 -0
  15. data/src/rubyjs/code_generator.rb +474 -0
  16. data/src/rubyjs/compiler.rb +2007 -0
  17. data/src/rubyjs/debug_name_generator.rb +75 -0
  18. data/src/rubyjs/encoder.rb +171 -0
  19. data/src/rubyjs/eval_into.rb +59 -0
  20. data/src/rubyjs/lib/core.rb +1008 -0
  21. data/src/rubyjs/lib/json.rb +101 -0
  22. data/src/rubyjs/model.rb +287 -0
  23. data/src/rubyjs/name_generator.rb +71 -0
  24. data/src/rwt/AbsolutePanel.rb +161 -0
  25. data/src/rwt/DOM.Konqueror.rb +89 -0
  26. data/src/rwt/DOM.Opera.rb +65 -0
  27. data/src/rwt/DOM.rb +1044 -0
  28. data/src/rwt/Event.Opera.rb +35 -0
  29. data/src/rwt/Event.rb +429 -0
  30. data/src/rwt/HTTPRequest.IE6.rb +5 -0
  31. data/src/rwt/HTTPRequest.rb +74 -0
  32. data/src/rwt/Label.rb +164 -0
  33. data/src/rwt/Panel.rb +90 -0
  34. data/src/rwt/RootPanel.rb +16 -0
  35. data/src/rwt/UIObject.rb +495 -0
  36. data/src/rwt/Widget.rb +193 -0
  37. data/src/rwt/ported-from/AbsolutePanel.java +158 -0
  38. data/src/rwt/ported-from/DOM.java +571 -0
  39. data/src/rwt/ported-from/DOMImpl.java +426 -0
  40. data/src/rwt/ported-from/DOMImplOpera.java +82 -0
  41. data/src/rwt/ported-from/DOMImplStandard.java +234 -0
  42. data/src/rwt/ported-from/HTTPRequest.java +81 -0
  43. data/src/rwt/ported-from/HTTPRequestImpl.java +103 -0
  44. data/src/rwt/ported-from/Label.java +163 -0
  45. data/src/rwt/ported-from/Panel.java +99 -0
  46. data/src/rwt/ported-from/UIObject.java +614 -0
  47. data/src/rwt/ported-from/Widget.java +221 -0
  48. data/test/benchmark/bm_call_conv1.js +16 -0
  49. data/test/benchmark/bm_call_conv2.js +14 -0
  50. data/test/benchmark/bm_var_acc1.js +13 -0
  51. data/test/benchmark/bm_var_acc2.js +11 -0
  52. data/test/benchmark/bm_vm1_block.js +15 -0
  53. data/test/benchmark/bm_vm1_block.rb +15 -0
  54. data/test/benchmark/bm_vm1_const.js +13 -0
  55. data/test/benchmark/bm_vm1_const.rb +13 -0
  56. data/test/benchmark/bm_vm1_ensure.js +17 -0
  57. data/test/benchmark/bm_vm1_ensure.rb +15 -0
  58. data/test/benchmark/common.js +4 -0
  59. data/test/benchmark/common.rb +5 -0
  60. data/test/benchmark/params.yaml +7 -0
  61. data/test/browser.test.html +4059 -0
  62. data/test/browser.test.js +3225 -0
  63. data/test/common.Browser.rb +13 -0
  64. data/test/common.rb +8 -0
  65. data/test/gen_browser_test_suite.rb +129 -0
  66. data/test/gen_test_suite.rb +41 -0
  67. data/test/run_benchs.rb +58 -0
  68. data/test/run_tests.rb +22 -0
  69. data/test/test_args.rb +24 -0
  70. data/test/test_array.rb +26 -0
  71. data/test/test_case.rb +35 -0
  72. data/test/test_class.rb +55 -0
  73. data/test/test_eql.rb +9 -0
  74. data/test/test_exception.rb +61 -0
  75. data/test/test_expr.rb +12 -0
  76. data/test/test_hash.rb +29 -0
  77. data/test/test_if.rb +28 -0
  78. data/test/test_inspect.rb +10 -0
  79. data/test/test_lebewesen.rb +39 -0
  80. data/test/test_massign.rb +66 -0
  81. data/test/test_new.rb +12 -0
  82. data/test/test_range.rb +53 -0
  83. data/test/test_regexp.rb +22 -0
  84. data/test/test_send.rb +65 -0
  85. data/test/test_simple_output.rb +5 -0
  86. data/test/test_splat.rb +21 -0
  87. data/test/test_string.rb +51 -0
  88. data/test/test_yield.rb +152 -0
  89. data/utils/js/Makefile +9 -0
  90. data/utils/js/RunScript.class +0 -0
  91. data/utils/js/RunScript.java +73 -0
  92. data/utils/js/js.jar +0 -0
  93. data/utils/js/run.sh +3 -0
  94. data/utils/jsc/Makefile +7 -0
  95. data/utils/jsc/README +3 -0
  96. data/utils/jsc/RunScript.c +93 -0
  97. data/utils/jsc/run.sh +15 -0
  98. data/utils/yuicompressor/README +1 -0
  99. data/utils/yuicompressor/yuicompressor-2.2.5.jar +0 -0
  100. data/vendor/ParseTree-1.7.1-patched/History.txt +217 -0
  101. data/vendor/ParseTree-1.7.1-patched/Manifest.txt +22 -0
  102. data/vendor/ParseTree-1.7.1-patched/README.txt +110 -0
  103. data/vendor/ParseTree-1.7.1-patched/Rakefile +41 -0
  104. data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_abc +89 -0
  105. data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_audit +28 -0
  106. data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_deps +62 -0
  107. data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_show +49 -0
  108. data/vendor/ParseTree-1.7.1-patched/demo/printer.rb +20 -0
  109. data/vendor/ParseTree-1.7.1-patched/lib/composite_sexp_processor.rb +49 -0
  110. data/vendor/ParseTree-1.7.1-patched/lib/parse_tree.rb +1013 -0
  111. data/vendor/ParseTree-1.7.1-patched/lib/sexp.rb +235 -0
  112. data/vendor/ParseTree-1.7.1-patched/lib/sexp_processor.rb +330 -0
  113. data/vendor/ParseTree-1.7.1-patched/lib/unique.rb +15 -0
  114. data/vendor/ParseTree-1.7.1-patched/test/pt_testcase.rb +1221 -0
  115. data/vendor/ParseTree-1.7.1-patched/test/something.rb +53 -0
  116. data/vendor/ParseTree-1.7.1-patched/test/test_all.rb +13 -0
  117. data/vendor/ParseTree-1.7.1-patched/test/test_composite_sexp_processor.rb +69 -0
  118. data/vendor/ParseTree-1.7.1-patched/test/test_parse_tree.rb +216 -0
  119. data/vendor/ParseTree-1.7.1-patched/test/test_sexp.rb +291 -0
  120. data/vendor/ParseTree-1.7.1-patched/test/test_sexp_processor.rb +244 -0
  121. data/vendor/ParseTree-1.7.1-patched/validate.sh +31 -0
  122. data/vendor/ParseTree-1.7.1/History.txt +217 -0
  123. data/vendor/ParseTree-1.7.1/Manifest.txt +22 -0
  124. data/vendor/ParseTree-1.7.1/README.txt +110 -0
  125. data/vendor/ParseTree-1.7.1/Rakefile +41 -0
  126. data/vendor/ParseTree-1.7.1/bin/parse_tree_abc +89 -0
  127. data/vendor/ParseTree-1.7.1/bin/parse_tree_audit +28 -0
  128. data/vendor/ParseTree-1.7.1/bin/parse_tree_deps +62 -0
  129. data/vendor/ParseTree-1.7.1/bin/parse_tree_show +49 -0
  130. data/vendor/ParseTree-1.7.1/demo/printer.rb +20 -0
  131. data/vendor/ParseTree-1.7.1/lib/composite_sexp_processor.rb +49 -0
  132. data/vendor/ParseTree-1.7.1/lib/parse_tree.rb +1004 -0
  133. data/vendor/ParseTree-1.7.1/lib/sexp.rb +235 -0
  134. data/vendor/ParseTree-1.7.1/lib/sexp_processor.rb +330 -0
  135. data/vendor/ParseTree-1.7.1/lib/unique.rb +15 -0
  136. data/vendor/ParseTree-1.7.1/test/pt_testcase.rb +1221 -0
  137. data/vendor/ParseTree-1.7.1/test/something.rb +53 -0
  138. data/vendor/ParseTree-1.7.1/test/test_all.rb +13 -0
  139. data/vendor/ParseTree-1.7.1/test/test_composite_sexp_processor.rb +69 -0
  140. data/vendor/ParseTree-1.7.1/test/test_parse_tree.rb +216 -0
  141. data/vendor/ParseTree-1.7.1/test/test_sexp.rb +291 -0
  142. data/vendor/ParseTree-1.7.1/test/test_sexp_processor.rb +244 -0
  143. data/vendor/ParseTree-1.7.1/validate.sh +31 -0
  144. metadata +230 -0
@@ -0,0 +1,101 @@
1
+ #
2
+ # JSON loading/dumping
3
+ #
4
+ # Parser code taken from http://www.json.org/json.js
5
+ #
6
+
7
+ class JSON
8
+ class SyntaxError < RuntimeError; end
9
+
10
+ #
11
+ # Parsing happens in three stages. In the first stage, we run the text against
12
+ # a regular expression which looks for non-JSON characters. We are especially
13
+ # concerned with '()' and 'new' because they can cause invocation, and '='
14
+ # because it can cause mutation. But just to be safe, we will reject all
15
+ # unexpected characters.
16
+ #
17
+ # We split the first stage into 4 regexp operations in order to work around
18
+ # crippling deficiencies in IE's and Safari's regexp engines. First we replace
19
+ # all backslash pairs with '@' (a non-JSON character). Second, we replace all
20
+ # simple value tokens with ']' characters. Third, we delete all open brackets
21
+ # that follow a colon or comma or that begin the text. Finally, we look to see
22
+ # that the remaining characters are only whitespace or ']' or ',' or ':' or '{'
23
+ # or '}'. If that is so, then the text is safe for eval.
24
+ #
25
+ # In the second stage we use the eval function to compile the text into a
26
+ # JavaScript structure. The '{' operator is subject to a syntactic ambiguity
27
+ # in JavaScript: it can begin a block or an object literal. We wrap the text
28
+ # in parens to eliminate the ambiguity.
29
+ #
30
+ def self._parse(str)
31
+ RubyJS::inline <<-'endjs'
32
+ if (/^[\],:{}\s]*$/.test(#<str>.replace(/\\./g, '@').
33
+ replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']').
34
+ replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
35
+ return eval('(' + #<str> + ')');
36
+ }
37
+ endjs
38
+
39
+ raise SyntaxError, str
40
+ end
41
+
42
+ def self.load(str)
43
+ obj = _parse(str)
44
+ `
45
+ var conv = function(obj) {
46
+ if (obj==null) return #<nil>;
47
+ else if (obj instanceof Array) {
48
+ for (var i=0; i<obj.length; i++) obj[i] = conv(obj[i]);
49
+ }
50
+ else if (typeof(obj) == 'object') {
51
+ var nobj = #<Hash>.#<m:new>();
52
+ for (var i in obj) {
53
+ nobj.#<m:[]=>(#<nil>, conv(i), conv(obj[i]));
54
+ }
55
+ return nobj;
56
+ }
57
+ return obj;
58
+ };
59
+ return conv(#<obj>);
60
+ `
61
+ end
62
+
63
+ def self.dump(obj)
64
+ obj.to_json
65
+ end
66
+ end
67
+
68
+ class Object
69
+ def to_json; raise end
70
+ end
71
+
72
+ class Boolean
73
+ alias to_json to_s
74
+ end
75
+
76
+ class NilClass
77
+ def to_json; "null" end
78
+ end
79
+
80
+ class String
81
+ alias to_json inspect # FIXME?
82
+ end
83
+
84
+ class Number
85
+ alias to_json to_s
86
+ end
87
+
88
+ class Array
89
+ def to_json
90
+ map {|a| a.to_json}.join(",")
91
+ end
92
+ end
93
+
94
+ class Hash
95
+ def to_json
96
+ str = "{"
97
+ str += map {|k, v| (k.to_json + ":" + v.to_json) }.join(",")
98
+ str += "}"
99
+ str
100
+ end
101
+ end
@@ -0,0 +1,287 @@
1
+ #
2
+ # Extract the class/module hierarchy and the methods.
3
+ #
4
+ # Copyright (c) 2007 by Michael Neumann (mneumann@ntecs.de).
5
+ # All rights reserved.
6
+ #
7
+
8
+ require 'parse_tree'
9
+ require 'sexp_processor'
10
+ require 'enumerator'
11
+ require 'rubyjs/encoder'
12
+ require 'set'
13
+
14
+ class MethodExtractor < SexpProcessor
15
+ attr_accessor :instance_methods, :methods
16
+
17
+ def initialize
18
+ super()
19
+
20
+ self.strict = false
21
+ self.auto_shift_type = false
22
+ self.require_empty = false
23
+
24
+ @instance_methods = {}
25
+ @methods = {}
26
+ end
27
+
28
+ def process_defn(exp)
29
+ defn, name, code = *exp
30
+ name = name.to_s
31
+ if name =~ /^self\.(.*)$/
32
+ @methods[$1] = exp
33
+ else
34
+ @instance_methods[name] = exp
35
+ end
36
+ return s()
37
+ end
38
+ end
39
+
40
+ class Model < Encoder
41
+ SCOPE_R = /^RubyJS::Environment::(.*)$/
42
+
43
+ attr_accessor :models
44
+ attr_accessor :current_model
45
+
46
+ attr_reader :method_calls
47
+
48
+ def initialize
49
+ super()
50
+
51
+ #
52
+ # record all (potential) names of all method calls
53
+ #
54
+ @method_calls = Set.new
55
+
56
+
57
+ @models = {}
58
+
59
+ # all modules and classes (a Class is_a Module)
60
+ ObjectSpace.each_object {|o|
61
+ @models[o] = model_for(o) if o.is_a?(::Module) && o.name =~ SCOPE_R
62
+ }
63
+ end
64
+
65
+ def add_method_call(name)
66
+ @method_calls.add(name)
67
+ end
68
+
69
+ def iterate_all(seen, &block)
70
+ @models.each_value do |v|
71
+ iterate_rec(v, seen, &block)
72
+ end
73
+ end
74
+
75
+ def iterate_rec(model, seen, &block)
76
+ return if seen.include?(model[:for])
77
+ iterate_rec(@models[model[:superclass]], seen, &block) if model[:superclass]
78
+
79
+ model[:modules].each do |m|
80
+ iterate_rec(@models[m], seen, &block)
81
+ end
82
+
83
+ with_current_model(model) do
84
+ block.call(model)
85
+ end
86
+ seen.add(model[:for])
87
+ end
88
+
89
+ alias old_encode_constant encode_constant
90
+
91
+ def encode_constant(name)
92
+ if @current_model
93
+ lookup_constant(name)
94
+ else
95
+ old_encode_constant(name)
96
+ end
97
+ end
98
+
99
+ #
100
+ # Compile time constant lookup.
101
+ #
102
+ # Lookup rules (like Ruby 1.9+):
103
+ #
104
+ # 1. Current class
105
+ # 2. Super classes except object
106
+ # 3. lexically enclosing modules/classes
107
+ # 4. Object
108
+ #
109
+ def lookup_constant(name)
110
+ model = @current_model
111
+ prefix, *path = name.split("::")
112
+
113
+ start_lookup_at = nil
114
+ done = false
115
+
116
+ if prefix.empty?
117
+ # e.g. "::A"
118
+ start_lookup_at = RubyJS::Environment
119
+ done = true
120
+ else
121
+
122
+ # 1. Current class
123
+ if model[:for].constants.include?(prefix)
124
+ start_lookup_at = model[:for].const_get(prefix)
125
+ done = true
126
+ end
127
+
128
+ # 2. Super classes except object
129
+ unless done
130
+ m = model
131
+ loop do
132
+ if m[:superclass] and m[:superclass] != RubyJS::Environment::Object
133
+ if m[:superclass].constants.include?(prefix)
134
+ start_lookup_at = m[:superclass].const_get(prefix)
135
+ done = true
136
+ break
137
+ else
138
+ m = @models[m[:superclass]]
139
+ end
140
+ else
141
+ break
142
+ end
143
+ end
144
+ end
145
+
146
+ # 3. lexically enclosing modules/classes
147
+ # FIXME
148
+ unless done
149
+ arr = model[:name].split("::")
150
+ loop do
151
+ arr.pop
152
+
153
+ begin
154
+ start_lookup_at = eval((["RubyJS", "Environment"] + arr + [prefix]).join("::"))
155
+ done = true
156
+ break
157
+ rescue NameError
158
+ end
159
+
160
+ break if arr.empty?
161
+ end
162
+ end
163
+
164
+ # 4. Object
165
+ unless done
166
+ begin
167
+ start_lookup_at = RubyJS::Environment::Object.const_get(prefix)
168
+ done = true
169
+ rescue NameError
170
+ end
171
+ end
172
+
173
+ end
174
+
175
+ unless done
176
+ raise "failed to lookup constant prefix #{prefix}"
177
+ end
178
+
179
+ #
180
+ # follow the whole path, e.g. A::B::C
181
+ #
182
+ value = start_lookup_at
183
+ path.each do |piece|
184
+ value = value.const_get(piece)
185
+ end
186
+
187
+ if value.is_a?(::Class) or value.is_a?(::Module)
188
+ # A class or module
189
+
190
+ if model = @models[value]
191
+ return old_encode_constant(model[:name])
192
+ else
193
+ raise("unrecognized class/module referenced by constant")
194
+ end
195
+ else
196
+ # A value
197
+ if value.is_a?(Fixnum)
198
+ # If it is the receiver of a method call, we have to surround it
199
+ # with parens, e.g. (1).
200
+ # As we can't easily decide whether it's a receiver of a method
201
+ # call, we simply surround every constant Fixnum with parens.
202
+ return "(" + value.inspect + ")"
203
+ elsif value.is_a?(String)
204
+ # FIXME: Generate a reference instead?
205
+ return value.inspect
206
+ else
207
+ raise
208
+ end
209
+ end
210
+ end
211
+
212
+ def namify(klass)
213
+ name = klass.name
214
+ if name =~ SCOPE_R
215
+ name = $1
216
+ else
217
+ raise "must be scoped inside RubyJS module"
218
+ end
219
+ return name
220
+ end
221
+
222
+ def with_current_model(model)
223
+ old_current_model = @current_model
224
+ @current_model = model
225
+ begin
226
+ yield
227
+ ensure
228
+ @current_model = old_current_model
229
+ end
230
+ end
231
+
232
+ def model_for(klass)
233
+ name = namify(klass)
234
+
235
+ me = MethodExtractor.new
236
+ me.process(ParseTree.new.parse_tree(klass))
237
+
238
+ if klass.is_a?(::Class)
239
+ a = klass.ancestors
240
+ a = a[0...(a.index(::Object))]
241
+
242
+ s = klass.superclass
243
+ s = nil if s == ::Object
244
+
245
+ # remove klass from the ancestor chain
246
+ a = a[1..-1] if a[0] == klass
247
+
248
+ # a now contains the included modules
249
+ a = a[0...(a.index(s))] if s
250
+
251
+ if klass == RubyJS::Environment::Object
252
+ raise unless s.nil?
253
+ s = nil
254
+ else
255
+ if s.nil?
256
+ s = RubyJS::Environment::Object
257
+ end
258
+ end
259
+
260
+ return {
261
+ :for => klass,
262
+ :modules => a,
263
+ :superclass => s,
264
+ :is_a => :class,
265
+ :name => name,
266
+ :instance_methods => me.instance_methods,
267
+ :methods => me.methods
268
+ }
269
+ elsif klass.is_a?(::Module)
270
+ a = klass.ancestors
271
+
272
+ # remove klass from the ancestor chain
273
+ a = a[1..-1] if a[0] == klass
274
+
275
+ return {
276
+ :for => klass,
277
+ :modules => a,
278
+ :is_a => :module,
279
+ :name => name,
280
+ :instance_methods => me.instance_methods,
281
+ :methods => me.methods
282
+ }
283
+ else
284
+ raise
285
+ end
286
+ end
287
+ end
@@ -0,0 +1,71 @@
1
+ #
2
+ # Generate unique names from a (custom) alphabet.
3
+ #
4
+ # Copyright (c) 2007 by Michael Neumann (mneumann@ntecs.de).
5
+ # All rights reserved.
6
+ #
7
+
8
+ class NameGenerator
9
+
10
+ DEFAULT_ALPHABET = ('a' .. 'z').to_a + ('A' .. 'Z').to_a + ('0' .. '9').to_a + ['_', '$']
11
+ RESERVED_WORDS = %w(this self new break continue if then else while true false null undefined function document window)
12
+
13
+ def initialize(alphabet=DEFAULT_ALPHABET, reserved_words=RESERVED_WORDS)
14
+ @alphabet = alphabet
15
+ @reserved_words = reserved_words
16
+ @digits = [0]
17
+ @cache = {}
18
+ end
19
+
20
+ #
21
+ # We generate names using a g-adic development (where g=alphabet.size)
22
+ #
23
+ # The least significant digit is the first. If you think of it as a
24
+ # bit-string, then bit 0 would be @digits[0].
25
+ #
26
+ # In each call to next we try to increase the least significant digit.
27
+ # If it overflows, then we reset it to zero and increase the next digit.
28
+ # This continues up to the most significant digit. If this overflows,
29
+ # we introduce a new most significant digit and set this to "zero".
30
+ #
31
+
32
+ def fresh
33
+ loop do
34
+ value = @digits.reverse.map {|d| @alphabet[d] }.join("")
35
+ sz = @alphabet.size
36
+
37
+ i = 0
38
+ loop do
39
+ # increase or initialize with 0
40
+ @digits[i] = @digits[i] ? @digits[i]+1 : 0
41
+
42
+ if @digits[i] >= sz
43
+ @digits[i] = 0
44
+ i += 1
45
+ else
46
+ break
47
+ end
48
+ end
49
+
50
+ return value unless @reserved_words.include?(value)
51
+ end
52
+ end
53
+
54
+ #
55
+ # Generate a name for +name+. Return the same name for the same
56
+ # +name+.
57
+ #
58
+
59
+ def get(name)
60
+ raise unless name.is_a?(String)
61
+ @cache[name] ||= self.fresh
62
+ end
63
+
64
+ def reverse_lookup(encoded_name)
65
+ @cache.index(encoded_name)
66
+ end
67
+
68
+ def cache
69
+ @cache
70
+ end
71
+ end