opal 0.6.3 → 0.7.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }