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
data/examples/hw/hw.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'rwt/DOM'
2
+ class HelloWorld
3
+ def self.main
4
+ out = DOM.getElementById('out')
5
+ DOM.setInnerText(out, 'hello world')
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ <html>
2
+ <body>
3
+ <script language="javascript" src="hw.js"></script>
4
+ <a href="#" onclick="main();">say hello</a>
5
+ <div id="out"/>
6
+ </body>
7
+ </html>
@@ -0,0 +1,34 @@
1
+ --- /usr/local/lib/ruby/gems/1.8/gems/ParseTree-1.7.1/lib/parse_tree.rb.old Fri Jun 29 22:19:28 2007
2
+ +++ /usr/local/lib/ruby/gems/1.8/gems/ParseTree-1.7.1/lib/parse_tree.rb Fri Jun 29 22:32:40 2007
3
+ @@ -454,21 +454,30 @@
4
+ break;
5
+
6
+ case NODE_ITER:
7
+ case NODE_FOR:
8
+ add_to_parse_tree(current, node->nd_iter, newlines, locals);
9
+ if (node->nd_var != (NODE *)1
10
+ && node->nd_var != (NODE *)2
11
+ && node->nd_var != NULL) {
12
+ add_to_parse_tree(current, node->nd_var, newlines, locals);
13
+ } else {
14
+ - rb_ary_push(current, Qnil);
15
+ + if (node->nd_var == NULL)
16
+ + {
17
+ + // e.g. proc {}
18
+ + rb_ary_push(current, Qnil);
19
+ + }
20
+ + else
21
+ + {
22
+ + // e.g. proc {||}
23
+ + rb_ary_push(current, ID2SYM(rb_intern("zero_arguments")));
24
+ + }
25
+ }
26
+ add_to_parse_tree(current, node->nd_body, newlines, locals);
27
+ break;
28
+
29
+ case NODE_BREAK:
30
+ case NODE_NEXT:
31
+ case NODE_YIELD:
32
+ if (node->nd_stts)
33
+ add_to_parse_tree(current, node->nd_stts, newlines, locals);
34
+ break;
data/rubyjs.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+
3
+ spec = Gem::Specification.new do |s|
4
+ s.name = 'rubyjs'
5
+ s.version = '0.7.0'
6
+ s.summary = 'RubyJS is a Ruby to Javascript Compiler.'
7
+
8
+ s.files = Dir['**/*']
9
+ s.add_dependency('RubyInline', '>= 3.6.0')
10
+
11
+ s.require_path = 'src'
12
+ s.bindir = 'bin'
13
+ s.executables = ['rubyjs']
14
+
15
+ s.author = "Michael Neumann"
16
+ s.email = "mneumann@ntecs.de"
17
+ s.homepage = "http://rubyforge.org/projects/rubyjs"
18
+ s.rubyforge_project = "rubyjs"
19
+ end
20
+
21
+ if __FILE__ == $0
22
+ Gem::manage_gems
23
+ Gem::Builder.new(spec).build
24
+ end
data/src/rubyjs.rb ADDED
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "../vendor/ParseTree-1.7.1-patched/lib")
2
+ require 'rubyjs/code_generator'
3
+ module RubyJS; module Environment; end end
4
+ require 'rubyjs/eval_into'
@@ -0,0 +1,474 @@
1
+ #
2
+ # Generate Javascript code.
3
+ #
4
+ # Copyright (c) 2007 by Michael Neumann (mneumann@ntecs.de).
5
+ # All rights reserved.
6
+ #
7
+
8
+ require 'rubyjs/compiler'
9
+ require 'rubyjs/model'
10
+ require 'set'
11
+
12
+ RUNTIME_MM = <<EOS
13
+ //
14
+ // Generates a new method_missing function
15
+ // for the given symbol +sym+.
16
+ //
17
+ var #<globalattr:mm_fun_cache> = {};
18
+ function #<globalattr:mm_fun>(sym)
19
+ {
20
+ if (!#<globalattr:mm_fun_cache>[sym])
21
+ {
22
+ var fn = function() {
23
+ return #<globalattr:call_method_missing>(this, arguments, sym);
24
+ };
25
+ fn.#<attr:_mm> = true;
26
+ #<globalattr:mm_fun_cache>[sym] = fn;
27
+ }
28
+
29
+ return #<globalattr:mm_fun_cache>[sym];
30
+ }
31
+
32
+ function #<globalattr:call_method_missing>(obj, args, sym)
33
+ {
34
+ var i, a;
35
+ a = [];
36
+ if (args.length == 0)
37
+ a.push(#<nil>);
38
+ else
39
+ a.push(args[0]);
40
+
41
+ a.push(#<globalattr:mm>[sym] || #<nil>);
42
+
43
+ for (i=1; i<args.length; i++)
44
+ a.push(args[i]);
45
+
46
+ var m = obj.#<m:method_missing>;
47
+
48
+ if (m)
49
+ return m.apply(obj, a);
50
+ else
51
+ throw "FATAL: method_missing missing";
52
+ }
53
+
54
+ //
55
+ // assign method_missing stubs
56
+ //
57
+ function #<globalattr:mm_assign>(c)
58
+ {
59
+ var i;
60
+
61
+ for (i in #<globalattr:mm>)
62
+ {
63
+ if (c.#<attr:object_constructor>.prototype[i]===undefined)
64
+ {
65
+ c.#<attr:object_constructor>.prototype[i] = #<globalattr:mm_fun>(i);
66
+ }
67
+ }
68
+
69
+ if (c.#<attr:superclass> != #<nil>)
70
+ {
71
+ for (i in c.#<attr:superclass>)
72
+ {
73
+ if (c[i]===undefined)
74
+ {
75
+ c[i] = #<globalattr:mm_fun>(i);
76
+ }
77
+ }
78
+ }
79
+ }
80
+ EOS
81
+
82
+ RUNTIME_INIT = <<EOS
83
+ // declare nil
84
+ function NilClass() {}
85
+
86
+ // FIXME: remove
87
+ NilClass.prototype.toString = function() { return "nil"; };
88
+ #<nil> = new NilClass();
89
+
90
+ //
91
+ // define a null-function (used by HTTPRequest)
92
+ //
93
+ function #<globalattr:null_func>()
94
+ {
95
+ }
96
+
97
+ //
98
+ // r: return value
99
+ // s: scope (method scope)
100
+ //
101
+ function #<globalattr:iter_jump>(r,s)
102
+ {
103
+ this.#<attr:return_value> = r;
104
+ this.#<attr:scope> = s;
105
+ return this;
106
+ }
107
+
108
+ //
109
+ // Throw in Javascript is a statement.
110
+ //
111
+ // This function can be used to overcome
112
+ // that limitation.
113
+ //
114
+ function #<globalattr:throw_expr>(x) { throw(x); }
115
+
116
+ function #<globalattr:to_splat>(a)
117
+ {
118
+ // TODO
119
+ return a;
120
+ }
121
+
122
+ //
123
+ // helper function for multiple assignment in
124
+ // iterator parameters.
125
+ //
126
+ // undefined -> []
127
+ // 1 -> [1]
128
+ // [1] -> [[1]]
129
+ // [] -> [[]]
130
+ // [1,2] -> [1,2]
131
+ //
132
+ function #<globalattr:masgn_iter>(a)
133
+ {
134
+ if (a===undefined) return [];
135
+ if (a.constructor!=Array || a.length<2) return [a];
136
+ return a;
137
+ }
138
+
139
+ //
140
+ // Call the method in the superclass.
141
+ //
142
+ // As super is used quite rarely, we dont optimize for it.
143
+ //
144
+ // object, method, iterator, arguments
145
+ //
146
+ function #<globalattr:supercall>(o, m, i, a)
147
+ {
148
+ var r = o[m]; // method in current class
149
+ var c = o.#<attr:_class>.#<attr:superclass>;
150
+ while (r === c.#<attr:object_constructor>.prototype[m])
151
+ c = c.#<attr:superclass>;
152
+ return c.#<attr:object_constructor>.prototype[m].apply(o, [i].concat(a));
153
+ }
154
+
155
+ function #<globalattr:zsupercall>(o, m, a)
156
+ {
157
+ var r = o[m]; // method in current class
158
+ var c = o.#<attr:_class>.#<attr:superclass>;
159
+ while (r === c.#<attr:object_constructor>.prototype[m])
160
+ c = c.#<attr:superclass>;
161
+ return c.#<attr:object_constructor>.prototype[m].apply(o, a);
162
+ }
163
+
164
+ //
165
+ // Whether o.kind_of?(c)
166
+ //
167
+ function #<globalattr:kind_of>(o, c)
168
+ {
169
+ var k,i,m;
170
+
171
+ k = o.#<attr:_class>;
172
+
173
+ while (k != #<nil>)
174
+ {
175
+ if (k === c) return true;
176
+
177
+ // check included modules
178
+ m = k.#<attr:modules>;
179
+ for (i=0; i<m.length; i++)
180
+ {
181
+ if (m[i] === c) return true;
182
+ }
183
+
184
+ k = k.#<attr:superclass>;
185
+ }
186
+
187
+ return false;
188
+ }
189
+
190
+ function #<globalattr:rebuild_classes>(c)
191
+ {
192
+ for (var i=0; i<c.length; i++)
193
+ #<globalattr:rebuild_class>(c[i]);
194
+ }
195
+
196
+ function #<globalattr:rebuild_class>(c)
197
+ {
198
+ var k,i;
199
+
200
+ //
201
+ // include modules
202
+ //
203
+ // do that before, because when assigning instance methods of
204
+ // the super class, a check for === undefined prevents this method
205
+ // from being overwritten.
206
+ //
207
+ for (i=0; i<c.#<attr:modules>.length; i++)
208
+ {
209
+ for (k in c.#<attr:modules>[i].#<attr:object_constructor>.prototype)
210
+ {
211
+ if (c.#<attr:object_constructor>.prototype[k]===undefined)
212
+ {
213
+ c.#<attr:object_constructor>.prototype[k] = c.#<attr:modules>[i].#<attr:object_constructor>.prototype[k];
214
+ }
215
+ }
216
+ }
217
+
218
+ // instance methods
219
+ if (c.#<attr:superclass> != #<nil>)
220
+ {
221
+ for (k in c.#<attr:superclass>.#<attr:object_constructor>.prototype)
222
+ {
223
+ if (c.#<attr:object_constructor>.prototype[k]===undefined)
224
+ {
225
+ c.#<attr:object_constructor>.prototype[k] = c.#<attr:superclass>.#<attr:object_constructor>.prototype[k];
226
+ }
227
+ }
228
+ }
229
+
230
+ // inherit class methods from superclass
231
+ if (c.#<attr:superclass> != #<nil>)
232
+ {
233
+ for (k in c.#<attr:superclass>)
234
+ {
235
+ if (c[k]===undefined)
236
+ {
237
+ c[k] = c.#<attr:superclass>[k];
238
+ }
239
+ }
240
+ }
241
+
242
+ // set class for instanciated objects
243
+ c.#<attr:object_constructor>.prototype.#<attr:_class> = c;
244
+ }
245
+
246
+ function #<globalattr:def_class>(h)
247
+ {
248
+ var c,k,i;
249
+ c = h.#<attr:_class> || #<Class>.#<m:new>(#<nil>, h.#<attr:superclass>, h.#<attr:classname>, h.#<attr:object_constructor>);
250
+
251
+ if (h.#<attr:instance_methods>)
252
+ {
253
+ for (k in h.#<attr:instance_methods>)
254
+ {
255
+ c.#<attr:object_constructor>.prototype[k] = h.#<attr:instance_methods>[k];
256
+ }
257
+ }
258
+
259
+ if (h.#<attr:methods>)
260
+ {
261
+ for (k in h.#<attr:methods>) c[k] = h.#<attr:methods>[k];
262
+ }
263
+
264
+ if (h.#<attr:modules>)
265
+ {
266
+ for (i=0; i<h.#<attr:modules>.length; i++)
267
+ {
268
+ c.#<attr:modules>.push(h.#<attr:modules>[i]);
269
+ }
270
+ }
271
+
272
+ return c;
273
+ }
274
+
275
+ function #<globalattr:MetaClass>(#<_class>, #<superclass>, #<classname>, #<object_constructor>)
276
+ {
277
+ this.#<attr:superclass> = #<superclass>;
278
+ this.#<attr:classname> = #<classname>;
279
+ this.#<attr:object_constructor> = #<object_constructor>;
280
+ this.#<attr:modules> = [];
281
+ this.#<attr:_class> = #<_class>;
282
+ return this;
283
+ }
284
+
285
+ #<globalattr:MetaClass>.#<m:name> = function() { return "MetaClass"; };
286
+ #<globalattr:MetaClass>.#<m:class> = function() { return this; };
287
+ EOS
288
+
289
+
290
+
291
+
292
+ class CodeGenerator
293
+ def initialize
294
+ @world = Model.new
295
+ end
296
+
297
+ def def_Class
298
+ m = @world.models[RubyJS::Environment::Class]
299
+
300
+ str = ""
301
+ str << generate_class_declaration(
302
+ m,
303
+ assign=true,
304
+ _class=ipol(%[new #<globalattr:MetaClass>(#<globalattr:MetaClass>, #<nil>, "Class", #<globalattr:MetaClass>)]),
305
+ obj_cons=nil,
306
+ use_superclass=false,
307
+ use_modules=false)
308
+
309
+ str << @world.encode_globalattr('rebuild_class') + "(" + @world.encode_constant(m[:name]) + ");"
310
+
311
+ str
312
+ end
313
+
314
+ def encode(code)
315
+ return ipol(code)
316
+ end
317
+
318
+ def gen_mm_stubs
319
+ # Method name mapping
320
+
321
+ mm_stubs = ""
322
+ mm_stubs << "// method map\n"
323
+ mm_stubs << "var #<globalattr:mm> = {"
324
+ i = []
325
+ # Javascript name -> Ruby name
326
+ @world.all_method_names do |k,v|
327
+ i << "#{v.inspect}:#{k.inspect}"
328
+ end
329
+ mm_stubs << i.join(",")
330
+ mm_stubs << "};\n"
331
+ mm_stubs << "var #<globalattr:mm_reverse> = {};\n"
332
+ mm_stubs << "for (var i in #<globalattr:mm>) #<globalattr:mm_reverse>[#<globalattr:mm>[i]] = i;\n"
333
+
334
+ ipol(mm_stubs)
335
+ end
336
+
337
+ def generate
338
+ str = ""
339
+
340
+ #
341
+ # Code for Class
342
+ #
343
+ # Required at the beginning because all other classes are created as
344
+ # objects from Class using Class.new.
345
+ #
346
+ str << def_Class()
347
+
348
+ #
349
+ # Now define all other classes/modules
350
+ #
351
+
352
+ @world.iterate_all(Set.new) do |m|
353
+
354
+ #
355
+ # We have to add the modules for class Class here.
356
+ #
357
+ if m[:for] == RubyJS::Environment::Class
358
+ h = { "_class" => @world.encode_constant(m[:name]) }
359
+ b_modules(m, h)
360
+ str << b_def_class(h)
361
+ next
362
+ end
363
+
364
+ begin
365
+ obj_cons = m[:for].const_get(:OBJECT_CONSTRUCTOR__)
366
+ rescue
367
+ obj_cons = nil
368
+ end
369
+
370
+ str << generate_class_declaration(m, assign=true, _class=nil, obj_cons)
371
+ end
372
+
373
+ #
374
+ # Class is a subclass of Object
375
+ #
376
+ str << ipol(<<-EOS)
377
+ #<Class>.#<attr:superclass> = #<Object>;
378
+ EOS
379
+
380
+ #
381
+ # rebuild all classes and modules
382
+ #
383
+ klasses = []
384
+ @world.iterate_all(Set.new) do |m|
385
+ klasses << @world.encode_constant(m[:name])
386
+ end
387
+ str << ipol("var #<globalattr:klasses> = [#{klasses.join(",")}];\n" +
388
+ "#<globalattr:rebuild_classes>(#<globalattr:klasses>);\n")
389
+
390
+ unless $RUBYJS__OPTS.include?('NoMethodMissing')
391
+ str << ipol("for (var i=0; i<#<globalattr:klasses>.length; i++) #<globalattr:mm_assign>(#<globalattr:klasses>[i]);\n")
392
+ end
393
+
394
+ #
395
+ # prepend
396
+ #
397
+
398
+ str_prep = ""
399
+
400
+ # Code of runtime
401
+ str_prep << ipol(RUNTIME_INIT)
402
+
403
+ unless $RUBYJS__OPTS.include?('NoMethodMissing')
404
+ str_prep << ipol(RUNTIME_MM)
405
+ str_prep << gen_mm_stubs()
406
+ end
407
+
408
+ return str_prep + str
409
+ end
410
+
411
+ def b_methods(kind, model, h)
412
+ m = {}
413
+ model[kind].each_pair do |name, pt|
414
+ @world.with_local do
415
+ m[name] = MethodCompiler.new(@world, @world.encode_method(name)).compile_method(pt)
416
+ end
417
+ end
418
+ unless m.empty?
419
+ h[kind.to_s] = "{" + m.map {|name, fn|
420
+ if $RUBYJS__OPTS.include?('PrettyPrint')
421
+ @world.encode_method(name) + ":\n" +
422
+ %[/* #{ model[:name] }#{kind.to_s == "methods" ? "." : "#"}#{ name } */\n#{fn}\n\n]
423
+ else
424
+ @world.encode_method(name) + ": #{fn}"
425
+ end
426
+ }.join(",") + "}"
427
+ end
428
+ end
429
+
430
+ def b_modules(model, h)
431
+ h["modules"] = "[" + model[:modules].map {|m|
432
+ @world.encode_constant(@world.namify(m))
433
+ }.join(",") + "]"
434
+ end
435
+
436
+ def b_def_class(h)
437
+ @world.encode_globalattr('def_class') + "({" +
438
+ h.map {|k, v| @world.encode_attr(k) + ": #{v}"}.join(",") + "});"
439
+ end
440
+
441
+ def generate_class_declaration(model, assign=true, _class=nil, object_constructor=nil, use_superclass=true, use_modules=true)
442
+ h = {}
443
+ h["_class"] = _class if _class
444
+ h["object_constructor"] = object_constructor if object_constructor
445
+
446
+ b_methods(:instance_methods, model, h)
447
+ b_methods(:methods, model, h)
448
+
449
+ h["classname"] = model[:name].inspect
450
+
451
+ if model[:superclass] and use_superclass
452
+ h["superclass"] = @world.old_encode_constant(@world.namify(model[:superclass]))
453
+ else
454
+ # we need this as def_class expects a nil value if no superclass
455
+ # is given!
456
+ h["superclass"] = @world.encode_nil
457
+ end
458
+
459
+ b_modules(model, h) if use_modules
460
+
461
+ str = ""
462
+ str << @world.encode_constant(model[:name]) + " = " if assign
463
+ str << b_def_class(h)
464
+
465
+ return str
466
+ end
467
+
468
+ private
469
+
470
+ # iterpolate strings
471
+ def ipol(str)
472
+ @world.interpolate(str)
473
+ end
474
+ end