opal 0.3.18 → 0.3.19
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -1
- data/Gemfile +1 -3
- data/README.md +472 -10
- data/Rakefile +10 -52
- data/core/array.rb +9 -14
- data/core/basic_object.rb +7 -10
- data/core/boolean.rb +5 -1
- data/core/class.rb +15 -38
- data/core/dir.rb +89 -0
- data/core/enumerable.rb +133 -57
- data/core/error.rb +15 -1
- data/core/file.rb +85 -0
- data/core/hash.rb +186 -32
- data/core/kernel.rb +30 -31
- data/core/load_order +4 -2
- data/core/module.rb +42 -62
- data/core/numeric.rb +7 -1
- data/core/object.rb +1 -1
- data/core/proc.rb +6 -2
- data/core/range.rb +16 -28
- data/core/regexp.rb +3 -3
- data/core/runtime.js +281 -350
- data/core/string.rb +100 -110
- data/docs/CNAME +1 -0
- data/docs/Rakefile +55 -0
- data/docs/css/styles.css +50 -0
- data/docs/css/syntax.css +63 -0
- data/docs/layout/post.html +3 -0
- data/docs/layout/pre.html +11 -0
- data/examples/dependencies/app.rb +3 -0
- data/lib/opal.rb +2 -1
- data/lib/opal/builder.rb +36 -10
- data/lib/opal/builder_task.rb +51 -24
- data/lib/opal/grammar.rb +2509 -2439
- data/lib/opal/grammar.y +38 -5
- data/lib/opal/lexer.rb +18 -2
- data/lib/opal/parser.rb +375 -349
- data/lib/opal/scope.rb +24 -2
- data/lib/opal/version.rb +1 -1
- data/spec/builder/build_order_spec.rb +20 -0
- data/spec/builder/lib_name_for_spec.rb +24 -0
- data/spec/grammar/call_spec.rb +9 -6
- data/spec/grammar/lambda_spec.rb +64 -0
- data/spec/grammar/sclass_spec.rb +5 -3
- data/{core/spec → test}/core/array/allocate_spec.rb +0 -0
- data/{core/spec → test}/core/array/append_spec.rb +0 -0
- data/{core/spec → test}/core/array/assoc_spec.rb +0 -0
- data/{core/spec → test}/core/array/at_spec.rb +0 -0
- data/{core/spec → test}/core/array/clear_spec.rb +0 -0
- data/{core/spec → test}/core/array/clone_spec.rb +0 -0
- data/{core/spec → test}/core/array/collect_spec.rb +0 -0
- data/{core/spec → test}/core/array/compact_spec.rb +0 -0
- data/{core/spec → test}/core/array/concat_spec.rb +0 -0
- data/{core/spec → test}/core/array/constructor_spec.rb +0 -0
- data/{core/spec → test}/core/array/count_spec.rb +0 -0
- data/{core/spec → test}/core/array/delete_at_spec.rb +0 -0
- data/{core/spec → test}/core/array/delete_if_spec.rb +0 -0
- data/{core/spec → test}/core/array/delete_spec.rb +0 -0
- data/{core/spec → test}/core/array/each_index_spec.rb +0 -0
- data/{core/spec → test}/core/array/each_spec.rb +0 -0
- data/{core/spec → test}/core/array/element_reference_spec.rb +0 -0
- data/{core/spec → test}/core/array/empty_spec.rb +0 -0
- data/{core/spec → test}/core/array/eql_spec.rb +0 -0
- data/{core/spec → test}/core/array/fetch_spec.rb +0 -0
- data/{core/spec → test}/core/array/first_spec.rb +0 -0
- data/{core/spec → test}/core/array/flatten_spec.rb +0 -0
- data/{core/spec → test}/core/array/include_spec.rb +0 -0
- data/{core/spec → test}/core/array/insert_spec.rb +0 -0
- data/{core/spec → test}/core/array/last_spec.rb +0 -0
- data/{core/spec → test}/core/array/length_spec.rb +0 -0
- data/{core/spec → test}/core/array/map_spec.rb +0 -0
- data/{core/spec → test}/core/array/plus_spec.rb +0 -0
- data/{core/spec → test}/core/array/pop_spec.rb +0 -0
- data/{core/spec → test}/core/array/push_spec.rb +0 -0
- data/{core/spec → test}/core/array/rassoc_spec.rb +0 -0
- data/{core/spec → test}/core/array/reject_spec.rb +0 -0
- data/{core/spec → test}/core/array/replace_spec.rb +0 -0
- data/{core/spec → test}/core/array/reverse_each_spec.rb +0 -0
- data/{core/spec → test}/core/array/reverse_spec.rb +0 -0
- data/{core/spec → test}/core/array/size_spec.rb +0 -0
- data/{core/spec → test}/core/array/to_ary_spec.rb +0 -0
- data/{core/spec → test}/core/array/uniq_spec.rb +0 -0
- data/{core/spec → test}/core/array/zip_spec.rb +0 -0
- data/test/core/class/fixtures/classes.rb +9 -0
- data/test/core/class/new_spec.rb +108 -0
- data/{core/spec → test}/core/enumerable/all_spec.rb +0 -0
- data/{core/spec → test}/core/enumerable/any_spec.rb +0 -0
- data/{core/spec → test}/core/enumerable/collect_spec.rb +0 -0
- data/{core/spec → test}/core/enumerable/count_spec.rb +0 -0
- data/test/core/enumerable/detect_spec.rb +48 -0
- data/test/core/enumerable/drop_spec.rb +17 -0
- data/test/core/enumerable/drop_while_spec.rb +24 -0
- data/test/core/enumerable/each_with_index_spec.rb +11 -0
- data/test/core/enumerable/each_with_object_spec.rb +17 -0
- data/test/core/enumerable/entries_spec.rb +6 -0
- data/test/core/enumerable/find_all_spec.rb +13 -0
- data/test/core/enumerable/find_index_spec.rb +45 -0
- data/test/core/enumerable/find_spec.rb +48 -0
- data/test/core/enumerable/first_spec.rb +40 -0
- data/{core/spec → test}/core/enumerable/fixtures/classes.rb +19 -0
- data/test/core/enumerable/grep_spec.rb +21 -0
- data/test/core/enumerable/take_spec.rb +40 -0
- data/test/core/enumerable/to_a_spec.rb +6 -0
- data/{core/spec → test}/core/false/and_spec.rb +0 -0
- data/{core/spec → test}/core/false/inspect_spec.rb +0 -0
- data/{core/spec → test}/core/false/or_spec.rb +0 -0
- data/{core/spec → test}/core/false/to_s_spec.rb +0 -0
- data/{core/spec → test}/core/false/xor_spec.rb +0 -0
- data/test/core/file/expand_path_spec.rb +20 -0
- data/{core/spec → test}/core/hash/allocate_spec.rb +0 -0
- data/{core/spec → test}/core/hash/assoc_spec.rb +0 -0
- data/{core/spec → test}/core/hash/clear_spec.rb +0 -0
- data/{core/spec → test}/core/hash/clone_spec.rb +0 -0
- data/test/core/hash/default_spec.rb +9 -0
- data/{core/spec → test}/core/hash/delete_if_spec.rb +0 -0
- data/test/core/hash/each_key_spec.rb +15 -0
- data/test/core/hash/each_pair_spec.rb +30 -0
- data/test/core/hash/each_spec.rb +30 -0
- data/test/core/hash/each_value_spec.rb +15 -0
- data/{core/spec → test}/core/hash/element_reference_spec.rb +14 -0
- data/{core/spec → test}/core/hash/element_set_spec.rb +1 -0
- data/test/core/hash/empty_spec.rb +10 -0
- data/test/core/hash/fetch_spec.rb +24 -0
- data/test/core/hash/flatten_spec.rb +46 -0
- data/test/core/hash/has_key_spec.rb +24 -0
- data/test/core/hash/has_value_spec.rb +12 -0
- data/test/core/hash/include_spec.rb +24 -0
- data/test/core/hash/index_spec.rb +13 -0
- data/test/core/hash/indexes_spec.rb +9 -0
- data/test/core/hash/indices_spec.rb +9 -0
- data/test/core/hash/invert_spec.rb +12 -0
- data/test/core/hash/keep_if_spec.rb +18 -0
- data/test/core/hash/key_spec.rb +24 -0
- data/test/core/hash/keys_spec.rb +10 -0
- data/test/core/hash/length_spec.rb +10 -0
- data/test/core/hash/member_spec.rb +24 -0
- data/{core/spec → test}/core/hash/merge_spec.rb +0 -0
- data/{core/spec → test}/core/hash/new_spec.rb +0 -0
- data/test/core/hash/rassoc_spec.rb +34 -0
- data/test/core/hash/replace_spec.rb +7 -0
- data/test/core/hash/select_spec.rb +52 -0
- data/test/core/hash/shift_spec.rb +19 -0
- data/test/core/hash/size_spec.rb +10 -0
- data/test/core/hash/update_spec.rb +17 -0
- data/test/core/hash/value_spec.rb +12 -0
- data/test/core/hash/values_at_spec.rb +9 -0
- data/test/core/hash/values_spec.rb +7 -0
- data/test/core/kernel/eql_spec.rb +15 -0
- data/test/core/kernel/equal_value_spec.rb +12 -0
- data/test/core/kernel/loop_spec.rb +23 -0
- data/test/core/kernel/nil_spec.rb +7 -0
- data/test/core/kernel/proc_spec.rb +9 -0
- data/test/core/kernel/rand_spec.rb +14 -0
- data/test/core/kernel/respond_to_spec.rb +24 -0
- data/test/core/kernel/send_spec.rb +56 -0
- data/test/core/kernel/tap_spec.rb +10 -0
- data/test/core/kernel/to_s_spec.rb +5 -0
- data/{core/spec → test}/core/matchdata/to_a_spec.rb +0 -0
- data/{core/spec → test}/core/nil/and_spec.rb +0 -0
- data/{core/spec → test}/core/nil/inspect_spec.rb +0 -0
- data/{core/spec → test}/core/nil/nil_spec.rb +0 -0
- data/{core/spec → test}/core/nil/or_spec.rb +0 -0
- data/{core/spec → test}/core/nil/to_a_spec.rb +0 -0
- data/{core/spec → test}/core/nil/to_f_spec.rb +0 -0
- data/{core/spec → test}/core/nil/to_i_spec.rb +0 -0
- data/{core/spec → test}/core/nil/to_s_spec.rb +0 -0
- data/{core/spec → test}/core/nil/xor_spec.rb +0 -0
- data/{core/spec → test}/core/numeric/equal_value_spec.rb +0 -0
- data/test/core/range/begin_spec.rb +9 -0
- data/test/core/range/case_compare_spec.rb +16 -0
- data/test/core/range/end_spec.rb +9 -0
- data/{core/spec → test}/core/regexp/match_spec.rb +0 -0
- data/test/core/string/capitalize_spec.rb +10 -0
- data/test/core/string/casecmp_spec.rb +16 -0
- data/test/core/string/chomp_spec.rb +43 -0
- data/test/core/string/chop_spec.rb +10 -0
- data/test/core/string/chr_spec.rb +13 -0
- data/test/core/string/comparison_spec.rb +13 -0
- data/test/core/string/downcase_spec.rb +6 -0
- data/test/core/string/element_reference_spec.rb +72 -0
- data/test/core/string/empty_spec.rb +8 -0
- data/test/core/string/end_with_spec.rb +12 -0
- data/test/core/string/fixtures/classes.rb +3 -0
- data/test/core/string/gsub_spec.rb +17 -0
- data/test/core/string/include_spec.rb +12 -0
- data/test/core/string/intern_spec.rb +9 -0
- data/test/core/string/length_spec.rb +9 -0
- data/test/core/string/lstrip_spec.rb +7 -0
- data/test/core/string/match_spec.rb +27 -0
- data/test/core/string/next_spec.rb +10 -0
- data/test/core/string/ord_spec.rb +9 -0
- data/test/core/string/partition_spec.rb +10 -0
- data/test/core/string/reverse_spec.rb +7 -0
- data/test/core/string/rstrip_spec.rb +7 -0
- data/test/core/string/size_spec.rb +9 -0
- data/test/core/string/slice_spec.rb +72 -0
- data/test/core/string/split_spec.rb +5 -0
- data/test/core/string/start_with_spec.rb +12 -0
- data/test/core/string/strip_spec.rb +6 -0
- data/test/core/string/sub_spec.rb +22 -0
- data/test/core/string/succ_spec.rb +10 -0
- data/test/core/string/sum_spec.rb +5 -0
- data/test/core/string/swapcase_spec.rb +18 -0
- data/test/core/string/to_a_spec.rb +9 -0
- data/test/core/string/to_f_spec.rb +14 -0
- data/test/core/string/to_i_spec.rb +25 -0
- data/test/core/string/to_s_spec.rb +13 -0
- data/test/core/string/to_str_spec.rb +13 -0
- data/test/core/string/to_sym_spec.rb +9 -0
- data/test/core/string/upcase_spec.rb +6 -0
- data/test/core/symbol/to_proc_spec.rb +12 -0
- data/{core/spec → test}/core/true/and_spec.rb +0 -0
- data/{core/spec → test}/core/true/inspect_spec.rb +0 -0
- data/{core/spec → test}/core/true/or_spec.rb +0 -0
- data/{core/spec → test}/core/true/to_s_spec.rb +0 -0
- data/{core/spec → test}/core/true/xor_spec.rb +0 -0
- data/test/index.html +11 -0
- data/{core/spec → test}/language/alias_spec.rb +4 -0
- data/{core/spec → test}/language/and_spec.rb +0 -0
- data/{core/spec → test}/language/array_spec.rb +0 -0
- data/{core/spec → test}/language/block_spec.rb +0 -0
- data/{core/spec → test}/language/break_spec.rb +0 -0
- data/{core/spec → test}/language/case_spec.rb +0 -0
- data/{core/spec → test}/language/defined_spec.rb +0 -0
- data/{core/spec → test}/language/ensure_spec.rb +0 -0
- data/test/language/fixtures/yield.rb +23 -0
- data/{core/spec → test}/language/hash_spec.rb +0 -0
- data/{core/spec → test}/language/if_spec.rb +0 -0
- data/test/language/literal_lambda_spec.rb +47 -0
- data/{core/spec → test}/language/loop_spec.rb +0 -0
- data/{core/spec → test}/language/metaclass_spec.rb +0 -0
- data/{core/spec → test}/language/next_spec.rb +0 -0
- data/{core/spec → test}/language/or_spec.rb +0 -0
- data/{core/spec → test}/language/predefined_spec.rb +0 -0
- data/{core/spec → test}/language/regexp_spec.rb +0 -0
- data/{core/spec → test}/language/send_spec.rb +0 -0
- data/{core/spec → test}/language/singleton_class_spec.rb +0 -0
- data/{core/spec → test}/language/super_spec.rb +0 -0
- data/{core/spec → test}/language/symbol_spec.rb +0 -0
- data/{core/spec → test}/language/undef_spec.rb +0 -0
- data/{core/spec → test}/language/unless_spec.rb +0 -0
- data/{core/spec → test}/language/until_spec.rb +0 -0
- data/{core/spec → test}/language/variables_spec.rb +0 -0
- data/{core/spec → test}/language/while_spec.rb +0 -0
- data/test/language/yield_spec.rb +100 -0
- data/test/opal/array/subclassing_spec.rb +32 -0
- data/test/opal/class/bridge_class_spec.rb +37 -0
- data/test/opal/exception/subclassing_spec.rb +17 -0
- data/test/opal/runtime/_methods_spec.rb +48 -0
- data/test/opal/runtime/class_hierarchy_spec.rb +22 -0
- data/test/opal/runtime/def_spec.rb +23 -0
- data/test/opal/string/subclassing_spec.rb +26 -0
- data/test/spec_helper.rb +3 -0
- metadata +437 -111
- data/core/spec/core/class/new_spec.rb +0 -16
- data/core/spec/core/hash/default_spec.rb +0 -4
- data/core/spec/core/symbol/to_proc_spec.rb +0 -6
- data/core/spec/index.html +0 -11
- data/spec/builder/build_source_spec.rb +0 -52
data/core/regexp.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
class Regexp
|
1
|
+
class Regexp < `RegExp`
|
2
2
|
def self.escape(string)
|
3
3
|
`string.replace(/([.*+?^=!:${}()|[\]\\/\\])/g, '\\$1')`
|
4
4
|
end
|
@@ -20,7 +20,7 @@ class Regexp
|
|
20
20
|
var result = this.exec(string);
|
21
21
|
|
22
22
|
if (result) {
|
23
|
-
var match = new
|
23
|
+
var match = new #{MatchData}._alloc();
|
24
24
|
match.$data = result;
|
25
25
|
|
26
26
|
#{$~ = `match`};
|
@@ -44,7 +44,7 @@ class Regexp
|
|
44
44
|
var result = this.exec(pattern);
|
45
45
|
|
46
46
|
if (result) {
|
47
|
-
var match = new
|
47
|
+
var match = new #{MatchData}._alloc();
|
48
48
|
match.$data = result;
|
49
49
|
|
50
50
|
return #{$~ = `match`};
|
data/core/runtime.js
CHANGED
@@ -1,243 +1,134 @@
|
|
1
|
-
|
1
|
+
// Top level Object scope (used by object and top_self).
|
2
|
+
var top_const_alloc = function(){};
|
3
|
+
var top_const_scope = top_const_alloc.prototype;
|
4
|
+
top_const_scope.alloc = top_const_alloc;
|
5
|
+
|
6
|
+
var Opal = this.Opal = top_const_scope;
|
2
7
|
|
3
8
|
Opal.global = this;
|
4
9
|
|
5
10
|
// Minify common function calls
|
6
|
-
var __hasOwn = Object.prototype.hasOwnProperty
|
7
|
-
|
8
|
-
|
9
|
-
// Types - also added to bridged objects
|
10
|
-
var T_CLASS = 0x0001,
|
11
|
-
T_MODULE = 0x0002,
|
12
|
-
T_OBJECT = 0x0004,
|
13
|
-
T_BOOLEAN = 0x0008,
|
14
|
-
T_STRING = 0x0010,
|
15
|
-
T_ARRAY = 0x0020,
|
16
|
-
T_NUMBER = 0x0040,
|
17
|
-
T_PROC = 0x0080,
|
18
|
-
T_HASH = 0x0100,
|
19
|
-
T_RANGE = 0x0200,
|
20
|
-
T_ICLASS = 0x0400,
|
21
|
-
FL_SINGLETON = 0x0800;
|
11
|
+
var __hasOwn = Object.prototype.hasOwnProperty;
|
12
|
+
var __slice = Opal.slice = Array.prototype.slice;
|
22
13
|
|
23
14
|
// Generates unique id for every ruby object
|
24
15
|
var unique_id = 0;
|
25
16
|
|
26
|
-
// Jump return - return in proc body
|
27
|
-
Opal.jump = function(value, func) {
|
28
|
-
throw new Error('jump return');
|
29
|
-
};
|
30
|
-
|
31
|
-
// Get constant with given id
|
32
|
-
Opal.const_get = function(const_table, id) {
|
33
|
-
if (const_table[id]) {
|
34
|
-
return const_table[id];
|
35
|
-
}
|
36
|
-
|
37
|
-
throw RubyNameError.$new('uninitialized constant ' + id);
|
38
|
-
};
|
39
|
-
|
40
17
|
// Table holds all class variables
|
41
18
|
Opal.cvars = {};
|
42
19
|
|
43
20
|
// Globals table
|
44
21
|
Opal.gvars = {};
|
45
22
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
var body = klass._proto[old_name];
|
52
|
-
|
53
|
-
if (!body) {
|
54
|
-
// throw RubyNameError.$new(null, "undefined method `" + old_name + "' for class `" + klass._name + "'");
|
55
|
-
throw new Error("undefined method `" + old_name + "' for class `" + klass._name + "'");
|
23
|
+
Opal.klass = function(base, superklass, id, body) {
|
24
|
+
var klass;
|
25
|
+
if (base._isObject) {
|
26
|
+
base = base._real;
|
56
27
|
}
|
57
28
|
|
58
|
-
|
59
|
-
|
60
|
-
};
|
61
|
-
|
62
|
-
// Actually define methods
|
63
|
-
var define_method = Opal.defn = function(klass, id, body) {
|
64
|
-
// If an object, make sure to use its class
|
65
|
-
if (klass._flags & T_OBJECT) {
|
66
|
-
klass = klass._klass;
|
29
|
+
if (superklass === null) {
|
30
|
+
superklass = RubyObject;
|
67
31
|
}
|
68
32
|
|
69
|
-
|
70
|
-
|
71
|
-
var included_in = klass.$included_in, includee;
|
72
|
-
|
73
|
-
if (included_in) {
|
74
|
-
for (var i = 0, ii = included_in.length; i < ii; i++) {
|
75
|
-
includee = included_in[i];
|
76
|
-
|
77
|
-
define_method(includee, id, body);
|
78
|
-
}
|
33
|
+
if (__hasOwn.call(base._scope, id)) {
|
34
|
+
klass = base._scope[id];
|
79
35
|
}
|
80
|
-
|
81
|
-
|
82
|
-
klass._bridge[id] = body;
|
36
|
+
else if (!superklass._klass || !superklass._proto) {
|
37
|
+
klass = bridge_class(superklass, id);
|
83
38
|
}
|
84
|
-
|
85
|
-
|
86
|
-
return null;
|
87
|
-
}
|
88
|
-
|
89
|
-
function define_module(base, id) {
|
90
|
-
var module;
|
91
|
-
|
92
|
-
module = boot_module();
|
93
|
-
module._name = (base === RubyObject ? id : base._name + '::' + id)
|
94
|
-
|
95
|
-
make_metaclass(module, RubyModule);
|
96
|
-
|
97
|
-
module._flags = T_MODULE;
|
98
|
-
module.$included_in = [];
|
99
|
-
|
100
|
-
var const_alloc = function() {};
|
101
|
-
var const_scope = const_alloc.prototype = new base._scope.alloc();
|
102
|
-
module._scope = const_scope;
|
103
|
-
const_scope.alloc = const_alloc;
|
104
|
-
|
105
|
-
base._scope[id] = module;
|
106
|
-
|
107
|
-
return module;
|
108
|
-
}
|
109
|
-
|
110
|
-
// Opal define class. 0: regular, 1: module, 2: shift class.
|
111
|
-
Opal.klass = function(base, superklass, id, body, type) {
|
112
|
-
var klass;
|
113
|
-
|
114
|
-
switch (type) {
|
115
|
-
case 0:
|
116
|
-
if (base._flags & T_OBJECT) {
|
117
|
-
base = class_real(base._klass);
|
118
|
-
}
|
119
|
-
|
120
|
-
if (superklass === null) {
|
121
|
-
superklass = RubyObject;
|
122
|
-
}
|
123
|
-
|
124
|
-
if (__hasOwn.call(base._scope, id)) {
|
125
|
-
klass = base._scope[id];
|
126
|
-
}
|
127
|
-
else {
|
128
|
-
klass = define_class(base, id, superklass);
|
129
|
-
}
|
130
|
-
|
131
|
-
break;
|
132
|
-
|
133
|
-
case 1:
|
134
|
-
if (base._flags & T_OBJECT) {
|
135
|
-
base = class_real(base._klass);
|
136
|
-
}
|
137
|
-
|
138
|
-
if (__hasOwn.call(base._scope, id)) {
|
139
|
-
klass = base._scope[id];
|
140
|
-
}
|
141
|
-
else {
|
142
|
-
klass = define_module(base, id);
|
143
|
-
}
|
144
|
-
|
145
|
-
break;
|
146
|
-
|
147
|
-
case 2:
|
148
|
-
klass = base.$singleton_class();
|
149
|
-
break;
|
39
|
+
else {
|
40
|
+
klass = define_class(base, id, superklass);
|
150
41
|
}
|
151
42
|
|
152
43
|
return body.call(klass);
|
153
44
|
};
|
154
45
|
|
155
|
-
Opal.
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
};
|
160
|
-
|
161
|
-
// Undefine one or more methods
|
162
|
-
Opal.undef = function(klass) {
|
163
|
-
var args = __slice.call(arguments, 1);
|
164
|
-
|
165
|
-
for (var i = 0, length = args.length; i < length; i++) {
|
166
|
-
var mid = args[i], id = mid_to_jsid[mid];
|
46
|
+
Opal.sklass = function(shift, body) {
|
47
|
+
var klass = shift.$singleton_class();
|
48
|
+
return body.call(klass);
|
49
|
+
}
|
167
50
|
|
168
|
-
|
51
|
+
Opal.module = function(base, id, body) {
|
52
|
+
var klass;
|
53
|
+
if (base._isObject) {
|
54
|
+
base = base._real;
|
169
55
|
}
|
170
|
-
};
|
171
56
|
|
172
|
-
|
173
|
-
|
174
|
-
var func = find_super(self._klass, callee, jsid);
|
175
|
-
|
176
|
-
if (!func) {
|
177
|
-
throw RubyNoMethodError.$new(null, "super: no superclass method `" +
|
178
|
-
jsid_to_mid(jsid) + "'" + " for " + self.$inspect());
|
57
|
+
if (__hasOwn.call(base._scope, id)) {
|
58
|
+
klass = base._scope[id];
|
179
59
|
}
|
60
|
+
else {
|
61
|
+
klass = boot_module();
|
62
|
+
klass._name = (base === RubyObject ? id : base._name + '::' + id);
|
180
63
|
|
181
|
-
|
182
|
-
};
|
64
|
+
make_metaclass(klass, RubyModule);
|
183
65
|
|
184
|
-
|
185
|
-
|
186
|
-
var method, scope = scopes[0];
|
66
|
+
klass._isModule = true;
|
67
|
+
klass.$included_in = [];
|
187
68
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
break;
|
193
|
-
}
|
194
|
-
}
|
69
|
+
var const_alloc = function() {};
|
70
|
+
var const_scope = const_alloc.prototype = new base._scope.alloc();
|
71
|
+
klass._scope = const_scope;
|
72
|
+
const_scope.alloc = const_alloc;
|
195
73
|
|
196
|
-
|
197
|
-
// one of the nested blocks was define_method'd
|
198
|
-
return Opal.zuper(method, jsid, self, args);
|
199
|
-
}
|
200
|
-
else if (defn) {
|
201
|
-
// blocks not define_method'd, but they were enclosed by a real method
|
202
|
-
return Opal.zuper(defn, jsid, self, args);
|
74
|
+
base._scope[id] = klass;
|
203
75
|
}
|
204
76
|
|
205
|
-
|
206
|
-
// been defined as a method
|
207
|
-
throw RubyNoMethodError.$new(null, "super: cannot call super when not in method");
|
77
|
+
return body.call(klass);
|
208
78
|
}
|
209
79
|
|
210
|
-
|
211
|
-
function
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
80
|
+
/**
|
81
|
+
This function serves two purposes. The first is to allow methods
|
82
|
+
defined in modules to be included into classes that have included
|
83
|
+
them. This is done at the end of a module body by calling this
|
84
|
+
method will all the defined methods. They are then passed onto
|
85
|
+
the includee classes.
|
86
|
+
|
87
|
+
The second purpose is to store an array of all the methods defined
|
88
|
+
directly in this class or module. This makes features such as
|
89
|
+
#methods and #instance_methods work. It is also used internally to
|
90
|
+
create subclasses of Arrays, as an annoyance with javascript is that
|
91
|
+
arrays cannot be subclassed (or they can't without problems arrising
|
92
|
+
with tracking the array length). Therefore, when a new instance of a
|
93
|
+
subclass is created, behind the scenes we copy all the methods from
|
94
|
+
the subclass onto an array prototype.
|
95
|
+
|
96
|
+
If the includee is also included into other modules or classes, then
|
97
|
+
this method will also set up donations for that module. If this is
|
98
|
+
the case, then 'indirect' will be set to true as we don't want those
|
99
|
+
modules/classes to think they had that method set on themselves. This
|
100
|
+
stops `Object` thinking it defines `#sprintf` when it is actually
|
101
|
+
`Kernel` that defines that method. Indirect is false by default when
|
102
|
+
called by generated code in the compiler output.
|
103
|
+
|
104
|
+
@param [RubyClass] klass the class or module that defined methods
|
105
|
+
@param [Array<String>] methods an array of jsid method names defined
|
106
|
+
@param [Boolean] indirect whether this is an indirect method define
|
107
|
+
*/
|
108
|
+
Opal.donate = function(klass, methods, indirect) {
|
109
|
+
var included_in = klass.$included_in, includee, method,
|
110
|
+
table = klass._proto, dest;
|
111
|
+
|
112
|
+
if (!indirect) {
|
113
|
+
klass._methods = klass._methods.concat(methods);
|
222
114
|
}
|
223
115
|
|
224
|
-
if (
|
116
|
+
if (included_in) {
|
117
|
+
for (var i = 0, length = included_in.length; i < length; i++) {
|
118
|
+
includee = included_in[i];
|
119
|
+
dest = includee._proto;
|
225
120
|
|
226
|
-
|
121
|
+
for (var j = 0, jj = methods.length; j < jj; j++) {
|
122
|
+
method = methods[j];
|
123
|
+
dest[method] = table[method];
|
124
|
+
}
|
227
125
|
|
228
|
-
|
229
|
-
|
230
|
-
// make sure our found method isnt the same - this can happen if this
|
231
|
-
// newly found method is from a module and we are now looking at the
|
232
|
-
// module it came from.
|
233
|
-
if (klass._proto[mid] !== callee) {
|
234
|
-
return klass._proto[mid];
|
126
|
+
if (includee.$included_in) {
|
127
|
+
Opal.donate(includee, methods, true);
|
235
128
|
}
|
236
129
|
}
|
237
|
-
|
238
|
-
klass = klass._super;
|
239
130
|
}
|
240
|
-
}
|
131
|
+
};
|
241
132
|
|
242
133
|
var mid_to_jsid = Opal.mid_to_jsid = function(mid) {
|
243
134
|
if (method_names[mid]) {
|
@@ -245,7 +136,7 @@ var mid_to_jsid = Opal.mid_to_jsid = function(mid) {
|
|
245
136
|
}
|
246
137
|
|
247
138
|
return '$' + mid.replace('!', '$b').replace('?', '$p').replace('=', '$e');
|
248
|
-
}
|
139
|
+
};
|
249
140
|
|
250
141
|
var jsid_to_mid = Opal.jsid_to_mid = function(jsid) {
|
251
142
|
if (reverse_method_names[jsid]) {
|
@@ -255,18 +146,16 @@ var jsid_to_mid = Opal.jsid_to_mid = function(jsid) {
|
|
255
146
|
jsid = jsid.substr(1); // remove '$'
|
256
147
|
|
257
148
|
return jsid.replace('$b', '!').replace('$p', '?').replace('$e', '=');
|
258
|
-
}
|
149
|
+
};
|
259
150
|
|
260
|
-
|
261
|
-
throw
|
151
|
+
var no_block_given = function() {
|
152
|
+
throw new Error('no block given');
|
262
153
|
};
|
263
154
|
|
264
155
|
// Boot a base class (makes instances).
|
265
156
|
function boot_defclass(superklass) {
|
266
157
|
var cls = function() {
|
267
158
|
this._id = unique_id++;
|
268
|
-
|
269
|
-
return this;
|
270
159
|
};
|
271
160
|
|
272
161
|
if (superklass) {
|
@@ -277,7 +166,7 @@ function boot_defclass(superklass) {
|
|
277
166
|
}
|
278
167
|
|
279
168
|
cls.prototype.constructor = cls;
|
280
|
-
cls.prototype.
|
169
|
+
cls.prototype._isObject = true;
|
281
170
|
|
282
171
|
return cls;
|
283
172
|
}
|
@@ -286,8 +175,6 @@ function boot_defclass(superklass) {
|
|
286
175
|
function boot_makemeta(id, klass, superklass) {
|
287
176
|
var meta = function() {
|
288
177
|
this._id = unique_id++;
|
289
|
-
|
290
|
-
return this;
|
291
178
|
};
|
292
179
|
|
293
180
|
var ctor = function() {};
|
@@ -297,16 +184,22 @@ function boot_makemeta(id, klass, superklass) {
|
|
297
184
|
|
298
185
|
var proto = meta.prototype;
|
299
186
|
proto.$included_in = [];
|
300
|
-
proto._alloc
|
301
|
-
proto.
|
302
|
-
proto._name
|
303
|
-
proto._super
|
187
|
+
proto._alloc = klass;
|
188
|
+
proto._isClass = true;
|
189
|
+
proto._name = id;
|
190
|
+
proto._super = superklass;
|
304
191
|
proto.constructor = meta;
|
192
|
+
proto._methods = [];
|
193
|
+
proto._isObject = false;
|
305
194
|
|
306
195
|
var result = new meta();
|
307
196
|
klass.prototype._klass = result;
|
197
|
+
klass.prototype._real = result;
|
198
|
+
|
308
199
|
result._proto = klass.prototype;
|
309
200
|
|
201
|
+
top_const_scope[id] = result;
|
202
|
+
|
310
203
|
return result;
|
311
204
|
}
|
312
205
|
|
@@ -315,8 +208,6 @@ function boot_class(superklass) {
|
|
315
208
|
// instances
|
316
209
|
var cls = function() {
|
317
210
|
this._id = unique_id++;
|
318
|
-
|
319
|
-
return this;
|
320
211
|
};
|
321
212
|
|
322
213
|
var ctor = function() {};
|
@@ -326,13 +217,11 @@ function boot_class(superklass) {
|
|
326
217
|
|
327
218
|
var proto = cls.prototype;
|
328
219
|
proto.constructor = cls;
|
329
|
-
proto.
|
220
|
+
proto._isObject = true;
|
330
221
|
|
331
222
|
// class itself
|
332
223
|
var meta = function() {
|
333
224
|
this._id = unique_id++;
|
334
|
-
|
335
|
-
return this;
|
336
225
|
};
|
337
226
|
|
338
227
|
var mtor = function() {};
|
@@ -340,14 +229,16 @@ function boot_class(superklass) {
|
|
340
229
|
|
341
230
|
meta.prototype = new mtor();
|
342
231
|
|
343
|
-
proto
|
344
|
-
proto._alloc
|
345
|
-
proto.
|
346
|
-
proto.constructor
|
347
|
-
proto._super
|
232
|
+
proto = meta.prototype;
|
233
|
+
proto._alloc = cls;
|
234
|
+
proto._isClass = true;
|
235
|
+
proto.constructor = meta;
|
236
|
+
proto._super = superklass;
|
237
|
+
proto._methods = [];
|
348
238
|
|
349
239
|
var result = new meta();
|
350
240
|
cls.prototype._klass = result;
|
241
|
+
cls.prototype._real = result;
|
351
242
|
|
352
243
|
result._proto = cls.prototype;
|
353
244
|
|
@@ -363,7 +254,6 @@ function boot_module() {
|
|
363
254
|
// Module itself
|
364
255
|
var meta = function() {
|
365
256
|
this._id = unique_id++;
|
366
|
-
return this;
|
367
257
|
};
|
368
258
|
|
369
259
|
var mtor = function(){};
|
@@ -371,30 +261,23 @@ function boot_module() {
|
|
371
261
|
meta.prototype = new mtor();
|
372
262
|
|
373
263
|
var proto = meta.prototype;
|
374
|
-
|
375
|
-
proto.
|
264
|
+
|
265
|
+
proto._alloc = module_cons;
|
266
|
+
proto._isModule = true;
|
376
267
|
proto.constructor = meta;
|
377
|
-
proto._super
|
268
|
+
proto._super = null;
|
269
|
+
proto._methods = [];
|
378
270
|
|
379
|
-
var module
|
380
|
-
module._proto
|
271
|
+
var module = new meta();
|
272
|
+
module._proto = module_inst;
|
381
273
|
|
382
274
|
return module;
|
383
275
|
}
|
384
276
|
|
385
|
-
// Get actual class ignoring singleton classes and iclasses.
|
386
|
-
function class_real(klass) {
|
387
|
-
while (klass._flags & FL_SINGLETON) {
|
388
|
-
klass = klass._super;
|
389
|
-
}
|
390
|
-
|
391
|
-
return klass;
|
392
|
-
}
|
393
|
-
|
394
277
|
// Make metaclass for the given class
|
395
278
|
function make_metaclass(klass, superklass) {
|
396
|
-
if (klass.
|
397
|
-
if (
|
279
|
+
if (klass._isClass) {
|
280
|
+
if (klass._isSingleton) {
|
398
281
|
throw RubyException.$new('too much meta: return klass?');
|
399
282
|
}
|
400
283
|
else {
|
@@ -404,8 +287,9 @@ function make_metaclass(klass, superklass) {
|
|
404
287
|
meta._name = class_id;
|
405
288
|
meta._alloc.prototype = klass.constructor.prototype;
|
406
289
|
meta._proto = meta._alloc.prototype;
|
407
|
-
meta.
|
290
|
+
meta._isSingleton = true;
|
408
291
|
meta._klass = RubyClass;
|
292
|
+
meta._real = RubyClass;
|
409
293
|
|
410
294
|
klass._klass = meta;
|
411
295
|
|
@@ -416,30 +300,25 @@ function make_metaclass(klass, superklass) {
|
|
416
300
|
}
|
417
301
|
}
|
418
302
|
else {
|
419
|
-
|
420
|
-
|
421
|
-
}
|
422
|
-
|
423
|
-
function make_singleton_class(obj) {
|
424
|
-
var orig_class = obj._klass,
|
425
|
-
class_id = "#<Class:#<" + orig_class._name + ":" + orig_class._id + ">>";
|
426
|
-
|
427
|
-
klass = boot_class(orig_class);
|
428
|
-
klass._name = class_id;
|
429
|
-
|
430
|
-
klass._flags |= FL_SINGLETON;
|
431
|
-
klass._bridge = obj;
|
432
|
-
|
433
|
-
obj._klass = klass;
|
303
|
+
var orig_class = klass._klass,
|
304
|
+
class_id = "#<Class:#<" + orig_class._name + ":" + orig_class._id + ">>";
|
434
305
|
|
435
|
-
|
306
|
+
var meta = boot_class(orig_class);
|
307
|
+
meta._name = class_id;
|
436
308
|
|
437
|
-
|
309
|
+
meta._isSingleton = true;
|
310
|
+
meta._proto = klass;
|
311
|
+
// FIXME: this should be removed. _proto should always point to this.
|
312
|
+
meta._alloc.prototype = klass;
|
313
|
+
klass._klass = meta;
|
314
|
+
meta.__attached__ = klass;
|
315
|
+
meta._klass = orig_class._real._klass
|
438
316
|
|
439
|
-
|
317
|
+
return meta;
|
318
|
+
}
|
440
319
|
}
|
441
320
|
|
442
|
-
function bridge_class(constructor,
|
321
|
+
function bridge_class(constructor, id) {
|
443
322
|
var klass = define_class(RubyObject, id, RubyObject),
|
444
323
|
prototype = constructor.prototype;
|
445
324
|
|
@@ -448,20 +327,69 @@ function bridge_class(constructor, flags, id) {
|
|
448
327
|
|
449
328
|
bridged_classes.push(klass);
|
450
329
|
|
451
|
-
prototype._klass
|
452
|
-
prototype.
|
330
|
+
prototype._klass = klass;
|
331
|
+
prototype._real = klass;
|
332
|
+
prototype._isObject = true;
|
333
|
+
|
334
|
+
var allocator = function(initializer) {
|
335
|
+
var result, kls = this, methods = kls._methods, proto = kls._proto;
|
336
|
+
|
337
|
+
if (initializer == null) {
|
338
|
+
result = new constructor
|
339
|
+
}
|
340
|
+
else {
|
341
|
+
result = new constructor(initializer);
|
342
|
+
}
|
343
|
+
|
344
|
+
if (kls === klass) {
|
345
|
+
return result;
|
346
|
+
}
|
347
|
+
|
348
|
+
result._klass = kls;
|
349
|
+
result._real = kls;
|
350
|
+
|
351
|
+
for (var i = 0, length = methods.length; i < length; i++) {
|
352
|
+
var method = methods[i];
|
353
|
+
result[method] = proto[method];
|
354
|
+
}
|
355
|
+
|
356
|
+
return result;
|
357
|
+
};
|
358
|
+
|
359
|
+
klass.constructor.prototype.$allocate = allocator;
|
360
|
+
|
361
|
+
var donator = RubyObject, table, methods;
|
362
|
+
|
363
|
+
while (donator) {
|
364
|
+
table = donator._proto;
|
365
|
+
methods = donator._methods;
|
366
|
+
|
367
|
+
for (var i = 0, length = methods.length; i < length; i++) {
|
368
|
+
var method = methods[i];
|
369
|
+
prototype[method] = table[method];
|
370
|
+
}
|
371
|
+
|
372
|
+
donator = donator._super;
|
373
|
+
}
|
453
374
|
|
454
375
|
return klass;
|
455
376
|
}
|
456
377
|
|
457
|
-
|
378
|
+
/**
|
379
|
+
Actually define a new class with the name `id`. The superklass is
|
380
|
+
required, and Object is currently the root class. The base is the
|
381
|
+
parent scope of this class. For example, defining a root `Foo`
|
382
|
+
class would have `Object` as the parent. Defining `Foo::Bar` would
|
383
|
+
use `Foo` as the parent.
|
384
|
+
|
385
|
+
@param [RubyClass] base the base class/module for this new class
|
386
|
+
@param [String] id the name for this class
|
387
|
+
@param [RubyClass] superklass the super class
|
388
|
+
@return [RubyClass] returns new class with given attributes
|
389
|
+
*/
|
458
390
|
function define_class(base, id, superklass) {
|
459
|
-
var klass;
|
460
|
-
|
461
|
-
var class_id = (base === RubyObject ? id : base._name + '::' + id);
|
462
|
-
|
463
|
-
klass = boot_class(superklass);
|
464
|
-
klass._name = class_id;
|
391
|
+
var klass = boot_class(superklass);
|
392
|
+
klass._name = (base === RubyObject ? id : base._name + '::' + id);
|
465
393
|
|
466
394
|
make_metaclass(klass, superklass._klass);
|
467
395
|
|
@@ -479,66 +407,118 @@ function define_class(base, id, superklass) {
|
|
479
407
|
return klass;
|
480
408
|
}
|
481
409
|
|
410
|
+
/**
|
411
|
+
An IClass is a fake class created when a module is included into a
|
412
|
+
class or another module. It is a "copy" of the module that is then
|
413
|
+
injected into the hierarchy so it appears internally that the iclass
|
414
|
+
is the super of the class instead of the old super class. This is
|
415
|
+
actually hidden from the ruby side of things, but allows internal
|
416
|
+
features such as super() etc to work. All useful properties from the
|
417
|
+
module are copied onto this iclass.
|
418
|
+
|
419
|
+
@param [RubyClass] klass the klass which is including the module
|
420
|
+
@param [RubyModule] module the module which is being included
|
421
|
+
@return [RubyIClass] returns newly created iclass
|
422
|
+
*/
|
482
423
|
function define_iclass(klass, module) {
|
483
|
-
var
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
424
|
+
var iclass = {
|
425
|
+
_proto: module._proto,
|
426
|
+
_super: klass._super,
|
427
|
+
_isIClass: true,
|
428
|
+
_klass: module,
|
429
|
+
_name: module._name,
|
430
|
+
_methods: module._methods
|
431
|
+
};
|
491
432
|
|
492
433
|
klass._super = iclass;
|
493
434
|
|
494
435
|
return iclass;
|
495
436
|
}
|
496
437
|
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
438
|
+
/**
|
439
|
+
This is a map of all file ids to their bodies. The file id is the
|
440
|
+
id used to require a file, and it does not have an extension name.
|
441
|
+
|
442
|
+
@type { String: Function }
|
443
|
+
*/
|
444
|
+
var factories = Opal.factories = {};
|
445
|
+
|
446
|
+
/**
|
447
|
+
This holds the name of the current file being executed by opal. This
|
448
|
+
gets set in require() below and it allows the file to get the
|
449
|
+
__FILE__ variable. This should never be accessed manually.
|
450
|
+
|
451
|
+
@type {String}
|
452
|
+
*/
|
453
|
+
Opal.file = "";
|
454
|
+
|
455
|
+
/**
|
456
|
+
Register the body for the given file id name. This will then allow
|
457
|
+
the file to be loaded with require().
|
458
|
+
|
459
|
+
@param [String] id the file id
|
460
|
+
@param [Function] body the body representing the file
|
461
|
+
*/
|
462
|
+
Opal.define = function(id, body) {
|
463
|
+
factories[id] = body;
|
464
|
+
};
|
465
|
+
|
466
|
+
/**
|
467
|
+
Require a specific file by id.
|
468
|
+
|
469
|
+
@param [String] id file id to require
|
470
|
+
@return [Boolean] if file has already been required
|
471
|
+
*/
|
472
|
+
Opal.require = function(id) {
|
473
|
+
var body = factories[id];
|
474
|
+
|
475
|
+
if (!body) {
|
476
|
+
throw new Error("No file: '" + id + "'");
|
477
|
+
}
|
478
|
+
|
479
|
+
if (body._loaded) {
|
480
|
+
return false;
|
481
|
+
}
|
482
|
+
|
483
|
+
Opal.file = id;
|
484
|
+
|
485
|
+
body._loaded = true;
|
486
|
+
body.call(Opal.top);
|
487
|
+
|
488
|
+
return true;
|
489
|
+
};
|
501
490
|
|
502
491
|
// Initialization
|
503
492
|
// --------------
|
504
493
|
|
505
494
|
// The *instances* of core objects
|
506
|
-
var
|
507
|
-
var
|
508
|
-
var
|
495
|
+
var BootBasicObject = boot_defclass();
|
496
|
+
var BootObject = boot_defclass(BootBasicObject);
|
497
|
+
var BootModule = boot_defclass(BootObject);
|
498
|
+
var BootClass = boot_defclass(BootModule);
|
509
499
|
|
510
500
|
// The *classes' of core objects
|
511
|
-
var
|
512
|
-
var
|
513
|
-
var
|
501
|
+
var RubyBasicObject = boot_makemeta('BasicObject', BootBasicObject, BootClass);
|
502
|
+
var RubyObject = boot_makemeta('Object', BootObject, RubyBasicObject.constructor);
|
503
|
+
var RubyModule = boot_makemeta('Module', BootModule, RubyObject.constructor);
|
504
|
+
var RubyClass = boot_makemeta('Class', BootClass, RubyModule.constructor);
|
514
505
|
|
515
506
|
// Fix boot classes to use meta class
|
507
|
+
RubyBasicObject._klass = RubyClass;
|
516
508
|
RubyObject._klass = RubyClass;
|
517
509
|
RubyModule._klass = RubyClass;
|
518
510
|
RubyClass._klass = RubyClass;
|
519
511
|
|
520
512
|
// fix superclasses
|
521
|
-
|
513
|
+
RubyBasicObject._super = null;
|
514
|
+
RubyObject._super = RubyBasicObject;
|
522
515
|
RubyModule._super = RubyObject;
|
523
516
|
RubyClass._super = RubyModule;
|
524
517
|
|
525
|
-
Opal.Object = RubyObject;
|
526
|
-
Opal.Module = RubyModule;
|
527
|
-
Opal.Class = RubyClass;
|
528
|
-
|
529
|
-
// Make object act like a module. Internally, `Object` gets included
|
530
|
-
// into all the bridged classes. This is because the native prototypes
|
531
|
-
// for these bridged classes need to get all the `Object` methods as
|
532
|
-
// well. This allows `Object` to just donate its instance methods to
|
533
|
-
// the bridged classes using the exact same method that modules use.
|
534
518
|
var bridged_classes = RubyObject.$included_in = [];
|
519
|
+
RubyBasicObject.$included_in = bridged_classes;
|
535
520
|
|
536
|
-
|
537
|
-
var top_const_alloc = function(){};
|
538
|
-
var top_const_scope = top_const_alloc.prototype;
|
539
|
-
top_const_scope.alloc = top_const_alloc;
|
540
|
-
|
541
|
-
RubyObject._scope = Opal.constants = top_const_scope;
|
521
|
+
RubyObject._scope = RubyBasicObject._scope = top_const_scope;
|
542
522
|
|
543
523
|
var module_const_alloc = function(){};
|
544
524
|
var module_const_scope = new top_const_alloc();
|
@@ -550,64 +530,15 @@ var class_const_scope = new top_const_alloc();
|
|
550
530
|
class_const_scope.alloc = class_const_alloc;
|
551
531
|
RubyClass._scope = class_const_scope;
|
552
532
|
|
553
|
-
RubyObject._scope.BasicObject = RubyObject;
|
554
|
-
RubyObject._scope.Object = RubyObject;
|
555
|
-
RubyObject._scope.Module = RubyModule;
|
556
|
-
RubyObject._scope.Class = RubyClass;
|
557
|
-
|
558
|
-
// Every ruby object (except natives) will have their #to_s method aliased
|
559
|
-
// to the native .toString() function so that accessing ruby objects from
|
560
|
-
// javascript will return a nicer string format. This is also used when
|
561
|
-
// interpolating objects into strings as the js engine will call toString
|
562
|
-
// which in turn calls #to_s.
|
563
|
-
//
|
564
|
-
// This is also used as the hashing function. In ruby, #hash should return
|
565
|
-
// an integer. This is not possible in Opal as strings cannot be mutable
|
566
|
-
// and can not therefore have unique integer hashes. Seeing as strings or
|
567
|
-
// symbols are used more often as hash keys, this role is changed in Opal
|
568
|
-
// so that hash values should be strings, and this function makes the #to_s
|
569
|
-
// value for an object the default.
|
570
533
|
RubyObject._proto.toString = function() {
|
571
534
|
return this.$to_s();
|
572
535
|
};
|
573
536
|
|
574
|
-
|
537
|
+
Opal.top = new RubyObject._alloc();
|
575
538
|
|
576
539
|
var RubyNilClass = define_class(RubyObject, 'NilClass', RubyObject);
|
577
540
|
Opal.nil = new RubyNilClass._alloc();
|
578
|
-
|
579
|
-
bridge_class(Array, T_OBJECT | T_ARRAY, 'Array');
|
580
|
-
bridge_class(Number, T_OBJECT | T_NUMBER, 'Numeric');
|
581
|
-
|
582
|
-
bridge_class(String, T_OBJECT | T_STRING, 'String');
|
583
|
-
bridge_class(Boolean, T_OBJECT | T_BOOLEAN, 'Boolean');
|
584
|
-
bridge_class(Function, T_OBJECT | T_PROC, 'Proc');
|
585
|
-
bridge_class(RegExp, T_OBJECT, 'Regexp');
|
586
|
-
|
587
|
-
var RubyMatch = define_class(RubyObject, 'MatchData', RubyObject);
|
588
|
-
var RubyRange = define_class(RubyObject, 'Range', RubyObject);
|
589
|
-
RubyRange._proto._flags = T_OBJECT | T_RANGE;
|
590
|
-
|
591
|
-
var RubyException = bridge_class(Error, T_OBJECT, 'Exception');
|
592
|
-
var RubyStandardError = define_class(RubyObject, 'StandardError', RubyException);
|
593
|
-
var RubyRuntimeError = define_class(RubyObject, 'RuntimeError', RubyException);
|
594
|
-
var RubyLocalJumpError = define_class(RubyObject, 'LocalJumpError', RubyStandardError);
|
595
|
-
var RubyTypeError = define_class(RubyObject, 'TypeError', RubyStandardError);
|
596
|
-
var RubyNameError = define_class(RubyObject, 'NameError', RubyStandardError);
|
597
|
-
var RubyNoMethodError = define_class(RubyObject, 'NoMethodError', RubyNameError);
|
598
|
-
var RubyArgError = define_class(RubyObject, 'ArgumentError', RubyStandardError);
|
599
|
-
var RubyScriptError = define_class(RubyObject, 'ScriptError', RubyException);
|
600
|
-
var RubyLoadError = define_class(RubyObject, 'LoadError', RubyScriptError);
|
601
|
-
var RubyIndexError = define_class(RubyObject, 'IndexError', RubyStandardError);
|
602
|
-
var RubyKeyError = define_class(RubyObject, 'KeyError', RubyIndexError);
|
603
|
-
var RubyRangeError = define_class(RubyObject, 'RangeError', RubyStandardError);
|
604
|
-
var RubyNotImplError = define_class(RubyObject, 'NotImplementedError', RubyException);
|
605
|
-
|
606
|
-
RubyException._alloc.prototype.toString = function() {
|
607
|
-
return this._klass._name + ': ' + this.message;
|
608
|
-
};
|
541
|
+
Opal.nil.call = Opal.nil.apply = no_block_given;
|
609
542
|
|
610
543
|
var breaker = Opal.breaker = new Error('unexpected break');
|
611
|
-
breaker._klass = RubyLocalJumpError;
|
612
544
|
breaker.$t = function() { throw this; };
|
613
|
-
|