opal 0.7.0.beta3 → 0.7.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitmodules +4 -0
- data/.travis.yml +7 -3
- data/.yardopts +6 -0
- data/CHANGELOG.md +28 -0
- data/Gemfile +1 -1
- data/README.md +3 -12
- data/Rakefile +4 -150
- data/bin/opal-mspec +1 -1
- data/docs/compiler_directives.md +127 -0
- data/examples/rack/.gitignore +1 -0
- data/examples/rack/app/user.rb +1 -0
- data/lib/mspec/opal/special_calls.rb +15 -2
- data/lib/opal/builder.rb +15 -8
- data/lib/opal/compiler.rb +75 -4
- data/lib/opal/erb.rb +22 -2
- data/lib/opal/fragment.rb +17 -5
- data/lib/opal/nodes/def.rb +174 -53
- data/lib/opal/nodes/if.rb +14 -0
- data/lib/opal/nodes/module.rb +0 -1
- data/lib/opal/nodes/rescue.rb +10 -2
- data/lib/opal/nodes/scope.rb +0 -17
- data/lib/opal/parser.rb +83 -19
- data/lib/opal/parser/grammar.rb +2511 -2414
- data/lib/opal/parser/grammar.y +71 -9
- data/lib/opal/parser/lexer.rb +44 -12
- data/lib/opal/parser/parser_scope.rb +3 -0
- data/lib/opal/parser/sexp.rb +7 -1
- data/lib/opal/paths.rb +5 -5
- data/lib/opal/sprockets/environment.rb +2 -10
- data/lib/opal/sprockets/path_reader.rb +1 -1
- data/lib/opal/sprockets/processor.rb +1 -0
- data/lib/opal/sprockets/server.rb +2 -0
- data/lib/opal/util.rb +7 -2
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +1 -0
- data/opal/README.md +1 -1
- data/opal/corelib/dir.rb +1 -1
- data/opal/corelib/enumerable.rb +3 -1
- data/opal/corelib/error.rb +3 -0
- data/opal/corelib/file.rb +2 -0
- data/opal/corelib/hash.rb +3 -0
- data/opal/corelib/io.rb +15 -1
- data/opal/corelib/kernel.rb +8 -0
- data/opal/corelib/module.rb +42 -17
- data/opal/corelib/runtime.js +223 -49
- data/opal/corelib/string.rb +1 -1
- data/opal/corelib/struct.rb +1 -7
- data/spec/README.md +8 -0
- data/spec/filters/bugs/language.rb +1 -0
- data/spec/filters/bugs/module.rb +4 -0
- data/spec/filters/unsupported/frozen.rb +2 -0
- data/spec/lib/compiler/pre_processed_conditionals_spec.rb +87 -0
- data/spec/lib/compiler_spec.rb +1 -67
- data/spec/lib/fixtures/file_with_directives.js +2 -0
- data/spec/lib/fixtures/required_file.js +1 -0
- data/spec/lib/parser/def_spec.rb +29 -16
- data/spec/lib/parser/variables_spec.rb +5 -5
- data/spec/lib/sprockets/path_reader_spec.rb +24 -8
- data/spec/lib/sprockets/server_spec.rb +10 -3
- data/spec/opal/core/date_spec.rb +14 -0
- data/spec/opal/core/language/versions/def_2_0_spec.rb +62 -0
- data/spec/opal/core/language_spec.rb +23 -0
- data/spec/opal/core/runtime/donate_spec.rb +53 -0
- data/spec/opal/stdlib/native/native_alias_spec.rb +19 -0
- data/spec/opal/stdlib/native/native_class_spec.rb +18 -0
- data/spec/opal/stdlib/native/native_module_spec.rb +13 -0
- data/spec/rubyspecs +2 -0
- data/stdlib/buffer.rb +1 -0
- data/stdlib/date.rb +18 -0
- data/stdlib/encoding.rb +3 -2
- data/stdlib/minitest.rb +780 -0
- data/stdlib/minitest/assertions.rb +662 -0
- data/stdlib/minitest/autorun.rb +12 -0
- data/stdlib/minitest/benchmark.rb +426 -0
- data/stdlib/minitest/expectations.rb +281 -0
- data/stdlib/minitest/hell.rb +11 -0
- data/stdlib/minitest/mock.rb +220 -0
- data/stdlib/minitest/parallel.rb +65 -0
- data/stdlib/minitest/pride.rb +4 -0
- data/stdlib/minitest/pride_plugin.rb +142 -0
- data/stdlib/minitest/spec.rb +310 -0
- data/stdlib/minitest/test.rb +293 -0
- data/stdlib/minitest/unit.rb +45 -0
- data/stdlib/native.rb +12 -3
- data/stdlib/nodejs/process.rb +16 -2
- data/stdlib/promise.rb +99 -0
- data/stdlib/test/unit.rb +10 -0
- data/stdlib/thread.rb +4 -0
- data/tasks/building.rake +58 -0
- data/tasks/documentation.rake +38 -0
- data/tasks/documenting.rake +37 -0
- data/tasks/testing.rake +102 -0
- metadata +57 -2
data/opal/corelib/module.rb
CHANGED
@@ -47,11 +47,17 @@ class Module
|
|
47
47
|
|
48
48
|
def alias_method(newname, oldname)
|
49
49
|
%x{
|
50
|
-
|
50
|
+
var newjsid = '$' + newname,
|
51
|
+
body = self.$$proto['$' + oldname];
|
51
52
|
|
52
|
-
if (self.$$
|
53
|
-
|
53
|
+
if (self.$$is_singleton) {
|
54
|
+
self.$$proto[newjsid] = body;
|
54
55
|
}
|
56
|
+
else {
|
57
|
+
Opal.defn(self, newjsid, body);
|
58
|
+
}
|
59
|
+
|
60
|
+
return self;
|
55
61
|
}
|
56
62
|
self
|
57
63
|
end
|
@@ -88,18 +94,16 @@ class Module
|
|
88
94
|
|
89
95
|
def attr_reader(*names)
|
90
96
|
%x{
|
91
|
-
var proto = self.$$proto, cls = self;
|
92
97
|
for (var i = 0, length = names.length; i < length; i++) {
|
93
98
|
(function(name) {
|
94
|
-
proto[name] = nil;
|
99
|
+
self.$$proto[name] = nil;
|
95
100
|
var func = function() { return this[name] };
|
96
101
|
|
97
|
-
if (
|
98
|
-
proto.constructor.prototype['$' + name] = func;
|
102
|
+
if (self.$$is_singleton) {
|
103
|
+
self.$$proto.constructor.prototype['$' + name] = func;
|
99
104
|
}
|
100
105
|
else {
|
101
|
-
|
102
|
-
Opal.donate(self, ['$' + name ]);
|
106
|
+
Opal.defn(self, '$' + name, func);
|
103
107
|
}
|
104
108
|
})(names[i]);
|
105
109
|
}
|
@@ -110,18 +114,16 @@ class Module
|
|
110
114
|
|
111
115
|
def attr_writer(*names)
|
112
116
|
%x{
|
113
|
-
var proto = self.$$proto, cls = self;
|
114
117
|
for (var i = 0, length = names.length; i < length; i++) {
|
115
118
|
(function(name) {
|
116
|
-
proto[name] = nil;
|
119
|
+
self.$$proto[name] = nil;
|
117
120
|
var func = function(value) { return this[name] = value; };
|
118
121
|
|
119
|
-
if (
|
120
|
-
proto.constructor.prototype['$' + name + '='] = func;
|
122
|
+
if (self.$$is_singleton) {
|
123
|
+
self.$$proto.constructor.prototype['$' + name + '='] = func;
|
121
124
|
}
|
122
125
|
else {
|
123
|
-
|
124
|
-
Opal.donate(self, ['$' + name + '=']);
|
126
|
+
Opal.defn(self, '$' + name + '=', func);
|
125
127
|
}
|
126
128
|
})(names[i]);
|
127
129
|
}
|
@@ -144,6 +146,25 @@ class Module
|
|
144
146
|
}
|
145
147
|
end
|
146
148
|
|
149
|
+
def class_variable_get(name)
|
150
|
+
name = Opal.coerce_to!(name, String, :to_str)
|
151
|
+
raise NameError, 'class vars should start with @@' if `name.length < 3 || name.slice(0,2) !== '@@'`
|
152
|
+
%x{
|
153
|
+
var value = Opal.cvars[name.slice(2)];
|
154
|
+
#{raise NameError, 'uninitialized class variable @@a in' if `value == null`}
|
155
|
+
return value;
|
156
|
+
}
|
157
|
+
end
|
158
|
+
|
159
|
+
def class_variable_set(name, value)
|
160
|
+
name = Opal.coerce_to!(name, String, :to_str)
|
161
|
+
raise NameError if `name.length < 3 || name.slice(0,2) !== '@@'`
|
162
|
+
%x{
|
163
|
+
Opal.cvars[name.slice(2)] = value;
|
164
|
+
return value;
|
165
|
+
}
|
166
|
+
end
|
167
|
+
|
147
168
|
def constants
|
148
169
|
`self.$$scope.constants`
|
149
170
|
end
|
@@ -241,8 +262,12 @@ class Module
|
|
241
262
|
block.$$s = null;
|
242
263
|
block.$$def = block;
|
243
264
|
|
244
|
-
self.$$
|
245
|
-
|
265
|
+
if (self.$$is_singleton) {
|
266
|
+
self.$$proto[jsid] = block;
|
267
|
+
}
|
268
|
+
else {
|
269
|
+
Opal.defn(self, jsid, block);
|
270
|
+
}
|
246
271
|
|
247
272
|
return name;
|
248
273
|
}
|
data/opal/corelib/runtime.js
CHANGED
@@ -43,7 +43,22 @@
|
|
43
43
|
// Globals table
|
44
44
|
Opal.gvars = {};
|
45
45
|
|
46
|
-
|
46
|
+
/**
|
47
|
+
Get a constant on the given scope. Every class and module in Opal has a
|
48
|
+
scope used to store, and inherit, constants. For example, the top level
|
49
|
+
`Object` in ruby has a scope accessible as `Opal.Object.$$scope`.
|
50
|
+
|
51
|
+
To get the `Array` class using this scope, you could use:
|
52
|
+
|
53
|
+
Opal.Object.$$scope.get("Array")
|
54
|
+
|
55
|
+
If a constant with the given name cannot be found, then a dispatch to the
|
56
|
+
class/module's `#const_method` is called, which by default will raise an
|
57
|
+
error.
|
58
|
+
|
59
|
+
@param [String] name the name of the constant to lookup
|
60
|
+
@returns [RubyObject]
|
61
|
+
*/
|
47
62
|
Opal.get = function(name) {
|
48
63
|
var constant = this[name];
|
49
64
|
|
@@ -148,7 +163,7 @@
|
|
148
163
|
|
149
164
|
// Copy all parent constants to child, unless parent is Object
|
150
165
|
if (superklass !== ObjectClass && superklass !== BasicObjectClass) {
|
151
|
-
|
166
|
+
donate_constants(superklass, klass);
|
152
167
|
}
|
153
168
|
|
154
169
|
// call .inherited() hook with new class on the superclass
|
@@ -253,7 +268,26 @@
|
|
253
268
|
module.$$inc = [];
|
254
269
|
}
|
255
270
|
|
256
|
-
|
271
|
+
/**
|
272
|
+
Define new module (or return existing module). The given `base` is basically
|
273
|
+
the current `self` value the `module` statement was defined in. If this is
|
274
|
+
a ruby module or class, then it is used, otherwise if the base is a ruby
|
275
|
+
object then that objects real ruby class is used (e.g. if the base is the
|
276
|
+
main object, then the top level `Object` class is used as the base).
|
277
|
+
|
278
|
+
If a module of the given name is already defined in the base, then that
|
279
|
+
instance is just returned.
|
280
|
+
|
281
|
+
If there is a class of the given name in the base, then an error is
|
282
|
+
generated instead (cannot have a class and module of same name in same base).
|
283
|
+
|
284
|
+
Otherwise, a new module is created in the base with the given name, and that
|
285
|
+
new instance is returned back (to be referenced at runtime).
|
286
|
+
|
287
|
+
@param [RubyModule or Class] base class or module this definition is inside
|
288
|
+
@param [String] id the name of the new (or existing) module
|
289
|
+
@returns [RubyModule]
|
290
|
+
*/
|
257
291
|
Opal.module = function(base, id) {
|
258
292
|
var module;
|
259
293
|
|
@@ -303,11 +337,19 @@
|
|
303
337
|
return module;
|
304
338
|
}
|
305
339
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
340
|
+
/**
|
341
|
+
Return the singleton class for the passed object.
|
342
|
+
|
343
|
+
If the given object alredy has a singleton class, then it will be stored on
|
344
|
+
the object as the `$$meta` property. If this exists, then it is simply
|
345
|
+
returned back.
|
346
|
+
|
347
|
+
Otherwise, a new singleton object for the class or object is created, set on
|
348
|
+
the object at `$$meta` for future use, and then returned.
|
349
|
+
|
350
|
+
@param [RubyObject] object the ruby object
|
351
|
+
@returns [RubyClass] the singleton class for object
|
352
|
+
*/
|
311
353
|
Opal.get_singleton_class = function(object) {
|
312
354
|
if (object.$$meta) {
|
313
355
|
return object.$$meta;
|
@@ -320,11 +362,14 @@
|
|
320
362
|
return build_object_singleton_class(object);
|
321
363
|
};
|
322
364
|
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
365
|
+
/**
|
366
|
+
Build the singleton class for an existing class.
|
367
|
+
|
368
|
+
NOTE: Actually in MRI a class' singleton class inherits from its
|
369
|
+
superclass' singleton class which in turn inherits from Class.
|
370
|
+
|
371
|
+
@param [RubyClass] klass
|
372
|
+
@returns [RubyClass]
|
328
373
|
*/
|
329
374
|
function build_class_singleton_class(klass) {
|
330
375
|
var meta = new Opal.Class.$$alloc;
|
@@ -340,8 +385,11 @@
|
|
340
385
|
return klass.$$meta = meta;
|
341
386
|
}
|
342
387
|
|
343
|
-
|
344
|
-
|
388
|
+
/**
|
389
|
+
Build the singleton class for a Ruby (non class) Object.
|
390
|
+
|
391
|
+
@param [RubyObject] object
|
392
|
+
@returns [RubyClass]
|
345
393
|
*/
|
346
394
|
function build_object_singleton_class(object) {
|
347
395
|
var orig_class = object.$$class,
|
@@ -358,9 +406,26 @@
|
|
358
406
|
return object.$$meta = meta;
|
359
407
|
}
|
360
408
|
|
361
|
-
|
362
|
-
|
363
|
-
|
409
|
+
/**
|
410
|
+
The actual inclusion of a module into a class.
|
411
|
+
|
412
|
+
## Class `$$parent` and `iclass`
|
413
|
+
|
414
|
+
To handle `super` calls, every class has a `$$parent`. This parent is
|
415
|
+
used to resolve the next class for a super call. A normal class would
|
416
|
+
have this point to its superclass. However, if a class includes a module
|
417
|
+
then this would need to take into account the module. The module would
|
418
|
+
also have to then point its `$$parent` to the actual superclass. We
|
419
|
+
cannot modify modules like this, because it might be included in more
|
420
|
+
then one class. To fix this, we actually insert an `iclass` as the class'
|
421
|
+
`$$parent` which can then point to the superclass. The `iclass` acts as
|
422
|
+
a proxy to the actual module, so the `super` chain can then search it for
|
423
|
+
the required method.
|
424
|
+
|
425
|
+
@param [RubyModule] module the module to include
|
426
|
+
@param [RubyClass] klass the target class to include module into
|
427
|
+
@returns [null]
|
428
|
+
*/
|
364
429
|
Opal.append_features = function(module, klass) {
|
365
430
|
var included = klass.$$inc;
|
366
431
|
|
@@ -406,10 +471,10 @@
|
|
406
471
|
}
|
407
472
|
|
408
473
|
if (klass.$$dep) {
|
409
|
-
|
474
|
+
donate_methods(klass, methods.slice(), true);
|
410
475
|
}
|
411
476
|
|
412
|
-
|
477
|
+
donate_constants(module, klass);
|
413
478
|
};
|
414
479
|
|
415
480
|
// Boot a base class (makes instances).
|
@@ -534,30 +599,11 @@
|
|
534
599
|
return base_scope[name] = value;
|
535
600
|
};
|
536
601
|
|
537
|
-
/*
|
538
|
-
* constant get
|
539
|
-
*/
|
540
|
-
Opal.cget = function(base_scope, path) {
|
541
|
-
if (path == null) {
|
542
|
-
path = base_scope;
|
543
|
-
base_scope = Opal.Object;
|
544
|
-
}
|
545
|
-
|
546
|
-
var result = base_scope;
|
547
|
-
|
548
|
-
path = path.split('::');
|
549
|
-
while (path.length !== 0) {
|
550
|
-
result = result.$const_get(path.shift());
|
551
|
-
}
|
552
|
-
|
553
|
-
return result;
|
554
|
-
};
|
555
|
-
|
556
602
|
/*
|
557
603
|
* When a source module is included into the target module, we must also copy
|
558
604
|
* its constants to the target.
|
559
605
|
*/
|
560
|
-
|
606
|
+
function donate_constants(source_mod, target_mod) {
|
561
607
|
var source_constants = source_mod.$$scope.constants,
|
562
608
|
target_scope = target_mod.$$scope,
|
563
609
|
target_constants = target_scope.constants;
|
@@ -844,6 +890,34 @@
|
|
844
890
|
return [value];
|
845
891
|
};
|
846
892
|
|
893
|
+
/**
|
894
|
+
Used to get a list of rest keyword arguments. Method takes the given
|
895
|
+
keyword args, i.e. the hash literal passed to the method containing all
|
896
|
+
keyword arguemnts passed to method, as well as the used args which are
|
897
|
+
the names of required and optional arguments defined. This method then
|
898
|
+
just returns all key/value pairs which have not been used, in a new
|
899
|
+
hash literal.
|
900
|
+
|
901
|
+
@param given_args [Hash] all kwargs given to method
|
902
|
+
@param used_args [Object<String: true>] all keys used as named kwargs
|
903
|
+
@return [Hash]
|
904
|
+
*/
|
905
|
+
Opal.kwrestargs = function(given_args, used_args) {
|
906
|
+
var keys = [],
|
907
|
+
map = {},
|
908
|
+
key = null,
|
909
|
+
given_map = given_args.smap;
|
910
|
+
|
911
|
+
for (key in given_map) {
|
912
|
+
if (!used_args[key]) {
|
913
|
+
keys.push(key);
|
914
|
+
map[key] = given_map[key];
|
915
|
+
}
|
916
|
+
}
|
917
|
+
|
918
|
+
return Opal.hash2(keys, map);
|
919
|
+
};
|
920
|
+
|
847
921
|
/*
|
848
922
|
* Call a ruby method on a ruby object with some arguments:
|
849
923
|
*
|
@@ -885,7 +959,7 @@
|
|
885
959
|
/*
|
886
960
|
* Donate methods for a class/module
|
887
961
|
*/
|
888
|
-
|
962
|
+
function donate_methods(klass, defined, indirect) {
|
889
963
|
var methods = klass.$$methods, included_in = klass.$$dep;
|
890
964
|
|
891
965
|
// if (!indirect) {
|
@@ -905,21 +979,121 @@
|
|
905
979
|
}
|
906
980
|
|
907
981
|
if (includee.$$dep) {
|
908
|
-
|
982
|
+
donate_methods(includee, defined, true);
|
909
983
|
}
|
910
984
|
}
|
911
985
|
}
|
912
986
|
};
|
913
987
|
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
988
|
+
/**
|
989
|
+
Define the given method on the module.
|
990
|
+
|
991
|
+
This also handles donating methods to all classes that include this
|
992
|
+
module. Method conflicts are also handled here, where a class might already
|
993
|
+
have defined a method of the same name, or another included module defined
|
994
|
+
the same method.
|
995
|
+
|
996
|
+
@param [RubyModule] module the module method defined on
|
997
|
+
@param [String] jsid javascript friendly method name (e.g. "$foo")
|
998
|
+
@param [Function] body method body of actual function
|
999
|
+
*/
|
1000
|
+
function define_module_method(module, jsid, body) {
|
1001
|
+
module.$$proto[jsid] = body;
|
1002
|
+
body.$$owner = module;
|
1003
|
+
|
1004
|
+
module.$$methods.push(jsid);
|
1005
|
+
|
1006
|
+
if (module.$$module_function) {
|
1007
|
+
module[jsid] = body;
|
1008
|
+
}
|
1009
|
+
|
1010
|
+
var included_in = module.$$dep;
|
1011
|
+
|
1012
|
+
if (included_in) {
|
1013
|
+
for (var i = 0, length = included_in.length; i < length; i++) {
|
1014
|
+
var includee = included_in[i];
|
1015
|
+
var dest = includee.$$proto;
|
1016
|
+
var current = dest[jsid];
|
1017
|
+
|
1018
|
+
|
1019
|
+
if (dest.hasOwnProperty(jsid) && !current.$$donated && !current.$$stub) {
|
1020
|
+
// target class has already defined the same method name - do nothing
|
1021
|
+
}
|
1022
|
+
else if (dest.hasOwnProperty(jsid) && !current.$$stub) {
|
1023
|
+
// target class includes another module that has defined this method
|
1024
|
+
var klass_includees = includee.$$inc;
|
1025
|
+
|
1026
|
+
for (var j = 0, jj = klass_includees.length; j < jj; j++) {
|
1027
|
+
if (klass_includees[j] === current.$$owner) {
|
1028
|
+
var current_owner_index = j;
|
1029
|
+
}
|
1030
|
+
if (klass_includees[j] === module) {
|
1031
|
+
var module_index = j;
|
1032
|
+
}
|
1033
|
+
}
|
1034
|
+
|
1035
|
+
// only redefine method on class if the module was included AFTER
|
1036
|
+
// the module which defined the current method body. Also make sure
|
1037
|
+
// a module can overwrite a method it defined before
|
1038
|
+
if (current_owner_index <= module_index) {
|
1039
|
+
dest[jsid] = body;
|
1040
|
+
dest[jsid].$$donated = true;
|
1041
|
+
}
|
1042
|
+
}
|
1043
|
+
else {
|
1044
|
+
// neither a class, or module included by class, has defined method
|
1045
|
+
dest[jsid] = body;
|
1046
|
+
dest[jsid].$$donated = true;
|
1047
|
+
}
|
918
1048
|
|
919
|
-
|
920
|
-
|
1049
|
+
if (includee.$$dep) {
|
1050
|
+
donate_methods(includee, [jsid], true);
|
1051
|
+
}
|
921
1052
|
}
|
922
1053
|
}
|
1054
|
+
}
|
1055
|
+
|
1056
|
+
/**
|
1057
|
+
Used to define methods on an object. This is a helper method, used by the
|
1058
|
+
compiled source to define methods on special case objects when the compiler
|
1059
|
+
can not determine the destination object, or the object is a Module
|
1060
|
+
instance. This can get called by `Module#define_method` as well.
|
1061
|
+
|
1062
|
+
## Modules
|
1063
|
+
|
1064
|
+
Any method defined on a module will come through this runtime helper.
|
1065
|
+
The method is added to the module body, and the owner of the method is
|
1066
|
+
set to be the module itself. This is used later when choosing which
|
1067
|
+
method should show on a class if more than 1 included modules define
|
1068
|
+
the same method. Finally, if the module is in `module_function` mode,
|
1069
|
+
then the method is also defined onto the module itself.
|
1070
|
+
|
1071
|
+
## Classes
|
1072
|
+
|
1073
|
+
This helper will only be called for classes when a method is being
|
1074
|
+
defined indirectly; either through `Module#define_method`, or by a
|
1075
|
+
literal `def` method inside an `instance_eval` or `class_eval` body. In
|
1076
|
+
either case, the method is simply added to the class' prototype. A special
|
1077
|
+
exception exists for `BasicObject` and `Object`. These two classes are
|
1078
|
+
special because they are used in toll-free bridged classes. In each of
|
1079
|
+
these two cases, extra work is required to define the methods on toll-free
|
1080
|
+
bridged class' prototypes as well.
|
1081
|
+
|
1082
|
+
## Objects
|
1083
|
+
|
1084
|
+
If a simple ruby object is the object, then the method is simply just
|
1085
|
+
defined on the object as a singleton method. This would be the case when
|
1086
|
+
a method is defined inside an `instance_eval` block.
|
1087
|
+
|
1088
|
+
@param [RubyObject or Class] obj the actual obj to define method for
|
1089
|
+
@param [String] jsid the javascript friendly method name (e.g. '$foo')
|
1090
|
+
@param [Function] body the literal javascript function used as method
|
1091
|
+
@returns [null]
|
1092
|
+
*/
|
1093
|
+
Opal.defn = function(obj, jsid, body) {
|
1094
|
+
if (obj.$$is_mod) {
|
1095
|
+
define_module_method(obj, jsid, body);
|
1096
|
+
}
|
923
1097
|
else if (obj.$$is_class) {
|
924
1098
|
obj.$$proto[jsid] = body;
|
925
1099
|
|
@@ -927,7 +1101,7 @@
|
|
927
1101
|
define_basic_object_method(jsid, body);
|
928
1102
|
}
|
929
1103
|
else if (obj === ObjectClass) {
|
930
|
-
|
1104
|
+
donate_methods(obj, [jsid]);
|
931
1105
|
}
|
932
1106
|
}
|
933
1107
|
else {
|