opal 0.6.3 → 0.7.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.spectator +2 -0
  4. data/.spectator-mspec +3 -0
  5. data/.travis.yml +8 -11
  6. data/CHANGELOG.md +33 -0
  7. data/CONTRIBUTING.md +8 -43
  8. data/Gemfile +15 -4
  9. data/Guardfile +77 -0
  10. data/README.md +15 -9
  11. data/Rakefile +36 -12
  12. data/benchmarks/operators.rb +11 -0
  13. data/bin/opal +10 -13
  14. data/bin/opal-build +4 -4
  15. data/bin/opal-mspec +10 -0
  16. data/bin/opal-repl +4 -3
  17. data/examples/sinatra/Gemfile +1 -1
  18. data/examples/sinatra/config.ru +3 -3
  19. data/lib/mspec/opal/main.rb.erb +2 -2
  20. data/lib/mspec/opal/rake_task.rb +31 -24
  21. data/lib/mspec/opal/runner.rb +18 -1
  22. data/lib/mspec/opal/sprockets.js +17 -0
  23. data/lib/opal.rb +1 -34
  24. data/lib/opal/builder.rb +92 -58
  25. data/lib/opal/builder_processors.rb +165 -0
  26. data/lib/opal/cli.rb +85 -144
  27. data/lib/opal/cli_options.rb +136 -90
  28. data/lib/opal/cli_runners.rb +10 -0
  29. data/lib/opal/cli_runners/nodejs.rb +56 -0
  30. data/lib/opal/cli_runners/phantom.js +35 -0
  31. data/lib/opal/cli_runners/phantomjs.rb +28 -0
  32. data/lib/opal/cli_runners/server.rb +54 -0
  33. data/lib/opal/compiler.rb +35 -16
  34. data/lib/opal/erb.rb +29 -15
  35. data/lib/opal/hike_path_finder.rb +18 -0
  36. data/lib/opal/nodes.rb +1 -0
  37. data/lib/opal/nodes/call.rb +107 -26
  38. data/lib/opal/nodes/call_special.rb +31 -6
  39. data/lib/opal/nodes/class.rb +2 -2
  40. data/lib/opal/nodes/constants.rb +5 -20
  41. data/lib/opal/nodes/def.rb +4 -4
  42. data/lib/opal/nodes/defined.rb +3 -3
  43. data/lib/opal/nodes/definitions.rb +1 -1
  44. data/lib/opal/nodes/for.rb +35 -0
  45. data/lib/opal/nodes/helpers.rb +2 -2
  46. data/lib/opal/nodes/iter.rb +3 -3
  47. data/lib/opal/nodes/literal.rb +10 -2
  48. data/lib/opal/nodes/masgn.rb +2 -2
  49. data/lib/opal/nodes/module.rb +2 -2
  50. data/lib/opal/nodes/scope.rb +1 -0
  51. data/lib/opal/nodes/singleton_class.rb +2 -2
  52. data/lib/opal/nodes/super.rb +2 -2
  53. data/lib/opal/nodes/top.rb +30 -3
  54. data/lib/opal/parser.rb +15 -1
  55. data/lib/opal/parser/grammar.rb +2571 -2452
  56. data/lib/opal/parser/grammar.y +37 -5
  57. data/lib/opal/parser/keywords.rb +2 -0
  58. data/lib/opal/parser/lexer.rb +21 -11
  59. data/lib/opal/path_reader.rb +28 -0
  60. data/lib/opal/paths.rb +38 -0
  61. data/lib/opal/source_map.rb +32 -15
  62. data/lib/opal/sprockets/environment.rb +9 -2
  63. data/lib/opal/sprockets/erb.rb +1 -2
  64. data/lib/opal/sprockets/path_reader.rb +34 -0
  65. data/lib/opal/sprockets/processor.rb +40 -39
  66. data/lib/opal/sprockets/server.rb +47 -33
  67. data/lib/opal/version.rb +1 -1
  68. data/opal.gemspec +10 -5
  69. data/opal/README.md +6 -0
  70. data/opal/corelib/array.rb +36 -4
  71. data/opal/corelib/array/inheritance.rb +6 -6
  72. data/opal/corelib/basic_object.rb +9 -9
  73. data/opal/corelib/boolean.rb +1 -1
  74. data/opal/corelib/class.rb +12 -12
  75. data/opal/corelib/dir.rb +20 -0
  76. data/opal/corelib/enumerable.rb +42 -42
  77. data/opal/corelib/enumerator.rb +1 -1
  78. data/opal/corelib/error.rb +2 -2
  79. data/opal/corelib/file.rb +56 -0
  80. data/opal/corelib/hash.rb +5 -5
  81. data/opal/corelib/helpers.rb +3 -3
  82. data/opal/corelib/io.rb +13 -10
  83. data/opal/corelib/kernel.rb +44 -68
  84. data/opal/corelib/method.rb +1 -1
  85. data/opal/corelib/module.rb +89 -114
  86. data/opal/corelib/nil_class.rb +1 -1
  87. data/opal/corelib/numeric.rb +27 -23
  88. data/opal/corelib/proc.rb +5 -5
  89. data/opal/corelib/range.rb +8 -4
  90. data/opal/corelib/regexp.rb +5 -5
  91. data/opal/corelib/runtime.js +589 -272
  92. data/opal/corelib/string.rb +52 -37
  93. data/opal/corelib/string/inheritance.rb +5 -5
  94. data/opal/corelib/time.rb +102 -52
  95. data/opal/corelib/variables.rb +3 -3
  96. data/opal/opal.rb +2 -0
  97. data/package.json +9 -0
  98. data/spec/filters/bugs/array.rb +0 -6
  99. data/spec/filters/bugs/language.rb +4 -0
  100. data/spec/filters/bugs/numeric.rb +7 -6
  101. data/spec/filters/bugs/opal.rb +2 -0
  102. data/spec/filters/bugs/regexp.rb +4 -0
  103. data/spec/filters/bugs/string.rb +0 -7
  104. data/spec/filters/bugs/stringscanner.rb +4 -1
  105. data/spec/filters/unsupported/private_methods.rb +2 -0
  106. data/spec/lib/builder_processors_spec.rb +27 -0
  107. data/spec/lib/builder_spec.rb +66 -0
  108. data/spec/{cli → lib}/cli_spec.rb +60 -5
  109. data/spec/{cli → lib}/compiler_spec.rb +66 -5
  110. data/spec/{cli → lib}/dependency_resolver_spec.rb +1 -1
  111. data/spec/lib/fixtures/no_requires.rb +1 -0
  112. data/spec/{cli → lib}/fixtures/opal_file.rb +0 -0
  113. data/spec/lib/fixtures/require_tree_test.rb +3 -0
  114. data/spec/lib/fixtures/required_tree_test/required_file1.rb +1 -0
  115. data/spec/lib/fixtures/required_tree_test/required_file2.rb +1 -0
  116. data/spec/lib/fixtures/requires.rb +7 -0
  117. data/spec/{cli → lib}/fixtures/sprockets_file.js.rb +0 -0
  118. data/spec/lib/fixtures/sprockets_require_tree_test.rb +3 -0
  119. data/spec/lib/hike_path_finder_spec.rb +23 -0
  120. data/spec/{cli → lib}/lexer_spec.rb +1 -1
  121. data/spec/{cli → lib}/parser/alias_spec.rb +1 -1
  122. data/spec/{cli → lib}/parser/and_spec.rb +1 -1
  123. data/spec/{cli → lib}/parser/attrasgn_spec.rb +1 -1
  124. data/spec/{cli → lib}/parser/begin_spec.rb +1 -1
  125. data/spec/{cli → lib}/parser/block_spec.rb +1 -1
  126. data/spec/{cli → lib}/parser/break_spec.rb +1 -1
  127. data/spec/{cli → lib}/parser/call_spec.rb +1 -1
  128. data/spec/{cli → lib}/parser/class_spec.rb +1 -1
  129. data/spec/{cli → lib}/parser/comments_spec.rb +1 -1
  130. data/spec/{cli → lib}/parser/def_spec.rb +1 -1
  131. data/spec/{cli → lib}/parser/if_spec.rb +1 -1
  132. data/spec/{cli → lib}/parser/iter_spec.rb +1 -1
  133. data/spec/{cli → lib}/parser/lambda_spec.rb +1 -1
  134. data/spec/{cli → lib}/parser/literal_spec.rb +1 -1
  135. data/spec/{cli → lib}/parser/masgn_spec.rb +1 -1
  136. data/spec/{cli → lib}/parser/module_spec.rb +1 -1
  137. data/spec/{cli → lib}/parser/not_spec.rb +1 -1
  138. data/spec/{cli → lib}/parser/op_asgn1_spec.rb +1 -1
  139. data/spec/{cli → lib}/parser/op_asgn2_spec.rb +1 -1
  140. data/spec/{cli → lib}/parser/or_spec.rb +1 -1
  141. data/spec/{cli → lib}/parser/return_spec.rb +1 -1
  142. data/spec/{cli → lib}/parser/sclass_spec.rb +1 -1
  143. data/spec/{cli → lib}/parser/string_spec.rb +8 -1
  144. data/spec/{cli → lib}/parser/super_spec.rb +1 -1
  145. data/spec/lib/parser/unary_spec.rb +48 -0
  146. data/spec/{cli → lib}/parser/undef_spec.rb +1 -1
  147. data/spec/{cli → lib}/parser/unless_spec.rb +1 -1
  148. data/spec/{cli → lib}/parser/variables_spec.rb +1 -1
  149. data/spec/{cli → lib}/parser/while_spec.rb +1 -1
  150. data/spec/{cli → lib}/parser/yield_spec.rb +1 -1
  151. data/spec/lib/path_reader_spec.rb +24 -0
  152. data/spec/lib/shared/path_finder_shared.rb +19 -0
  153. data/spec/lib/shared/path_reader_shared.rb +31 -0
  154. data/spec/lib/spec_helper.rb +9 -0
  155. data/spec/lib/sprockets/environment_spec.rb +30 -0
  156. data/spec/{cli → lib}/sprockets/erb_spec.rb +1 -1
  157. data/spec/lib/sprockets/path_reader_spec.rb +25 -0
  158. data/spec/{cli → lib}/sprockets/processor_spec.rb +9 -2
  159. data/spec/lib/sprockets/server_spec.rb +20 -0
  160. data/spec/opal/compiler/irb_spec.rb +11 -11
  161. data/spec/opal/core/fixtures/require_tree_files/file 1.rb +1 -0
  162. data/spec/opal/core/fixtures/require_tree_files/file 2.rb +1 -0
  163. data/spec/opal/core/fixtures/require_tree_files/file 3.rb +1 -0
  164. data/spec/opal/core/fixtures/require_tree_files/file 4.rb +1 -0
  165. data/spec/opal/core/fixtures/require_tree_files/file 5.rb +1 -0
  166. data/spec/opal/core/kernel/require_tree_spec.rb +7 -0
  167. data/spec/opal/core/kernel/respond_to_spec.rb +2 -2
  168. data/spec/opal/core/runtime/method_missing_spec.rb +19 -0
  169. data/spec/opal/core/source_map_spec.rb +2 -2
  170. data/spec/opal/core/string_spec.rb +11 -0
  171. data/spec/opal/stdlib/erb/erb_spec.rb +0 -1
  172. data/spec/opal/stdlib/thread/mutex_spec.rb +40 -0
  173. data/spec/opal/stdlib/thread/thread_queue_spec.rb +32 -0
  174. data/spec/opal/stdlib/thread/thread_spec.rb +60 -0
  175. data/spec/rubyspecs +54 -11
  176. data/spec/spec_helper.rb +18 -3
  177. data/spec/support/mspec_rspec_adapter.rb +33 -0
  178. data/spec/{cli/spec_helper.rb → support/parser_helpers.rb} +10 -10
  179. data/stdlib/README.md +3 -0
  180. data/stdlib/benchmark.rb +10 -0
  181. data/stdlib/date.rb +2 -2
  182. data/stdlib/dir.rb +1 -5
  183. data/stdlib/file.rb +1 -7
  184. data/stdlib/json.rb +10 -1
  185. data/stdlib/native.rb +5 -5
  186. data/stdlib/nodejs.rb +5 -0
  187. data/stdlib/nodejs/dir.rb +13 -0
  188. data/stdlib/nodejs/file.rb +98 -0
  189. data/stdlib/nodejs/fileutils.rb +26 -0
  190. data/stdlib/nodejs/io.rb +2 -0
  191. data/stdlib/nodejs/irb.rb +45 -0
  192. data/stdlib/nodejs/process.rb +16 -0
  193. data/stdlib/nodejs/require.rb +32 -0
  194. data/stdlib/nodejs/rubygems.rb +68 -0
  195. data/stdlib/nodejs/runtime.rb +25 -0
  196. data/stdlib/nodejs/yaml.rb +11 -0
  197. data/stdlib/opal-parser.rb +1 -2
  198. data/stdlib/opal-source-maps.rb +2 -0
  199. data/stdlib/phantomjs.rb +8 -0
  200. data/stdlib/process.rb +10 -0
  201. data/stdlib/promise.rb +12 -4
  202. data/stdlib/set.rb +27 -0
  203. data/stdlib/source_map.rb +5 -63
  204. data/stdlib/source_map/map.rb +220 -0
  205. data/stdlib/source_map/mapping.rb +26 -0
  206. data/stdlib/source_map/offset.rb +88 -0
  207. data/stdlib/source_map/version.rb +3 -0
  208. data/stdlib/source_map/vlq.rb +77 -101
  209. data/stdlib/sourcemap.rb +1 -0
  210. data/stdlib/strscan.rb +7 -1
  211. data/stdlib/template.rb +1 -1
  212. data/stdlib/thread.rb +147 -7
  213. metadata +238 -104
  214. data/lib/mspec/opal/mspec_fixes.rb +0 -87
  215. data/spec/cli/sprockets/environment_spec.rb +0 -14
  216. data/spec/filters/bugs/symbol.rb +0 -5
  217. data/spec/opal/core/kernel/warn_spec.rb +0 -83
  218. data/spec/opal/core/language/numbers_spec.rb +0 -60
  219. data/stdlib/opal-source-maps.js.erb +0 -2
  220. data/stdlib/source_map/generator.rb +0 -251
  221. data/stdlib/source_map/parser.rb +0 -102
@@ -54,7 +54,7 @@ class NilClass
54
54
  end
55
55
 
56
56
  def object_id
57
- `#{NilClass}._id || (#{NilClass}._id = $opal.uid())`
57
+ `#{NilClass}.$$id || (#{NilClass}.$$id = $opal.uid())`
58
58
  end
59
59
  alias hash object_id
60
60
  end
@@ -3,11 +3,11 @@ require 'corelib/comparable'
3
3
  class Numeric
4
4
  include Comparable
5
5
 
6
- `def._isNumber = true`
6
+ `def.$$is_number = true`
7
7
 
8
8
  def coerce(other, type = :operation)
9
9
  %x{
10
- if (other._isNumber) {
10
+ if (other.$$is_number) {
11
11
  return [self, other];
12
12
  }
13
13
  else {
@@ -17,7 +17,7 @@ class Numeric
17
17
  rescue
18
18
  case type
19
19
  when :operation
20
- raise TypeError, "#{other.class} can't be coerce into Numeric"
20
+ raise TypeError, "#{other.class} can't be coerced into Numeric"
21
21
 
22
22
  when :comparison
23
23
  raise ArgumentError, "comparison of #{self.class} with #{other.class} failed"
@@ -39,7 +39,7 @@ class Numeric
39
39
 
40
40
  def +(other)
41
41
  %x{
42
- if (other._isNumber) {
42
+ if (other.$$is_number) {
43
43
  return self + other;
44
44
  }
45
45
  else {
@@ -50,7 +50,7 @@ class Numeric
50
50
 
51
51
  def -(other)
52
52
  %x{
53
- if (other._isNumber) {
53
+ if (other.$$is_number) {
54
54
  return self - other;
55
55
  }
56
56
  else {
@@ -61,7 +61,7 @@ class Numeric
61
61
 
62
62
  def *(other)
63
63
  %x{
64
- if (other._isNumber) {
64
+ if (other.$$is_number) {
65
65
  return self * other;
66
66
  }
67
67
  else {
@@ -72,7 +72,7 @@ class Numeric
72
72
 
73
73
  def /(other)
74
74
  %x{
75
- if (other._isNumber) {
75
+ if (other.$$is_number) {
76
76
  return self / other;
77
77
  }
78
78
  else {
@@ -83,7 +83,7 @@ class Numeric
83
83
 
84
84
  def %(other)
85
85
  %x{
86
- if (other._isNumber) {
86
+ if (other.$$is_number) {
87
87
  if (other < 0 || self < 0) {
88
88
  return (self % other + other) % other;
89
89
  }
@@ -99,7 +99,7 @@ class Numeric
99
99
 
100
100
  def &(other)
101
101
  %x{
102
- if (other._isNumber) {
102
+ if (other.$$is_number) {
103
103
  return self & other;
104
104
  }
105
105
  else {
@@ -110,7 +110,7 @@ class Numeric
110
110
 
111
111
  def |(other)
112
112
  %x{
113
- if (other._isNumber) {
113
+ if (other.$$is_number) {
114
114
  return self | other;
115
115
  }
116
116
  else {
@@ -121,7 +121,7 @@ class Numeric
121
121
 
122
122
  def ^(other)
123
123
  %x{
124
- if (other._isNumber) {
124
+ if (other.$$is_number) {
125
125
  return self ^ other;
126
126
  }
127
127
  else {
@@ -132,7 +132,7 @@ class Numeric
132
132
 
133
133
  def <(other)
134
134
  %x{
135
- if (other._isNumber) {
135
+ if (other.$$is_number) {
136
136
  return self < other;
137
137
  }
138
138
  else {
@@ -143,7 +143,7 @@ class Numeric
143
143
 
144
144
  def <=(other)
145
145
  %x{
146
- if (other._isNumber) {
146
+ if (other.$$is_number) {
147
147
  return self <= other;
148
148
  }
149
149
  else {
@@ -154,7 +154,7 @@ class Numeric
154
154
 
155
155
  def >(other)
156
156
  %x{
157
- if (other._isNumber) {
157
+ if (other.$$is_number) {
158
158
  return self > other;
159
159
  }
160
160
  else {
@@ -165,7 +165,7 @@ class Numeric
165
165
 
166
166
  def >=(other)
167
167
  %x{
168
- if (other._isNumber) {
168
+ if (other.$$is_number) {
169
169
  return self >= other;
170
170
  }
171
171
  else {
@@ -176,7 +176,7 @@ class Numeric
176
176
 
177
177
  def <=>(other)
178
178
  %x{
179
- if (other._isNumber) {
179
+ if (other.$$is_number) {
180
180
  return self > other ? 1 : (self < other ? -1 : 0);
181
181
  }
182
182
  else {
@@ -188,11 +188,15 @@ class Numeric
188
188
  end
189
189
 
190
190
  def <<(count)
191
- `self << #{count.to_int}`
191
+ count = Opal.coerce_to! count, Integer, :to_int
192
+
193
+ `#{count} > 0 ? self << #{count} : self >> -#{count}`
192
194
  end
193
195
 
194
196
  def >>(count)
195
- `self >> #{count.to_int}`
197
+ count = Opal.coerce_to! count, Integer, :to_int
198
+
199
+ `#{count} > 0 ? self >> #{count} : self << -#{count}`
196
200
  end
197
201
 
198
202
  def [](bit)
@@ -217,7 +221,7 @@ class Numeric
217
221
 
218
222
  def **(other)
219
223
  %x{
220
- if (other._isNumber) {
224
+ if (other.$$is_number) {
221
225
  return Math.pow(self, other);
222
226
  }
223
227
  else {
@@ -228,7 +232,7 @@ class Numeric
228
232
 
229
233
  def ==(other)
230
234
  %x{
231
- if (other._isNumber) {
235
+ if (other.$$is_number) {
232
236
  return self == Number(other);
233
237
  }
234
238
  else if (#{other.respond_to? :==}) {
@@ -248,7 +252,7 @@ class Numeric
248
252
  `Math.ceil(self)`
249
253
  end
250
254
 
251
- def chr
255
+ def chr(encoding=undefined)
252
256
  `String.fromCharCode(self)`
253
257
  end
254
258
 
@@ -503,7 +507,7 @@ Fixnum = Numeric
503
507
  class Integer < Numeric
504
508
  def self.===(other)
505
509
  %x{
506
- if (!other._isNumber) {
510
+ if (!other.$$is_number) {
507
511
  return false;
508
512
  }
509
513
 
@@ -514,7 +518,7 @@ end
514
518
 
515
519
  class Float < Numeric
516
520
  def self.===(other)
517
- `!!other._isNumber`
521
+ `!!other.$$is_number`
518
522
  end
519
523
 
520
524
  INFINITY = `Infinity`
data/opal/corelib/proc.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  class Proc
2
- `def._isProc = true`
3
- `def.is_lambda = false`
2
+ `def.$$is_proc = true`
3
+ `def.$$is_lambda = false`
4
4
 
5
5
  def self.new(&block)
6
6
  unless block
@@ -13,12 +13,12 @@ class Proc
13
13
  def call(*args, &block)
14
14
  %x{
15
15
  if (block !== nil) {
16
- self._p = block;
16
+ self.$$p = block;
17
17
  }
18
18
 
19
19
  var result;
20
20
 
21
- if (self.is_lambda) {
21
+ if (self.$$is_lambda) {
22
22
  result = self.apply(null, args);
23
23
  }
24
24
  else {
@@ -42,7 +42,7 @@ class Proc
42
42
  def lambda?
43
43
  # This method should tell the user if the proc tricks are unavailable,
44
44
  # (see Proc#lambda? on ruby docs to find out more).
45
- `!!self.is_lambda`
45
+ `!!self.$$is_lambda`
46
46
  end
47
47
 
48
48
  # FIXME: this should support the various splats and optional arguments
@@ -3,11 +3,13 @@ require 'corelib/enumerable'
3
3
  class Range
4
4
  include Enumerable
5
5
 
6
- `def._isRange = true;`
6
+ `def.$$is_range = true;`
7
7
 
8
8
  attr_reader :begin, :end
9
9
 
10
10
  def initialize(first, last, exclude = false)
11
+ raise ArgumentError unless first <=> last
12
+
11
13
  @begin = first
12
14
  @end = last
13
15
  @exclude = exclude
@@ -15,7 +17,7 @@ class Range
15
17
 
16
18
  def ==(other)
17
19
  %x{
18
- if (!other._isRange) {
20
+ if (!other.$$is_range) {
19
21
  return false;
20
22
  }
21
23
 
@@ -26,10 +28,12 @@ class Range
26
28
  end
27
29
 
28
30
  def ===(value)
29
- @begin <= value && (@exclude ? value < @end : value <= @end)
31
+ include? value
30
32
  end
31
33
 
32
- alias :cover? :===
34
+ def cover?(value)
35
+ @begin <= value && (@exclude ? value < @end : value <= @end)
36
+ end
33
37
 
34
38
  def each(&block)
35
39
  return enum_for :each unless block_given?
@@ -1,10 +1,10 @@
1
1
  class Regexp
2
- `def._isRegexp = true`
2
+ `def.$$is_regexp = true`
3
3
 
4
4
  class << self
5
5
  def escape(string)
6
6
  %x{
7
- return string.replace(/([-[\]\/{}()*+?.^$\\| ])/g, '\\$1')
7
+ return string.replace(/([-[\]/{}()*+?.^$\\| ])/g, '\\$1')
8
8
  .replace(/[\n]/g, '\\n')
9
9
  .replace(/[\r]/g, '\\r')
10
10
  .replace(/[\f]/g, '\\f')
@@ -29,11 +29,11 @@ class Regexp
29
29
 
30
30
  def ===(str)
31
31
  %x{
32
- if (!str._isString && #{str.respond_to?(:to_str)}) {
32
+ if (!str.$$is_string && #{str.respond_to?(:to_str)}) {
33
33
  #{str = str.to_str};
34
34
  }
35
35
 
36
- if (!str._isString) {
36
+ if (!str.$$is_string) {
37
37
  return false;
38
38
  }
39
39
 
@@ -88,7 +88,7 @@ class Regexp
88
88
  return
89
89
  end
90
90
 
91
- if `string._isString == null`
91
+ if `string.$$is_string == null`
92
92
  unless string.respond_to? :to_str
93
93
  raise TypeError, "no implicit conversion of #{string.class} into String"
94
94
  end
@@ -1,36 +1,14 @@
1
1
  (function(undefined) {
2
- // The Opal object that is exposed globally
3
- var Opal = this.Opal = {};
4
-
5
- // The actual class for BasicObject
6
- var RubyBasicObject;
7
-
8
- // The actual Object class
9
- var RubyObject;
10
-
11
- // The actual Module class
12
- var RubyModule;
13
-
14
- // The actual Class class
15
- var RubyClass;
16
-
17
- // Constructor for instances of BasicObject
18
- function BasicObject(){}
19
-
20
- // Constructor for instances of Object
21
- function Object(){}
22
-
23
- // Constructor for instances of Class
24
- function Class(){}
25
-
26
- // Constructor for instances of Module
27
- function Module(){}
2
+ if (typeof(this.Opal) !== 'undefined') {
3
+ console.warn('Opal already loaded. Loading twice can cause troubles, please fix your setup.');
4
+ return this.Opal;
5
+ }
28
6
 
29
- // Constructor for instances of NilClass (nil)
30
- function NilClass(){}
7
+ // The Opal object that is exposed globally
8
+ var Opal = this.Opal = {}, $opal = Opal;
31
9
 
32
10
  // All bridged classes - keep track to donate methods from Object
33
- var bridged_classes = [];
11
+ var bridged_classes = Opal.bridged_classes = [];
34
12
 
35
13
  // TopScope is used for inheriting constants from the top scope
36
14
  var TopScope = function(){};
@@ -39,8 +17,9 @@
39
17
  TopScope.prototype = Opal;
40
18
 
41
19
  // To inherit scopes
42
- Opal.constructor = TopScope;
20
+ Opal.constructor = TopScope;
43
21
 
22
+ // List top scope constants
44
23
  Opal.constants = [];
45
24
 
46
25
  // This is a useful reference to global object inside ruby files
@@ -64,22 +43,35 @@
64
43
  // Globals table
65
44
  Opal.gvars = {};
66
45
 
46
+ // Get constants
47
+ Opal.get = function(name) {
48
+ var constant = this[name];
49
+
50
+ if (constant == null) {
51
+ return this.base.$const_missing(name);
52
+ }
53
+
54
+ return constant;
55
+ };
56
+
67
57
  /*
68
58
  * Create a new constants scope for the given class with the given
69
59
  * base. Constants are looked up through their parents, so the base
70
60
  * scope will be the outer scope of the new klass.
71
61
  */
72
62
  function create_scope(base, klass, id) {
73
- var const_alloc = function() {};
74
- var const_scope = const_alloc.prototype = new base.constructor();
75
- klass._scope = const_scope;
76
- const_scope.base = klass;
77
- klass._base_module = base.base;
63
+ var const_alloc = function() {};
64
+ var const_scope = const_alloc.prototype = new base.constructor();
65
+
66
+ klass.$$scope = const_scope;
67
+ klass.$$base_module = base.base;
68
+
69
+ const_scope.base = klass;
78
70
  const_scope.constructor = const_alloc;
79
- const_scope.constants = [];
71
+ const_scope.constants = [];
80
72
 
81
73
  if (id) {
82
- klass._orig_scope = base;
74
+ klass.$$orig_scope = base;
83
75
  base[id] = base.constructor[id] = klass;
84
76
  base.constants.push(id);
85
77
  }
@@ -113,29 +105,27 @@
113
105
  * @return [Class] new or existing ruby class
114
106
  */
115
107
  Opal.klass = function(base, superklass, id, constructor) {
116
-
117
108
  // If base is an object, use its class
118
- if (!base._isClass) {
119
- base = base._klass;
109
+ if (!base.$$is_class) {
110
+ base = base.$$class;
120
111
  }
121
112
 
122
113
  // Not specifying a superclass means we can assume it to be Object
123
114
  if (superklass === null) {
124
- superklass = RubyObject;
115
+ superklass = ObjectClass;
125
116
  }
126
117
 
127
- var klass = base._scope[id];
118
+ var klass = base.$$scope[id];
128
119
 
129
120
  // If a constant exists in the scope, then we must use that
130
- if ($hasOwn.call(base._scope, id) && klass._orig_scope === base._scope) {
131
-
121
+ if ($hasOwn.call(base.$$scope, id) && klass.$$orig_scope === base.$$scope) {
132
122
  // Make sure the existing constant is a class, or raise error
133
- if (!klass._isClass) {
123
+ if (!klass.$$is_class) {
134
124
  throw Opal.TypeError.$new(id + " is not a class");
135
125
  }
136
126
 
137
127
  // Make sure existing class has same superclass
138
- if (superklass !== klass._super && superklass !== RubyObject) {
128
+ if (superklass !== klass.$$super && superklass !== ObjectClass) {
139
129
  throw Opal.TypeError.$new("superclass mismatch for class " + id);
140
130
  }
141
131
  }
@@ -148,16 +138,16 @@
148
138
  klass = boot_class(superklass, constructor);
149
139
 
150
140
  // name class using base (e.g. Foo or Foo::Baz)
151
- klass._name = id;
141
+ klass.$$name = id;
152
142
 
153
143
  // every class gets its own constant scope, inherited from current scope
154
- create_scope(base._scope, klass, id);
144
+ create_scope(base.$$scope, klass, id);
155
145
 
156
146
  // Name new class directly onto current scope (Opal.Foo.Baz = klass)
157
- base[id] = base._scope[id] = klass;
147
+ base[id] = base.$$scope[id] = klass;
158
148
 
159
149
  // Copy all parent constants to child, unless parent is Object
160
- if (superklass !== RubyObject && superklass !== RubyBasicObject) {
150
+ if (superklass !== ObjectClass && superklass !== BasicObjectClass) {
161
151
  Opal.donate_constants(superklass, klass);
162
152
  }
163
153
 
@@ -171,66 +161,121 @@
171
161
  };
172
162
 
173
163
  // Create generic class with given superclass.
174
- var boot_class = Opal.boot = function(superklass, constructor) {
175
- // instances
176
- var ctor = function() {};
177
- ctor.prototype = superklass._proto;
164
+ function boot_class(superklass, constructor) {
165
+ var alloc = boot_class_alloc(null, constructor, superklass)
178
166
 
179
- constructor.prototype = new ctor();
180
-
181
- constructor.prototype.constructor = constructor;
167
+ return boot_class_object(superklass, alloc);
168
+ }
182
169
 
183
- return boot_class_meta(superklass, constructor);
184
- };
170
+ // Make `boot_class` available to the JS-API
171
+ Opal.boot = boot_class;
185
172
 
186
- // class itself
187
- function boot_class_meta(superklass, constructor) {
188
- var mtor = function() {};
189
- mtor.prototype = superklass.constructor.prototype;
173
+ /*
174
+ * The class object itself (as in `Class.new`)
175
+ *
176
+ * @param [(Opal) Class] superklass Another class object (as in `Class.new`)
177
+ * @param [constructor] alloc The constructor that holds the prototype
178
+ * that will be used for instances of the
179
+ * newly constructed class.
180
+ */
181
+ function boot_class_object(superklass, alloc) {
182
+ var singleton_class = function() {};
183
+ singleton_class.prototype = superklass.constructor.prototype;
190
184
 
191
- function OpalClass() {};
192
- OpalClass.prototype = new mtor();
185
+ function OpalClass() {}
186
+ OpalClass.prototype = new singleton_class();
193
187
 
194
188
  var klass = new OpalClass();
195
189
 
196
- klass._id = unique_id++;
197
- klass._alloc = constructor;
198
- klass._isClass = true;
199
- klass.constructor = OpalClass;
200
- klass._super = superklass;
201
- klass._methods = [];
202
- klass.__inc__ = [];
203
- klass.__parent = superklass;
204
- klass._proto = constructor.prototype;
190
+ setup_module_or_class_object(klass, OpalClass, superklass, alloc.prototype);
191
+
192
+ // @property $$alloc This is the constructor of instances of the current
193
+ // class. Its prototype will be used for method lookup
194
+ klass.$$alloc = alloc;
205
195
 
206
- constructor.prototype._klass = klass;
196
+ // @property $$proto.$$class Make available to instances a reference to the
197
+ // class they belong to.
198
+ klass.$$proto.$$class = klass;
207
199
 
208
200
  return klass;
209
201
  }
210
202
 
203
+ /*
204
+ * Adds common/required properties to a module or class object
205
+ * (as in `Module.new` / `Class.new`)
206
+ *
207
+ * @param module The module or class that needs to be prepared
208
+ *
209
+ * @param constructor The constructor of the module or class itself,
210
+ * usually it's already assigned by using `new`. Some
211
+ * ipothesis on why it's needed can be found below.
212
+ *
213
+ * @param superklass The superclass of the class/module object, for modules
214
+ * is `Module` (of `ModuleClass` in JS context)
215
+ *
216
+ * @param prototype The prototype on which the class/module methods will
217
+ * be stored.
218
+ */
219
+ function setup_module_or_class_object(module, constructor, superklass, prototype) {
220
+ // @property $$id Each class is assigned a unique `id` that helps
221
+ // comparation and implementation of `#object_id`
222
+ module.$$id = unique_id++;
223
+
224
+ // @property $$proto This is the prototype on which methods will be defined
225
+ module.$$proto = prototype;
226
+
227
+ // @property constructor keeps a ref to the constructor, but apparently the
228
+ // constructor is already set on:
229
+ //
230
+ // `var module = new constructor` is called.
231
+ //
232
+ // Maybe there are some browsers not abiding (IE6?)
233
+ module.constructor = constructor;
234
+
235
+ // @property $$is_class Clearly mark this as a class-like
236
+ module.$$is_class = true;
237
+
238
+ // @property $$super the superclass, doesn't get changed by module inclusions
239
+ module.$$super = superklass;
240
+
241
+ // @property $$parent direct parent class or module
242
+ // starts with the superclass, after module inclusion is
243
+ // the last included module
244
+ module.$$parent = superklass;
245
+
246
+ // @property $$methods keeps track of methods defined on the class
247
+ // but seems to be used just by `define_basic_object_method`
248
+ // and for donating (Ruby) Object methods to bridged classes
249
+ // TODO: check if it can be removed
250
+ module.$$methods = [];
251
+
252
+ // @property $$inc included modules
253
+ module.$$inc = [];
254
+ }
255
+
211
256
  // Define new module (or return existing module)
212
257
  Opal.module = function(base, id) {
213
258
  var module;
214
259
 
215
- if (!base._isClass) {
216
- base = base._klass;
260
+ if (!base.$$is_class) {
261
+ base = base.$$class;
217
262
  }
218
263
 
219
- if ($hasOwn.call(base._scope, id)) {
220
- module = base._scope[id];
264
+ if ($hasOwn.call(base.$$scope, id)) {
265
+ module = base.$$scope[id];
221
266
 
222
- if (!module.__mod__ && module !== RubyObject) {
223
- throw Opal.TypeError.$new(id + " is not a module")
267
+ if (!module.$$is_mod && module !== ObjectClass) {
268
+ throw Opal.TypeError.$new(id + " is not a module");
224
269
  }
225
270
  }
226
271
  else {
227
- module = boot_module()
228
- module._name = id;
272
+ module = boot_module_object();
273
+ module.$$name = id;
229
274
 
230
- create_scope(base._scope, module, id);
275
+ create_scope(base.$$scope, module, id);
231
276
 
232
277
  // Name new module directly onto current scope (Opal.Foo.Baz = module)
233
- base[id] = base._scope[id] = module;
278
+ base[id] = base.$$scope[id] = module;
234
279
  }
235
280
 
236
281
  return module;
@@ -240,34 +285,143 @@
240
285
  * Internal function to create a new module instance. This simply sets up
241
286
  * the prototype hierarchy and method tables.
242
287
  */
243
- function boot_module() {
288
+ function boot_module_object() {
244
289
  var mtor = function() {};
245
- mtor.prototype = RubyModule.constructor.prototype;
290
+ mtor.prototype = ModuleClass.constructor.prototype;
246
291
 
247
- function OpalModule() {};
248
- OpalModule.prototype = new mtor();
292
+ function module_constructor() {}
293
+ module_constructor.prototype = new mtor();
249
294
 
250
- var module = new OpalModule();
295
+ var module = new module_constructor();
296
+ var module_prototype = {};
251
297
 
252
- module._id = unique_id++;
253
- module._isClass = true;
254
- module.constructor = OpalModule;
255
- module._super = RubyModule;
256
- module._methods = [];
257
- module.__inc__ = [];
258
- module.__parent = RubyModule;
259
- module._proto = {};
260
- module.__mod__ = true;
261
- module.__dep__ = [];
298
+ setup_module_or_class_object(module, module_constructor, ModuleClass, module_prototype);
299
+
300
+ module.$$is_mod = true;
301
+ module.$$dep = [];
262
302
 
263
303
  return module;
264
304
  }
265
305
 
306
+ /*
307
+ * Get (or prepare) the singleton class for the passed object.
308
+ *
309
+ * @param object [Ruby Object]
310
+ */
311
+ Opal.get_singleton_class = function(object) {
312
+ if (object.$$meta) {
313
+ return object.$$meta;
314
+ }
315
+
316
+ if (object.$$is_class) {
317
+ return build_class_singleton_class(object);
318
+ }
319
+
320
+ return build_object_singleton_class(object);
321
+ };
322
+
323
+ /*
324
+ * Build the singleton class for an existing class.
325
+ *
326
+ * NOTE: Actually in MRI a class' singleton class inherits from its
327
+ * superclass' singleton class which in turn inherits from Class;
328
+ */
329
+ function build_class_singleton_class(klass) {
330
+ var meta = new $opal.Class.$$alloc;
331
+
332
+ meta.$$class = $opal.Class;
333
+ meta.$$proto = klass.constructor.prototype;
334
+
335
+ meta.$$is_singleton = true;
336
+ meta.$$inc = [];
337
+ meta.$$methods = [];
338
+ meta.$$scope = klass.$$scope;
339
+
340
+ return klass.$$meta = meta;
341
+ }
342
+
343
+ /*
344
+ * Build the singleton class for a Ruby (non class) Object.
345
+ */
346
+ function build_object_singleton_class(object) {
347
+ var orig_class = object.$$class,
348
+ class_id = "#<Class:#<" + orig_class.$$name + ":" + orig_class.$$id + ">>";
349
+
350
+ var Singleton = function () {};
351
+ var meta = Opal.boot(orig_class, Singleton);
352
+ meta.$$name = class_id;
353
+
354
+ meta.$$proto = object;
355
+ meta.$$class = orig_class.$$class;
356
+ meta.$$scope = orig_class.$$scope;
357
+ meta.$$parent = orig_class;
358
+ return object.$$meta = meta;
359
+ }
360
+
361
+ /*
362
+ * The actual inclusion of a module into a class.
363
+ */
364
+ Opal.append_features = function(module, klass) {
365
+ var included = klass.$$inc;
366
+
367
+ // check if this module is already included in the klass
368
+ for (var j = 0, jj = included.length; j < jj; j++) {
369
+ if (included[j] === module) {
370
+ return;
371
+ }
372
+ }
373
+
374
+ included.push(module);
375
+ module.$$dep.push(klass);
376
+
377
+ // iclass
378
+ var iclass = {
379
+ $$name: module.$$name,
380
+ $$proto: module.$$proto,
381
+ $$parent: klass.$$parent,
382
+ $$module: module,
383
+ $$iclass: true
384
+ };
385
+
386
+ klass.$$parent = iclass;
387
+
388
+ var donator = module.$$proto,
389
+ prototype = klass.$$proto,
390
+ methods = module.$$methods;
391
+
392
+ for (var i = 0, length = methods.length; i < length; i++) {
393
+ var method = methods[i], current;
394
+
395
+
396
+ if ( prototype.hasOwnProperty(method) &&
397
+ !(current = prototype[method]).$$donated && !current.$$stub ) {
398
+ // if the target class already has a method of the same name defined
399
+ // and that method was NOT donated, then it must be a method defined
400
+ // by the class so we do not want to override it
401
+ }
402
+ else {
403
+ prototype[method] = donator[method];
404
+ prototype[method].$$donated = true;
405
+ }
406
+ }
407
+
408
+ if (klass.$$dep) {
409
+ $opal.donate(klass, methods.slice(), true);
410
+ }
411
+
412
+ $opal.donate_constants(module, klass);
413
+ };
414
+
415
+
266
416
  // Boot a base class (makes instances).
267
- var boot_defclass = function(id, constructor, superklass) {
417
+ function boot_class_alloc(id, constructor, superklass) {
268
418
  if (superklass) {
269
- var ctor = function() {};
270
- ctor.prototype = superklass.prototype;
419
+ var ctor = function() {};
420
+ ctor.prototype = superklass.$$proto || superklass.prototype;
421
+
422
+ if (id) {
423
+ ctor.displayName = id;
424
+ }
271
425
 
272
426
  constructor.prototype = new ctor();
273
427
  }
@@ -275,37 +429,42 @@
275
429
  constructor.prototype.constructor = constructor;
276
430
 
277
431
  return constructor;
278
- };
432
+ }
279
433
 
280
- // Boot the actual (meta?) classes of core classes
281
- var boot_makemeta = function(id, constructor, superklass) {
434
+ /*
435
+ * Builds the class object for core classes:
436
+ * - make the class object have a singleton class
437
+ * - make the singleton class inherit from its parent singleton class
438
+ *
439
+ * @param id [String] the name of the class
440
+ * @param alloc [Function] the constructor for the core class instances
441
+ * @param superclass [Class alloc] the constructor of the superclass
442
+ */
443
+ function boot_core_class_object(id, alloc, superclass) {
444
+ var superclass_constructor = function() {};
445
+ superclass_constructor.prototype = superclass.prototype;
282
446
 
283
- var mtor = function() {};
284
- mtor.prototype = superklass.prototype;
447
+ var singleton_class = function() {};
448
+ singleton_class.prototype = new superclass_constructor();
285
449
 
286
- function OpalClass() {};
287
- OpalClass.prototype = new mtor();
450
+ singleton_class.displayName = "#<Class:"+id+">";
288
451
 
289
- var klass = new OpalClass();
452
+ // the singleton_class acts as the class object constructor
453
+ var klass = new singleton_class();
290
454
 
291
- klass._id = unique_id++;
292
- klass._alloc = constructor;
293
- klass._isClass = true;
294
- klass._name = id;
295
- klass._super = superklass;
296
- klass.constructor = OpalClass;
297
- klass._methods = [];
298
- klass.__inc__ = [];
299
- klass.__parent = superklass;
300
- klass._proto = constructor.prototype;
455
+ setup_module_or_class_object(klass, singleton_class, superclass, alloc.prototype);
301
456
 
302
- constructor.prototype._klass = klass;
457
+ klass.$$alloc = alloc;
458
+ klass.$$name = id;
459
+
460
+ // Give all instances a ref to their class
461
+ alloc.prototype.$$class = klass;
303
462
 
304
463
  Opal[id] = klass;
305
464
  Opal.constants.push(id);
306
465
 
307
466
  return klass;
308
- };
467
+ }
309
468
 
310
469
  /*
311
470
  * For performance, some core ruby classes are toll-free bridged to their
@@ -331,35 +490,37 @@
331
490
  * @return [Class] returns new ruby class
332
491
  */
333
492
  function bridge_class(name, constructor) {
334
- var klass = boot_class_meta(RubyObject, constructor);
493
+ var klass = boot_class_object(ObjectClass, constructor);
335
494
 
336
- klass._name = name;
495
+ klass.$$name = name;
337
496
 
338
497
  create_scope(Opal, klass, name);
339
498
  bridged_classes.push(klass);
340
499
 
341
- var object_methods = RubyBasicObject._methods.concat(RubyObject._methods);
500
+ var object_methods = BasicObjectClass.$$methods.concat(ObjectClass.$$methods);
342
501
 
343
502
  for (var i = 0, len = object_methods.length; i < len; i++) {
344
503
  var meth = object_methods[i];
345
- constructor.prototype[meth] = RubyObject._proto[meth];
504
+ constructor.prototype[meth] = ObjectClass.$$proto[meth];
346
505
  }
347
506
 
507
+ add_stubs_subscriber(constructor.prototype);
508
+
348
509
  return klass;
349
- };
510
+ }
350
511
 
351
512
  /*
352
513
  * constant assign
353
514
  */
354
515
  Opal.casgn = function(base_module, name, value) {
355
- var scope = base_module._scope;
516
+ var scope = base_module.$$scope;
356
517
 
357
- if (value._isClass && value._name === nil) {
358
- value._name = name;
518
+ if (value.$$is_class && value.$$name === nil) {
519
+ value.$$name = name;
359
520
  }
360
521
 
361
- if (value._isClass) {
362
- value._base_module = base_module;
522
+ if (value.$$is_class) {
523
+ value.$$base_module = base_module;
363
524
  }
364
525
 
365
526
  scope.constants.push(name);
@@ -386,25 +547,25 @@
386
547
  var result = base_scope;
387
548
 
388
549
  path = path.split('::');
389
- while (path.length != 0) {
550
+ while (path.length !== 0) {
390
551
  result = result.$const_get(path.shift());
391
552
  }
392
553
 
393
554
  return result;
394
- }
555
+ };
395
556
 
396
557
  /*
397
558
  * When a source module is included into the target module, we must also copy
398
559
  * its constants to the target.
399
560
  */
400
561
  Opal.donate_constants = function(source_mod, target_mod) {
401
- var source_constants = source_mod._scope.constants,
402
- target_scope = target_mod._scope,
562
+ var source_constants = source_mod.$$scope.constants,
563
+ target_scope = target_mod.$$scope,
403
564
  target_constants = target_scope.constants;
404
565
 
405
566
  for (var i = 0, length = source_constants.length; i < length; i++) {
406
567
  target_constants.push(source_constants[i]);
407
- target_scope[source_constants[i]] = source_mod._scope[source_constants[i]];
568
+ target_scope[source_constants[i]] = source_mod.$$scope[source_constants[i]];
408
569
  }
409
570
  };
410
571
 
@@ -430,57 +591,86 @@
430
591
  *
431
592
  * Opal.add_stubs(["$foo", "$bar", "$baz="]);
432
593
  *
433
- * All stub functions will have a private `rb_stub` property set to true so
594
+ * All stub functions will have a private `$$stub` property set to true so
434
595
  * that other internal methods can detect if a method is just a stub or not.
435
596
  * `Kernel#respond_to?` uses this property to detect a methods presence.
436
597
  *
437
598
  * @param [Array] stubs an array of method stubs to add
438
599
  */
439
600
  Opal.add_stubs = function(stubs) {
601
+ var subscribers = Opal.stub_subscribers;
602
+ var subscriber;
603
+
440
604
  for (var i = 0, length = stubs.length; i < length; i++) {
441
- var stub = stubs[i];
605
+ var method_name = stubs[i], stub = stub_for(method_name);
442
606
 
443
- if (!BasicObject.prototype[stub]) {
444
- BasicObject.prototype[stub] = true;
445
- add_stub_for(BasicObject.prototype, stub);
607
+ for (var j = 0; j < subscribers.length; j++) {
608
+ subscriber = subscribers[j];
609
+ if (!(method_name in subscriber)) {
610
+ subscriber[method_name] = stub;
611
+ }
446
612
  }
447
613
  }
448
614
  };
449
615
 
450
616
  /*
451
- * Actuall add a method_missing stub function to the given prototype for the
617
+ * Add a prototype to the subscribers list, and (TODO) add previously stubbed
618
+ * methods.
619
+ *
620
+ * @param [Prototype]
621
+ */
622
+ function add_stubs_subscriber(prototype) {
623
+ // TODO: Add previously stubbed methods too.
624
+ Opal.stub_subscribers.push(prototype);
625
+ }
626
+
627
+ /*
628
+ * Keep a list of prototypes that want method_missing stubs to be added.
629
+ *
630
+ * @default [Prototype List] BasicObject.prototype
631
+ */
632
+ Opal.stub_subscribers = [BasicObject.prototype];
633
+
634
+ /*
635
+ * Add a method_missing stub function to the given prototype for the
452
636
  * given name.
453
637
  *
454
638
  * @param [Prototype] prototype the target prototype
455
639
  * @param [String] stub stub name to add (e.g. "$foo")
456
640
  */
457
641
  function add_stub_for(prototype, stub) {
642
+ var method_missing_stub = stub_for(stub);
643
+ prototype[stub] = method_missing_stub;
644
+ }
645
+
646
+ /*
647
+ * Generate the method_missing stub for a given method name.
648
+ *
649
+ * @param [String] method_name The js-name of the method to stub (e.g. "$foo")
650
+ */
651
+ function stub_for(method_name) {
458
652
  function method_missing_stub() {
459
653
  // Copy any given block onto the method_missing dispatcher
460
- this.$method_missing._p = method_missing_stub._p;
654
+ this.$method_missing.$$p = method_missing_stub.$$p;
461
655
 
462
656
  // Set block property to null ready for the next call (stop false-positives)
463
- method_missing_stub._p = null;
657
+ method_missing_stub.$$p = null;
464
658
 
465
659
  // call method missing with correct args (remove '$' prefix on method name)
466
- return this.$method_missing.apply(this, [stub.slice(1)].concat($slice.call(arguments)));
660
+ return this.$method_missing.apply(this, [method_name.slice(1)].concat($slice.call(arguments)));
467
661
  }
468
662
 
469
- method_missing_stub.rb_stub = true;
470
- prototype[stub] = method_missing_stub;
663
+ method_missing_stub.$$stub = true;
664
+
665
+ return method_missing_stub;
471
666
  }
472
667
 
473
668
  // Expose for other parts of Opal to use
474
669
  Opal.add_stub_for = add_stub_for;
475
670
 
476
- // Const missing dispatcher
477
- Opal.cm = function(name) {
478
- return this.base.$const_missing(name);
479
- };
480
-
481
671
  // Arity count error dispatcher
482
672
  Opal.ac = function(actual, expected, object, meth) {
483
- var inspect = (object._isClass ? object._name + '.' : object._klass._name + '#') + meth;
673
+ var inspect = (object.$$is_class ? object.$$name + '.' : object.$$class.$$name + '#') + meth;
484
674
  var msg = '[' + inspect + '] wrong number of arguments(' + actual + ' for ' + expected + ')';
485
675
  throw Opal.ArgumentError.$new(msg);
486
676
  };
@@ -490,11 +680,11 @@
490
680
  var dispatcher;
491
681
 
492
682
  if (defs) {
493
- dispatcher = obj._isClass ? defs._super : obj._klass._proto;
683
+ dispatcher = obj.$$is_class ? defs.$$super : obj.$$class.$$proto;
494
684
  }
495
685
  else {
496
- if (obj._isClass) {
497
- dispatcher = obj._super;
686
+ if (obj.$$is_class) {
687
+ dispatcher = obj.$$super;
498
688
  }
499
689
  else {
500
690
  dispatcher = find_obj_super_dispatcher(obj, jsid, current_func);
@@ -502,31 +692,32 @@
502
692
  }
503
693
 
504
694
  dispatcher = dispatcher['$' + jsid];
505
- dispatcher._p = iter;
695
+ dispatcher.$$p = iter;
506
696
 
507
697
  return dispatcher;
508
698
  };
509
699
 
510
700
  // Iter dispatcher for super in a block
511
701
  Opal.find_iter_super_dispatcher = function(obj, jsid, current_func, iter, defs) {
512
- if (current_func._def) {
513
- return Opal.find_super_dispatcher(obj, current_func._jsid, current_func, iter, defs);
702
+ if (current_func.$$def) {
703
+ return Opal.find_super_dispatcher(obj, current_func.$$jsid, current_func, iter, defs);
514
704
  }
515
705
  else {
516
706
  return Opal.find_super_dispatcher(obj, jsid, current_func, iter, defs);
517
707
  }
518
708
  };
519
709
 
520
- var find_obj_super_dispatcher = function(obj, jsid, current_func) {
521
- var klass = obj.__meta__ || obj._klass;
710
+ function find_obj_super_dispatcher(obj, jsid, current_func) {
711
+ var klass = obj.$$meta || obj.$$class;
712
+ jsid = '$' + jsid;
522
713
 
523
714
  while (klass) {
524
- if (klass._proto['$' + jsid] === current_func) {
715
+ if (klass.$$proto[jsid] === current_func) {
525
716
  // ok
526
717
  break;
527
718
  }
528
719
 
529
- klass = klass.__parent;
720
+ klass = klass.$$parent;
530
721
  }
531
722
 
532
723
  // if we arent in a class, we couldnt find current?
@@ -534,21 +725,21 @@
534
725
  throw new Error("could not find current class for super()");
535
726
  }
536
727
 
537
- klass = klass.__parent;
728
+ klass = klass.$$parent;
538
729
 
539
730
  // else, let's find the next one
540
731
  while (klass) {
541
- var working = klass._proto['$' + jsid];
732
+ var working = klass.$$proto[jsid];
542
733
 
543
734
  if (working && working !== current_func) {
544
735
  // ok
545
736
  break;
546
737
  }
547
738
 
548
- klass = klass.__parent;
739
+ klass = klass.$$parent;
549
740
  }
550
741
 
551
- return klass._proto;
742
+ return klass.$$proto;
552
743
  };
553
744
 
554
745
  /*
@@ -570,13 +761,8 @@
570
761
  throw Opal.LocalJumpError.$new("no block given");
571
762
  }
572
763
 
573
- if (block.length > 1) {
574
- if (arg._isArray) {
575
- return block.apply(null, arg);
576
- }
577
- else {
578
- return block(arg);
579
- }
764
+ if (block.length > 1 && arg.$$is_array) {
765
+ return block.apply(null, arg);
580
766
  }
581
767
  else {
582
768
  return block(arg);
@@ -590,12 +776,12 @@
590
776
  }
591
777
 
592
778
  if (block.length > 1 && args.length == 1) {
593
- if (args[0]._isArray) {
779
+ if (args[0].$$is_array) {
594
780
  return block.apply(null, args[0]);
595
781
  }
596
782
  }
597
783
 
598
- if (!args._isArray) {
784
+ if (!args.$$is_array) {
599
785
  args = $slice.call(args);
600
786
  }
601
787
 
@@ -607,9 +793,9 @@
607
793
  Opal.$rescue = function(exception, candidates) {
608
794
  for (var i = 0; i != candidates.length; i++) {
609
795
  var candidate = candidates[i];
610
- if (candidate._isArray) {
611
- var subresult;
612
- if (subresult = Opal.$rescue(exception, candidate)) {
796
+ if (candidate.$$is_array) {
797
+ var subresult = Opal.$rescue(exception, candidate);
798
+ if (subresult) {
613
799
  return subresult;
614
800
  }
615
801
  }
@@ -621,35 +807,35 @@
621
807
  };
622
808
 
623
809
  Opal.is_a = function(object, klass) {
624
- if (object.__meta__ === klass) {
810
+ if (object.$$meta === klass) {
625
811
  return true;
626
812
  }
627
813
 
628
- var search = object._klass;
814
+ var search = object.$$class;
629
815
 
630
816
  while (search) {
631
817
  if (search === klass) {
632
818
  return true;
633
819
  }
634
820
 
635
- for (var i = 0, length = search.__inc__.length; i < length; i++) {
636
- if (search.__inc__[i] == klass) {
821
+ for (var i = 0, length = search.$$inc.length; i < length; i++) {
822
+ if (search.$$inc[i] == klass) {
637
823
  return true;
638
824
  }
639
825
  }
640
826
 
641
- search = search._super;
827
+ search = search.$$super;
642
828
  }
643
829
 
644
830
  return false;
645
- }
831
+ };
646
832
 
647
833
  // Helper to convert the given object to an array
648
834
  Opal.to_ary = function(value) {
649
- if (value._isArray) {
835
+ if (value.$$is_array) {
650
836
  return value;
651
837
  }
652
- else if (value.$to_ary && !value.$to_ary.rb_stub) {
838
+ else if (value.$to_ary && !value.$to_ary.$$stub) {
653
839
  return value.$to_ary();
654
840
  }
655
841
 
@@ -657,20 +843,20 @@
657
843
  };
658
844
 
659
845
  /*
660
- Call a ruby method on a ruby object with some arguments:
661
-
662
- var my_array = [1, 2, 3, 4]
663
- Opal.send(my_array, 'length') # => 4
664
- Opal.send(my_array, 'reverse!') # => [4, 3, 2, 1]
665
-
666
- A missing method will be forwarded to the object via
667
- method_missing.
668
-
669
- The result of either call with be returned.
670
-
671
- @param [Object] recv the ruby object
672
- @param [String] mid ruby method to call
673
- */
846
+ * Call a ruby method on a ruby object with some arguments:
847
+ *
848
+ * var my_array = [1, 2, 3, 4]
849
+ * Opal.send(my_array, 'length') # => 4
850
+ * Opal.send(my_array, 'reverse!') # => [4, 3, 2, 1]
851
+ *
852
+ * A missing method will be forwarded to the object via
853
+ * method_missing.
854
+ *
855
+ * The result of either call with be returned.
856
+ *
857
+ * @param [Object] recv the ruby object
858
+ * @param [String] mid ruby method to call
859
+ */
674
860
  Opal.send = function(recv, mid) {
675
861
  var args = $slice.call(arguments, 2),
676
862
  func = recv['$' + mid];
@@ -687,35 +873,36 @@
687
873
  func = recv['$' + mid];
688
874
 
689
875
  if (func) {
690
- func._p = block;
876
+ func.$$p = block;
691
877
  return func.apply(recv, args);
692
878
  }
693
879
 
694
880
  return recv.$method_missing.apply(recv, [mid].concat(args));
695
881
  };
696
882
 
697
- /**
883
+ /*
698
884
  * Donate methods for a class/module
699
885
  */
700
886
  Opal.donate = function(klass, defined, indirect) {
701
- var methods = klass._methods, included_in = klass.__dep__;
887
+ var methods = klass.$$methods, included_in = klass.$$dep;
702
888
 
703
889
  // if (!indirect) {
704
- klass._methods = methods.concat(defined);
890
+ klass.$$methods = methods.concat(defined);
705
891
  // }
706
892
 
707
893
  if (included_in) {
708
894
  for (var i = 0, length = included_in.length; i < length; i++) {
709
895
  var includee = included_in[i];
710
- var dest = includee._proto;
896
+ var dest = includee.$$proto;
711
897
 
712
898
  for (var j = 0, jj = defined.length; j < jj; j++) {
713
899
  var method = defined[j];
714
- dest[method] = klass._proto[method];
715
- dest[method]._donated = true;
900
+
901
+ dest[method] = klass.$$proto[method];
902
+ dest[method].$$donated = true;
716
903
  }
717
904
 
718
- if (includee.__dep__) {
905
+ if (includee.$$dep) {
719
906
  Opal.donate(includee, defined, true);
720
907
  }
721
908
  }
@@ -723,17 +910,17 @@
723
910
  };
724
911
 
725
912
  Opal.defn = function(obj, jsid, body) {
726
- if (obj.__mod__) {
727
- obj._proto[jsid] = body;
913
+ if (obj.$$is_mod) {
914
+ obj.$$proto[jsid] = body;
728
915
  Opal.donate(obj, [jsid]);
729
916
  }
730
- else if (obj._isClass) {
731
- obj._proto[jsid] = body;
917
+ else if (obj.$$is_class) {
918
+ obj.$$proto[jsid] = body;
732
919
 
733
- if (obj === RubyBasicObject) {
920
+ if (obj === BasicObjectClass) {
734
921
  define_basic_object_method(jsid, body);
735
922
  }
736
- else if (obj === RubyObject) {
923
+ else if (obj === ObjectClass) {
737
924
  Opal.donate(obj, [jsid]);
738
925
  }
739
926
  }
@@ -748,7 +935,7 @@
748
935
  * Define a singleton method on the given object.
749
936
  */
750
937
  Opal.defs = function(obj, jsid, body) {
751
- if (obj._isClass || obj.__mod__) {
938
+ if (obj.$$is_class || obj.$$is_mod) {
752
939
  obj.constructor.prototype[jsid] = body;
753
940
  }
754
941
  else {
@@ -757,37 +944,38 @@
757
944
  };
758
945
 
759
946
  function define_basic_object_method(jsid, body) {
760
- RubyBasicObject._methods.push(jsid);
947
+ BasicObjectClass.$$methods.push(jsid);
761
948
  for (var i = 0, len = bridged_classes.length; i < len; i++) {
762
- bridged_classes[i]._proto[jsid] = body;
949
+ bridged_classes[i].$$proto[jsid] = body;
763
950
  }
764
951
  }
765
952
 
766
953
  Opal.hash = function() {
767
- if (arguments.length == 1 && arguments[0]._klass == Opal.Hash) {
954
+ if (arguments.length == 1 && arguments[0].$$class == Opal.Hash) {
768
955
  return arguments[0];
769
956
  }
770
957
 
771
- var hash = new Opal.Hash._alloc,
958
+ var hash = new Opal.Hash.$$alloc(),
772
959
  keys = [],
773
- assocs = {};
960
+ assocs = {},
961
+ key, obj, length;
774
962
 
775
963
  hash.map = assocs;
776
964
  hash.keys = keys;
777
965
 
778
966
  if (arguments.length == 1) {
779
- if (arguments[0]._isArray) {
967
+ if (arguments[0].$$is_array) {
780
968
  var args = arguments[0];
781
969
 
782
- for (var i = 0, length = args.length; i < length; i++) {
970
+ for (var i = 0, ii = args.length; i < ii; i++) {
783
971
  var pair = args[i];
784
972
 
785
973
  if (pair.length !== 2) {
786
974
  throw Opal.ArgumentError.$new("value not of length 2: " + pair.$inspect());
787
975
  }
788
976
 
789
- var key = pair[0],
790
- obj = pair[1];
977
+ key = pair[0];
978
+ obj = pair[1];
791
979
 
792
980
  if (assocs[key] == null) {
793
981
  keys.push(key);
@@ -797,22 +985,22 @@
797
985
  }
798
986
  }
799
987
  else {
800
- var obj = arguments[0];
801
- for (var key in obj) {
988
+ obj = arguments[0];
989
+ for (key in obj) {
802
990
  assocs[key] = obj[key];
803
991
  keys.push(key);
804
992
  }
805
993
  }
806
994
  }
807
995
  else {
808
- var length = arguments.length;
996
+ length = arguments.length;
809
997
  if (length % 2 !== 0) {
810
998
  throw Opal.ArgumentError.$new("odd number of arguments for Hash");
811
999
  }
812
1000
 
813
- for (var i = 0; i < length; i++) {
814
- var key = arguments[i],
815
- obj = arguments[++i];
1001
+ for (var j = 0; j < length; j++) {
1002
+ key = arguments[j];
1003
+ obj = arguments[++j];
816
1004
 
817
1005
  if (assocs[key] == null) {
818
1006
  keys.push(key);
@@ -832,7 +1020,7 @@
832
1020
  * function
833
1021
  */
834
1022
  Opal.hash2 = function(keys, map) {
835
- var hash = new Opal.Hash._alloc;
1023
+ var hash = new Opal.Hash.$$alloc();
836
1024
 
837
1025
  hash.keys = keys;
838
1026
  hash.map = map;
@@ -845,7 +1033,7 @@
845
1033
  * range excludes the last value.
846
1034
  */
847
1035
  Opal.range = function(first, last, exc) {
848
- var range = new Opal.Range._alloc;
1036
+ var range = new Opal.Range.$$alloc();
849
1037
  range.begin = first;
850
1038
  range.end = last;
851
1039
  range.exclude = exc;
@@ -853,71 +1041,200 @@
853
1041
  return range;
854
1042
  };
855
1043
 
1044
+ // Require system
1045
+ // --------------
1046
+ (function(Opal) {
1047
+ var loaded_features = ['corelib/runtime.js'],
1048
+ require_table = {'corelib/runtime.js': true},
1049
+ modules = {};
1050
+
1051
+ var current_dir = '.',
1052
+ current_file = '.';
1053
+
1054
+ function mark_as_loaded(filename) {
1055
+ if (require_table[filename]) {
1056
+ return false;
1057
+ }
1058
+
1059
+ loaded_features.push(filename);
1060
+ require_table[filename] = true;
1061
+
1062
+ return true;
1063
+ }
1064
+
1065
+ function normalize_loadable_path(path) {
1066
+ var parts, part, new_parts = [], SEPARATOR = '/';
1067
+
1068
+ if (current_dir !== '.') {
1069
+ path = current_dir.replace(/\/*$/, '/') + path;
1070
+ }
1071
+
1072
+ parts = path.split(SEPARATOR);
1073
+
1074
+ for (var i = 0, ii = parts.length; i < ii; i++) {
1075
+ part = parts[i];
1076
+ (part === '..') ? new_parts.pop() : new_parts.push(part)
1077
+ }
1078
+
1079
+ return new_parts.join(SEPARATOR);
1080
+ }
1081
+
1082
+ function load(path) {
1083
+ mark_as_loaded(path);
1084
+
1085
+ var module = modules[path];
1086
+
1087
+ if (module) {
1088
+ var tmp = current_file;
1089
+ current_file = path;
1090
+
1091
+ module(Opal);
1092
+
1093
+ current_file = tmp;
1094
+ }
1095
+ else {
1096
+ var severity = Opal.dynamic_require_severity || 'warning';
1097
+ var message = 'cannot load such file -- ' + path;
1098
+
1099
+ if (severity === "error") {
1100
+ Opal.LoadError ? Opal.LoadError.$new(message) : function(){throw message}();
1101
+ }
1102
+ else if (severity === "warning") {
1103
+ Opal.gvars.stderr.$puts('WARNING: LoadError: ' + message);
1104
+ }
1105
+ }
1106
+
1107
+ return true;
1108
+ }
1109
+
1110
+ function require(path) {
1111
+ if (require_table[path]) {
1112
+ return false;
1113
+ }
1114
+
1115
+ return load(path);
1116
+ }
1117
+
1118
+ Opal.modules = modules;
1119
+ Opal.loaded_features = loaded_features;
1120
+
1121
+ Opal.normalize_loadable_path = normalize_loadable_path;
1122
+ Opal.mark_as_loaded = mark_as_loaded;
1123
+
1124
+ Opal.load = load;
1125
+ Opal.require = require;
1126
+
1127
+ Opal.current_file = current_file;
1128
+ })(Opal);
1129
+
856
1130
  // Initialization
857
1131
  // --------------
858
1132
 
1133
+ // The actual class for BasicObject
1134
+ var BasicObjectClass;
1135
+
1136
+ // The actual Object class
1137
+ var ObjectClass;
1138
+
1139
+ // The actual Module class
1140
+ var ModuleClass;
1141
+
1142
+ // The actual Class class
1143
+ var ClassClass;
1144
+
1145
+ // Constructor for instances of BasicObject
1146
+ function BasicObject(){}
1147
+
1148
+ // Constructor for instances of Object
1149
+ function Object(){}
1150
+
1151
+ // Constructor for instances of Class
1152
+ function Class(){}
1153
+
1154
+ // Constructor for instances of Module
1155
+ function Module(){}
1156
+
1157
+ // Constructor for instances of NilClass (nil)
1158
+ function NilClass(){}
1159
+
859
1160
  // Constructors for *instances* of core objects
860
- boot_defclass('BasicObject', BasicObject);
861
- boot_defclass('Object', Object, BasicObject);
862
- boot_defclass('Module', Module, Object);
863
- boot_defclass('Class', Class, Module);
1161
+ boot_class_alloc('BasicObject', BasicObject);
1162
+ boot_class_alloc('Object', Object, BasicObject);
1163
+ boot_class_alloc('Module', Module, Object);
1164
+ boot_class_alloc('Class', Class, Module);
864
1165
 
865
1166
  // Constructors for *classes* of core objects
866
- RubyBasicObject = boot_makemeta('BasicObject', BasicObject, Class);
867
- RubyObject = boot_makemeta('Object', Object, RubyBasicObject.constructor);
868
- RubyModule = boot_makemeta('Module', Module, RubyObject.constructor);
869
- RubyClass = boot_makemeta('Class', Class, RubyModule.constructor);
1167
+ BasicObjectClass = boot_core_class_object('BasicObject', BasicObject, Class);
1168
+ ObjectClass = boot_core_class_object('Object', Object, BasicObjectClass.constructor);
1169
+ ModuleClass = boot_core_class_object('Module', Module, ObjectClass.constructor);
1170
+ ClassClass = boot_core_class_object('Class', Class, ModuleClass.constructor);
870
1171
 
871
1172
  // Fix booted classes to use their metaclass
872
- RubyBasicObject._klass = RubyClass;
873
- RubyObject._klass = RubyClass;
874
- RubyModule._klass = RubyClass;
875
- RubyClass._klass = RubyClass;
1173
+ BasicObjectClass.$$class = ClassClass;
1174
+ ObjectClass.$$class = ClassClass;
1175
+ ModuleClass.$$class = ClassClass;
1176
+ ClassClass.$$class = ClassClass;
876
1177
 
877
1178
  // Fix superclasses of booted classes
878
- RubyBasicObject._super = null;
879
- RubyObject._super = RubyBasicObject;
880
- RubyModule._super = RubyObject;
881
- RubyClass._super = RubyModule;
1179
+ BasicObjectClass.$$super = null;
1180
+ ObjectClass.$$super = BasicObjectClass;
1181
+ ModuleClass.$$super = ObjectClass;
1182
+ ClassClass.$$super = ModuleClass;
1183
+
1184
+ BasicObjectClass.$$parent = null;
1185
+ ObjectClass.$$parent = BasicObjectClass;
1186
+ ModuleClass.$$parent = ObjectClass;
1187
+ ClassClass.$$parent = ModuleClass;
882
1188
 
883
1189
  // Internally, Object acts like a module as it is "included" into bridged
884
1190
  // classes. In other words, we donate methods from Object into our bridged
885
1191
  // classes as their prototypes don't inherit from our root Object, so they
886
1192
  // act like module includes.
887
- RubyObject.__dep__ = bridged_classes;
1193
+ ObjectClass.$$dep = bridged_classes;
888
1194
 
889
- Opal.base = RubyObject;
890
- RubyBasicObject._scope = RubyObject._scope = Opal;
891
- RubyBasicObject._orig_scope = RubyObject._orig_scope = Opal;
892
- Opal.Kernel = RubyObject;
1195
+ Opal.base = ObjectClass;
1196
+ BasicObjectClass.$$scope = ObjectClass.$$scope = Opal;
1197
+ BasicObjectClass.$$orig_scope = ObjectClass.$$orig_scope = Opal;
1198
+ Opal.Kernel = ObjectClass;
893
1199
 
894
- RubyModule._scope = RubyObject._scope;
895
- RubyClass._scope = RubyObject._scope;
896
- RubyModule._orig_scope = RubyObject._orig_scope;
897
- RubyClass._orig_scope = RubyObject._orig_scope;
1200
+ ModuleClass.$$scope = ObjectClass.$$scope;
1201
+ ModuleClass.$$orig_scope = ObjectClass.$$orig_scope;
1202
+ ClassClass.$$scope = ObjectClass.$$scope;
1203
+ ClassClass.$$orig_scope = ObjectClass.$$orig_scope;
898
1204
 
899
- RubyObject._proto.toString = function() {
1205
+ ObjectClass.$$proto.toString = function() {
900
1206
  return this.$to_s();
901
1207
  };
902
1208
 
903
- Opal.top = new RubyObject._alloc();
1209
+ ObjectClass.$$proto.$require = Opal.require;
1210
+
1211
+ Opal.top = new ObjectClass.$$alloc();
904
1212
 
905
- Opal.klass(RubyObject, RubyObject, 'NilClass', NilClass);
1213
+ Opal.klass(ObjectClass, ObjectClass, 'NilClass', NilClass);
906
1214
 
907
- var nil = Opal.nil = new NilClass;
1215
+ var nil = Opal.nil = new NilClass();
908
1216
  nil.call = nil.apply = function() { throw Opal.LocalJumpError.$new('no block given'); };
909
1217
 
910
1218
  Opal.breaker = new Error('unexpected break');
911
1219
  Opal.returner = new Error('unexpected return');
912
1220
 
913
- bridge_class('Array', Array);
914
- bridge_class('Boolean', Boolean);
915
- bridge_class('Numeric', Number);
916
- bridge_class('String', String);
917
- bridge_class('Proc', Function);
1221
+ bridge_class('Array', Array);
1222
+ bridge_class('Boolean', Boolean);
1223
+ bridge_class('Numeric', Number);
1224
+ bridge_class('String', String);
1225
+ bridge_class('Proc', Function);
918
1226
  bridge_class('Exception', Error);
919
- bridge_class('Regexp', RegExp);
920
- bridge_class('Time', Date);
1227
+ bridge_class('Regexp', RegExp);
1228
+ bridge_class('Time', Date);
921
1229
 
922
- TypeError._super = Error;
1230
+ TypeError.$$super = Error;
923
1231
  }).call(this);
1232
+
1233
+ if (typeof(global) !== 'undefined') {
1234
+ global.Opal = this.Opal;
1235
+ Opal.global = global;
1236
+ }
1237
+ if (typeof(window) !== 'undefined') {
1238
+ window.Opal = this.Opal;
1239
+ Opal.global = window;
1240
+ }