opal 0.3.10 → 0.3.11
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 +47 -46
- data/lib/opal.rb +11 -3
- data/lib/opal/builder.rb +4 -46
- data/lib/opal/bundle.rb +11 -25
- data/lib/opal/command.rb +101 -22
- data/lib/opal/context.rb +16 -50
- data/lib/opal/lexer.rb +21 -2
- data/lib/opal/nodes.rb +134 -20
- data/lib/opal/parser.rb +7 -7
- data/lib/opal/parser.y +7 -7
- data/lib/opal/rake/bundle_task.rb +24 -23
- data/lib/opal/version.rb +3 -0
- data/opal-parser.js +8343 -0
- data/opal.js +5685 -0
- data/stdlib/dev.rb +6 -4
- data/templates/init/Rakefile +7 -0
- data/templates/init/index.html +17 -0
- data/templates/init/lib/__NAME__.rb +2 -0
- metadata +9 -32
- data/corelib/array.rb +0 -1424
- data/corelib/boolean.rb +0 -20
- data/corelib/class.rb +0 -58
- data/corelib/core.rb +0 -66
- data/corelib/dir.rb +0 -22
- data/corelib/enumerable.rb +0 -33
- data/corelib/error.rb +0 -19
- data/corelib/file.rb +0 -60
- data/corelib/hash.rb +0 -729
- data/corelib/kernel.rb +0 -251
- data/corelib/load_order +0 -21
- data/corelib/match_data.rb +0 -33
- data/corelib/module.rb +0 -101
- data/corelib/nil_class.rb +0 -54
- data/corelib/numeric.rb +0 -352
- data/corelib/object.rb +0 -37
- data/corelib/proc.rb +0 -55
- data/corelib/range.rb +0 -27
- data/corelib/regexp.rb +0 -69
- data/corelib/string.rb +0 -300
- data/corelib/top_self.rb +0 -8
- data/runtime/class.js +0 -386
- data/runtime/fs.js +0 -199
- data/runtime/init.js +0 -556
- data/runtime/loader.js +0 -330
- data/runtime/module.js +0 -103
- data/runtime/post.js +0 -10
- data/runtime/pre.js +0 -7
- data/runtime/runtime.js +0 -345
data/corelib/regexp.rb
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
# A `Regexp` holds a regular expression, that can be used to match
|
2
|
-
# against strings. Regexps may be created as literals, or using the
|
3
|
-
# {Regexp.new} method:
|
4
|
-
#
|
5
|
-
# /abc/ # => /abc/
|
6
|
-
# Regexp.new '[a-z]' # => /[a-z]/
|
7
|
-
#
|
8
|
-
# Implementation details
|
9
|
-
# ----------------------
|
10
|
-
#
|
11
|
-
# Instances of {Regexp} are toll-free bridged to native javascript
|
12
|
-
# regular expressions. This means that javascript regexp instances may
|
13
|
-
# be passed directly into ruby methods that expect a regexp instance.
|
14
|
-
#
|
15
|
-
# Due to the limitations of some browser engines, regexps from ruby are
|
16
|
-
# not always compatible with the target browser javascript engine.
|
17
|
-
# Compatibility differences change between engines, so reading up on a
|
18
|
-
# particular browsers documentation might point to differences
|
19
|
-
# discovered. The majority of regexp syntax is typically the same.
|
20
|
-
class Regexp
|
21
|
-
|
22
|
-
def self.escape(s)
|
23
|
-
s
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.new(s)
|
27
|
-
`return new RegExp(s);`
|
28
|
-
end
|
29
|
-
|
30
|
-
def inspect
|
31
|
-
`return self.toString();`
|
32
|
-
end
|
33
|
-
|
34
|
-
def to_s
|
35
|
-
`return self.source;`
|
36
|
-
end
|
37
|
-
|
38
|
-
def ==(other)
|
39
|
-
`return self.toString() === other.toString();`
|
40
|
-
end
|
41
|
-
|
42
|
-
def eql?(other)
|
43
|
-
self == other
|
44
|
-
end
|
45
|
-
|
46
|
-
# Match - matches the regular expression against the given string. If
|
47
|
-
# the string matches, the index of the match is returned. Otherwise,
|
48
|
-
# `nil` is returned to imply no match.
|
49
|
-
#
|
50
|
-
# @param [String] str The string to match
|
51
|
-
# @return [Numeric, nil]
|
52
|
-
def =~(str)
|
53
|
-
`var result = self.exec(str);
|
54
|
-
$rb.X = result;
|
55
|
-
|
56
|
-
if (result) {
|
57
|
-
return result.index;
|
58
|
-
}
|
59
|
-
else {
|
60
|
-
return nil;
|
61
|
-
}`
|
62
|
-
end
|
63
|
-
|
64
|
-
def match(pattern)
|
65
|
-
self =~ pattern
|
66
|
-
$~
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
data/corelib/string.rb
DELETED
@@ -1,300 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
|
-
class String
|
4
|
-
|
5
|
-
def self.new(str = "")
|
6
|
-
str
|
7
|
-
end
|
8
|
-
|
9
|
-
def ==(other)
|
10
|
-
`return self.valueOf() === other.valueOf();`
|
11
|
-
end
|
12
|
-
|
13
|
-
# Returns a copy of `self` with the first character converted to uppercase and
|
14
|
-
# the remaining to lowercase.
|
15
|
-
#
|
16
|
-
# @example
|
17
|
-
#
|
18
|
-
# 'hello'.capitalize
|
19
|
-
# # => 'Hello'
|
20
|
-
# 'HELLO'.capitalize
|
21
|
-
# # => 'Hello'
|
22
|
-
# '123ABC'.capitalize
|
23
|
-
# # => '123abc'
|
24
|
-
#
|
25
|
-
# @return [String]
|
26
|
-
def capitalize
|
27
|
-
`return self.charAt(0).toUpperCase() + self.substr(1).toLowerCase();`
|
28
|
-
end
|
29
|
-
|
30
|
-
# Returns a copy of `self` with all uppercase letters replaces with their
|
31
|
-
# lowercase counterparts.
|
32
|
-
#
|
33
|
-
# @example
|
34
|
-
#
|
35
|
-
# 'hELLo'.downcase
|
36
|
-
# # => 'hello'
|
37
|
-
#
|
38
|
-
# @return [String]
|
39
|
-
def downcase
|
40
|
-
`return self.toLowerCase();`
|
41
|
-
end
|
42
|
-
|
43
|
-
def upcase
|
44
|
-
`return self.toUpperCase();`
|
45
|
-
end
|
46
|
-
|
47
|
-
# Returns a printable version of `self`, surrounded with quotation marks, with
|
48
|
-
# all special characters escaped.
|
49
|
-
#
|
50
|
-
# @example
|
51
|
-
#
|
52
|
-
# str = "hello"
|
53
|
-
# str.inspect
|
54
|
-
# # => "\"hello\""
|
55
|
-
#
|
56
|
-
# @return [String]
|
57
|
-
def inspect
|
58
|
-
`/* borrowed from json2.js, see file for license */
|
59
|
-
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
60
|
-
|
61
|
-
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
62
|
-
|
63
|
-
meta = {
|
64
|
-
'\b': '\\b',
|
65
|
-
'\t': '\\t',
|
66
|
-
'\n': '\\n',
|
67
|
-
'\f': '\\f',
|
68
|
-
'\r': '\\r',
|
69
|
-
'"' : '\\"',
|
70
|
-
'\\': '\\\\'
|
71
|
-
};
|
72
|
-
|
73
|
-
escapable.lastIndex = 0;
|
74
|
-
|
75
|
-
return escapable.test(self) ? '"' + self.replace(escapable, function (a) {
|
76
|
-
var c = meta[a];
|
77
|
-
return typeof c === 'string' ? c :
|
78
|
-
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
79
|
-
}) + '"' : '"' + self + '"';`
|
80
|
-
end
|
81
|
-
|
82
|
-
# Returns the number of characters in `self`.
|
83
|
-
#
|
84
|
-
# @return [Numeric]
|
85
|
-
def length
|
86
|
-
`return self.length;`
|
87
|
-
end
|
88
|
-
|
89
|
-
def to_i
|
90
|
-
`return parseInt(self);`
|
91
|
-
end
|
92
|
-
|
93
|
-
# Returns the corresponding symbol for the receiver.
|
94
|
-
#
|
95
|
-
# @example
|
96
|
-
#
|
97
|
-
# "koala".to_sym # => :Koala
|
98
|
-
# 'cat'.to_sym # => :cat
|
99
|
-
# '@cat'.to_sym # => :@cat
|
100
|
-
#
|
101
|
-
# This can also be used to create symbols that cannot be created using the
|
102
|
-
# :xxxx notation.
|
103
|
-
#
|
104
|
-
# @return [Symbol]
|
105
|
-
def to_sym
|
106
|
-
`return $rb.Y(self);`
|
107
|
-
end
|
108
|
-
|
109
|
-
def intern
|
110
|
-
`return $rb.Y(self);`
|
111
|
-
end
|
112
|
-
|
113
|
-
# Returns a new string with the characters from `self` in reverse order.
|
114
|
-
#
|
115
|
-
# @example
|
116
|
-
#
|
117
|
-
# 'stressed'.reverse
|
118
|
-
# # => 'desserts'
|
119
|
-
#
|
120
|
-
# @return [String]
|
121
|
-
def reverse
|
122
|
-
`return self.split('').reverse().join('');`
|
123
|
-
end
|
124
|
-
|
125
|
-
def succ
|
126
|
-
`return String.fromCharCode(self.charCodeAt(0));`
|
127
|
-
end
|
128
|
-
|
129
|
-
def [](idx)
|
130
|
-
`return self.substr(idx, idx + 1);`
|
131
|
-
end
|
132
|
-
|
133
|
-
def sub(pattern)
|
134
|
-
`return self.replace(pattern, function(str) {
|
135
|
-
return #{yield `str`};
|
136
|
-
});`
|
137
|
-
end
|
138
|
-
|
139
|
-
def gsub(pattern, replace)
|
140
|
-
`var r = pattern.toString();
|
141
|
-
r = r.substr(1, r.lastIndexOf('/') - 1);
|
142
|
-
r = new RegExp(r, 'g');
|
143
|
-
return self.replace(r, function(str) {
|
144
|
-
return replace;
|
145
|
-
});`
|
146
|
-
end
|
147
|
-
|
148
|
-
def slice(start, finish = nil)
|
149
|
-
`return self.substr(start, finish);`
|
150
|
-
end
|
151
|
-
|
152
|
-
def split(split, limit = nil)
|
153
|
-
`return self.split(split);`
|
154
|
-
end
|
155
|
-
|
156
|
-
# Comparison - returns -1 if `other` is greater than, 0 if `other` is equal to
|
157
|
-
# or 1 if `other` is less than `self. Returns nil if `other` is not a string.
|
158
|
-
#
|
159
|
-
# @example
|
160
|
-
#
|
161
|
-
# 'abcdef' <=> 'abcde' # => 1
|
162
|
-
# 'abcdef' <=> 'abcdef' # => 0
|
163
|
-
# 'abcdef' <=> 'abcdefg' # => -1
|
164
|
-
# 'abcdef' <=> 'ABCDEF' # => 1
|
165
|
-
#
|
166
|
-
# @param [String] other string to compare
|
167
|
-
# @return [-1, 0, 1, nil] result
|
168
|
-
def <=>(other)
|
169
|
-
`if (!(other.o$f & T_STRING)) return nil;
|
170
|
-
else if (self > other) return 1;
|
171
|
-
else if (self < other) return -1;
|
172
|
-
return 0;`
|
173
|
-
end
|
174
|
-
|
175
|
-
# Match - if obj is a Regexp, then uses it to match against self, returning
|
176
|
-
# nil if there is no match, or the index of the match location otherwise. If
|
177
|
-
# obj is not a regexp, then it calls =~ on it, using the receiver as an
|
178
|
-
# argument
|
179
|
-
#
|
180
|
-
# TODO passing a non regexp is not currently supported
|
181
|
-
#
|
182
|
-
# @param [Regexp, Objec] obj
|
183
|
-
# @return [Numeric, nil]
|
184
|
-
def =~(obj)
|
185
|
-
`if (obj.o$f & T_STRING) {
|
186
|
-
raise(eTypeError, "type mismatch: String given");
|
187
|
-
}`
|
188
|
-
|
189
|
-
obj =~ self
|
190
|
-
end
|
191
|
-
|
192
|
-
# Case-insensitive version of {#<=>}
|
193
|
-
#
|
194
|
-
# @example
|
195
|
-
#
|
196
|
-
# 'abcdef'.casecmp 'abcde' # => 1
|
197
|
-
# 'aBcDeF'.casecmp 'abcdef' # => 0
|
198
|
-
# 'abcdef'.casecmp 'aBcdEFg' # => -1
|
199
|
-
#
|
200
|
-
# @param [String] other string to compare
|
201
|
-
# @return [-1, 0, 1, nil]
|
202
|
-
def casecmp(other)
|
203
|
-
`if (typeof other != 'string') return nil;
|
204
|
-
var a = self.toLowerCase(), b = other.toLowerCase();
|
205
|
-
if (a > b) return 1;
|
206
|
-
else if (a < b) return -1;
|
207
|
-
return 0;`
|
208
|
-
end
|
209
|
-
|
210
|
-
# Returns `true` if self has a length of zero.
|
211
|
-
#
|
212
|
-
# @example
|
213
|
-
#
|
214
|
-
# 'hello'.empty?
|
215
|
-
# # => false
|
216
|
-
# ''.empty?
|
217
|
-
# # => true
|
218
|
-
#
|
219
|
-
# @return [true, false]
|
220
|
-
def empty?
|
221
|
-
`return self.length == 0;`
|
222
|
-
end
|
223
|
-
|
224
|
-
# Returns true is self ends with the given suffix.
|
225
|
-
#
|
226
|
-
# @example
|
227
|
-
#
|
228
|
-
# 'hello'.end_with? 'lo'
|
229
|
-
# # => true
|
230
|
-
#
|
231
|
-
# @param [String] suffix the suffix to check
|
232
|
-
# @return [true, false]
|
233
|
-
def end_with?(suffix)
|
234
|
-
`if (self.lastIndexOf(suffix) == self.length - suffix.length) {
|
235
|
-
return true;
|
236
|
-
}
|
237
|
-
|
238
|
-
return false;`
|
239
|
-
end
|
240
|
-
|
241
|
-
# Two strings are equal if they have the same length and content.
|
242
|
-
#
|
243
|
-
# @param [String] other string to compare
|
244
|
-
# @return [true, false]
|
245
|
-
def eql?(other)
|
246
|
-
`return self == other;`
|
247
|
-
end
|
248
|
-
|
249
|
-
def +(other)
|
250
|
-
`return self + other;`
|
251
|
-
end
|
252
|
-
|
253
|
-
# Returns true if self contains the given string `other`.
|
254
|
-
#
|
255
|
-
# @example
|
256
|
-
#
|
257
|
-
# 'hello'.include? 'lo' # => true
|
258
|
-
# 'hello'.include? 'ol' # => false
|
259
|
-
#
|
260
|
-
# @param [String] other string to check for
|
261
|
-
# @return [true, false]
|
262
|
-
def include?(other)
|
263
|
-
`return self.indexOf(other) == -1 ? false : true;`
|
264
|
-
end
|
265
|
-
|
266
|
-
# Returns the index of the first occurance of the given `substr` or pattern in
|
267
|
-
# self. Returns `nil` if not found. If the second param is present then it
|
268
|
-
# specifies the index of self to begin searching.
|
269
|
-
#
|
270
|
-
# **TODO** regexp and offsets not yet implemented.
|
271
|
-
#
|
272
|
-
# @example
|
273
|
-
#
|
274
|
-
# 'hello'.index 'e' # => 1
|
275
|
-
# 'hello'.index 'lo' # => 3
|
276
|
-
# 'hello'.index 'a' # => nil
|
277
|
-
#
|
278
|
-
# @param [String] substr string to check for
|
279
|
-
# @return [Numeric, nil]
|
280
|
-
def index(substr)
|
281
|
-
`var res = self.indexOf(substr);
|
282
|
-
|
283
|
-
return res == -1 ? nil : res;`
|
284
|
-
end
|
285
|
-
|
286
|
-
# Returns a copy of self with leading whitespace removed.
|
287
|
-
#
|
288
|
-
# @example
|
289
|
-
#
|
290
|
-
# ' hello '.lstrip
|
291
|
-
# # => 'hello '
|
292
|
-
# 'hello'.lstrip
|
293
|
-
# # => 'hello'
|
294
|
-
#
|
295
|
-
# @return [String]
|
296
|
-
def lstrip
|
297
|
-
`return self.replace(/^\s*/, '');`
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
data/corelib/top_self.rb
DELETED
data/runtime/class.js
DELETED
@@ -1,386 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
Root of all objects and classes inside opalscript, except for
|
3
|
-
native toll free bridges.
|
4
|
-
*/
|
5
|
-
var rb_boot_root = function() {};
|
6
|
-
|
7
|
-
/**
|
8
|
-
Returns the hash value for the receiver. By default on regular
|
9
|
-
objects this is just the objects' id
|
10
|
-
*/
|
11
|
-
rb_boot_root.$h = function() {
|
12
|
-
return this.$id;
|
13
|
-
};
|
14
|
-
|
15
|
-
/**
|
16
|
-
To benefit javascript debug consoles, the toString of any ruby
|
17
|
-
object is its' #inspect method.
|
18
|
-
*/
|
19
|
-
rb_boot_root.toString = function() {
|
20
|
-
return this.m$inspect();
|
21
|
-
};
|
22
|
-
|
23
|
-
/**
|
24
|
-
Boot a base class. This is only used for the very core ruby
|
25
|
-
objects and classes (Object, Module, Class). This returns
|
26
|
-
what will be the actual instances of our root classes.
|
27
|
-
|
28
|
-
@param {String} id The class id
|
29
|
-
@param {RubyClass} superklass The super
|
30
|
-
*/
|
31
|
-
function rb_boot_defclass(id, superklass) {
|
32
|
-
var cls = function() {
|
33
|
-
this.$id = rb_yield_hash();
|
34
|
-
return this;
|
35
|
-
};
|
36
|
-
|
37
|
-
if (superklass) {
|
38
|
-
var ctor = function() {};
|
39
|
-
ctor.prototype = superklass.prototype;
|
40
|
-
cls.prototype = new ctor();
|
41
|
-
}
|
42
|
-
else {
|
43
|
-
cls.prototype = new rb_boot_root();
|
44
|
-
}
|
45
|
-
|
46
|
-
cls.prototype.constructor = cls;
|
47
|
-
cls.prototype.$f = T_OBJECT;
|
48
|
-
|
49
|
-
cls.prototype.$h = function() {
|
50
|
-
return this.$id;
|
51
|
-
};
|
52
|
-
|
53
|
-
return cls;
|
54
|
-
};
|
55
|
-
|
56
|
-
/**
|
57
|
-
Make the actual (meta) classes: Object, Class, Module.
|
58
|
-
|
59
|
-
@param {String} id The class id
|
60
|
-
@param {RubyClass} klass The class of the result
|
61
|
-
@param {RubyClass} superklass The superklass
|
62
|
-
*/
|
63
|
-
function rb_boot_makemeta(id, klass, superklass) {
|
64
|
-
var meta = function() {
|
65
|
-
this.$id = rb_yield_hash();
|
66
|
-
return this;
|
67
|
-
};
|
68
|
-
|
69
|
-
var ctor = function() {};
|
70
|
-
ctor.prototype = superklass.prototype;
|
71
|
-
meta.prototype = new ctor();
|
72
|
-
|
73
|
-
var proto = meta.prototype;
|
74
|
-
proto.$included_in = [];
|
75
|
-
proto.$m = {};
|
76
|
-
proto.$methods = [];
|
77
|
-
|
78
|
-
proto.$a = klass;
|
79
|
-
proto.$f = T_CLASS;
|
80
|
-
proto.__classid__ = id;
|
81
|
-
proto.$s = superklass;
|
82
|
-
proto.constructor = meta;
|
83
|
-
|
84
|
-
// constants
|
85
|
-
if (superklass.prototype.$constants_alloc) {
|
86
|
-
proto.$c = new superklass.prototype.$constants_alloc();
|
87
|
-
proto.$constants_alloc = function() {};
|
88
|
-
proto.$constants_alloc.prototype = proto.$c;
|
89
|
-
}
|
90
|
-
else {
|
91
|
-
proto.$constants_alloc = function() {};
|
92
|
-
proto.$c = proto.$constants_alloc.prototype;
|
93
|
-
}
|
94
|
-
|
95
|
-
var result = new meta();
|
96
|
-
klass.prototype.$k = result;
|
97
|
-
return result;
|
98
|
-
};
|
99
|
-
|
100
|
-
/**
|
101
|
-
Fixes the class of boot classes to their meta.
|
102
|
-
*/
|
103
|
-
function rb_boot_defmetameta(klass, meta) {
|
104
|
-
klass.$k = meta;
|
105
|
-
};
|
106
|
-
|
107
|
-
/**
|
108
|
-
Boot class
|
109
|
-
|
110
|
-
@param {RubyClass} superklass Class to inherit from
|
111
|
-
*/
|
112
|
-
function rb_class_boot(superklass) {
|
113
|
-
// instances
|
114
|
-
var cls = function() {
|
115
|
-
this.$id = rb_yield_hash();
|
116
|
-
return this;
|
117
|
-
};
|
118
|
-
|
119
|
-
var ctor = function() {};
|
120
|
-
ctor.prototype = superklass.$a.prototype;
|
121
|
-
cls.prototype = new ctor();
|
122
|
-
|
123
|
-
var proto = cls.prototype;
|
124
|
-
proto.constructor = cls;
|
125
|
-
proto.$f = T_OBJECT;
|
126
|
-
|
127
|
-
// class itself
|
128
|
-
var meta = function() {
|
129
|
-
this.$id = rb_yield_hash();
|
130
|
-
return this;
|
131
|
-
};
|
132
|
-
|
133
|
-
var mtor = function() {};
|
134
|
-
mtor.prototype = superklass.constructor.prototype;
|
135
|
-
meta.prototype = new mtor();
|
136
|
-
|
137
|
-
proto = meta.prototype;
|
138
|
-
proto.$a = cls;
|
139
|
-
proto.$f = T_CLASS;
|
140
|
-
proto.$m = {};
|
141
|
-
proto.$methods = [];
|
142
|
-
proto.constructor = meta;
|
143
|
-
proto.$s = superklass;
|
144
|
-
|
145
|
-
// constants
|
146
|
-
proto.$c = new superklass.$constants_alloc();
|
147
|
-
proto.$constants_alloc = function() {};
|
148
|
-
proto.$constants_alloc.prototype = proto.$c;
|
149
|
-
|
150
|
-
var result = new meta();
|
151
|
-
cls.prototype.$k = result;
|
152
|
-
return result;
|
153
|
-
};
|
154
|
-
|
155
|
-
/**
|
156
|
-
Get actual class ignoring singleton classes and iclasses.
|
157
|
-
*/
|
158
|
-
function rb_class_real(klass) {
|
159
|
-
while (klass.$f & FL_SINGLETON) { klass = klass.$s; }
|
160
|
-
return klass;
|
161
|
-
};
|
162
|
-
|
163
|
-
/**
|
164
|
-
Name the class with the given id.
|
165
|
-
*/
|
166
|
-
function rb_name_class(klass, id) {
|
167
|
-
klass.__classid__ = id;
|
168
|
-
};
|
169
|
-
|
170
|
-
/**
|
171
|
-
Make metaclass for the given class
|
172
|
-
*/
|
173
|
-
function rb_make_metaclass(klass, super_class) {
|
174
|
-
if (klass.$f & T_CLASS) {
|
175
|
-
if ((klass.$f & T_CLASS) && (klass.$f & FL_SINGLETON)) {
|
176
|
-
return rb_make_metametaclass(klass);
|
177
|
-
}
|
178
|
-
else {
|
179
|
-
// FIXME this needs fixinfg to remove hacked stuff now in make_singleton_class
|
180
|
-
var meta = rb_class_boot(super_class);
|
181
|
-
// remove this??!
|
182
|
-
meta.$a.prototype = klass.constructor.prototype;
|
183
|
-
meta.$c = meta.$k.$c_prototype;
|
184
|
-
meta.$f |= FL_SINGLETON;
|
185
|
-
meta.__classid__ = "#<Class:" + klass.__classid__ + ">";
|
186
|
-
klass.$k = meta;
|
187
|
-
meta.$c = klass.$c;
|
188
|
-
rb_singleton_class_attached(meta, klass);
|
189
|
-
// console.log("meta id: " + klass.__classid__);
|
190
|
-
return meta;
|
191
|
-
}
|
192
|
-
} else {
|
193
|
-
// if we want metaclass of an object, do this
|
194
|
-
return rb_make_singleton_class(klass);
|
195
|
-
}
|
196
|
-
};
|
197
|
-
|
198
|
-
function rb_make_singleton_class(obj) {
|
199
|
-
var orig_class = obj.$k;
|
200
|
-
var klass = rb_class_boot(orig_class);
|
201
|
-
|
202
|
-
klass.$f |= FL_SINGLETON;
|
203
|
-
|
204
|
-
obj.$k = klass;
|
205
|
-
|
206
|
-
// make methods we define here actually point to instance
|
207
|
-
// FIXME: we could just take advantage of $bridge_prototype like we
|
208
|
-
// use for bridged classes?? means we can make more instances...
|
209
|
-
klass.$bridge_prototype = obj;
|
210
|
-
|
211
|
-
rb_singleton_class_attached(klass, obj);
|
212
|
-
|
213
|
-
klass.$k = rb_class_real(orig_class).$k;
|
214
|
-
klass.__classid__ = "#<Class:#<" + orig_class.__classid__ + ":" + klass.$id + ">>";
|
215
|
-
|
216
|
-
return klass;
|
217
|
-
};
|
218
|
-
|
219
|
-
function rb_singleton_class_attached(klass, obj) {
|
220
|
-
if (klass.$f & FL_SINGLETON) {
|
221
|
-
klass.__attached__ = obj;
|
222
|
-
}
|
223
|
-
};
|
224
|
-
|
225
|
-
function rb_make_metametaclass(metaclass) {
|
226
|
-
var metametaclass, super_of_metaclass;
|
227
|
-
|
228
|
-
if (metaclass.$k == metaclass) {
|
229
|
-
metametaclass = rb_class_boot(null);
|
230
|
-
metametaclass.$k = metametaclass;
|
231
|
-
}
|
232
|
-
else {
|
233
|
-
metametaclass = rb_class_boot(null);
|
234
|
-
metametaclass.$k = metaclass.$k.$k == metaclass.$k
|
235
|
-
? rb_make_metametaclass(metaclass.$k)
|
236
|
-
: metaclass.$k.$k;
|
237
|
-
}
|
238
|
-
|
239
|
-
metametaclass.$f |= FL_SINGLETON;
|
240
|
-
|
241
|
-
rb_singleton_class_attached(metametaclass, metaclass);
|
242
|
-
rb_metaclass.$k = metametaclass;
|
243
|
-
metaclass.$m = metametaclass.$m_tbl;
|
244
|
-
super_of_metaclass = metaclass.$s;
|
245
|
-
|
246
|
-
metametaclass.$s = super_of_metaclass.$k.__attached__
|
247
|
-
== super_of_metaclass
|
248
|
-
? super_of_metaclass.$k
|
249
|
-
: rb_make_metametaclass(super_of_metaclass);
|
250
|
-
|
251
|
-
return metametaclass;
|
252
|
-
};
|
253
|
-
|
254
|
-
function rb_boot_defmetametaclass(klass, metametaclass) {
|
255
|
-
klass.$k.$k = metametaclass;
|
256
|
-
};
|
257
|
-
|
258
|
-
// Holds an array of all prototypes that are bridged. Any method defined on
|
259
|
-
// Object in ruby will also be added to the bridge classes.
|
260
|
-
var rb_bridged_classes = [];
|
261
|
-
|
262
|
-
/**
|
263
|
-
Define toll free bridged class
|
264
|
-
*/
|
265
|
-
function rb_bridge_class(prototype, flags, id, super_class) {
|
266
|
-
var klass = rb_define_class(id, super_class);
|
267
|
-
|
268
|
-
klass.$bridge_prototype = prototype;
|
269
|
-
rb_bridged_classes.push(prototype);
|
270
|
-
|
271
|
-
prototype.$k = klass;
|
272
|
-
prototype.$m = klass.$m_tbl;
|
273
|
-
prototype.$f = flags;
|
274
|
-
prototype.$r = true;
|
275
|
-
|
276
|
-
prototype.$h = function() { return flags + '_' + this; };
|
277
|
-
|
278
|
-
return klass;
|
279
|
-
};
|
280
|
-
|
281
|
-
// make native prototype from class
|
282
|
-
function rb_native_prototype(cls, proto) {
|
283
|
-
var sup = cls.$s;
|
284
|
-
|
285
|
-
if (sup != rb_cObject) {
|
286
|
-
rb_raise(rb_eRuntimeError, "native_error must be used on subclass of Object only");
|
287
|
-
}
|
288
|
-
|
289
|
-
proto.$k = cls;
|
290
|
-
proto.$f = T_OBJECT;
|
291
|
-
|
292
|
-
proto.$h = function() { return this.$id || (this.$id = rb_yield_hash()); };
|
293
|
-
|
294
|
-
return cls;
|
295
|
-
}
|
296
|
-
|
297
|
-
/**
|
298
|
-
Define a new class (normal way), with the given id and superclass. Will be
|
299
|
-
top level.
|
300
|
-
*/
|
301
|
-
function rb_define_class(id, super_klass) {
|
302
|
-
return rb_define_class_under(rb_cObject, id, super_klass);
|
303
|
-
};
|
304
|
-
|
305
|
-
function rb_define_class_under(base, id, super_klass) {
|
306
|
-
var klass;
|
307
|
-
|
308
|
-
if (rb_const_defined(base, id)) {
|
309
|
-
klass = rb_const_get(base, id);
|
310
|
-
|
311
|
-
if (!(klass.$f & T_CLASS)) {
|
312
|
-
rb_raise(rb_eException, id + " is not a class");
|
313
|
-
}
|
314
|
-
|
315
|
-
if (klass.$s != super_klass && super_klass != rb_cObject) {
|
316
|
-
rb_raise(rb_eException, "Wrong superclass given for " + id);
|
317
|
-
}
|
318
|
-
|
319
|
-
return klass;
|
320
|
-
}
|
321
|
-
|
322
|
-
klass = rb_define_class_id(id, super_klass);
|
323
|
-
|
324
|
-
if (base == rb_cObject) {
|
325
|
-
rb_name_class(klass, id);
|
326
|
-
} else {
|
327
|
-
rb_name_class(klass, base.__classid__ + '::' + id);
|
328
|
-
}
|
329
|
-
|
330
|
-
rb_const_set(base, id, klass);
|
331
|
-
klass.$parent = base;
|
332
|
-
|
333
|
-
// Class#inherited hook - here is a good place to call. We check method
|
334
|
-
// is actually defined first (incase we are calling it during boot). We
|
335
|
-
// can't do this earlier as an error will cause constant names not to be
|
336
|
-
// set etc (this is the last place before returning back to scope).
|
337
|
-
if (super_klass.m$inherited) {
|
338
|
-
super_klass.m$inherited(klass);
|
339
|
-
}
|
340
|
-
|
341
|
-
return klass;
|
342
|
-
};
|
343
|
-
|
344
|
-
/**
|
345
|
-
Actually create class
|
346
|
-
*/
|
347
|
-
function rb_define_class_id(id, super_klass) {
|
348
|
-
var klass;
|
349
|
-
|
350
|
-
if (!super_klass) {
|
351
|
-
super_klass = rb_cObject;
|
352
|
-
}
|
353
|
-
klass = rb_class_create(super_klass);
|
354
|
-
rb_name_class(klass, id);
|
355
|
-
rb_make_metaclass(klass, super_klass.$k);
|
356
|
-
|
357
|
-
return klass;
|
358
|
-
};
|
359
|
-
|
360
|
-
function rb_class_create(super_klass) {
|
361
|
-
return rb_class_boot(super_klass);
|
362
|
-
};
|
363
|
-
|
364
|
-
/**
|
365
|
-
Get singleton class of obj
|
366
|
-
*/
|
367
|
-
function rb_singleton_class(obj) {
|
368
|
-
var klass;
|
369
|
-
|
370
|
-
if (obj.$f & T_OBJECT) {
|
371
|
-
if ((obj.$f & T_NUMBER) || (obj.$f & T_SYMBOL)) {
|
372
|
-
rb_raise(rb_eTypeError, "can't define singleton");
|
373
|
-
}
|
374
|
-
}
|
375
|
-
|
376
|
-
if ((obj.$k.$f & FL_SINGLETON) && obj.$k.__attached__ == obj) {
|
377
|
-
klass = obj.$k;
|
378
|
-
}
|
379
|
-
else {
|
380
|
-
var class_id = obj.$k.__classid__;
|
381
|
-
klass = rb_make_metaclass(obj, obj.$k);
|
382
|
-
}
|
383
|
-
|
384
|
-
return klass;
|
385
|
-
};
|
386
|
-
|