opal 0.3.6 → 0.3.9
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.
- data/README.md +69 -97
- data/bin/opal +2 -2
- data/{lib/core → corelib}/array.rb +85 -56
- data/corelib/boolean.rb +20 -0
- data/corelib/class.rb +58 -0
- data/{lib → corelib}/core.rb +2 -50
- data/corelib/dir.rb +22 -0
- data/{lib/core → corelib}/enumerable.rb +0 -0
- data/corelib/error.rb +19 -0
- data/{lib/core → corelib}/file.rb +7 -9
- data/{lib/core → corelib}/hash.rb +104 -144
- data/{lib/core → corelib}/kernel.rb +38 -44
- data/corelib/load_order +21 -0
- data/{lib/core → corelib}/match_data.rb +0 -0
- data/{lib/core → corelib}/module.rb +12 -8
- data/{lib/core → corelib}/nil_class.rb +2 -2
- data/{lib/core → corelib}/numeric.rb +37 -100
- data/corelib/object.rb +37 -0
- data/{lib/core → corelib}/proc.rb +3 -3
- data/corelib/range.rb +27 -0
- data/{lib/core → corelib}/regexp.rb +1 -1
- data/{lib/core → corelib}/string.rb +16 -107
- data/{lib/core → corelib}/top_self.rb +0 -0
- data/lib/opal.rb +7 -0
- data/lib/opal/browserify.rb +34 -0
- data/{opal_lib → lib}/opal/builder.rb +70 -24
- data/lib/opal/command.rb +52 -0
- data/lib/opal/context.rb +197 -0
- data/{opal_lib/opal/ruby/parser.rb → lib/opal/lexer.rb} +20 -4
- data/{opal_lib/opal/ruby → lib/opal}/nodes.rb +238 -127
- data/lib/opal/parser.rb +4894 -0
- data/{opal_lib/opal/ruby/ruby_parser.y → lib/opal/parser.y} +38 -18
- data/lib/rbp.rb +2 -0
- data/lib/rbp/package.rb +49 -0
- data/runtime/class.js +216 -189
- data/runtime/fs.js +2 -2
- data/runtime/init.js +242 -244
- data/runtime/loader.js +78 -99
- data/runtime/module.js +34 -40
- data/runtime/post.js +2 -2
- data/runtime/pre.js +1 -1
- data/runtime/runtime.js +129 -135
- data/{lib → stdlib}/dev.rb +10 -10
- data/{lib → stdlib}/racc/parser.rb +0 -6
- data/{lib → stdlib}/strscan.rb +4 -4
- metadata +57 -105
- data/lib/core/basic_object.rb +0 -51
- data/lib/core/class.rb +0 -38
- data/lib/core/dir.rb +0 -26
- data/lib/core/error.rb +0 -75
- data/lib/core/false_class.rb +0 -81
- data/lib/core/object.rb +0 -6
- data/lib/core/range.rb +0 -27
- data/lib/core/symbol.rb +0 -42
- data/lib/core/true_class.rb +0 -41
- data/lib/ospec.rb +0 -7
- data/lib/ospec/autorun.rb +0 -8
- data/lib/ospec/dsl.rb +0 -15
- data/lib/ospec/example.rb +0 -11
- data/lib/ospec/example/before_and_after_hooks.rb +0 -56
- data/lib/ospec/example/errors.rb +0 -17
- data/lib/ospec/example/example_group.rb +0 -12
- data/lib/ospec/example/example_group_factory.rb +0 -18
- data/lib/ospec/example/example_group_hierarchy.rb +0 -21
- data/lib/ospec/example/example_group_methods.rb +0 -100
- data/lib/ospec/example/example_group_proxy.rb +0 -15
- data/lib/ospec/example/example_methods.rb +0 -46
- data/lib/ospec/example/example_proxy.rb +0 -18
- data/lib/ospec/expectations.rb +0 -19
- data/lib/ospec/expectations/errors.rb +0 -8
- data/lib/ospec/expectations/fail_with.rb +0 -9
- data/lib/ospec/expectations/handler.rb +0 -33
- data/lib/ospec/helpers/scratch.rb +0 -18
- data/lib/ospec/matchers.rb +0 -24
- data/lib/ospec/matchers/be.rb +0 -1
- data/lib/ospec/matchers/generated_descriptions.rb +0 -20
- data/lib/ospec/matchers/operator_matcher.rb +0 -54
- data/lib/ospec/matchers/raise_error.rb +0 -38
- data/lib/ospec/runner.rb +0 -90
- data/lib/ospec/runner/example_group_runner.rb +0 -41
- data/lib/ospec/runner/formatter/html_formatter.rb +0 -139
- data/lib/ospec/runner/formatter/terminal_formatter.rb +0 -48
- data/lib/ospec/runner/options.rb +0 -34
- data/lib/ospec/runner/reporter.rb +0 -82
- data/opal_lib/opal.rb +0 -16
- data/opal_lib/opal/build_methods.rb +0 -51
- data/opal_lib/opal/bundle.rb +0 -70
- data/opal_lib/opal/command.rb +0 -68
- data/opal_lib/opal/context.rb +0 -81
- data/opal_lib/opal/context/console.rb +0 -10
- data/opal_lib/opal/context/file_system.rb +0 -34
- data/opal_lib/opal/context/loader.rb +0 -135
- data/opal_lib/opal/gem.rb +0 -84
- data/opal_lib/opal/rake/builder_task.rb +0 -44
- data/opal_lib/opal/rake/spec_task.rb +0 -32
- data/opal_lib/opal/ruby/ruby_parser.rb +0 -4862
- data/opal_lib/opal/version.rb +0 -4
- data/runtime/debug.js +0 -84
data/runtime/loader.js
CHANGED
|
@@ -20,7 +20,7 @@ load_extensions['.rb'] = function(loader, path) {
|
|
|
20
20
|
@param {String} id lib path/name
|
|
21
21
|
@return {Boolean}
|
|
22
22
|
*/
|
|
23
|
-
var
|
|
23
|
+
var rb_require = Op.require = function(lib) {
|
|
24
24
|
var resolved = Op.loader.resolve_lib(lib);
|
|
25
25
|
var cached = Op.cache[resolved];
|
|
26
26
|
|
|
@@ -61,91 +61,94 @@ Op.run = function(body) {
|
|
|
61
61
|
var res = Qnil;
|
|
62
62
|
|
|
63
63
|
if (typeof body != 'function') {
|
|
64
|
-
|
|
64
|
+
rb_raise(rb_eException, "Expected body to be a function");
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
try {
|
|
68
|
-
res = body(Rt,
|
|
69
|
-
}
|
|
70
|
-
catch (
|
|
71
|
-
var
|
|
72
|
-
|
|
73
|
-
if (
|
|
74
|
-
puts(
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
puts('
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
else if (stack = exc.stack) {
|
|
86
|
-
puts(stack);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
67
|
+
// try {
|
|
68
|
+
res = body(Rt, rb_top_self, "(opal)");
|
|
69
|
+
// }
|
|
70
|
+
// catch (err) {
|
|
71
|
+
// var stack;
|
|
72
|
+
|
|
73
|
+
// if (err.$message) {
|
|
74
|
+
// puts(err.$k.__classid__ + ': ' + err.$message);
|
|
75
|
+
// }
|
|
76
|
+
// else if (err.message) {
|
|
77
|
+
// puts(err.$k.__classid__ + ': ' + err.message);
|
|
78
|
+
// }
|
|
79
|
+
// else {
|
|
80
|
+
// puts('NativeError: ' + err.message);
|
|
81
|
+
// console.log(err);
|
|
82
|
+
// }
|
|
83
|
+
// }
|
|
89
84
|
return res;
|
|
90
85
|
};
|
|
91
86
|
|
|
92
87
|
/**
|
|
93
|
-
Register a lib
|
|
94
|
-
|
|
95
|
-
of the gemspec for the gem. If the info is simply a function (or
|
|
96
|
-
string?) then a singular lib will be registerd with the function as
|
|
97
|
-
its body.
|
|
88
|
+
Register a simple lib file. This file is simply just put into the lib
|
|
89
|
+
"directory" so it is ready to load"
|
|
98
90
|
|
|
99
91
|
@param {String} name The lib/gem name
|
|
100
|
-
@param {
|
|
92
|
+
@param {String, Function} info
|
|
101
93
|
*/
|
|
102
|
-
Op.
|
|
103
|
-
// make sure name
|
|
94
|
+
Op.lib = function(name, info) {
|
|
95
|
+
// make sure name if useful
|
|
104
96
|
if (typeof name !== 'string') {
|
|
105
|
-
|
|
97
|
+
rb_raise(rb_eException, "Cannot register a lib without a proper name");
|
|
106
98
|
}
|
|
107
99
|
|
|
108
|
-
//
|
|
100
|
+
// make sure info is useful
|
|
109
101
|
if (typeof info === 'string' || typeof info === 'function') {
|
|
110
|
-
load_register_lib(name, info);
|
|
102
|
+
return load_register_lib(name, info);
|
|
111
103
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
104
|
+
|
|
105
|
+
// something went wrong..
|
|
106
|
+
rb_raise(rb_eException, "Invalid lib data for: " + name);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
External api for defining a package. This takes an object that defines
|
|
111
|
+
all the package info and files.
|
|
112
|
+
|
|
113
|
+
@param {Object} info Package info
|
|
114
|
+
*/
|
|
115
|
+
Op.package = function(info) {
|
|
116
|
+
if (typeof info === 'object') {
|
|
117
|
+
load_register_package(info);
|
|
115
118
|
}
|
|
116
|
-
// something has gone wrong..
|
|
117
119
|
else {
|
|
118
|
-
|
|
120
|
+
rb_raise(rb_eException, "Invalid package data");
|
|
119
121
|
}
|
|
120
122
|
};
|
|
121
123
|
|
|
122
124
|
/**
|
|
123
|
-
Actually register a predefined
|
|
124
|
-
where
|
|
125
|
+
Actually register a predefined package. This is for the browser context
|
|
126
|
+
where package can be serialized into JSON and defined before hand.
|
|
125
127
|
|
|
126
|
-
@param {String} name Gem name
|
|
127
128
|
@param {Object} info Serialized gemspec
|
|
128
129
|
*/
|
|
129
|
-
function
|
|
130
|
+
function load_register_package(info) {
|
|
130
131
|
var factories = Op.loader.factories,
|
|
131
|
-
paths = Op.loader.paths
|
|
132
|
+
paths = Op.loader.paths,
|
|
133
|
+
name = info.name;
|
|
132
134
|
|
|
133
135
|
// register all lib files
|
|
134
|
-
var
|
|
136
|
+
var libs = info.libs || {};
|
|
135
137
|
|
|
136
138
|
// root dir for gem is '/gem_name'
|
|
137
139
|
var root_dir = '/' + name;
|
|
138
140
|
|
|
139
141
|
// for now assume './lib' as dir for all libs (should be dynamic..)
|
|
140
|
-
var lib_dir = '
|
|
142
|
+
var lib_dir = '/' + name + '/lib/';
|
|
141
143
|
|
|
142
144
|
// add lib dir to paths
|
|
143
145
|
paths.unshift(fs_expand_path(fs_join(root_dir, lib_dir)));
|
|
144
146
|
|
|
145
|
-
for (var
|
|
146
|
-
if (
|
|
147
|
-
var file_path =
|
|
148
|
-
factories[file_path] =
|
|
147
|
+
for (var lib in libs) {
|
|
148
|
+
if (hasOwnProperty.call(libs, lib)) {
|
|
149
|
+
var file_path = lib_dir + lib;
|
|
150
|
+
Op.loader.factories[file_path] = libs[lib];
|
|
151
|
+
Op.loader.libs[lib] = file_path;
|
|
149
152
|
}
|
|
150
153
|
}
|
|
151
154
|
|
|
@@ -160,8 +163,9 @@ function load_register_gem(name, info) {
|
|
|
160
163
|
@param {Function, String} factory
|
|
161
164
|
*/
|
|
162
165
|
function load_register_lib(name, factory) {
|
|
163
|
-
var path = '/' + name;
|
|
166
|
+
var path = '/lib/' + name;
|
|
164
167
|
Op.loader.factories[path] = factory;
|
|
168
|
+
Op.loader.libs[name] = path;
|
|
165
169
|
}
|
|
166
170
|
|
|
167
171
|
/**
|
|
@@ -179,6 +183,7 @@ function Loader(opal) {
|
|
|
179
183
|
this.opal = opal;
|
|
180
184
|
this.paths = ['', '/lib'];
|
|
181
185
|
this.factories = {};
|
|
186
|
+
this.libs = {};
|
|
182
187
|
return this;
|
|
183
188
|
}
|
|
184
189
|
|
|
@@ -215,52 +220,31 @@ Lp.resolve_lib = function(lib) {
|
|
|
215
220
|
var resolved = this.find_lib(lib, this.paths);
|
|
216
221
|
|
|
217
222
|
if (!resolved) {
|
|
218
|
-
|
|
223
|
+
raise(eLoadError, "no such file to load -- " + lib);
|
|
219
224
|
}
|
|
220
225
|
|
|
221
226
|
return resolved;
|
|
222
227
|
};
|
|
223
228
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
@param {String} lib The lib path/file to look for
|
|
228
|
-
@param {Array} paths Load paths to use
|
|
229
|
-
@return {String} Located path
|
|
230
|
-
*/
|
|
231
|
-
Lp.find_lib = function(id, paths) {
|
|
232
|
-
var extensions = this.valid_extensions, factories = this.factories, candidate;
|
|
229
|
+
Lp.find_lib = function(id) {
|
|
230
|
+
var libs = this.libs;
|
|
231
|
+
var id_with_ext = id + '.rb';
|
|
233
232
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
if (factories[candidate]) {
|
|
239
|
-
return candidate;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
233
|
+
// try to load a lib path first - i.e. something in our load path
|
|
234
|
+
if (libs[id_with_ext]) {
|
|
235
|
+
return libs[id_with_ext];
|
|
242
236
|
}
|
|
243
237
|
|
|
244
|
-
//
|
|
245
|
-
if (factories[id]) {
|
|
246
|
-
return id;
|
|
247
|
-
}
|
|
238
|
+
// go through full paths..
|
|
248
239
|
|
|
249
|
-
//
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
if (
|
|
253
|
-
return
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// try each path with no extension (if id already has extension)
|
|
258
|
-
for (var i = 0; i < paths.length; i++) {
|
|
259
|
-
candidate = fs_join(paths[j], id);
|
|
260
|
-
|
|
261
|
-
if (factories[candidate]) {
|
|
262
|
-
return candidate;
|
|
240
|
+
// next, incase our require() has a ruby extension..
|
|
241
|
+
if (id.lastIndexOf('.rb') == id.length - 3) {
|
|
242
|
+
// id = id.substr(0, id.length - 3);
|
|
243
|
+
if (libs[id]) {
|
|
244
|
+
return libs[id];
|
|
263
245
|
}
|
|
246
|
+
// if not..
|
|
247
|
+
// return null;
|
|
264
248
|
}
|
|
265
249
|
|
|
266
250
|
return null;
|
|
@@ -292,7 +276,7 @@ function load_file(loader, path) {
|
|
|
292
276
|
var ext = load_extensions[PATH_RE.exec(path)[3] || '.js'];
|
|
293
277
|
|
|
294
278
|
if (!ext) {
|
|
295
|
-
|
|
279
|
+
rb_raise(rb_eException, "load_run_file - Bad extension for resolved path");
|
|
296
280
|
}
|
|
297
281
|
|
|
298
282
|
ext(loader, path);
|
|
@@ -310,7 +294,7 @@ function load_file(loader, path) {
|
|
|
310
294
|
@param {String} path
|
|
311
295
|
*/
|
|
312
296
|
function load_execute_file(loader, content, path) {
|
|
313
|
-
var args = [Rt,
|
|
297
|
+
var args = [Rt, rb_top_self, path];
|
|
314
298
|
|
|
315
299
|
if (typeof content === 'function') {
|
|
316
300
|
return content.apply(Op, args);
|
|
@@ -320,8 +304,7 @@ function load_execute_file(loader, content, path) {
|
|
|
320
304
|
return func.apply(Op, args);
|
|
321
305
|
|
|
322
306
|
} else {
|
|
323
|
-
|
|
324
|
-
"Loader.execute - bad content sent for '" + path + "'");
|
|
307
|
+
rb_raise(rb_eException, "Loader.execute - bad content for: " + path);
|
|
325
308
|
}
|
|
326
309
|
}
|
|
327
310
|
|
|
@@ -331,8 +314,8 @@ function load_execute_file(loader, content, path) {
|
|
|
331
314
|
@param {String} id The globals id being retrieved.
|
|
332
315
|
@return {Array} Load paths
|
|
333
316
|
*/
|
|
334
|
-
function
|
|
335
|
-
return
|
|
317
|
+
function rb_load_path_getter(id) {
|
|
318
|
+
return Op.loader.paths;
|
|
336
319
|
}
|
|
337
320
|
|
|
338
321
|
/**
|
|
@@ -341,11 +324,7 @@ function load_path_getter(id) {
|
|
|
341
324
|
@param {String} id Feature global id
|
|
342
325
|
@return {Array} Loaded features
|
|
343
326
|
*/
|
|
344
|
-
function
|
|
327
|
+
function rb_loaded_feature_getter(id) {
|
|
345
328
|
return loaded_features;
|
|
346
329
|
}
|
|
347
330
|
|
|
348
|
-
function obj_require(obj, path) {
|
|
349
|
-
return Rt.require(path) ? Qtrue : Qfalse;
|
|
350
|
-
}
|
|
351
|
-
|
data/runtime/module.js
CHANGED
|
@@ -2,49 +2,49 @@
|
|
|
2
2
|
/**
|
|
3
3
|
Define a top level module with the given id
|
|
4
4
|
*/
|
|
5
|
-
function
|
|
6
|
-
return
|
|
5
|
+
function rb_define_module(id) {
|
|
6
|
+
return rb_define_module_under(rb_cObject, id);
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
function
|
|
9
|
+
function rb_define_module_under(base, id) {
|
|
10
10
|
var module;
|
|
11
11
|
|
|
12
|
-
if (
|
|
13
|
-
module =
|
|
14
|
-
if (module.$
|
|
12
|
+
if (rb_const_defined(base, id)) {
|
|
13
|
+
module = rb_const_get(base, id);
|
|
14
|
+
if (module.$f & T_MODULE) {
|
|
15
15
|
return module;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
rb_raise(rb_eException, id + " is not a module");
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
module =
|
|
21
|
+
module = rb_define_module_id(id);
|
|
22
22
|
|
|
23
|
-
if (base ==
|
|
24
|
-
|
|
23
|
+
if (base == rb_cObject) {
|
|
24
|
+
rb_name_class(module, id);
|
|
25
25
|
} else {
|
|
26
|
-
|
|
26
|
+
rb_name_class(module, base.__classid__ + '::' + id);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
rb_const_set(base, id, module);
|
|
30
30
|
module.$parent = base;
|
|
31
31
|
return module;
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
function
|
|
35
|
-
var module =
|
|
36
|
-
|
|
34
|
+
function rb_define_module_id(id) {
|
|
35
|
+
var module = rb_class_create(rb_cModule);
|
|
36
|
+
rb_make_metaclass(module, rb_cModule);
|
|
37
37
|
|
|
38
|
-
module.$
|
|
38
|
+
module.$f = T_MODULE;
|
|
39
39
|
module.$included_in = [];
|
|
40
40
|
return module;
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
function
|
|
44
|
-
return
|
|
43
|
+
function rb_mod_create() {
|
|
44
|
+
return rb_class_boot(rb_cModule);
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
-
function
|
|
47
|
+
function rb_include_module(klass, module) {
|
|
48
48
|
|
|
49
49
|
if (!klass.$included_modules) {
|
|
50
50
|
klass.$included_modules = [];
|
|
@@ -61,24 +61,21 @@ function include_module(klass, module) {
|
|
|
61
61
|
|
|
62
62
|
module.$included_in.push(klass);
|
|
63
63
|
|
|
64
|
-
for (var method in module.$
|
|
65
|
-
if (module.$
|
|
66
|
-
|
|
67
|
-
module.$
|
|
68
|
-
module.$m_tbl['$' + method]);
|
|
64
|
+
for (var method in module.$m) {
|
|
65
|
+
if (hasOwnProperty.call(module.$m, method)) {
|
|
66
|
+
rb_define_raw_method(klass, method,
|
|
67
|
+
module.$a.prototype[method]);
|
|
69
68
|
}
|
|
70
69
|
}
|
|
71
70
|
|
|
72
|
-
for (var constant in module.$c) {
|
|
73
|
-
if (module.$c
|
|
74
|
-
const_set(klass, constant, module.$c[constant]);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
71
|
+
// for (var constant in module.$c) {
|
|
72
|
+
// if (hasOwnProperty.call(module.$c, constant)) {
|
|
73
|
+
// const_set(klass, constant, module.$c[constant]);
|
|
74
|
+
// }
|
|
75
|
+
// }
|
|
77
76
|
};
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
function extend_module(klass, module) {
|
|
78
|
+
function rb_extend_module(klass, module) {
|
|
82
79
|
if (!klass.$extended_modules) {
|
|
83
80
|
klass.$extended_modules = [];
|
|
84
81
|
}
|
|
@@ -94,16 +91,13 @@ function extend_module(klass, module) {
|
|
|
94
91
|
|
|
95
92
|
module.$extended_in.push(klass);
|
|
96
93
|
|
|
97
|
-
var meta = klass.$
|
|
94
|
+
var meta = klass.$k;
|
|
98
95
|
|
|
99
|
-
for (var method in module
|
|
100
|
-
if (module
|
|
101
|
-
|
|
102
|
-
module
|
|
103
|
-
module.$m_tbl['$' + method]);
|
|
96
|
+
for (var method in module.o$m) {
|
|
97
|
+
if (hasOwnProperty.call(module.o$m, method)) {
|
|
98
|
+
rb_define_raw_method(meta, method,
|
|
99
|
+
module.o$a.prototype[method]);
|
|
104
100
|
}
|
|
105
101
|
}
|
|
106
102
|
};
|
|
107
103
|
|
|
108
|
-
Rt.extend_module = extend_module;
|
|
109
|
-
|
data/runtime/post.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
|
|
2
2
|
init();
|
|
3
3
|
|
|
4
|
-
})();
|
|
4
|
+
})(undefined);
|
|
5
5
|
|
|
6
6
|
// if in a commonjs system already (node etc), exports become our opal
|
|
7
7
|
// object. Otherwise, in the browser, we just get a top level opal var
|
|
8
8
|
if ((typeof require !== 'undefined') && (typeof module !== 'undefined')) {
|
|
9
|
-
module.exports =
|
|
9
|
+
module.exports = opalscript;
|
|
10
10
|
}
|
data/runtime/pre.js
CHANGED
data/runtime/runtime.js
CHANGED
|
@@ -2,56 +2,53 @@
|
|
|
2
2
|
All methods and properties available to ruby/js sources at runtime. These
|
|
3
3
|
are kept in their own namespace to keep the opal namespace clean.
|
|
4
4
|
*/
|
|
5
|
-
Op.runtime = {};
|
|
5
|
+
var Rt = Op.runtime = {};
|
|
6
6
|
|
|
7
|
-
// for minimizng
|
|
8
|
-
var Rt = Op.runtime;
|
|
9
7
|
Rt.opal = Op;
|
|
10
8
|
|
|
11
9
|
/**
|
|
12
10
|
Opal platform - this is overriden in gem context and nodejs context. These
|
|
13
11
|
are the default values used in the browser, `opal-browser'.
|
|
14
12
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
var PLATFORM_PLATFORM = "opal";
|
|
14
|
+
var PLATFORM_ENGINE = "opal-browser";
|
|
15
|
+
var PLATFORM_VERSION = "1.9.2";
|
|
16
|
+
var PLATFORM_ARGV = [];
|
|
17
|
+
|
|
18
|
+
// Minimize js types
|
|
19
|
+
var ArrayProto = Array.prototype,
|
|
20
|
+
ObjectProto = Object.prototype,
|
|
21
|
+
|
|
22
|
+
ArraySlice = ArrayProto.slice,
|
|
23
|
+
|
|
24
|
+
hasOwnProperty = ObjectProto.hasOwnProperty;
|
|
21
25
|
|
|
22
26
|
/**
|
|
23
27
|
Core runtime classes, objects and literals.
|
|
24
28
|
*/
|
|
25
|
-
var
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Qfalse, Qtrue,
|
|
29
|
+
var rb_cBasirb_cObject, rb_cObject, rb_cModule, rb_cClass,
|
|
30
|
+
rb_mKernel, rb_cNilClass, rb_cBoolean,
|
|
31
|
+
rb_cArray, rb_cNumeric,
|
|
32
|
+
rb_cRegexp, rb_cMatch, rb_top_self, Qnil,
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
rb_cDir;
|
|
32
35
|
|
|
33
36
|
/**
|
|
34
37
|
Core object type flags. Added as local variables, and onto runtime.
|
|
35
38
|
*/
|
|
36
|
-
var T_CLASS =
|
|
37
|
-
T_MODULE =
|
|
38
|
-
T_OBJECT =
|
|
39
|
-
T_BOOLEAN =
|
|
40
|
-
T_STRING =
|
|
41
|
-
T_ARRAY =
|
|
42
|
-
T_NUMBER =
|
|
43
|
-
T_PROC =
|
|
44
|
-
T_SYMBOL =
|
|
45
|
-
T_HASH =
|
|
46
|
-
T_RANGE =
|
|
47
|
-
T_ICLASS =
|
|
48
|
-
FL_SINGLETON =
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
Method visibility modes
|
|
52
|
-
*/
|
|
53
|
-
var FL_PUBLIC = 0,
|
|
54
|
-
FL_PRIVATE = 1;
|
|
39
|
+
var T_CLASS = 1,
|
|
40
|
+
T_MODULE = 2,
|
|
41
|
+
T_OBJECT = 4,
|
|
42
|
+
T_BOOLEAN = 8,
|
|
43
|
+
T_STRING = 16,
|
|
44
|
+
T_ARRAY = 32,
|
|
45
|
+
T_NUMBER = 64,
|
|
46
|
+
T_PROC = 128,
|
|
47
|
+
T_SYMBOL = 256,
|
|
48
|
+
T_HASH = 512,
|
|
49
|
+
T_RANGE = 1024,
|
|
50
|
+
T_ICLASS = 2056,
|
|
51
|
+
FL_SINGLETON = 4112;
|
|
55
52
|
|
|
56
53
|
/**
|
|
57
54
|
Define classes. This is the public API for defining classes, shift classes
|
|
@@ -68,35 +65,32 @@ Rt.dc = function(base, super_class, id, body, flag) {
|
|
|
68
65
|
|
|
69
66
|
switch (flag) {
|
|
70
67
|
case 0:
|
|
71
|
-
if (base.$
|
|
72
|
-
base =
|
|
68
|
+
if (base.$f & T_OBJECT) {
|
|
69
|
+
base = rb_class_real(base.$k);
|
|
73
70
|
}
|
|
74
71
|
|
|
75
72
|
if (super_class == Qnil) {
|
|
76
|
-
super_class =
|
|
73
|
+
super_class = rb_cObject;
|
|
77
74
|
}
|
|
78
75
|
|
|
79
|
-
klass =
|
|
76
|
+
klass = rb_define_class_under(base, id, super_class);
|
|
80
77
|
break;
|
|
81
78
|
|
|
82
79
|
case 1:
|
|
83
|
-
klass =
|
|
80
|
+
klass = rb_singleton_class(base);
|
|
84
81
|
break;
|
|
85
82
|
|
|
86
83
|
case 2:
|
|
87
|
-
if (base.$
|
|
88
|
-
base =
|
|
84
|
+
if (base.$f & T_OBJECT) {
|
|
85
|
+
base = rb_class_real(base.$k);
|
|
89
86
|
}
|
|
90
|
-
klass =
|
|
87
|
+
klass = rb_define_module_under(base, id);
|
|
91
88
|
break;
|
|
92
89
|
|
|
93
90
|
default:
|
|
94
|
-
|
|
91
|
+
rb_raise(rb_eException, "define_class got a unknown flag " + flag);
|
|
95
92
|
}
|
|
96
93
|
|
|
97
|
-
// when reopening a class always set it back to public
|
|
98
|
-
klass.$mode = FL_PUBLIC;
|
|
99
|
-
|
|
100
94
|
var res = body(klass);
|
|
101
95
|
|
|
102
96
|
return res;
|
|
@@ -117,79 +111,38 @@ Rt.um = function(kls) {
|
|
|
117
111
|
for (var i = 0, ii = args.length; i < ii; i++) {
|
|
118
112
|
(function(mid) {
|
|
119
113
|
var func = function() {
|
|
120
|
-
|
|
114
|
+
rb_raise(rb_eNoMethodError, "undefined method `" + mid + "' for " + this.m$inspect());
|
|
121
115
|
};
|
|
122
116
|
|
|
123
|
-
kls.
|
|
117
|
+
kls.o$a.prototype['m$' + mid] = func;
|
|
124
118
|
|
|
125
|
-
if (kls.$bridge_prototype) {
|
|
126
|
-
kls.$bridge_prototype['m$' + mid] = func;
|
|
127
|
-
}
|
|
128
119
|
})(args[i].m$to_s());
|
|
129
120
|
}
|
|
130
121
|
|
|
131
122
|
return Qnil;
|
|
132
123
|
};
|
|
133
124
|
|
|
134
|
-
/**
|
|
135
|
-
Method missing support - used in debug mode (opt in).
|
|
136
|
-
*/
|
|
137
|
-
Rt.mm = function(method_ids) {
|
|
138
|
-
var prototype = cBasicObject.$m_tbl;
|
|
139
|
-
|
|
140
|
-
for (var i = 0, ii = method_ids.length; i < ii; i++) {
|
|
141
|
-
var mid = method_ids[i];
|
|
142
|
-
|
|
143
|
-
if (!prototype[mid]) {
|
|
144
|
-
var imp = (function(mid, method_id) {
|
|
145
|
-
return function(self) {
|
|
146
|
-
var args = [].slice.call(arguments, 0);
|
|
147
|
-
args.unshift(intern(method_id));
|
|
148
|
-
args.unshift(self);
|
|
149
|
-
return self.$m.method_missing.apply(null, args);
|
|
150
|
-
};
|
|
151
|
-
})(mid, method_ids[i]);
|
|
152
|
-
|
|
153
|
-
imp.$rbMM = true;
|
|
154
|
-
|
|
155
|
-
prototype[mid] = prototype['$' + mid] = imp;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
|
|
160
125
|
/**
|
|
161
126
|
Define methods. Public method for defining a method on the given base.
|
|
162
127
|
|
|
163
128
|
@param {Object} klass The base to define method on
|
|
164
129
|
@param {String} name Ruby mid
|
|
165
|
-
@param {Function}
|
|
130
|
+
@param {Function} body The method implementation
|
|
166
131
|
@param {Number} arity Method arity
|
|
167
132
|
@return {Qnil}
|
|
168
133
|
*/
|
|
169
|
-
Rt.dm = function(klass, name,
|
|
170
|
-
if (klass.$
|
|
171
|
-
klass = klass.$
|
|
134
|
+
Rt.dm = function(klass, name, body, arity) {
|
|
135
|
+
if (klass.$f & T_OBJECT) {
|
|
136
|
+
klass = klass.$k;
|
|
172
137
|
}
|
|
173
138
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (mode == FL_PRIVATE) {
|
|
178
|
-
public_body = function() {
|
|
179
|
-
raise(eNoMethodError, "private method `" + name +
|
|
180
|
-
"' called for " + this.$m$inspect());
|
|
181
|
-
};
|
|
182
|
-
public_body.$arity = -1;
|
|
139
|
+
if (!body.$rbName) {
|
|
140
|
+
body.$rbName = name;
|
|
141
|
+
body.$arity = arity;
|
|
183
142
|
}
|
|
184
143
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
private_body.$rbArity = arity;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// FIXME: add to private/public methods
|
|
191
|
-
// klass.$methods.push(intern(name));
|
|
192
|
-
define_raw_method(klass, name, private_body, public_body);
|
|
144
|
+
rb_define_raw_method(klass, 'm$' + name, body);
|
|
145
|
+
klass.$methods.push(name);
|
|
193
146
|
|
|
194
147
|
return Qnil;
|
|
195
148
|
};
|
|
@@ -204,7 +157,7 @@ Rt.dm = function(klass, name, public_body, arity) {
|
|
|
204
157
|
@return {Qnil}
|
|
205
158
|
*/
|
|
206
159
|
Rt.ds = function(base, method_id, body, arity) {
|
|
207
|
-
return Rt.dm(
|
|
160
|
+
return Rt.dm(rb_singleton_class(base), method_id, body);
|
|
208
161
|
};
|
|
209
162
|
|
|
210
163
|
/**
|
|
@@ -215,44 +168,45 @@ Rt.ds = function(base, method_id, body, arity) {
|
|
|
215
168
|
This is actually done in super_find.
|
|
216
169
|
*/
|
|
217
170
|
Rt.S = function(callee, self, args) {
|
|
218
|
-
var mid = callee.$rbName;
|
|
219
|
-
var func =
|
|
171
|
+
var mid = 'm$' + callee.$rbName;
|
|
172
|
+
var func = rb_super_find(self.$k, callee, mid);
|
|
220
173
|
|
|
221
174
|
if (!func) {
|
|
222
|
-
|
|
175
|
+
rb_raise(rb_eNoMethodError, "super: no super class method `" + mid + "`" +
|
|
223
176
|
" for " + self.m$inspect());
|
|
224
177
|
}
|
|
225
178
|
|
|
226
|
-
var args_to_send = [self].concat(args);
|
|
179
|
+
// var args_to_send = [self].concat(args);
|
|
180
|
+
var args_to_send = [].concat(args);
|
|
227
181
|
return func.apply(self, args_to_send);
|
|
228
182
|
};
|
|
229
183
|
|
|
230
184
|
/**
|
|
231
185
|
Actually find super impl to call. Returns null if cannot find it.
|
|
232
186
|
*/
|
|
233
|
-
function
|
|
187
|
+
function rb_super_find(klass, callee, mid) {
|
|
234
188
|
var cur_method;
|
|
235
189
|
|
|
236
190
|
while (klass) {
|
|
237
|
-
if (klass.$
|
|
238
|
-
if (klass.$
|
|
239
|
-
cur_method = klass.$
|
|
191
|
+
if (klass.$m[mid]) {
|
|
192
|
+
if (klass.$m[mid] == callee) {
|
|
193
|
+
cur_method = klass.$m[mid];
|
|
240
194
|
break;
|
|
241
195
|
}
|
|
242
196
|
}
|
|
243
|
-
klass = klass.$
|
|
197
|
+
klass = klass.$s;
|
|
244
198
|
}
|
|
245
199
|
|
|
246
200
|
if (!(klass && cur_method)) { return null; }
|
|
247
201
|
|
|
248
|
-
klass = klass.$
|
|
202
|
+
klass = klass.$s;
|
|
249
203
|
|
|
250
204
|
while (klass) {
|
|
251
|
-
if (klass.$
|
|
252
|
-
return klass.$
|
|
205
|
+
if (klass.$m[mid]) {
|
|
206
|
+
return klass.$m[mid];
|
|
253
207
|
}
|
|
254
208
|
|
|
255
|
-
klass = klass.$
|
|
209
|
+
klass = klass.$s;
|
|
256
210
|
}
|
|
257
211
|
|
|
258
212
|
return null;
|
|
@@ -262,19 +216,19 @@ function super_find(klass, callee, mid) {
|
|
|
262
216
|
Exception classes. Some of these are used by runtime so they are here for
|
|
263
217
|
convenience.
|
|
264
218
|
*/
|
|
265
|
-
var
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
219
|
+
var rb_eException, rb_eStandardError, rb_eLocalJumpError, rb_eNameError,
|
|
220
|
+
rb_eNoMethodError, rb_eArgError, rb_eScriptError, rb_eLoadError,
|
|
221
|
+
rb_eRuntimeError, rb_eTypeError, rb_eIndexError, rb_eKeyError,
|
|
222
|
+
rb_eRangeError;
|
|
269
223
|
|
|
270
|
-
var
|
|
224
|
+
var rb_eExceptionInstance;
|
|
271
225
|
|
|
272
226
|
/**
|
|
273
227
|
Standard jump exceptions to save re-creating them everytime they are needed
|
|
274
228
|
*/
|
|
275
|
-
var
|
|
276
|
-
|
|
277
|
-
|
|
229
|
+
var rb_eReturnInstance,
|
|
230
|
+
rb_eBreakInstance,
|
|
231
|
+
rb_eNextInstance;
|
|
278
232
|
|
|
279
233
|
/**
|
|
280
234
|
Ruby break statement with the given value. When no break value is needed, nil
|
|
@@ -284,8 +238,8 @@ var eReturnInstance,
|
|
|
284
238
|
@param {RubyObject} value The break value.
|
|
285
239
|
*/
|
|
286
240
|
Rt.B = function(value) {
|
|
287
|
-
|
|
288
|
-
|
|
241
|
+
rb_eBreakInstance.$value = value;
|
|
242
|
+
rb_raise_exc(rb_eBreakInstance);
|
|
289
243
|
};
|
|
290
244
|
|
|
291
245
|
/**
|
|
@@ -293,53 +247,70 @@ Rt.B = function(value) {
|
|
|
293
247
|
represents the method that this statement must return from.
|
|
294
248
|
*/
|
|
295
249
|
Rt.R = function(value, func) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
throw
|
|
250
|
+
rb_eReturnInstance.$value = value;
|
|
251
|
+
rb_eReturnInstance.$func = func;
|
|
252
|
+
throw rb_eReturnInstance;
|
|
299
253
|
};
|
|
300
254
|
|
|
301
255
|
/**
|
|
302
256
|
Get the given constant name from the given base
|
|
303
257
|
*/
|
|
304
258
|
Rt.cg = function(base, id) {
|
|
305
|
-
if (base.$
|
|
306
|
-
base =
|
|
259
|
+
if (base.$f & T_OBJECT) {
|
|
260
|
+
base = rb_class_real(base.$k);
|
|
307
261
|
}
|
|
308
|
-
return
|
|
262
|
+
return rb_const_get(base, id);
|
|
309
263
|
};
|
|
310
264
|
|
|
311
265
|
/**
|
|
312
266
|
Set constant from runtime
|
|
313
267
|
*/
|
|
314
268
|
Rt.cs = function(base, id, val) {
|
|
315
|
-
if (base.$
|
|
316
|
-
base =
|
|
269
|
+
if (base.$f & T_OBJECT) {
|
|
270
|
+
base = rb_class_real(base.$k);
|
|
317
271
|
}
|
|
318
|
-
return
|
|
272
|
+
return rb_const_set(base, id, val);
|
|
319
273
|
};
|
|
320
274
|
|
|
321
275
|
/**
|
|
322
276
|
Get global by id
|
|
323
277
|
*/
|
|
324
278
|
Rt.gg = function(id) {
|
|
325
|
-
return
|
|
279
|
+
return rb_gvar_get(id);
|
|
326
280
|
};
|
|
327
281
|
|
|
328
282
|
/**
|
|
329
283
|
Set global by id
|
|
330
284
|
*/
|
|
331
285
|
Rt.gs = function(id, value) {
|
|
332
|
-
return
|
|
286
|
+
return rb_gvar_set(id, value);
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
Class variables table
|
|
291
|
+
*/
|
|
292
|
+
var rb_class_variables = {};
|
|
293
|
+
|
|
294
|
+
Rt.cvg = function(id) {
|
|
295
|
+
var v = rb_class_variables[id];
|
|
296
|
+
|
|
297
|
+
if (v) return v;
|
|
298
|
+
|
|
299
|
+
return Qnil;
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
Rt.cvs = function(id, val) {
|
|
303
|
+
return rb_class_variables[id] = val;
|
|
333
304
|
};
|
|
334
305
|
|
|
335
|
-
function
|
|
306
|
+
function rb_regexp_match_getter(id) {
|
|
336
307
|
var matched = Rt.X;
|
|
337
308
|
|
|
338
309
|
if (matched) {
|
|
339
310
|
if (matched.$md) {
|
|
340
311
|
return matched.$md;
|
|
341
312
|
} else {
|
|
342
|
-
var res = new cMatch.
|
|
313
|
+
var res = new cMatch.o$a();
|
|
343
314
|
res.$data = matched;
|
|
344
315
|
matched.$md = res;
|
|
345
316
|
return res;
|
|
@@ -349,3 +320,26 @@ function regexp_match_getter(id) {
|
|
|
349
320
|
}
|
|
350
321
|
}
|
|
351
322
|
|
|
323
|
+
/**
|
|
324
|
+
An array of procs to call for at_exit()
|
|
325
|
+
|
|
326
|
+
@param {Function} proc implementation
|
|
327
|
+
*/
|
|
328
|
+
var rb_end_procs = [];
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
Called upon exit: we need to run all of our registered procs
|
|
332
|
+
in reverse order: i.e. call last ones first.
|
|
333
|
+
|
|
334
|
+
FIXME: do we need to try/catch this??
|
|
335
|
+
*/
|
|
336
|
+
Rt.do_at_exit = function() {
|
|
337
|
+
var proc;
|
|
338
|
+
|
|
339
|
+
while (proc = rb_end_procs.pop()) {
|
|
340
|
+
proc.call(proc.$self);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return null;
|
|
344
|
+
};
|
|
345
|
+
|