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.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.spectator +2 -0
- data/.spectator-mspec +3 -0
- data/.travis.yml +8 -11
- data/CHANGELOG.md +33 -0
- data/CONTRIBUTING.md +8 -43
- data/Gemfile +15 -4
- data/Guardfile +77 -0
- data/README.md +15 -9
- data/Rakefile +36 -12
- data/benchmarks/operators.rb +11 -0
- data/bin/opal +10 -13
- data/bin/opal-build +4 -4
- data/bin/opal-mspec +10 -0
- data/bin/opal-repl +4 -3
- data/examples/sinatra/Gemfile +1 -1
- data/examples/sinatra/config.ru +3 -3
- data/lib/mspec/opal/main.rb.erb +2 -2
- data/lib/mspec/opal/rake_task.rb +31 -24
- data/lib/mspec/opal/runner.rb +18 -1
- data/lib/mspec/opal/sprockets.js +17 -0
- data/lib/opal.rb +1 -34
- data/lib/opal/builder.rb +92 -58
- data/lib/opal/builder_processors.rb +165 -0
- data/lib/opal/cli.rb +85 -144
- data/lib/opal/cli_options.rb +136 -90
- data/lib/opal/cli_runners.rb +10 -0
- data/lib/opal/cli_runners/nodejs.rb +56 -0
- data/lib/opal/cli_runners/phantom.js +35 -0
- data/lib/opal/cli_runners/phantomjs.rb +28 -0
- data/lib/opal/cli_runners/server.rb +54 -0
- data/lib/opal/compiler.rb +35 -16
- data/lib/opal/erb.rb +29 -15
- data/lib/opal/hike_path_finder.rb +18 -0
- data/lib/opal/nodes.rb +1 -0
- data/lib/opal/nodes/call.rb +107 -26
- data/lib/opal/nodes/call_special.rb +31 -6
- data/lib/opal/nodes/class.rb +2 -2
- data/lib/opal/nodes/constants.rb +5 -20
- data/lib/opal/nodes/def.rb +4 -4
- data/lib/opal/nodes/defined.rb +3 -3
- data/lib/opal/nodes/definitions.rb +1 -1
- data/lib/opal/nodes/for.rb +35 -0
- data/lib/opal/nodes/helpers.rb +2 -2
- data/lib/opal/nodes/iter.rb +3 -3
- data/lib/opal/nodes/literal.rb +10 -2
- data/lib/opal/nodes/masgn.rb +2 -2
- data/lib/opal/nodes/module.rb +2 -2
- data/lib/opal/nodes/scope.rb +1 -0
- data/lib/opal/nodes/singleton_class.rb +2 -2
- data/lib/opal/nodes/super.rb +2 -2
- data/lib/opal/nodes/top.rb +30 -3
- data/lib/opal/parser.rb +15 -1
- data/lib/opal/parser/grammar.rb +2571 -2452
- data/lib/opal/parser/grammar.y +37 -5
- data/lib/opal/parser/keywords.rb +2 -0
- data/lib/opal/parser/lexer.rb +21 -11
- data/lib/opal/path_reader.rb +28 -0
- data/lib/opal/paths.rb +38 -0
- data/lib/opal/source_map.rb +32 -15
- data/lib/opal/sprockets/environment.rb +9 -2
- data/lib/opal/sprockets/erb.rb +1 -2
- data/lib/opal/sprockets/path_reader.rb +34 -0
- data/lib/opal/sprockets/processor.rb +40 -39
- data/lib/opal/sprockets/server.rb +47 -33
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +10 -5
- data/opal/README.md +6 -0
- data/opal/corelib/array.rb +36 -4
- data/opal/corelib/array/inheritance.rb +6 -6
- data/opal/corelib/basic_object.rb +9 -9
- data/opal/corelib/boolean.rb +1 -1
- data/opal/corelib/class.rb +12 -12
- data/opal/corelib/dir.rb +20 -0
- data/opal/corelib/enumerable.rb +42 -42
- data/opal/corelib/enumerator.rb +1 -1
- data/opal/corelib/error.rb +2 -2
- data/opal/corelib/file.rb +56 -0
- data/opal/corelib/hash.rb +5 -5
- data/opal/corelib/helpers.rb +3 -3
- data/opal/corelib/io.rb +13 -10
- data/opal/corelib/kernel.rb +44 -68
- data/opal/corelib/method.rb +1 -1
- data/opal/corelib/module.rb +89 -114
- data/opal/corelib/nil_class.rb +1 -1
- data/opal/corelib/numeric.rb +27 -23
- data/opal/corelib/proc.rb +5 -5
- data/opal/corelib/range.rb +8 -4
- data/opal/corelib/regexp.rb +5 -5
- data/opal/corelib/runtime.js +589 -272
- data/opal/corelib/string.rb +52 -37
- data/opal/corelib/string/inheritance.rb +5 -5
- data/opal/corelib/time.rb +102 -52
- data/opal/corelib/variables.rb +3 -3
- data/opal/opal.rb +2 -0
- data/package.json +9 -0
- data/spec/filters/bugs/array.rb +0 -6
- data/spec/filters/bugs/language.rb +4 -0
- data/spec/filters/bugs/numeric.rb +7 -6
- data/spec/filters/bugs/opal.rb +2 -0
- data/spec/filters/bugs/regexp.rb +4 -0
- data/spec/filters/bugs/string.rb +0 -7
- data/spec/filters/bugs/stringscanner.rb +4 -1
- data/spec/filters/unsupported/private_methods.rb +2 -0
- data/spec/lib/builder_processors_spec.rb +27 -0
- data/spec/lib/builder_spec.rb +66 -0
- data/spec/{cli → lib}/cli_spec.rb +60 -5
- data/spec/{cli → lib}/compiler_spec.rb +66 -5
- data/spec/{cli → lib}/dependency_resolver_spec.rb +1 -1
- data/spec/lib/fixtures/no_requires.rb +1 -0
- data/spec/{cli → lib}/fixtures/opal_file.rb +0 -0
- data/spec/lib/fixtures/require_tree_test.rb +3 -0
- data/spec/lib/fixtures/required_tree_test/required_file1.rb +1 -0
- data/spec/lib/fixtures/required_tree_test/required_file2.rb +1 -0
- data/spec/lib/fixtures/requires.rb +7 -0
- data/spec/{cli → lib}/fixtures/sprockets_file.js.rb +0 -0
- data/spec/lib/fixtures/sprockets_require_tree_test.rb +3 -0
- data/spec/lib/hike_path_finder_spec.rb +23 -0
- data/spec/{cli → lib}/lexer_spec.rb +1 -1
- data/spec/{cli → lib}/parser/alias_spec.rb +1 -1
- data/spec/{cli → lib}/parser/and_spec.rb +1 -1
- data/spec/{cli → lib}/parser/attrasgn_spec.rb +1 -1
- data/spec/{cli → lib}/parser/begin_spec.rb +1 -1
- data/spec/{cli → lib}/parser/block_spec.rb +1 -1
- data/spec/{cli → lib}/parser/break_spec.rb +1 -1
- data/spec/{cli → lib}/parser/call_spec.rb +1 -1
- data/spec/{cli → lib}/parser/class_spec.rb +1 -1
- data/spec/{cli → lib}/parser/comments_spec.rb +1 -1
- data/spec/{cli → lib}/parser/def_spec.rb +1 -1
- data/spec/{cli → lib}/parser/if_spec.rb +1 -1
- data/spec/{cli → lib}/parser/iter_spec.rb +1 -1
- data/spec/{cli → lib}/parser/lambda_spec.rb +1 -1
- data/spec/{cli → lib}/parser/literal_spec.rb +1 -1
- data/spec/{cli → lib}/parser/masgn_spec.rb +1 -1
- data/spec/{cli → lib}/parser/module_spec.rb +1 -1
- data/spec/{cli → lib}/parser/not_spec.rb +1 -1
- data/spec/{cli → lib}/parser/op_asgn1_spec.rb +1 -1
- data/spec/{cli → lib}/parser/op_asgn2_spec.rb +1 -1
- data/spec/{cli → lib}/parser/or_spec.rb +1 -1
- data/spec/{cli → lib}/parser/return_spec.rb +1 -1
- data/spec/{cli → lib}/parser/sclass_spec.rb +1 -1
- data/spec/{cli → lib}/parser/string_spec.rb +8 -1
- data/spec/{cli → lib}/parser/super_spec.rb +1 -1
- data/spec/lib/parser/unary_spec.rb +48 -0
- data/spec/{cli → lib}/parser/undef_spec.rb +1 -1
- data/spec/{cli → lib}/parser/unless_spec.rb +1 -1
- data/spec/{cli → lib}/parser/variables_spec.rb +1 -1
- data/spec/{cli → lib}/parser/while_spec.rb +1 -1
- data/spec/{cli → lib}/parser/yield_spec.rb +1 -1
- data/spec/lib/path_reader_spec.rb +24 -0
- data/spec/lib/shared/path_finder_shared.rb +19 -0
- data/spec/lib/shared/path_reader_shared.rb +31 -0
- data/spec/lib/spec_helper.rb +9 -0
- data/spec/lib/sprockets/environment_spec.rb +30 -0
- data/spec/{cli → lib}/sprockets/erb_spec.rb +1 -1
- data/spec/lib/sprockets/path_reader_spec.rb +25 -0
- data/spec/{cli → lib}/sprockets/processor_spec.rb +9 -2
- data/spec/lib/sprockets/server_spec.rb +20 -0
- data/spec/opal/compiler/irb_spec.rb +11 -11
- data/spec/opal/core/fixtures/require_tree_files/file 1.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 2.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 3.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 4.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 5.rb +1 -0
- data/spec/opal/core/kernel/require_tree_spec.rb +7 -0
- data/spec/opal/core/kernel/respond_to_spec.rb +2 -2
- data/spec/opal/core/runtime/method_missing_spec.rb +19 -0
- data/spec/opal/core/source_map_spec.rb +2 -2
- data/spec/opal/core/string_spec.rb +11 -0
- data/spec/opal/stdlib/erb/erb_spec.rb +0 -1
- data/spec/opal/stdlib/thread/mutex_spec.rb +40 -0
- data/spec/opal/stdlib/thread/thread_queue_spec.rb +32 -0
- data/spec/opal/stdlib/thread/thread_spec.rb +60 -0
- data/spec/rubyspecs +54 -11
- data/spec/spec_helper.rb +18 -3
- data/spec/support/mspec_rspec_adapter.rb +33 -0
- data/spec/{cli/spec_helper.rb → support/parser_helpers.rb} +10 -10
- data/stdlib/README.md +3 -0
- data/stdlib/benchmark.rb +10 -0
- data/stdlib/date.rb +2 -2
- data/stdlib/dir.rb +1 -5
- data/stdlib/file.rb +1 -7
- data/stdlib/json.rb +10 -1
- data/stdlib/native.rb +5 -5
- data/stdlib/nodejs.rb +5 -0
- data/stdlib/nodejs/dir.rb +13 -0
- data/stdlib/nodejs/file.rb +98 -0
- data/stdlib/nodejs/fileutils.rb +26 -0
- data/stdlib/nodejs/io.rb +2 -0
- data/stdlib/nodejs/irb.rb +45 -0
- data/stdlib/nodejs/process.rb +16 -0
- data/stdlib/nodejs/require.rb +32 -0
- data/stdlib/nodejs/rubygems.rb +68 -0
- data/stdlib/nodejs/runtime.rb +25 -0
- data/stdlib/nodejs/yaml.rb +11 -0
- data/stdlib/opal-parser.rb +1 -2
- data/stdlib/opal-source-maps.rb +2 -0
- data/stdlib/phantomjs.rb +8 -0
- data/stdlib/process.rb +10 -0
- data/stdlib/promise.rb +12 -4
- data/stdlib/set.rb +27 -0
- data/stdlib/source_map.rb +5 -63
- data/stdlib/source_map/map.rb +220 -0
- data/stdlib/source_map/mapping.rb +26 -0
- data/stdlib/source_map/offset.rb +88 -0
- data/stdlib/source_map/version.rb +3 -0
- data/stdlib/source_map/vlq.rb +77 -101
- data/stdlib/sourcemap.rb +1 -0
- data/stdlib/strscan.rb +7 -1
- data/stdlib/template.rb +1 -1
- data/stdlib/thread.rb +147 -7
- metadata +238 -104
- data/lib/mspec/opal/mspec_fixes.rb +0 -87
- data/spec/cli/sprockets/environment_spec.rb +0 -14
- data/spec/filters/bugs/symbol.rb +0 -5
- data/spec/opal/core/kernel/warn_spec.rb +0 -83
- data/spec/opal/core/language/numbers_spec.rb +0 -60
- data/stdlib/opal-source-maps.js.erb +0 -2
- data/stdlib/source_map/generator.rb +0 -251
- data/stdlib/source_map/parser.rb +0 -102
data/opal/corelib/nil_class.rb
CHANGED
data/opal/corelib/numeric.rb
CHANGED
|
@@ -3,11 +3,11 @@ require 'corelib/comparable'
|
|
|
3
3
|
class Numeric
|
|
4
4
|
include Comparable
|
|
5
5
|
|
|
6
|
-
`def
|
|
6
|
+
`def.$$is_number = true`
|
|
7
7
|
|
|
8
8
|
def coerce(other, type = :operation)
|
|
9
9
|
%x{
|
|
10
|
-
if (other
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
3
|
-
`def
|
|
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
|
|
16
|
+
self.$$p = block;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
var result;
|
|
20
20
|
|
|
21
|
-
if (self
|
|
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
|
|
45
|
+
`!!self.$$is_lambda`
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
# FIXME: this should support the various splats and optional arguments
|
data/opal/corelib/range.rb
CHANGED
|
@@ -3,11 +3,13 @@ require 'corelib/enumerable'
|
|
|
3
3
|
class Range
|
|
4
4
|
include Enumerable
|
|
5
5
|
|
|
6
|
-
`def
|
|
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
|
|
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
|
-
|
|
31
|
+
include? value
|
|
30
32
|
end
|
|
31
33
|
|
|
32
|
-
|
|
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?
|
data/opal/corelib/regexp.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
class Regexp
|
|
2
|
-
`def
|
|
2
|
+
`def.$$is_regexp = true`
|
|
3
3
|
|
|
4
4
|
class << self
|
|
5
5
|
def escape(string)
|
|
6
6
|
%x{
|
|
7
|
-
return string.replace(/([-[\]
|
|
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
|
|
32
|
+
if (!str.$$is_string && #{str.respond_to?(:to_str)}) {
|
|
33
33
|
#{str = str.to_str};
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
if (!str
|
|
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
|
|
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
|
data/opal/corelib/runtime.js
CHANGED
|
@@ -1,36 +1,14 @@
|
|
|
1
1
|
(function(undefined) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
//
|
|
30
|
-
|
|
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
|
|
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
|
|
74
|
-
var const_scope
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
klass
|
|
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
|
|
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
|
|
119
|
-
base = base
|
|
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 =
|
|
115
|
+
superklass = ObjectClass;
|
|
125
116
|
}
|
|
126
117
|
|
|
127
|
-
var klass = base
|
|
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
|
|
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
|
|
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
|
|
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
|
|
141
|
+
klass.$$name = id;
|
|
152
142
|
|
|
153
143
|
// every class gets its own constant scope, inherited from current scope
|
|
154
|
-
create_scope(base
|
|
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
|
|
147
|
+
base[id] = base.$$scope[id] = klass;
|
|
158
148
|
|
|
159
149
|
// Copy all parent constants to child, unless parent is Object
|
|
160
|
-
if (superklass !==
|
|
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
|
-
|
|
175
|
-
|
|
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
|
-
|
|
180
|
-
|
|
181
|
-
constructor.prototype.constructor = constructor;
|
|
167
|
+
return boot_class_object(superklass, alloc);
|
|
168
|
+
}
|
|
182
169
|
|
|
183
|
-
|
|
184
|
-
|
|
170
|
+
// Make `boot_class` available to the JS-API
|
|
171
|
+
Opal.boot = boot_class;
|
|
185
172
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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
|
|
185
|
+
function OpalClass() {}
|
|
186
|
+
OpalClass.prototype = new singleton_class();
|
|
193
187
|
|
|
194
188
|
var klass = new OpalClass();
|
|
195
189
|
|
|
196
|
-
klass.
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
klass
|
|
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
|
-
|
|
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
|
|
216
|
-
base = base
|
|
260
|
+
if (!base.$$is_class) {
|
|
261
|
+
base = base.$$class;
|
|
217
262
|
}
|
|
218
263
|
|
|
219
|
-
if ($hasOwn.call(base
|
|
220
|
-
module = base
|
|
264
|
+
if ($hasOwn.call(base.$$scope, id)) {
|
|
265
|
+
module = base.$$scope[id];
|
|
221
266
|
|
|
222
|
-
if (!module
|
|
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 =
|
|
228
|
-
module
|
|
272
|
+
module = boot_module_object();
|
|
273
|
+
module.$$name = id;
|
|
229
274
|
|
|
230
|
-
create_scope(base
|
|
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
|
|
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
|
|
288
|
+
function boot_module_object() {
|
|
244
289
|
var mtor = function() {};
|
|
245
|
-
mtor.prototype =
|
|
290
|
+
mtor.prototype = ModuleClass.constructor.prototype;
|
|
246
291
|
|
|
247
|
-
function
|
|
248
|
-
|
|
292
|
+
function module_constructor() {}
|
|
293
|
+
module_constructor.prototype = new mtor();
|
|
249
294
|
|
|
250
|
-
var module = new
|
|
295
|
+
var module = new module_constructor();
|
|
296
|
+
var module_prototype = {};
|
|
251
297
|
|
|
252
|
-
module
|
|
253
|
-
|
|
254
|
-
module
|
|
255
|
-
module
|
|
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
|
-
|
|
417
|
+
function boot_class_alloc(id, constructor, superklass) {
|
|
268
418
|
if (superklass) {
|
|
269
|
-
var ctor
|
|
270
|
-
ctor.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
|
-
|
|
281
|
-
|
|
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
|
|
284
|
-
|
|
447
|
+
var singleton_class = function() {};
|
|
448
|
+
singleton_class.prototype = new superclass_constructor();
|
|
285
449
|
|
|
286
|
-
|
|
287
|
-
OpalClass.prototype = new mtor();
|
|
450
|
+
singleton_class.displayName = "#<Class:"+id+">";
|
|
288
451
|
|
|
289
|
-
|
|
452
|
+
// the singleton_class acts as the class object constructor
|
|
453
|
+
var klass = new singleton_class();
|
|
290
454
|
|
|
291
|
-
klass.
|
|
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
|
-
|
|
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 =
|
|
493
|
+
var klass = boot_class_object(ObjectClass, constructor);
|
|
335
494
|
|
|
336
|
-
klass
|
|
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 =
|
|
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] =
|
|
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
|
|
516
|
+
var scope = base_module.$$scope;
|
|
356
517
|
|
|
357
|
-
if (value
|
|
358
|
-
value
|
|
518
|
+
if (value.$$is_class && value.$$name === nil) {
|
|
519
|
+
value.$$name = name;
|
|
359
520
|
}
|
|
360
521
|
|
|
361
|
-
if (value
|
|
362
|
-
value
|
|
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
|
|
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.
|
|
402
|
-
target_scope = target_mod
|
|
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
|
|
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 `
|
|
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
|
|
605
|
+
var method_name = stubs[i], stub = stub_for(method_name);
|
|
442
606
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
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
|
-
*
|
|
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
|
|
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
|
|
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, [
|
|
660
|
+
return this.$method_missing.apply(this, [method_name.slice(1)].concat($slice.call(arguments)));
|
|
467
661
|
}
|
|
468
662
|
|
|
469
|
-
method_missing_stub
|
|
470
|
-
|
|
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
|
|
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
|
|
683
|
+
dispatcher = obj.$$is_class ? defs.$$super : obj.$$class.$$proto;
|
|
494
684
|
}
|
|
495
685
|
else {
|
|
496
|
-
if (obj
|
|
497
|
-
dispatcher = obj
|
|
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
|
|
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
|
|
513
|
-
return Opal.find_super_dispatcher(obj, current_func
|
|
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
|
-
|
|
521
|
-
var klass = obj
|
|
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
|
|
715
|
+
if (klass.$$proto[jsid] === current_func) {
|
|
525
716
|
// ok
|
|
526
717
|
break;
|
|
527
718
|
}
|
|
528
719
|
|
|
529
|
-
klass = klass
|
|
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
|
|
728
|
+
klass = klass.$$parent;
|
|
538
729
|
|
|
539
730
|
// else, let's find the next one
|
|
540
731
|
while (klass) {
|
|
541
|
-
var working = klass
|
|
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
|
|
739
|
+
klass = klass.$$parent;
|
|
549
740
|
}
|
|
550
741
|
|
|
551
|
-
return klass
|
|
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
|
-
|
|
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]
|
|
779
|
+
if (args[0].$$is_array) {
|
|
594
780
|
return block.apply(null, args[0]);
|
|
595
781
|
}
|
|
596
782
|
}
|
|
597
783
|
|
|
598
|
-
if (!args
|
|
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
|
|
611
|
-
var subresult;
|
|
612
|
-
if (subresult
|
|
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
|
|
810
|
+
if (object.$$meta === klass) {
|
|
625
811
|
return true;
|
|
626
812
|
}
|
|
627
813
|
|
|
628
|
-
var search = object
|
|
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.
|
|
636
|
-
if (search
|
|
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
|
|
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
|
|
835
|
+
if (value.$$is_array) {
|
|
650
836
|
return value;
|
|
651
837
|
}
|
|
652
|
-
else if (value.$to_ary && !value.$to_ary
|
|
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
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
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
|
|
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
|
|
887
|
+
var methods = klass.$$methods, included_in = klass.$$dep;
|
|
702
888
|
|
|
703
889
|
// if (!indirect) {
|
|
704
|
-
klass
|
|
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
|
|
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
|
-
|
|
715
|
-
dest[method]
|
|
900
|
+
|
|
901
|
+
dest[method] = klass.$$proto[method];
|
|
902
|
+
dest[method].$$donated = true;
|
|
716
903
|
}
|
|
717
904
|
|
|
718
|
-
if (includee
|
|
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
|
|
727
|
-
obj
|
|
913
|
+
if (obj.$$is_mod) {
|
|
914
|
+
obj.$$proto[jsid] = body;
|
|
728
915
|
Opal.donate(obj, [jsid]);
|
|
729
916
|
}
|
|
730
|
-
else if (obj
|
|
731
|
-
obj
|
|
917
|
+
else if (obj.$$is_class) {
|
|
918
|
+
obj.$$proto[jsid] = body;
|
|
732
919
|
|
|
733
|
-
if (obj ===
|
|
920
|
+
if (obj === BasicObjectClass) {
|
|
734
921
|
define_basic_object_method(jsid, body);
|
|
735
922
|
}
|
|
736
|
-
else if (obj ===
|
|
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
|
|
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
|
-
|
|
947
|
+
BasicObjectClass.$$methods.push(jsid);
|
|
761
948
|
for (var i = 0, len = bridged_classes.length; i < len; i++) {
|
|
762
|
-
bridged_classes[i]
|
|
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]
|
|
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
|
|
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]
|
|
967
|
+
if (arguments[0].$$is_array) {
|
|
780
968
|
var args = arguments[0];
|
|
781
969
|
|
|
782
|
-
for (var i = 0,
|
|
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
|
-
|
|
790
|
-
|
|
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
|
-
|
|
801
|
-
for (
|
|
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
|
-
|
|
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
|
|
814
|
-
|
|
815
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
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
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
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
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
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
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
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
|
-
|
|
1193
|
+
ObjectClass.$$dep = bridged_classes;
|
|
888
1194
|
|
|
889
|
-
Opal.base
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
Opal.Kernel
|
|
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
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
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
|
-
|
|
1205
|
+
ObjectClass.$$proto.toString = function() {
|
|
900
1206
|
return this.$to_s();
|
|
901
1207
|
};
|
|
902
1208
|
|
|
903
|
-
|
|
1209
|
+
ObjectClass.$$proto.$require = Opal.require;
|
|
1210
|
+
|
|
1211
|
+
Opal.top = new ObjectClass.$$alloc();
|
|
904
1212
|
|
|
905
|
-
Opal.klass(
|
|
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',
|
|
914
|
-
bridge_class('Boolean',
|
|
915
|
-
bridge_class('Numeric',
|
|
916
|
-
bridge_class('String',
|
|
917
|
-
bridge_class('Proc',
|
|
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',
|
|
920
|
-
bridge_class('Time',
|
|
1227
|
+
bridge_class('Regexp', RegExp);
|
|
1228
|
+
bridge_class('Time', Date);
|
|
921
1229
|
|
|
922
|
-
TypeError
|
|
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
|
+
}
|