opal 0.9.4 → 0.10.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.gitignore +2 -3
  4. data/.gitmodules +5 -2
  5. data/.jshintrc +1 -8
  6. data/.rspec +1 -1
  7. data/.travis.yml +15 -23
  8. data/CHANGELOG.md +511 -326
  9. data/CODE_OF_CONDUCT.md +13 -15
  10. data/CONTRIBUTING.md +26 -216
  11. data/Gemfile +20 -12
  12. data/Guardfile +2 -2
  13. data/HACKING.md +230 -0
  14. data/README.md +6 -7
  15. data/bin/opal-mspec +1 -1
  16. data/config.ru +2 -2
  17. data/docs/faq.md +1 -1
  18. data/docs/source_maps.md +1 -1
  19. data/lib/opal.rb +1 -0
  20. data/lib/opal/builder.rb +1 -1
  21. data/lib/opal/cli.rb +30 -28
  22. data/lib/opal/cli_options.rb +3 -0
  23. data/lib/opal/cli_runners.rb +14 -1
  24. data/lib/opal/cli_runners/{apple_script.rb → applescript.rb} +3 -3
  25. data/lib/opal/cli_runners/nashorn.rb +2 -2
  26. data/lib/opal/cli_runners/nodejs.rb +2 -2
  27. data/lib/opal/cli_runners/phantom.js +24 -0
  28. data/lib/opal/cli_runners/phantomjs.rb +10 -10
  29. data/lib/opal/cli_runners/server.rb +3 -3
  30. data/lib/opal/compiler.rb +43 -4
  31. data/lib/opal/config.rb +3 -1
  32. data/lib/opal/errors.rb +13 -0
  33. data/lib/opal/fragment.rb +0 -13
  34. data/lib/opal/nodes.rb +10 -0
  35. data/lib/opal/nodes/args/initialize_kwargs.rb +28 -0
  36. data/lib/opal/nodes/args/kwarg.rb +29 -0
  37. data/lib/opal/nodes/args/kwoptarg.rb +29 -0
  38. data/lib/opal/nodes/args/kwrestarg.rb +39 -0
  39. data/lib/opal/nodes/args/mlhsarg.rb +79 -0
  40. data/lib/opal/nodes/args/normarg.rb +26 -0
  41. data/lib/opal/nodes/args/optarg.rb +27 -0
  42. data/lib/opal/nodes/args/post_args.rb +200 -0
  43. data/lib/opal/nodes/args/post_kwargs.rb +31 -0
  44. data/lib/opal/nodes/args/restarg.rb +33 -0
  45. data/lib/opal/nodes/base.rb +12 -0
  46. data/lib/opal/nodes/call.rb +92 -33
  47. data/lib/opal/nodes/def.rb +26 -169
  48. data/lib/opal/nodes/hash.rb +10 -4
  49. data/lib/opal/nodes/helpers.rb +6 -3
  50. data/lib/opal/nodes/inline_args.rb +61 -0
  51. data/lib/opal/nodes/iter.rb +73 -82
  52. data/lib/opal/nodes/logic.rb +12 -2
  53. data/lib/opal/nodes/masgn.rb +1 -2
  54. data/lib/opal/nodes/node_with_args.rb +141 -0
  55. data/lib/opal/nodes/rescue.rb +121 -43
  56. data/lib/opal/nodes/scope.rb +24 -5
  57. data/lib/opal/nodes/super.rb +122 -54
  58. data/lib/opal/nodes/top.rb +0 -12
  59. data/lib/opal/nodes/yield.rb +2 -13
  60. data/lib/opal/parser.rb +67 -39
  61. data/lib/opal/parser/grammar.rb +3319 -2961
  62. data/lib/opal/parser/grammar.y +234 -46
  63. data/lib/opal/parser/lexer.rb +105 -17
  64. data/lib/opal/parser/sexp.rb +4 -0
  65. data/lib/opal/paths.rb +4 -0
  66. data/lib/opal/regexp_anchors.rb +19 -1
  67. data/lib/opal/sprockets.rb +21 -18
  68. data/lib/opal/sprockets/environment.rb +0 -8
  69. data/lib/opal/sprockets/processor.rb +13 -16
  70. data/lib/opal/sprockets/server.rb +6 -12
  71. data/lib/opal/version.rb +1 -1
  72. data/opal.gemspec +1 -0
  73. data/opal/corelib/array.rb +209 -131
  74. data/opal/corelib/basic_object.rb +7 -3
  75. data/opal/corelib/class.rb +11 -17
  76. data/opal/corelib/constants.rb +2 -2
  77. data/opal/corelib/enumerable.rb +178 -355
  78. data/opal/corelib/enumerator.rb +3 -46
  79. data/opal/corelib/error.rb +2 -2
  80. data/opal/corelib/file.rb +13 -1
  81. data/opal/corelib/hash.rb +26 -56
  82. data/opal/corelib/helpers.rb +10 -0
  83. data/opal/corelib/kernel.rb +6 -3
  84. data/opal/corelib/module.rb +62 -31
  85. data/opal/corelib/number.rb +7 -16
  86. data/opal/corelib/proc.rb +24 -9
  87. data/opal/corelib/range.rb +4 -13
  88. data/opal/corelib/runtime.js +515 -378
  89. data/opal/corelib/string.rb +21 -49
  90. data/opal/corelib/struct.rb +50 -35
  91. data/opal/corelib/unsupported.rb +18 -30
  92. data/opal/opal.rb +0 -1
  93. data/opal/opal/mini.rb +1 -0
  94. data/spec/README.md +6 -4
  95. data/spec/filters/bugs/array.rb +0 -42
  96. data/spec/filters/bugs/basicobject.rb +0 -2
  97. data/spec/filters/bugs/bigdecimal.rb +160 -0
  98. data/spec/filters/bugs/class.rb +0 -5
  99. data/spec/filters/bugs/date.rb +1 -48
  100. data/spec/filters/bugs/enumerable.rb +4 -12
  101. data/spec/filters/bugs/enumerator.rb +0 -1
  102. data/spec/filters/bugs/exception.rb +4 -3
  103. data/spec/filters/bugs/float.rb +4 -2
  104. data/spec/filters/bugs/kernel.rb +25 -10
  105. data/spec/filters/bugs/language.rb +119 -68
  106. data/spec/filters/bugs/method.rb +135 -0
  107. data/spec/filters/bugs/module.rb +13 -28
  108. data/spec/filters/bugs/proc.rb +18 -8
  109. data/spec/filters/bugs/range.rb +0 -3
  110. data/spec/filters/bugs/rational.rb +4 -0
  111. data/spec/filters/bugs/regexp.rb +68 -36
  112. data/spec/filters/bugs/string.rb +1 -1
  113. data/spec/filters/bugs/struct.rb +0 -12
  114. data/spec/filters/bugs/time.rb +1 -0
  115. data/spec/filters/bugs/unboundmethod.rb +2 -1
  116. data/spec/filters/unsupported/freeze.rb +3 -1
  117. data/spec/filters/unsupported/language.rb +0 -7
  118. data/spec/filters/unsupported/privacy.rb +7 -6
  119. data/spec/filters/unsupported/string.rb +10 -0
  120. data/spec/filters/unsupported/struct.rb +3 -0
  121. data/spec/filters/unsupported/symbol.rb +9 -0
  122. data/spec/filters/unsupported/taint.rb +0 -3
  123. data/spec/filters/unsupported/thread.rb +1 -0
  124. data/spec/lib/cli_runners/phantomjs_spec.rb +39 -0
  125. data/spec/lib/cli_spec.rb +42 -1
  126. data/spec/lib/compiler/call_spec.rb +700 -0
  127. data/spec/lib/compiler_spec.rb +46 -28
  128. data/spec/lib/config_spec.rb +13 -0
  129. data/spec/lib/parser/call_spec.rb +18 -0
  130. data/spec/lib/parser/def_spec.rb +29 -0
  131. data/spec/lib/parser/iter_spec.rb +15 -15
  132. data/spec/lib/parser/lambda_spec.rb +153 -12
  133. data/spec/lib/parser/string_spec.rb +5 -0
  134. data/spec/lib/parser/undef_spec.rb +1 -1
  135. data/spec/lib/parser/variables_spec.rb +24 -0
  136. data/spec/lib/paths_spec.rb +12 -5
  137. data/spec/lib/spec_helper.rb +5 -0
  138. data/spec/lib/sprockets/processor_spec.rb +6 -5
  139. data/spec/lib/sprockets_spec.rb +8 -0
  140. data/spec/mspec-opal/formatters.rb +188 -0
  141. data/spec/mspec-opal/runner.rb +193 -0
  142. data/spec/opal/core/enumerator/with_index_spec.rb +6 -0
  143. data/spec/opal/core/kernel/define_singleton_method_spec.rb +1 -1
  144. data/spec/opal/core/kernel/instance_variables_spec.rb +14 -0
  145. data/spec/opal/core/kernel/loop_spec.rb +1 -1
  146. data/spec/opal/core/kernel/raise_spec.rb +1 -1
  147. data/spec/opal/core/language/heredoc_spec.rb +42 -0
  148. data/spec/opal/core/language/rescue_spec.rb +18 -0
  149. data/spec/opal/core/language_spec.rb +22 -0
  150. data/spec/opal/core/module/const_defined_spec.rb +1 -2
  151. data/spec/opal/core/module/name_spec.rb +6 -0
  152. data/spec/opal/core/runtime/bridged_classes_spec.rb +14 -2
  153. data/spec/opal/core/runtime/rescue_spec.rb +12 -2
  154. data/spec/opal/core/runtime/super_spec.rb +1 -0
  155. data/spec/opal/core/string_spec.rb +21 -0
  156. data/spec/opal/stdlib/js_spec.rb +1 -1
  157. data/spec/opal/stdlib/native/hash_spec.rb +7 -0
  158. data/spec/opal/stdlib/promise/always_spec.rb +24 -5
  159. data/spec/opal/stdlib/promise/rescue_spec.rb +15 -6
  160. data/spec/opal/stdlib/promise/then_spec.rb +13 -5
  161. data/spec/opal/stdlib/promise/trace_spec.rb +5 -6
  162. data/spec/opal/stdlib/strscan/scan_spec.rb +1 -1
  163. data/spec/ruby_specs +122 -0
  164. data/spec/spec_helper.rb +3 -15
  165. data/stdlib/base64.rb +51 -121
  166. data/stdlib/bigdecimal.rb +231 -0
  167. data/stdlib/bigdecimal/bignumber.js.rb +11 -0
  168. data/stdlib/bigdecimal/kernel.rb +5 -0
  169. data/stdlib/date.rb +252 -10
  170. data/stdlib/native.rb +38 -38
  171. data/stdlib/nodejs/dir.rb +8 -6
  172. data/stdlib/nodejs/file.rb +28 -3
  173. data/stdlib/nodejs/node_modules/.bin/js-yaml +1 -0
  174. data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esparse +1 -0
  175. data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esvalidate +1 -0
  176. data/stdlib/nodejs/require.rb +1 -1
  177. data/stdlib/nodejs/yaml.rb +3 -2
  178. data/stdlib/opal-parser.rb +7 -2
  179. data/stdlib/pathname.rb +23 -1
  180. data/stdlib/phantomjs.rb +10 -0
  181. data/stdlib/promise.rb +38 -23
  182. data/tasks/building.rake +3 -3
  183. data/tasks/testing.rake +27 -14
  184. data/tasks/testing/mspec_special_calls.rb +1 -1
  185. data/tasks/testing/sprockets-phantomjs.js +4 -0
  186. data/test/opal/test_keyword.rb +110 -110
  187. data/test/opal/unsupported_and_bugs.rb +30 -0
  188. data/vendored-minitest/minitest/assertions.rb +1 -1
  189. metadata +65 -15
  190. data/.spectator +0 -2
  191. data/.spectator-mspec +0 -3
  192. data/opal/corelib/array/inheritance.rb +0 -127
  193. data/spec/rubyspecs +0 -139
@@ -67,23 +67,12 @@ class Enumerator
67
67
  var param = #{Opal.destructure(`arguments`)},
68
68
  value = block(param, index);
69
69
 
70
- if (value === $breaker) {
71
- result = $breaker.$v;
72
- return $breaker;
73
- }
74
-
75
70
  index++;
76
71
 
77
72
  return value;
78
73
  }
79
74
 
80
- self.$each();
81
-
82
- if (result !== undefined) {
83
- return result;
84
- }
85
-
86
- return self.object;
75
+ return self.$each();
87
76
  }
88
77
  end
89
78
 
@@ -115,9 +104,7 @@ class Enumerator
115
104
  try {
116
105
  args.unshift(#{yielder});
117
106
 
118
- if (Opal.yieldX(#@block, args) === $breaker) {
119
- return $breaker.$v;
120
- }
107
+ Opal.yieldX(#@block, args);
121
108
  }
122
109
  catch (e) {
123
110
  if (e === $breaker) {
@@ -173,9 +160,7 @@ class Enumerator
173
160
  %x{
174
161
  args.unshift(#{yielder});
175
162
 
176
- if (Opal.yieldX(block, args) === $breaker) {
177
- return $breaker;
178
- }
163
+ Opal.yieldX(block, args);
179
164
  }
180
165
  }
181
166
  rescue Exception
@@ -199,10 +184,6 @@ class Enumerator
199
184
  %x{
200
185
  var value = Opal.yieldX(block, args);
201
186
 
202
- if (value === $breaker) {
203
- return $breaker;
204
- }
205
-
206
187
  #{enum.yield `value`};
207
188
  }
208
189
  }
@@ -217,10 +198,6 @@ class Enumerator
217
198
  %x{
218
199
  var value = Opal.yieldX(block, args);
219
200
 
220
- if (value === $breaker) {
221
- return $breaker;
222
- }
223
-
224
201
  if (#{`value`.respond_to? :force} && #{`value`.respond_to? :each}) {
225
202
  #{`value`.each { |v| enum.yield v }}
226
203
  }
@@ -273,10 +250,6 @@ class Enumerator
273
250
  %x{
274
251
  var value = Opal.yieldX(block, args);
275
252
 
276
- if (value === $breaker) {
277
- return $breaker;
278
- }
279
-
280
253
  if (#{Opal.falsy?(`value`)}) {
281
254
  succeeding = false;
282
255
 
@@ -302,10 +275,6 @@ class Enumerator
302
275
  %x{
303
276
  var value = Opal.yieldX(block, args);
304
277
 
305
- if (value === $breaker) {
306
- return $breaker;
307
- }
308
-
309
278
  if (#{Opal.truthy?(`value`)}) {
310
279
  #{enum.yield(*args)};
311
280
  }
@@ -325,10 +294,6 @@ class Enumerator
325
294
  if (#{Opal.truthy?(`value`)}) {
326
295
  value = Opal.yield1(block, param);
327
296
 
328
- if (value === $breaker) {
329
- return $breaker;
330
- }
331
-
332
297
  #{enum.yield `Opal.yield1(block, param)`};
333
298
  }
334
299
  }
@@ -360,10 +325,6 @@ class Enumerator
360
325
  %x{
361
326
  var value = Opal.yieldX(block, args);
362
327
 
363
- if (value === $breaker) {
364
- return $breaker;
365
- }
366
-
367
328
  if (#{Opal.falsy?(`value`)}) {
368
329
  #{enum.yield(*args)};
369
330
  }
@@ -405,10 +366,6 @@ class Enumerator
405
366
  %x{
406
367
  var value = Opal.yieldX(block, args);
407
368
 
408
- if (value === $breaker) {
409
- return $breaker;
410
- }
411
-
412
369
  if (#{Opal.truthy?(`value`)}) {
413
370
  #{enum.yield(*args)};
414
371
  }
@@ -118,14 +118,14 @@ class NameError
118
118
 
119
119
  def initialize(message, name=nil)
120
120
  super message
121
- @name = name
121
+ @name = name
122
122
  end
123
123
  end
124
124
 
125
125
  class NoMethodError
126
126
  attr_reader :args
127
127
 
128
- def initialize(message, name, args=[])
128
+ def initialize(message, name=nil, args=[])
129
129
  super message, name
130
130
  @args = args
131
131
  end
data/opal/corelib/file.rb CHANGED
@@ -9,6 +9,7 @@ class File < IO
9
9
  parts = path.split(SEPARATOR)
10
10
  new_parts = []
11
11
  parts[0] = Dir.home if parts.first == '~'
12
+ parts[0] = Dir.pwd if parts.first == '.'
12
13
 
13
14
  parts.each do |part|
14
15
  if part == '..'
@@ -22,13 +23,24 @@ class File < IO
22
23
  alias realpath expand_path
23
24
 
24
25
  def dirname(path)
25
- split(path)[0..-2]
26
+ split(path)[0..-2].join(SEPARATOR)
26
27
  end
27
28
 
28
29
  def basename(path)
29
30
  split(path)[-1]
30
31
  end
31
32
 
33
+ def extname(path)
34
+ raise TypeError, 'no implicit conversion of nil into String' if path.nil?
35
+ path = path.to_path if path.respond_to?(:to_path)
36
+ raise TypeError, "no implicit conversion of #{path.class} into String" unless path.is_a?(String)
37
+ filename = basename(path)
38
+ return '' if filename.nil?
39
+ last_dot_idx = filename[1..-1].rindex('.')
40
+ # extension name must contains at least one character .(something)
41
+ (last_dot_idx.nil? || last_dot_idx + 1 == filename.length - 1) ? '' : filename[(last_dot_idx + 1)..-1]
42
+ end
43
+
32
44
  def exist? path
33
45
  `Opal.modules[#{path}] != null`
34
46
  end
data/opal/corelib/hash.rb CHANGED
@@ -61,8 +61,8 @@ class Hash
61
61
 
62
62
  Opal.hash_init(hash);
63
63
 
64
- hash.none = nil;
65
- hash.proc = nil;
64
+ hash.$$none = nil;
65
+ hash.$$proc = nil;
66
66
 
67
67
  return hash;
68
68
  }
@@ -77,8 +77,8 @@ class Hash
77
77
  if (defaults !== undefined && block !== nil) {
78
78
  #{raise ArgumentError, 'wrong number of arguments (1 for 0)'}
79
79
  }
80
- self.none = (defaults === undefined ? nil : defaults);
81
- self.proc = block;
80
+ self.$$none = (defaults === undefined ? nil : defaults);
81
+ self.$$proc = block;
82
82
  }
83
83
  self
84
84
  end
@@ -175,25 +175,33 @@ class Hash
175
175
  end
176
176
 
177
177
  def default(key = undefined)
178
- %x{
179
- if (key !== undefined && #@proc !== nil) {
180
- return #@proc.$call(self, key);
178
+ %x{
179
+ if (key !== undefined && self.$$proc !== nil && self.$$proc !== undefined) {
180
+ return self.$$proc.$call(self, key);
181
+ }
182
+ if (self.$$none === undefined) {
183
+ return nil;
181
184
  }
182
- return #@none;
185
+ return self.$$none;
183
186
  }
184
187
  end
185
188
 
186
189
  def default=(object)
187
190
  %x{
188
- self.proc = nil;
189
- self.none = object;
191
+ self.$$proc = nil;
192
+ self.$$none = object;
190
193
 
191
194
  return object;
192
195
  }
193
196
  end
194
197
 
195
198
  def default_proc
196
- @proc
199
+ %x{
200
+ if (self.$$proc !== undefined) {
201
+ return self.$$proc;
202
+ }
203
+ return nil;
204
+ }
197
205
  end
198
206
 
199
207
  def default_proc=(proc)
@@ -206,8 +214,8 @@ class Hash
206
214
  }
207
215
  }
208
216
 
209
- self.none = nil;
210
- self.proc = proc;
217
+ self.$$none = nil;
218
+ self.$$proc = proc;
211
219
 
212
220
  return proc;
213
221
  }
@@ -245,10 +253,6 @@ class Hash
245
253
 
246
254
  obj = block(key, value);
247
255
 
248
- if (obj === $breaker) {
249
- return $breaker.$v;
250
- }
251
-
252
256
  if (obj !== false && obj !== nil) {
253
257
  if (Opal.hash_delete(self, key) !== undefined) {
254
258
  length--;
@@ -267,7 +271,7 @@ class Hash
267
271
  return enum_for(:each){self.size} unless block
268
272
 
269
273
  %x{
270
- for (var i = 0, keys = self.$$keys, length = keys.length, key, value, obj; i < length; i++) {
274
+ for (var i = 0, keys = self.$$keys, length = keys.length, key, value; i < length; i++) {
271
275
  key = keys[i];
272
276
 
273
277
  if (key.$$is_string) {
@@ -277,11 +281,7 @@ class Hash
277
281
  key = key.key;
278
282
  }
279
283
 
280
- obj = Opal.yield1(block, [key, value]);
281
-
282
- if (obj === $breaker) {
283
- return $breaker.$v;
284
- }
284
+ Opal.yield1(block, [key, value]);
285
285
  }
286
286
 
287
287
  return self;
@@ -295,9 +295,7 @@ class Hash
295
295
  for (var i = 0, keys = self.$$keys, length = keys.length, key; i < length; i++) {
296
296
  key = keys[i];
297
297
 
298
- if (block(key.$$is_string ? key : key.key) === $breaker) {
299
- return $breaker.$v;
300
- }
298
+ block(key.$$is_string ? key : key.key);
301
299
  }
302
300
 
303
301
  return self;
@@ -313,9 +311,7 @@ class Hash
313
311
  for (var i = 0, keys = self.$$keys, length = keys.length, key; i < length; i++) {
314
312
  key = keys[i];
315
313
 
316
- if (block(key.$$is_string ? self.$$smap[key] : key.value) === $breaker) {
317
- return $breaker.$v;
318
- }
314
+ block(key.$$is_string ? self.$$smap[key] : key.value);
319
315
  }
320
316
 
321
317
  return self;
@@ -337,13 +333,7 @@ class Hash
337
333
  }
338
334
 
339
335
  if (block !== nil) {
340
- value = block(key);
341
-
342
- if (value === $breaker) {
343
- return $breaker.$v;
344
- }
345
-
346
- return value;
336
+ return block(key);
347
337
  }
348
338
 
349
339
  if (defaults !== undefined) {
@@ -578,10 +568,6 @@ class Hash
578
568
 
579
569
  obj = block(key, value);
580
570
 
581
- if (obj === $breaker) {
582
- return $breaker.$v;
583
- }
584
-
585
571
  if (obj === false || obj === nil) {
586
572
  if (Opal.hash_delete(self, key) !== undefined) {
587
573
  length--;
@@ -721,10 +707,6 @@ class Hash
721
707
 
722
708
  obj = block(key, value);
723
709
 
724
- if (obj === $breaker) {
725
- return $breaker.$v;
726
- }
727
-
728
710
  if (obj === false || obj === nil) {
729
711
  Opal.hash_put(hash, key, value);
730
712
  }
@@ -752,10 +734,6 @@ class Hash
752
734
 
753
735
  obj = block(key, value);
754
736
 
755
- if (obj === $breaker) {
756
- return $breaker.$v;
757
- }
758
-
759
737
  if (obj !== false && obj !== nil) {
760
738
  if (Opal.hash_delete(self, key) !== undefined) {
761
739
  changes_were_made = true;
@@ -816,10 +794,6 @@ class Hash
816
794
 
817
795
  obj = block(key, value);
818
796
 
819
- if (obj === $breaker) {
820
- return $breaker.$v;
821
- }
822
-
823
797
  if (obj !== false && obj !== nil) {
824
798
  Opal.hash_put(hash, key, value);
825
799
  }
@@ -847,10 +821,6 @@ class Hash
847
821
 
848
822
  obj = block(key, value);
849
823
 
850
- if (obj === $breaker) {
851
- return $breaker.$v;
852
- }
853
-
854
824
  if (obj === false || obj === nil) {
855
825
  if (Opal.hash_delete(self, key) !== undefined) {
856
826
  length--;
@@ -113,4 +113,14 @@ module Opal
113
113
 
114
114
  name
115
115
  end
116
+
117
+ def self.const_name!(const_name)
118
+ const_name = Opal.coerce_to!(const_name, String, :to_str)
119
+
120
+ if const_name[0] != const_name[0].upcase
121
+ raise NameError, "wrong constant name #{const_name}"
122
+ end
123
+
124
+ const_name
125
+ end
116
126
  end
@@ -971,9 +971,7 @@ module Kernel
971
971
  def loop(&block)
972
972
  %x{
973
973
  while (true) {
974
- if (block() === $breaker) {
975
- return $breaker.$v;
976
- }
974
+ block()
977
975
  }
978
976
  }
979
977
 
@@ -1175,6 +1173,11 @@ module Kernel
1175
1173
  def throw(*args)
1176
1174
  raise UncaughtThrowError.new(args)
1177
1175
  end
1176
+
1177
+ # basic implementation of open, delegate to File.open
1178
+ def open(*args, &block)
1179
+ File.open(*args, &block)
1180
+ end
1178
1181
  end
1179
1182
 
1180
1183
  class Object
@@ -1,27 +1,18 @@
1
1
  class Module
2
- def self.new(&block)
2
+ def self.allocate
3
3
  %x{
4
- var klass = Opal.boot_module_object();
5
- klass.$$name = nil;
6
- klass.$$class = Opal.Module;
7
- klass.$$dep = []
8
- klass.$$is_module = true;
9
- klass.$$proto = {};
10
-
11
- // inherit scope from parent
12
- Opal.create_scope(Opal.Module.$$scope, klass);
13
-
14
- if (block !== nil) {
15
- var block_self = block.$$s;
16
- block.$$s = null;
17
- block.call(klass);
18
- block.$$s = block_self;
19
- }
4
+ var module;
20
5
 
21
- return klass;
6
+ module = Opal.module_allocate();
7
+ Opal.create_scope(Opal.Module.$$scope, module, null);
8
+ return module;
22
9
  }
23
10
  end
24
11
 
12
+ def initialize(&block)
13
+ `Opal.module_initialize(self, block)`
14
+ end
15
+
25
16
  def ===(object)
26
17
  return false if `object == null`
27
18
 
@@ -227,7 +218,9 @@ class Module
227
218
  # check for constant within current scope
228
219
  # if inherit is true or self is Object, will also check ancestors
229
220
  def const_defined?(name, inherit = true)
230
- raise NameError.new("wrong constant name #{name}", name) unless name =~ /^[A-Z]\w*$/
221
+ name = Opal.const_name!(name)
222
+
223
+ raise NameError.new("wrong constant name #{name}", name) unless name =~ Opal::CONST_NAME_REGEXP
231
224
 
232
225
  %x{
233
226
  var scopes = [self.$$scope];
@@ -253,11 +246,19 @@ class Module
253
246
  end
254
247
 
255
248
  def const_get(name, inherit = true)
249
+ name = Opal.const_name!(name)
250
+
251
+ %x{
252
+ if (name.indexOf('::') === 0 && name !== '::'){
253
+ name = name.slice(2);
254
+ }
255
+ }
256
+
256
257
  if `name.indexOf('::') != -1 && name != '::'`
257
258
  return name.split('::').inject(self) { |o, c| o.const_get(c) }
258
259
  end
259
260
 
260
- raise NameError.new("wrong constant name #{name}", name) unless `/^[A-Z]\w*$/.test(name)`
261
+ raise NameError.new("wrong constant name #{name}", name) unless name =~ Opal::CONST_NAME_REGEXP
261
262
 
262
263
  %x{
263
264
  var scopes = [self.$$scope];
@@ -295,16 +296,16 @@ class Module
295
296
  }
296
297
  }
297
298
 
298
- raise NameError.new("uninitialized constant #{self}::#{name}", name)
299
+ full_const_name = self == Object ? name : "#{self}::#{name}"
300
+
301
+ raise NameError.new("uninitialized constant #{full_const_name}", name)
299
302
  end
300
303
 
301
304
  def const_set(name, value)
302
- raise NameError.new("wrong constant name #{name}", name) unless name =~ /^[A-Z]\w*$/
305
+ name = Opal.const_name!(name)
303
306
 
304
- begin
305
- name = name.to_str
306
- rescue
307
- raise TypeError, 'conversion with #to_str failed'
307
+ if !(name =~ Opal::CONST_NAME_REGEXP) || name.start_with?('::')
308
+ raise NameError.new("wrong constant name #{name}", name)
308
309
  end
309
310
 
310
311
  `Opal.casgn(self, name, value)`
@@ -337,9 +338,10 @@ class Module
337
338
  %x{
338
339
  var id = '$' + name;
339
340
 
340
- block.$$jsid = name;
341
- block.$$s = null;
342
- block.$$def = block;
341
+ block.$$jsid = name;
342
+ block.$$s = null;
343
+ block.$$def = block;
344
+ block.$$define_meth = true;
343
345
 
344
346
  Opal.defn(self, id, block);
345
347
 
@@ -381,6 +383,35 @@ class Module
381
383
 
382
384
  self
383
385
  end
386
+
387
+ def included_modules
388
+ %x{
389
+ var results;
390
+
391
+ var module_chain = function(klass) {
392
+ var included = [];
393
+
394
+ for (var i = 0; i != klass.$$inc.length; i++) {
395
+ var mod_or_class = klass.$$inc[i];
396
+ included.push(mod_or_class);
397
+ included = included.concat(module_chain(mod_or_class));
398
+ }
399
+
400
+ return included;
401
+ };
402
+
403
+ results = module_chain(self);
404
+
405
+ // need superclass's modules
406
+ if (self.$$is_class) {
407
+ for (var cls = self; cls; cls = cls.$$super) {
408
+ results = results.concat(module_chain(cls));
409
+ }
410
+ }
411
+
412
+ return results;
413
+ }
414
+ end
384
415
 
385
416
  def include?(mod)
386
417
  %x{
@@ -449,7 +480,7 @@ class Module
449
480
 
450
481
  def included(mod)
451
482
  end
452
-
483
+
453
484
  def extended(mod)
454
485
  end
455
486
 
@@ -470,7 +501,7 @@ class Module
470
501
  result;
471
502
 
472
503
  block.$$s = null;
473
- result = block.call(self);
504
+ result = block.apply(self, [self]);
474
505
  block.$$s = old;
475
506
 
476
507
  return result;