opal 0.5.0 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -2
- data/README.md +1 -1
- data/Rakefile +11 -8
- data/lib/opal.rb +1 -1
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +1 -1
- data/{corelib → opal/core}/array.rb +47 -40
- data/{corelib → opal/core}/basic_object.rb +4 -0
- data/{corelib → opal/core}/boolean.rb +2 -6
- data/{corelib → opal/core}/class.rb +0 -0
- data/{corelib → opal/core}/comparable.rb +0 -0
- data/{corelib → opal/core}/encoding.rb +0 -0
- data/{corelib → opal/core}/enumerable.rb +160 -38
- data/opal/core/enumerator.rb +416 -0
- data/{corelib → opal/core}/error.rb +0 -0
- data/{corelib → opal/core}/hash.rb +38 -48
- data/{corelib → opal/core}/io.rb +13 -9
- data/{corelib → opal/core}/kernel.rb +75 -49
- data/{corelib → opal/core}/main.rb +0 -0
- data/{corelib → opal/core}/match_data.rb +0 -4
- data/{corelib → opal/core}/method.rb +0 -0
- data/{corelib → opal/core}/module.rb +24 -3
- data/{corelib → opal/core}/nil_class.rb +0 -4
- data/{corelib → opal/core}/numeric.rb +3 -4
- data/{corelib → opal/core}/proc.rb +0 -4
- data/{corelib → opal/core}/range.rb +0 -0
- data/{corelib → opal/core}/regexp.rb +0 -4
- data/{corelib → opal/core}/runtime.js +0 -0
- data/{corelib → opal/core}/string.rb +4 -6
- data/{corelib → opal/core}/struct.rb +3 -21
- data/{corelib → opal/core}/time.rb +0 -4
- data/opal/opal.rb +121 -0
- data/spec/corelib/array/select_spec.rb +14 -0
- data/spec/filters/20.rb +4 -0
- data/spec/filters/bugs/enumerable.rb +1 -48
- data/spec/filters/unsupported/enumerator.rb +13 -0
- data/spec/opal/compiler/irb_spec.rb +1 -0
- data/spec/rubyspecs +1 -0
- data/spec/{corelib → stdlib}/native/alias_native_spec.rb +6 -4
- data/spec/{corelib → stdlib}/native/each_spec.rb +3 -1
- data/spec/{corelib → stdlib}/native/element_reference_spec.rb +3 -1
- data/spec/stdlib/native/ext_spec.rb +19 -0
- data/spec/{corelib → stdlib}/native/initialize_spec.rb +4 -4
- data/spec/{corelib → stdlib}/native/method_missing_spec.rb +13 -1
- data/spec/{corelib → stdlib}/native/new_spec.rb +3 -1
- data/stdlib/enumerator.rb +1 -0
- data/stdlib/json.rb +1 -1
- data/stdlib/native.rb +483 -0
- metadata +52 -47
- data/corelib/enumerator.rb +0 -55
- data/corelib/native.rb +0 -270
- data/corelib/opal.rb +0 -88
- data/spec/corelib/native/ext_spec.rb +0 -5
- data/spec/filters/bugs/enumerator.rb +0 -6
data/opal/opal.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'core/runtime'
|
2
|
+
require 'core/module'
|
3
|
+
require 'core/class'
|
4
|
+
require 'core/basic_object'
|
5
|
+
require 'core/kernel'
|
6
|
+
require 'core/nil_class'
|
7
|
+
require 'core/boolean'
|
8
|
+
require 'core/error'
|
9
|
+
require 'core/regexp'
|
10
|
+
require 'core/comparable'
|
11
|
+
require 'core/enumerable'
|
12
|
+
require 'core/enumerator'
|
13
|
+
require 'core/array'
|
14
|
+
require 'core/hash'
|
15
|
+
require 'core/string'
|
16
|
+
require 'core/match_data'
|
17
|
+
require 'core/encoding'
|
18
|
+
require 'core/numeric'
|
19
|
+
require 'core/proc'
|
20
|
+
require 'core/method'
|
21
|
+
require 'core/range'
|
22
|
+
require 'core/time'
|
23
|
+
require 'core/struct'
|
24
|
+
require 'core/io'
|
25
|
+
require 'core/main'
|
26
|
+
require 'native'
|
27
|
+
|
28
|
+
# regexp matches
|
29
|
+
$& = $~ = $` = $' = nil
|
30
|
+
|
31
|
+
# stub library path
|
32
|
+
$: = []
|
33
|
+
$" = []
|
34
|
+
|
35
|
+
# split lines
|
36
|
+
$/ = "\n"
|
37
|
+
$, = " "
|
38
|
+
|
39
|
+
ARGV = []
|
40
|
+
ARGF = Object.new
|
41
|
+
ENV = {}
|
42
|
+
|
43
|
+
$VERBOSE = false
|
44
|
+
$DEBUG = false
|
45
|
+
$SAFE = 0
|
46
|
+
|
47
|
+
RUBY_PLATFORM = 'opal'
|
48
|
+
RUBY_ENGINE = 'opal'
|
49
|
+
RUBY_VERSION = '1.9.3'
|
50
|
+
RUBY_ENGINE_VERSION = '0.5.2'
|
51
|
+
RUBY_RELEASE_DATE = '2013-11-11'
|
52
|
+
|
53
|
+
module Opal
|
54
|
+
def self.coerce_to(object, type, method)
|
55
|
+
return object if type === object
|
56
|
+
|
57
|
+
unless object.respond_to? method
|
58
|
+
raise TypeError, "no implicit conversion of #{object.class} into #{type}"
|
59
|
+
end
|
60
|
+
|
61
|
+
object.__send__ method
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.coerce_to!(object, type, method)
|
65
|
+
coerced = coerce_to(object, type, method)
|
66
|
+
|
67
|
+
unless type === coerced
|
68
|
+
raise TypeError, "can't convert #{object.class} into #{type} (#{object.class}##{method} gives #{coerced.class}"
|
69
|
+
end
|
70
|
+
|
71
|
+
coerced
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.try_convert(object, type, method)
|
75
|
+
return object if type === object
|
76
|
+
|
77
|
+
if object.respond_to? method
|
78
|
+
object.__send__ method
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.compare(a, b)
|
83
|
+
compare = a <=> b
|
84
|
+
|
85
|
+
if `compare === nil`
|
86
|
+
raise ArgumentError, "comparison of #{a.class.name} with #{b.class.name} failed"
|
87
|
+
end
|
88
|
+
|
89
|
+
compare
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.truthy?(value)
|
93
|
+
if value
|
94
|
+
true
|
95
|
+
else
|
96
|
+
false
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.falsy?(value)
|
101
|
+
if value
|
102
|
+
false
|
103
|
+
else
|
104
|
+
true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.destructure(args)
|
109
|
+
%x{
|
110
|
+
if (args.length == 1) {
|
111
|
+
return args[0];
|
112
|
+
}
|
113
|
+
else if (args._isArray) {
|
114
|
+
return args;
|
115
|
+
}
|
116
|
+
else {
|
117
|
+
return $slice.call(args);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
describe "Array#select" do
|
2
|
+
it "passes an array item into a single default-block parameter" do
|
3
|
+
[["ABC", "DEF"]].select do |x|
|
4
|
+
x.should == ["ABC", "DEF"]
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
it "splits an array item into a list of default block parameters" do
|
9
|
+
[["ABC", "DEF"]].select do |x,y|
|
10
|
+
x.should == "ABC"
|
11
|
+
y.should == "DEF"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/spec/filters/20.rb
ADDED
@@ -1,58 +1,11 @@
|
|
1
1
|
opal_filter "Enumerable" do
|
2
|
-
fails "Enumerable#
|
3
|
-
|
4
|
-
fails "Enumerable#drop_while passes elements to the block until the first false"
|
5
|
-
|
6
|
-
fails "Enumerable#each_slice raises an Argument Error if there is not a single parameter > 0"
|
7
|
-
|
8
|
-
fails "Enumerable#each_with_index provides each element to the block"
|
9
|
-
fails "Enumerable#each_with_index provides each element to the block and its index"
|
10
|
-
fails "Enumerable#each_with_index binds splat arguments properly"
|
11
|
-
fails "Enumerable#each_with_index passes extra parameters to each"
|
12
|
-
|
13
|
-
fails "Enumerable#entries passes arguments to each"
|
14
|
-
|
15
|
-
fails "Enumerable#first when passed an argument consumes only what is needed"
|
16
|
-
fails "Enumerable#first when passed an argument raises a TypeError if the passed argument is not numeric"
|
17
|
-
fails "Enumerable#first when passed an argument tries to convert the passed argument to an Integer using #to_int"
|
18
|
-
fails "Enumerable#first when passed an argument raises an ArgumentError when count is negative"
|
2
|
+
fails "Enumerable#cycle passed a number n as an argument raises an ArgumentError if more arguments are passed"
|
19
3
|
|
20
4
|
fails "Enumerable#grep can use $~ in the block when used with a Regexp"
|
21
5
|
|
22
|
-
fails "Enumerable#group_by returns a hash without default_proc"
|
23
|
-
fails "Enumerable#group_by gathers whole arrays as elements when each yields multiple"
|
24
|
-
|
25
|
-
fails "Enumerable#include? returns true if any element == argument for numbers"
|
26
|
-
fails "Enumerable#include? gathers whole arrays as elements when each yields multiple"
|
27
|
-
|
28
6
|
fails "Enumerable#inject returns nil when fails(legacy rubycon)"
|
29
7
|
fails "Enumerable#inject without inject arguments(legacy rubycon)"
|
30
|
-
fails "Enumerable#inject can take a symbol argument"
|
31
|
-
fails "Enumerable#inject ignores the block if two arguments"
|
32
|
-
fails "Enumerable#inject can take two argument"
|
33
|
-
|
34
|
-
fails "Enumerable#max raises an ArgumentError for incomparable elements"
|
35
|
-
fails "Enumerable#max gathers whole arrays as elements when each yields multiple"
|
36
|
-
|
37
|
-
fails "Enumerable#member? returns true if any element == argument for numbers"
|
38
|
-
fails "Enumerable#member? gathers whole arrays as elements when each yields multiple"
|
39
|
-
|
40
|
-
fails "Enumerable#min raises an ArgumentError for incomparable elements"
|
41
|
-
fails "Enumerable#min gathers whole arrays as elements when each yields multiple"
|
42
8
|
|
43
9
|
fails "Enumerable#reduce returns nil when fails(legacy rubycon)"
|
44
10
|
fails "Enumerable#reduce without inject arguments(legacy rubycon)"
|
45
|
-
fails "Enumerable#reduce can take a symbol argument"
|
46
|
-
fails "Enumerable#reduce ignores the block if two arguments"
|
47
|
-
fails "Enumerable#reduce can take two argument"
|
48
|
-
|
49
|
-
fails "Enumerable#select passes through the values yielded by #each_with_index"
|
50
|
-
fails "Enumerable#select returns an enumerator when no block given"
|
51
|
-
|
52
|
-
fails "Enumerable#take when passed an argument consumes only what is needed"
|
53
|
-
fails "Enumerable#take when passed an argument raises a TypeError if the passed argument is not numeric"
|
54
|
-
fails "Enumerable#take when passed an argument tries to convert the passed argument to an Integer using #to_int"
|
55
|
-
fails "Enumerable#take when passed an argument raises an ArgumentError when count is negative"
|
56
|
-
|
57
|
-
fails "Enumerable#to_a passes arguments to each"
|
58
11
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
opal_filter "Enumerator as generator" do
|
2
|
+
fails "Enumerator#next returns the next element of the enumeration"
|
3
|
+
fails "Enumerator#next raises a StopIteration exception at the end of the stream"
|
4
|
+
fails "Enumerator#next cannot be called again until the enumerator is rewound"
|
5
|
+
|
6
|
+
fails "Enumerator#rewind resets the enumerator to its initial state"
|
7
|
+
fails "Enumerator#rewind returns self"
|
8
|
+
fails "Enumerator#rewind has no effect on a new enumerator"
|
9
|
+
fails "Enumerator#rewind has no effect if called multiple, consecutive times"
|
10
|
+
fails "Enumerator#rewind does nothing if the object doesn't have a #rewind method"
|
11
|
+
fails "Enumerator#rewind works with peek to reset the position"
|
12
|
+
fails "Enumerator#rewind calls the enclosed object's rewind method if one exists"
|
13
|
+
end
|
data/spec/rubyspecs
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
|
1
|
+
require 'native'
|
2
|
+
|
3
|
+
describe "Native.alias_native" do
|
2
4
|
it "refers to an attribute on @native" do
|
3
5
|
Class.new {
|
4
|
-
include Native
|
6
|
+
include Native
|
5
7
|
|
6
8
|
alias_native :a, :a
|
7
9
|
}.new(`{ a: 2 }`).a.should == 2
|
@@ -9,7 +11,7 @@ describe "Native::Base.alias_native" do
|
|
9
11
|
|
10
12
|
it "refers to an attribute on @native and calls it if it's a function" do
|
11
13
|
Class.new {
|
12
|
-
include Native
|
14
|
+
include Native
|
13
15
|
|
14
16
|
alias_native :a, :a
|
15
17
|
}.new(`{ a: function() { return 42; } }`).a.should == 42
|
@@ -17,7 +19,7 @@ describe "Native::Base.alias_native" do
|
|
17
19
|
|
18
20
|
it "defaults old to new" do
|
19
21
|
Class.new {
|
20
|
-
include Native
|
22
|
+
include Native
|
21
23
|
|
22
24
|
alias_native :a
|
23
25
|
}.new(`{ a: 42 }`).a.should == 42
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'native'
|
2
|
+
|
3
|
+
describe Hash do
|
4
|
+
describe '#initialize' do
|
5
|
+
it "returns a hash with a nil value" do
|
6
|
+
h = Hash.new(`{a: null}`)
|
7
|
+
h[:a].should == nil
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#to_n' do
|
12
|
+
it "should return a js object representing hash" do
|
13
|
+
Hash.new({:a => 100, :b => 200}.to_n).should == {:a => 100, :b => 200}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "Hash#to_n" do
|
19
|
+
end
|
@@ -1,17 +1,17 @@
|
|
1
1
|
require 'native'
|
2
2
|
|
3
|
-
describe "Native
|
4
|
-
it "works when Native
|
3
|
+
describe "Native#initialize" do
|
4
|
+
it "works when Native is included in a BasicObject" do
|
5
5
|
basic_class = Class.new(BasicObject)
|
6
6
|
basic_object = basic_class.new
|
7
7
|
lambda { basic_object.native? }.should raise_error(NoMethodError)
|
8
8
|
|
9
|
-
basic_class.send :include, Native
|
9
|
+
basic_class.send :include, Native
|
10
10
|
lambda { basic_class.new(`{}`) }.should_not raise_error
|
11
11
|
end
|
12
12
|
|
13
13
|
it "detects a non native object" do
|
14
14
|
object = Object.new
|
15
|
-
lambda { Native.new(object) }.should raise_error(ArgumentError)
|
15
|
+
lambda { Native::Object.new(object) }.should raise_error(ArgumentError)
|
16
16
|
end
|
17
17
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'native'
|
2
|
+
|
3
|
+
describe "Native::Object#method_missing" do
|
2
4
|
it "should return values" do
|
3
5
|
Native(`{ a: 23 }`).a.should == 23
|
4
6
|
Native(`{ a: { b: 42 } }`).a.b.should == 42
|
@@ -36,4 +38,14 @@ describe "Native#method_missing" do
|
|
36
38
|
it "should pass the block as function" do
|
37
39
|
Native(`{ a: function(func) { return func(); } }`).a { 42 }.should == 42
|
38
40
|
end
|
41
|
+
|
42
|
+
it "should unwrap arguments" do
|
43
|
+
x = `{}`
|
44
|
+
|
45
|
+
Native(`{ a: function(a, b) { return a === b } }`).a(Native(x), x).should == true
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should wrap result" do
|
49
|
+
Native(`{ a: function() { return {}; } }`).a.class.should == Native::Object
|
50
|
+
end
|
39
51
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# stub
|
data/stdlib/json.rb
CHANGED
data/stdlib/native.rb
ADDED
@@ -0,0 +1,483 @@
|
|
1
|
+
module Kernel
|
2
|
+
def native?(value)
|
3
|
+
`value == null || !value._klass`
|
4
|
+
end
|
5
|
+
|
6
|
+
def Native(obj)
|
7
|
+
if `#{obj} == null`
|
8
|
+
nil
|
9
|
+
elsif native?(obj)
|
10
|
+
Native::Object.new(obj)
|
11
|
+
else
|
12
|
+
obj
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def Array(object, *args, &block)
|
17
|
+
%x{
|
18
|
+
if (object == null || object === nil) {
|
19
|
+
return [];
|
20
|
+
}
|
21
|
+
else if (#{native?(object)}) {
|
22
|
+
return #{Native::Array.new(object, *args, &block).to_a};
|
23
|
+
}
|
24
|
+
else if (#{object.respond_to? :to_ary}) {
|
25
|
+
return #{object.to_ary};
|
26
|
+
}
|
27
|
+
else if (#{object.respond_to? :to_a}) {
|
28
|
+
return #{object.to_a};
|
29
|
+
}
|
30
|
+
else {
|
31
|
+
return [object];
|
32
|
+
}
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module Native
|
38
|
+
def self.is_a?(object, klass)
|
39
|
+
%x{
|
40
|
+
try {
|
41
|
+
return #{object} instanceof #{Native.try_convert(klass)};
|
42
|
+
}
|
43
|
+
catch (e) {
|
44
|
+
return false;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.try_convert(value)
|
50
|
+
%x{
|
51
|
+
if (#{native?(value)}) {
|
52
|
+
return #{value};
|
53
|
+
}
|
54
|
+
else if (#{value.respond_to? :to_n}) {
|
55
|
+
return #{value.to_n};
|
56
|
+
}
|
57
|
+
else {
|
58
|
+
return nil;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.convert(value)
|
64
|
+
native = try_convert(value)
|
65
|
+
|
66
|
+
if `#{native} === nil`
|
67
|
+
raise ArgumentError, "the passed value isn't a native"
|
68
|
+
end
|
69
|
+
|
70
|
+
native
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.call(obj, key, *args, &block)
|
74
|
+
%x{
|
75
|
+
var prop = #{obj}[#{key}];
|
76
|
+
|
77
|
+
if (prop == null) {
|
78
|
+
return nil;
|
79
|
+
}
|
80
|
+
else if (prop instanceof Function) {
|
81
|
+
if (block !== nil) {
|
82
|
+
args.push(block);
|
83
|
+
}
|
84
|
+
|
85
|
+
args = #{args.map {|value|
|
86
|
+
native = try_convert(value)
|
87
|
+
|
88
|
+
if nil === native
|
89
|
+
value
|
90
|
+
else
|
91
|
+
native
|
92
|
+
end
|
93
|
+
}};
|
94
|
+
|
95
|
+
return #{Native(`prop.apply(#{obj}, #{args})`)};
|
96
|
+
}
|
97
|
+
else if (#{native?(`prop`)}) {
|
98
|
+
return #{Native(`prop`)};
|
99
|
+
}
|
100
|
+
else {
|
101
|
+
return prop;
|
102
|
+
}
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
module Helpers
|
107
|
+
def alias_native(new, old = new, options = {})
|
108
|
+
if old.end_with? ?=
|
109
|
+
define_method new do |value|
|
110
|
+
`#@native[#{old[0 .. -2]}] = #{Native.convert(value)}`
|
111
|
+
|
112
|
+
value
|
113
|
+
end
|
114
|
+
else
|
115
|
+
if as = options[:as]
|
116
|
+
define_method new do |*args, &block|
|
117
|
+
if value = Native.call(@native, old, *args, &block)
|
118
|
+
as.new(value.to_n)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
else
|
122
|
+
define_method new do |*args, &block|
|
123
|
+
Native.call(@native, old, *args, &block)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.included(klass)
|
131
|
+
klass.extend Helpers
|
132
|
+
end
|
133
|
+
|
134
|
+
def initialize(native)
|
135
|
+
unless Kernel.native?(native)
|
136
|
+
Kernel.raise ArgumentError, "the passed value isn't native"
|
137
|
+
end
|
138
|
+
|
139
|
+
@native = native
|
140
|
+
end
|
141
|
+
|
142
|
+
def to_n
|
143
|
+
@native
|
144
|
+
end
|
145
|
+
|
146
|
+
class Object < BasicObject
|
147
|
+
include Native
|
148
|
+
|
149
|
+
def ==(other)
|
150
|
+
`#@native === #{Native.try_convert(other)}`
|
151
|
+
end
|
152
|
+
|
153
|
+
def has_key?(name)
|
154
|
+
`#@native.hasOwnProperty(#{name})`
|
155
|
+
end
|
156
|
+
|
157
|
+
alias key? has_key?
|
158
|
+
alias include? has_key?
|
159
|
+
alias member? has_key?
|
160
|
+
|
161
|
+
def each(*args)
|
162
|
+
if block_given?
|
163
|
+
%x{
|
164
|
+
for (var key in #@native) {
|
165
|
+
#{yield `key`, `#@native[key]`}
|
166
|
+
}
|
167
|
+
}
|
168
|
+
|
169
|
+
self
|
170
|
+
else
|
171
|
+
method_missing(:each, *args)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def [](key)
|
176
|
+
%x{
|
177
|
+
var prop = #@native[key];
|
178
|
+
|
179
|
+
if (prop instanceof Function) {
|
180
|
+
return prop;
|
181
|
+
}
|
182
|
+
else {
|
183
|
+
return #{::Native.call(@native, key)}
|
184
|
+
}
|
185
|
+
}
|
186
|
+
end
|
187
|
+
|
188
|
+
def []=(key, value)
|
189
|
+
native = Native.try_convert(value)
|
190
|
+
|
191
|
+
if `#{native} === nil`
|
192
|
+
`#@native[key] = #{value}`
|
193
|
+
else
|
194
|
+
`#@native[key] = #{native}`
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def method_missing(mid, *args, &block)
|
199
|
+
%x{
|
200
|
+
if (mid.charAt(mid.length - 1) === '=') {
|
201
|
+
return #{self[mid.slice(0, mid.length - 1)] = args[0]};
|
202
|
+
}
|
203
|
+
else {
|
204
|
+
return #{::Native.call(@native, mid, *args, &block)};
|
205
|
+
}
|
206
|
+
}
|
207
|
+
end
|
208
|
+
|
209
|
+
def nil?
|
210
|
+
false
|
211
|
+
end
|
212
|
+
|
213
|
+
def is_a?(klass)
|
214
|
+
klass == Native
|
215
|
+
end
|
216
|
+
|
217
|
+
alias kind_of? is_a?
|
218
|
+
|
219
|
+
def instance_of?(klass)
|
220
|
+
klass == Native
|
221
|
+
end
|
222
|
+
|
223
|
+
def class
|
224
|
+
`self._klass`
|
225
|
+
end
|
226
|
+
|
227
|
+
def to_a(options = {}, &block)
|
228
|
+
Native::Array.new(@native, options, &block).to_a
|
229
|
+
end
|
230
|
+
|
231
|
+
def to_ary(options = {}, &block)
|
232
|
+
Native::Array.new(@native, options, &block)
|
233
|
+
end
|
234
|
+
|
235
|
+
def inspect
|
236
|
+
"#<Native:#{`String(#@native)`}>"
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
class Array
|
241
|
+
include Native
|
242
|
+
include Enumerable
|
243
|
+
|
244
|
+
def initialize(native, options = {}, &block)
|
245
|
+
super(native)
|
246
|
+
|
247
|
+
@get = options[:get] || options[:access]
|
248
|
+
@named = options[:named]
|
249
|
+
@set = options[:set] || options[:access]
|
250
|
+
@length = options[:length] || :length
|
251
|
+
@block = block
|
252
|
+
|
253
|
+
if `#{length} == null`
|
254
|
+
raise ArgumentError, "no length found on the array-like object"
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def each(&block)
|
259
|
+
return enum_for :each unless block
|
260
|
+
|
261
|
+
index = 0
|
262
|
+
length = self.length
|
263
|
+
|
264
|
+
while index < length
|
265
|
+
block.call(self[index])
|
266
|
+
|
267
|
+
index += 1
|
268
|
+
end
|
269
|
+
|
270
|
+
self
|
271
|
+
end
|
272
|
+
|
273
|
+
def [](index)
|
274
|
+
result = case index
|
275
|
+
when String, Symbol
|
276
|
+
@named ? `#@native[#@named](#{index})` : `#@native[#{index}]`
|
277
|
+
|
278
|
+
when Integer
|
279
|
+
@get ? `#@native[#@get](#{index})` : `#@native[#{index}]`
|
280
|
+
end
|
281
|
+
|
282
|
+
if result
|
283
|
+
if @block
|
284
|
+
@block.call(result)
|
285
|
+
else
|
286
|
+
Native(result)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
def []=(index, value)
|
292
|
+
if @set
|
293
|
+
`#@native[#@set](#{index}, #{value})`
|
294
|
+
else
|
295
|
+
`#@native[#{index}] = #{value}`
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
def last(count = nil)
|
300
|
+
if count
|
301
|
+
index = length - 1
|
302
|
+
result = []
|
303
|
+
|
304
|
+
while index >= 0
|
305
|
+
result << self[index]
|
306
|
+
index -= 1
|
307
|
+
end
|
308
|
+
|
309
|
+
result
|
310
|
+
else
|
311
|
+
self[length - 1]
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
def length
|
316
|
+
`#@native[#@length]`
|
317
|
+
end
|
318
|
+
|
319
|
+
def to_ary
|
320
|
+
self
|
321
|
+
end
|
322
|
+
|
323
|
+
def inspect
|
324
|
+
to_a.inspect
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
class Numeric
|
330
|
+
def to_n
|
331
|
+
`self.valueOf()`
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
class Proc
|
336
|
+
def to_n
|
337
|
+
self
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
class String
|
342
|
+
def to_n
|
343
|
+
`self.valueOf()`
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
class Regexp
|
348
|
+
def to_n
|
349
|
+
`self.valueOf()`
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
class MatchData
|
354
|
+
def to_n
|
355
|
+
@matches
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
class Struct
|
360
|
+
def initialize(*args)
|
361
|
+
if args.length == 1 && native?(args[0])
|
362
|
+
object = args[0]
|
363
|
+
|
364
|
+
members.each {|name|
|
365
|
+
instance_variable_set "@#{name}", Native(`#{object}[#{name}]`)
|
366
|
+
}
|
367
|
+
else
|
368
|
+
members.each_with_index {|name, index|
|
369
|
+
instance_variable_set "@#{name}", args[index]
|
370
|
+
}
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
def to_n
|
375
|
+
result = `{}`
|
376
|
+
|
377
|
+
each_pair {|name, value|
|
378
|
+
`#{result}[#{name}] = #{value.to_n}`
|
379
|
+
}
|
380
|
+
|
381
|
+
result
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
class Array
|
386
|
+
def to_n
|
387
|
+
%x{
|
388
|
+
var result = [];
|
389
|
+
|
390
|
+
for (var i = 0, length = self.length; i < length; i++) {
|
391
|
+
var obj = self[i];
|
392
|
+
|
393
|
+
if (#{`obj`.respond_to? :to_n}) {
|
394
|
+
result.push(#{`obj`.to_n});
|
395
|
+
}
|
396
|
+
else {
|
397
|
+
result.push(obj);
|
398
|
+
}
|
399
|
+
}
|
400
|
+
|
401
|
+
return result;
|
402
|
+
}
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
class Boolean
|
407
|
+
def to_n
|
408
|
+
`self.valueOf()`
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
class Time
|
413
|
+
def to_n
|
414
|
+
self
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
class NilClass
|
419
|
+
def to_n
|
420
|
+
`null`
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
class Hash
|
425
|
+
def initialize(defaults = undefined, &block)
|
426
|
+
%x{
|
427
|
+
if (defaults != null) {
|
428
|
+
if (defaults.constructor === Object) {
|
429
|
+
var map = self.map,
|
430
|
+
keys = self.keys;
|
431
|
+
|
432
|
+
for (var key in defaults) {
|
433
|
+
var value = defaults[key];
|
434
|
+
|
435
|
+
if (value && value.constructor === Object) {
|
436
|
+
map[key] = #{Hash.new(`value`)};
|
437
|
+
}
|
438
|
+
else {
|
439
|
+
map[key] = #{Native(`defaults[key]`)};
|
440
|
+
}
|
441
|
+
|
442
|
+
keys.push(key);
|
443
|
+
}
|
444
|
+
}
|
445
|
+
else {
|
446
|
+
self.none = defaults;
|
447
|
+
}
|
448
|
+
}
|
449
|
+
else if (block !== nil) {
|
450
|
+
self.proc = block;
|
451
|
+
}
|
452
|
+
|
453
|
+
return self;
|
454
|
+
}
|
455
|
+
end
|
456
|
+
|
457
|
+
def to_n
|
458
|
+
%x{
|
459
|
+
var result = {},
|
460
|
+
keys = self.keys,
|
461
|
+
map = self.map,
|
462
|
+
bucket,
|
463
|
+
value;
|
464
|
+
|
465
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
466
|
+
var key = keys[i],
|
467
|
+
obj = map[key];
|
468
|
+
|
469
|
+
if (#{`obj`.respond_to? :to_n}) {
|
470
|
+
result[key] = #{`obj`.to_n};
|
471
|
+
}
|
472
|
+
else {
|
473
|
+
result[key] = obj;
|
474
|
+
}
|
475
|
+
}
|
476
|
+
|
477
|
+
return result;
|
478
|
+
}
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
# native global
|
483
|
+
$$ = $global = Native(`Opal.global`)
|