opal 0.5.2 → 0.5.4
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.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/lib/opal.rb +0 -5
- data/lib/opal/compiler.rb +24 -44
- data/lib/opal/nodes/base.rb +5 -8
- data/lib/opal/nodes/call.rb +4 -0
- data/lib/opal/nodes/class.rb +6 -7
- data/lib/opal/nodes/def.rb +4 -4
- data/lib/opal/nodes/definitions.rb +0 -14
- data/lib/opal/nodes/iter.rb +51 -38
- data/lib/opal/nodes/literal.rb +21 -24
- data/lib/opal/nodes/module.rb +4 -4
- data/lib/opal/nodes/runtime_helpers.rb +45 -0
- data/lib/opal/nodes/scope.rb +280 -0
- data/lib/opal/nodes/singleton_class.rb +4 -5
- data/lib/opal/nodes/super.rb +1 -1
- data/lib/opal/nodes/top.rb +9 -7
- data/lib/opal/nodes/yield.rb +14 -3
- data/lib/opal/parser.rb +4 -18
- data/lib/opal/parser/grammar.rb +3745 -3667
- data/lib/opal/parser/grammar.y +1692 -1778
- data/lib/opal/parser/keywords.rb +35 -35
- data/lib/opal/parser/lexer.rb +356 -325
- data/lib/opal/parser/sexp.rb +1 -1
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +1 -0
- data/opal/core/array.rb +320 -81
- data/opal/core/enumerable.rb +46 -5
- data/opal/core/hash.rb +6 -64
- data/opal/core/helpers.rb +67 -0
- data/opal/core/method.rb +1 -1
- data/opal/core/module.rb +4 -4
- data/opal/core/range.rb +1 -12
- data/opal/core/regexp.rb +2 -8
- data/opal/core/runtime.js +74 -3
- data/opal/core/string.rb +99 -74
- data/opal/opal.rb +3 -72
- data/spec/filters/bugs/array.rb +2 -30
- data/spec/filters/bugs/basic_object.rb +0 -1
- data/spec/filters/bugs/string.rb +26 -21
- data/spec/filters/unsupported/enumerator.rb +3 -0
- data/spec/filters/unsupported/float.rb +1 -0
- data/spec/filters/unsupported/immutable_strings.rb +15 -0
- data/spec/filters/unsupported/tainted.rb +58 -30
- data/spec/filters/unsupported/trusted.rb +35 -15
- data/spec/opal/parser/class_spec.rb +4 -4
- data/spec/opal/parser/def_spec.rb +4 -4
- data/spec/opal/parser/lvar_spec.rb +6 -6
- data/spec/opal/parser/module_spec.rb +4 -4
- data/spec/opal/parser/sclass_spec.rb +2 -2
- data/spec/stdlib/native/exposure_spec.rb +33 -0
- data/stdlib/buffer.rb +1 -1
- data/stdlib/buffer/view.rb +1 -1
- data/stdlib/native.rb +193 -174
- data/stdlib/opal-parser.rb +0 -6
- data/stdlib/pp.rb +9 -0
- data/tasks/mspec.rake +3 -1
- metadata +9 -9
- data/lib/opal/nodes/base_scope.rb +0 -11
- data/lib/opal/target_scope.rb +0 -281
- data/spec/filters/20.rb +0 -4
- data/spec/filters/unsupported/array_subclasses.rb +0 -37
data/stdlib/buffer.rb
CHANGED
data/stdlib/buffer/view.rb
CHANGED
data/stdlib/native.rb
CHANGED
@@ -1,39 +1,3 @@
|
|
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
1
|
module Native
|
38
2
|
def self.is_a?(object, klass)
|
39
3
|
%x{
|
@@ -61,13 +25,17 @@ module Native
|
|
61
25
|
end
|
62
26
|
|
63
27
|
def self.convert(value)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
28
|
+
%x{
|
29
|
+
if (#{native?(value)}) {
|
30
|
+
return #{value};
|
31
|
+
}
|
32
|
+
else if (#{value.respond_to? :to_n}) {
|
33
|
+
return #{value.to_n};
|
34
|
+
}
|
35
|
+
else {
|
36
|
+
#{raise ArgumentError, "the passed value isn't a native"};
|
37
|
+
}
|
38
|
+
}
|
71
39
|
end
|
72
40
|
|
73
41
|
def self.call(obj, key, *args, &block)
|
@@ -142,187 +110,224 @@ module Native
|
|
142
110
|
def to_n
|
143
111
|
@native
|
144
112
|
end
|
113
|
+
end
|
145
114
|
|
146
|
-
|
147
|
-
|
115
|
+
module Kernel
|
116
|
+
def native?(value)
|
117
|
+
`value == null || !value._klass`
|
118
|
+
end
|
148
119
|
|
149
|
-
|
150
|
-
|
120
|
+
def Native(obj)
|
121
|
+
if `#{obj} == null`
|
122
|
+
nil
|
123
|
+
elsif native?(obj)
|
124
|
+
Native::Object.new(obj)
|
125
|
+
else
|
126
|
+
obj
|
151
127
|
end
|
128
|
+
end
|
152
129
|
|
153
|
-
|
154
|
-
|
155
|
-
|
130
|
+
def Array(object, *args, &block)
|
131
|
+
%x{
|
132
|
+
if (object == null || object === nil) {
|
133
|
+
return [];
|
134
|
+
}
|
135
|
+
else if (#{native?(object)}) {
|
136
|
+
return #{Native::Array.new(object, *args, &block).to_a};
|
137
|
+
}
|
138
|
+
else if (#{object.respond_to? :to_ary}) {
|
139
|
+
return #{object.to_ary};
|
140
|
+
}
|
141
|
+
else if (#{object.respond_to? :to_a}) {
|
142
|
+
return #{object.to_a};
|
143
|
+
}
|
144
|
+
else {
|
145
|
+
return [object];
|
146
|
+
}
|
147
|
+
}
|
148
|
+
end
|
149
|
+
end
|
156
150
|
|
157
|
-
|
158
|
-
|
159
|
-
alias member? has_key?
|
151
|
+
class Native::Object < BasicObject
|
152
|
+
include Native
|
160
153
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
for (var key in #@native) {
|
165
|
-
#{yield `key`, `#@native[key]`}
|
166
|
-
}
|
167
|
-
}
|
154
|
+
def ==(other)
|
155
|
+
`#@native === #{Native.try_convert(other)}`
|
156
|
+
end
|
168
157
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
end
|
173
|
-
end
|
158
|
+
def has_key?(name)
|
159
|
+
`#@native.hasOwnProperty(#{name})`
|
160
|
+
end
|
174
161
|
|
175
|
-
|
176
|
-
|
177
|
-
|
162
|
+
alias key? has_key?
|
163
|
+
alias include? has_key?
|
164
|
+
alias member? has_key?
|
178
165
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
166
|
+
def each(*args)
|
167
|
+
if block_given?
|
168
|
+
%x{
|
169
|
+
for (var key in #@native) {
|
170
|
+
#{yield `key`, `#@native[key]`}
|
184
171
|
}
|
185
172
|
}
|
186
|
-
end
|
187
|
-
|
188
|
-
def []=(key, value)
|
189
|
-
native = Native.try_convert(value)
|
190
173
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
`#@native[key] = #{native}`
|
195
|
-
end
|
174
|
+
self
|
175
|
+
else
|
176
|
+
method_missing(:each, *args)
|
196
177
|
end
|
178
|
+
end
|
197
179
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
return #{::Native.call(@native, mid, *args, &block)};
|
205
|
-
}
|
180
|
+
def [](key)
|
181
|
+
%x{
|
182
|
+
var prop = #@native[key];
|
183
|
+
|
184
|
+
if (prop instanceof Function) {
|
185
|
+
return prop;
|
206
186
|
}
|
207
|
-
|
187
|
+
else {
|
188
|
+
return #{::Native.call(@native, key)}
|
189
|
+
}
|
190
|
+
}
|
191
|
+
end
|
208
192
|
|
209
|
-
|
210
|
-
|
211
|
-
end
|
193
|
+
def []=(key, value)
|
194
|
+
native = Native.try_convert(value)
|
212
195
|
|
213
|
-
|
214
|
-
|
196
|
+
if `#{native} === nil`
|
197
|
+
`#@native[key] = #{value}`
|
198
|
+
else
|
199
|
+
`#@native[key] = #{native}`
|
215
200
|
end
|
201
|
+
end
|
216
202
|
|
217
|
-
|
203
|
+
def method_missing(mid, *args, &block)
|
204
|
+
%x{
|
205
|
+
if (mid.charAt(mid.length - 1) === '=') {
|
206
|
+
return #{self[mid.slice(0, mid.length - 1)] = args[0]};
|
207
|
+
}
|
208
|
+
else {
|
209
|
+
return #{::Native.call(@native, mid, *args, &block)};
|
210
|
+
}
|
211
|
+
}
|
212
|
+
end
|
218
213
|
|
219
|
-
|
220
|
-
|
221
|
-
|
214
|
+
def nil?
|
215
|
+
false
|
216
|
+
end
|
222
217
|
|
223
|
-
|
224
|
-
|
225
|
-
|
218
|
+
def is_a?(klass)
|
219
|
+
klass == Native
|
220
|
+
end
|
226
221
|
|
227
|
-
|
228
|
-
Native::Array.new(@native, options, &block).to_a
|
229
|
-
end
|
222
|
+
alias kind_of? is_a?
|
230
223
|
|
231
|
-
|
232
|
-
|
233
|
-
|
224
|
+
def instance_of?(klass)
|
225
|
+
klass == Native
|
226
|
+
end
|
234
227
|
|
235
|
-
|
236
|
-
|
237
|
-
|
228
|
+
def class
|
229
|
+
`self._klass`
|
230
|
+
end
|
231
|
+
|
232
|
+
def to_a(options = {}, &block)
|
233
|
+
Native::Array.new(@native, options, &block).to_a
|
238
234
|
end
|
239
235
|
|
240
|
-
|
241
|
-
|
242
|
-
|
236
|
+
def to_ary(options = {}, &block)
|
237
|
+
Native::Array.new(@native, options, &block)
|
238
|
+
end
|
243
239
|
|
244
|
-
|
245
|
-
|
240
|
+
def inspect
|
241
|
+
"#<Native:#{`String(#@native)`}>"
|
242
|
+
end
|
243
|
+
end
|
246
244
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
@length = options[:length] || :length
|
251
|
-
@block = block
|
245
|
+
class Native::Array
|
246
|
+
include Native
|
247
|
+
include Enumerable
|
252
248
|
|
253
|
-
|
254
|
-
|
255
|
-
end
|
256
|
-
end
|
249
|
+
def initialize(native, options = {}, &block)
|
250
|
+
super(native)
|
257
251
|
|
258
|
-
|
259
|
-
|
252
|
+
@get = options[:get] || options[:access]
|
253
|
+
@named = options[:named]
|
254
|
+
@set = options[:set] || options[:access]
|
255
|
+
@length = options[:length] || :length
|
256
|
+
@block = block
|
260
257
|
|
261
|
-
|
262
|
-
length
|
258
|
+
if `#{length} == null`
|
259
|
+
raise ArgumentError, "no length found on the array-like object"
|
260
|
+
end
|
261
|
+
end
|
263
262
|
|
264
|
-
|
265
|
-
|
263
|
+
def each(&block)
|
264
|
+
return enum_for :each unless block
|
266
265
|
|
267
|
-
|
268
|
-
|
266
|
+
%x{
|
267
|
+
for (var i = 0, length = #{length}; i < length; i++) {
|
268
|
+
var value = $opal.$yield1(block, #{self[`i`]});
|
269
269
|
|
270
|
-
|
271
|
-
|
270
|
+
if (value === $breaker) {
|
271
|
+
return $breaker.$v;
|
272
|
+
}
|
273
|
+
}
|
274
|
+
}
|
272
275
|
|
273
|
-
|
274
|
-
|
275
|
-
when String, Symbol
|
276
|
-
@named ? `#@native[#@named](#{index})` : `#@native[#{index}]`
|
276
|
+
self
|
277
|
+
end
|
277
278
|
|
278
|
-
|
279
|
-
|
280
|
-
|
279
|
+
def [](index)
|
280
|
+
result = case index
|
281
|
+
when String, Symbol
|
282
|
+
@named ? `#@native[#@named](#{index})` : `#@native[#{index}]`
|
281
283
|
|
282
|
-
|
283
|
-
|
284
|
-
@block.call(result)
|
285
|
-
else
|
286
|
-
Native(result)
|
287
|
-
end
|
288
|
-
end
|
284
|
+
when Integer
|
285
|
+
@get ? `#@native[#@get](#{index})` : `#@native[#{index}]`
|
289
286
|
end
|
290
287
|
|
291
|
-
|
292
|
-
if @
|
293
|
-
|
288
|
+
if result
|
289
|
+
if @block
|
290
|
+
@block.call(result)
|
294
291
|
else
|
295
|
-
|
292
|
+
Native(result)
|
296
293
|
end
|
297
294
|
end
|
295
|
+
end
|
298
296
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
297
|
+
def []=(index, value)
|
298
|
+
if @set
|
299
|
+
`#@native[#@set](#{index}, #{Native.convert(value)})`
|
300
|
+
else
|
301
|
+
`#@native[#{index}] = #{Native.convert(value)}`
|
302
|
+
end
|
303
|
+
end
|
303
304
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
305
|
+
def last(count = nil)
|
306
|
+
if count
|
307
|
+
index = length - 1
|
308
|
+
result = []
|
308
309
|
|
309
|
-
|
310
|
-
|
311
|
-
|
310
|
+
while index >= 0
|
311
|
+
result << self[index]
|
312
|
+
index -= 1
|
312
313
|
end
|
313
|
-
end
|
314
314
|
|
315
|
-
|
316
|
-
|
315
|
+
result
|
316
|
+
else
|
317
|
+
self[length - 1]
|
317
318
|
end
|
319
|
+
end
|
318
320
|
|
319
|
-
|
320
|
-
|
321
|
-
|
321
|
+
def length
|
322
|
+
`#@native[#@length]`
|
323
|
+
end
|
322
324
|
|
323
|
-
|
324
|
-
|
325
|
-
|
325
|
+
def to_ary
|
326
|
+
self
|
327
|
+
end
|
328
|
+
|
329
|
+
def inspect
|
330
|
+
to_a.inspect
|
326
331
|
end
|
327
332
|
end
|
328
333
|
|
@@ -479,5 +484,19 @@ class Hash
|
|
479
484
|
end
|
480
485
|
end
|
481
486
|
|
487
|
+
class Module
|
488
|
+
def native_module
|
489
|
+
`Opal.global[#{self.name}] = #{self}`
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
class Class
|
494
|
+
def native_alias(jsid, mid)
|
495
|
+
`#{self}._proto[#{jsid}] = #{self}._proto['$' + #{mid}]`
|
496
|
+
end
|
497
|
+
|
498
|
+
alias native_class native_module
|
499
|
+
end
|
500
|
+
|
482
501
|
# native global
|
483
502
|
$$ = $global = Native(`Opal.global`)
|