opal 0.3.37 → 0.3.38
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +11 -0
- data/Gemfile +0 -8
- data/README.md +7 -6
- data/bin/opal +18 -10
- data/config.ru +8 -21
- data/lib/assets/javascripts/opal-parser.js.erb +3 -60
- data/lib/assets/javascripts/opal/array.rb +87 -43
- data/lib/assets/javascripts/opal/basic_object.rb +4 -0
- data/lib/assets/javascripts/opal/boolean.rb +5 -3
- data/lib/assets/javascripts/opal/class.rb +19 -4
- data/lib/assets/javascripts/opal/comparable.rb +1 -1
- data/lib/assets/javascripts/opal/enumerable.rb +32 -0
- data/lib/assets/javascripts/opal/error.rb +1 -1
- data/lib/assets/javascripts/opal/hash.rb +166 -103
- data/lib/assets/javascripts/opal/json.rb +3 -2
- data/lib/assets/javascripts/opal/kernel.rb +9 -1
- data/lib/assets/javascripts/opal/native.rb +29 -0
- data/lib/assets/javascripts/opal/nil_class.rb +9 -1
- data/lib/assets/javascripts/opal/numeric.rb +6 -4
- data/lib/assets/javascripts/opal/parser.js +57 -0
- data/lib/assets/javascripts/opal/proc.rb +5 -5
- data/lib/assets/javascripts/opal/regexp.rb +1 -1
- data/lib/assets/javascripts/opal/runtime.js +13 -0
- data/lib/assets/javascripts/opal/string.rb +14 -3
- data/lib/assets/javascripts/opal/time.rb +1 -1
- data/lib/opal.rb +1 -1
- data/lib/opal/parser.rb +39 -13
- data/lib/opal/processor.rb +13 -2
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +3 -0
- data/spec/core/array/fill_spec.rb +26 -0
- data/spec/core/array/try_convert_spec.rb +15 -0
- data/spec/core/enumerable/each_slice_spec.rb +24 -0
- data/spec/core/enumerable/group_by_spec.rb +16 -0
- data/spec/core/module/const_get_spec.rb +34 -0
- data/spec/core/module/undef_method_spec.rb +67 -0
- data/spec/core/nil/to_h_spec.rb +10 -0
- data/spec/core/proc/element_reference_spec.rb +21 -0
- data/spec/{core → core_ext}/array/to_json_spec.rb +0 -0
- data/spec/core_ext/method_missing_spec.rb +43 -0
- data/spec/core_ext/native/fixtures/classes.rb +5 -0
- data/spec/core_ext/native/initialize_spec.rb +8 -0
- data/spec/core_ext/native/method_missing_spec.rb +7 -0
- data/spec/core_ext/native/to_native_spec.rb +7 -0
- data/spec/grammar/parser_spec.rb +1 -1
- data/spec/language/super_spec.rb +20 -0
- data/spec/language/variables_spec.rb +69 -0
- data/spec/spec_helper.rb +9 -5
- metadata +66 -8
- data/lib/assets/javascripts/opal/core.rb +0 -36
- data/spec/autorun.rb +0 -3
data/CHANGELOG.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
## Edge ##
|
2
|
+
|
3
|
+
* Add Native module used for wrapping objects to forward calls as native
|
4
|
+
calls.
|
5
|
+
|
6
|
+
* Support method_missing for all objects. Feature can be enabled/disabled on
|
7
|
+
Opal::Processor.
|
8
|
+
|
9
|
+
* Hash can now use any ruby object as a key.
|
10
|
+
|
11
|
+
* Move to Sprockets based building via `Opal::Processor`.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -14,11 +14,13 @@ See the website, [http://opalrb.org](http://opalrb.org).
|
|
14
14
|
|
15
15
|
## Running tests
|
16
16
|
|
17
|
+
First, install dependencies:
|
18
|
+
|
19
|
+
$ bundle install
|
20
|
+
|
17
21
|
Tests can be run with phantomjs using:
|
18
22
|
|
19
|
-
|
20
|
-
$ rake
|
21
|
-
```
|
23
|
+
$ rake
|
22
24
|
|
23
25
|
Alternatively, you can just load up a rack instance using `rackup`, and
|
24
26
|
visit `http://localhost:9292/` in any web browser.
|
@@ -34,14 +36,13 @@ to allow compilation in any javascript environment.
|
|
34
36
|
### lib/assets/javascripts
|
35
37
|
|
36
38
|
This directory holds the opal runtime and corelib implemented in ruby and
|
37
|
-
javascript. These are built using `rake
|
39
|
+
javascript. These are built using `rake`, as above.
|
38
40
|
|
39
41
|
### spec
|
40
42
|
|
41
43
|
* **core** contains rubyspecs that apply to opal.
|
42
44
|
* **language** applicable specs from rubyspec for testing language semantics
|
43
|
-
* **
|
44
|
-
* **lib** specs for opal lib (parser, lexer, grammar etc)
|
45
|
+
* **grammar** specs for opal lib (parser, lexer, grammar etc)
|
45
46
|
|
46
47
|
## License
|
47
48
|
|
data/bin/opal
CHANGED
@@ -1,16 +1,24 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
require 'optparse'
|
3
4
|
require 'opal'
|
4
5
|
|
5
|
-
|
6
|
+
options = {}
|
7
|
+
parser = OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: opal [options] file.rb"
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
opts.on("-v", "--version", "Opal Version") do |v|
|
11
|
+
puts Opal::VERSION
|
12
|
+
exit
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
parser.parse!
|
17
|
+
|
18
|
+
if ARGV.empty?
|
19
|
+
puts parser.banner
|
14
20
|
else
|
15
|
-
|
21
|
+
src = ARGV.first
|
22
|
+
src = File.read src if File.exist? src
|
23
|
+
puts Opal.parse(src)
|
16
24
|
end
|
data/config.ru
CHANGED
@@ -1,26 +1,13 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
Bundler.require
|
3
3
|
|
4
|
-
|
5
|
-
<!DOCTYPE html>
|
6
|
-
<html>
|
7
|
-
<head>
|
8
|
-
<title>Opal corelib and runtime specs</title>
|
9
|
-
</head>
|
10
|
-
<body>
|
11
|
-
<script type="text/javascript" src="/assets/autorun.js"></script>
|
12
|
-
</body>
|
13
|
-
</html>
|
14
|
-
HTML
|
4
|
+
require 'opal/spec/server'
|
15
5
|
|
16
|
-
|
17
|
-
|
18
|
-
env.append_path 'spec'
|
19
|
-
run env
|
20
|
-
end
|
6
|
+
# method_missing can be turned off if required (on by default)
|
7
|
+
# Opal::Processor.method_missing_enabled = false
|
21
8
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
9
|
+
# Run in non-debug mode (faster, all files concatenated into 1 file)
|
10
|
+
run Opal::Spec::Server.new(false)
|
11
|
+
|
12
|
+
# Run in debug mode - all files loaded seperately, but slower
|
13
|
+
# run Opal::Spec::Server.new
|
@@ -1,65 +1,8 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
<% require_asset 'opal/racc' %>
|
2
|
+
<% require_asset 'opal/strscan' %>
|
3
|
+
<% require_asset 'opal/parser' %>
|
3
4
|
|
4
5
|
// We need (some) of the libs from our real ruby parser (not in sprockets load path)
|
5
6
|
<% ['/grammar', '/lexer', '/parser', '/scope', ''].each do |f| %>
|
6
7
|
<%= Opal.parse File.read(File.join Opal.core_dir, '..', '..', "opal#{f}.rb") %>
|
7
8
|
<% end %>
|
8
|
-
|
9
|
-
(function() {
|
10
|
-
// quick exit if not insde browser
|
11
|
-
if (typeof(window) === 'undefined' || typeof(document) === 'undefined') {
|
12
|
-
return;
|
13
|
-
}
|
14
|
-
|
15
|
-
function findRubyScripts() {
|
16
|
-
var all = document.getElementsByTagName('script');
|
17
|
-
for (var i = 0, script; i < all.length; i++) {
|
18
|
-
script = all[i];
|
19
|
-
if (script.type === 'text/ruby') {
|
20
|
-
if (script.src) {
|
21
|
-
request(script.src, function(result) {
|
22
|
-
runRuby(result);
|
23
|
-
});
|
24
|
-
}
|
25
|
-
else {
|
26
|
-
runRuby(script.innerHTML);
|
27
|
-
}
|
28
|
-
}
|
29
|
-
else if (script.type === 'text/erb') {
|
30
|
-
runERB(script.innerHTML);
|
31
|
-
}
|
32
|
-
}
|
33
|
-
}
|
34
|
-
|
35
|
-
function runRuby(source) {
|
36
|
-
var js = Opal.Opal.Parser.$new().$parse(source);
|
37
|
-
eval('(' + js + ')()');
|
38
|
-
}
|
39
|
-
|
40
|
-
function request(url, callback) {
|
41
|
-
var xhr = new (window.ActiveXObject || XMLHttpRequest)('Microsoft.XMLHTTP');
|
42
|
-
xhr.open('GET', url, true);
|
43
|
-
if ('overrideMimeType' in xhr) {
|
44
|
-
xhr.overrideMimeType('text/plain');
|
45
|
-
}
|
46
|
-
xhr.onreadystatechange = function() {
|
47
|
-
if (xhr.readyState === 4) {
|
48
|
-
if (xhr.status === 0 || xhr.status === 200) {
|
49
|
-
callback(xhr.responseText);
|
50
|
-
}
|
51
|
-
else {
|
52
|
-
throw new Error('Could not load ruby at: ' + url);
|
53
|
-
}
|
54
|
-
}
|
55
|
-
};
|
56
|
-
xhr.send(null);
|
57
|
-
}
|
58
|
-
|
59
|
-
if (window.addEventListener) {
|
60
|
-
window.addEventListener('DOMContentLoaded', findRubyScripts, false);
|
61
|
-
}
|
62
|
-
else {
|
63
|
-
window.attachEvent('onload', findRubyScripts);
|
64
|
-
}
|
65
|
-
})();
|
@@ -1,14 +1,11 @@
|
|
1
1
|
class Array < `Array`
|
2
|
-
%x{
|
3
|
-
Array.prototype._isArray = true;
|
4
|
-
}
|
5
|
-
|
6
2
|
include Enumerable
|
7
3
|
|
4
|
+
# Mark all javascript arrays as being valid ruby arrays
|
5
|
+
`def._isArray = true`
|
6
|
+
|
8
7
|
def self.[](*objects)
|
9
|
-
|
10
|
-
return objects;
|
11
|
-
}
|
8
|
+
objects
|
12
9
|
end
|
13
10
|
|
14
11
|
def self.new(size, obj = nil, &block)
|
@@ -37,6 +34,16 @@ class Array < `Array`
|
|
37
34
|
}
|
38
35
|
end
|
39
36
|
|
37
|
+
def self.try_convert(obj)
|
38
|
+
%x{
|
39
|
+
if (obj._isArray) {
|
40
|
+
return obj;
|
41
|
+
}
|
42
|
+
|
43
|
+
return nil;
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
40
47
|
def &(other)
|
41
48
|
%x{
|
42
49
|
var result = [],
|
@@ -416,6 +423,23 @@ class Array < `Array`
|
|
416
423
|
}
|
417
424
|
end
|
418
425
|
|
426
|
+
def fill(obj = undefined, &block)
|
427
|
+
%x{
|
428
|
+
if (block !== nil) {
|
429
|
+
for (var i = 0, length = #{self}.length; i < length; i++) {
|
430
|
+
#{self}[i] = block(i);
|
431
|
+
}
|
432
|
+
}
|
433
|
+
else {
|
434
|
+
for (var i = 0, length = #{self}.length; i < length; i++) {
|
435
|
+
#{self}[i] = obj;
|
436
|
+
}
|
437
|
+
}
|
438
|
+
}
|
439
|
+
|
440
|
+
self
|
441
|
+
end
|
442
|
+
|
419
443
|
def first(count)
|
420
444
|
%x{
|
421
445
|
if (count != null) {
|
@@ -760,6 +784,19 @@ class Array < `Array`
|
|
760
784
|
|
761
785
|
alias size length
|
762
786
|
|
787
|
+
def shuffle()
|
788
|
+
%x{
|
789
|
+
for (var i = #{self}.length - 1; i > 0; i--) {
|
790
|
+
var j = Math.floor(Math.random() * (i + 1));
|
791
|
+
var tmp = #{self}[i];
|
792
|
+
#{self}[i] = #{self}[j];
|
793
|
+
#{self}[j] = tmp;
|
794
|
+
}
|
795
|
+
|
796
|
+
return #{self};
|
797
|
+
}
|
798
|
+
end
|
799
|
+
|
763
800
|
alias slice :[]
|
764
801
|
|
765
802
|
def slice!(index, length)
|
@@ -780,6 +817,28 @@ class Array < `Array`
|
|
780
817
|
}
|
781
818
|
end
|
782
819
|
|
820
|
+
def sort(&block)
|
821
|
+
%x{
|
822
|
+
var copy = #{self}.slice();
|
823
|
+
|
824
|
+
if (block !== nil) {
|
825
|
+
return copy.sort(block);
|
826
|
+
}
|
827
|
+
|
828
|
+
return copy.sort();
|
829
|
+
}
|
830
|
+
end
|
831
|
+
|
832
|
+
def sort!(&block)
|
833
|
+
%x{
|
834
|
+
if (block !== nil) {
|
835
|
+
return #{self}.sort(block);
|
836
|
+
}
|
837
|
+
|
838
|
+
return #{self}.sort();
|
839
|
+
}
|
840
|
+
end
|
841
|
+
|
783
842
|
def take(count)
|
784
843
|
`#{self}.slice(0, count)`
|
785
844
|
end
|
@@ -824,6 +883,26 @@ class Array < `Array`
|
|
824
883
|
}
|
825
884
|
end
|
826
885
|
|
886
|
+
def to_native
|
887
|
+
%x{
|
888
|
+
var result = [], obj
|
889
|
+
|
890
|
+
for (var i = 0, len = #{self}.length; i < len; i++) {
|
891
|
+
obj = #{self}[i];
|
892
|
+
|
893
|
+
if (obj.$to_native) {
|
894
|
+
result.push(#{ `obj`.to_native });
|
895
|
+
}
|
896
|
+
else {
|
897
|
+
result.push(obj);
|
898
|
+
}
|
899
|
+
}
|
900
|
+
|
901
|
+
return result;
|
902
|
+
}
|
903
|
+
end
|
904
|
+
|
905
|
+
|
827
906
|
alias to_s inspect
|
828
907
|
|
829
908
|
def uniq
|
@@ -911,39 +990,4 @@ class Array < `Array`
|
|
911
990
|
return result;
|
912
991
|
}
|
913
992
|
end
|
914
|
-
|
915
|
-
def sort(&block)
|
916
|
-
%x{
|
917
|
-
var copy = #{self}.slice();
|
918
|
-
|
919
|
-
if (block !== nil) {
|
920
|
-
return copy.sort(block);
|
921
|
-
}
|
922
|
-
|
923
|
-
return copy.sort();
|
924
|
-
}
|
925
|
-
end
|
926
|
-
|
927
|
-
def sort!(&block)
|
928
|
-
%x{
|
929
|
-
if (block !== nil) {
|
930
|
-
return #{self}.sort(block);
|
931
|
-
}
|
932
|
-
|
933
|
-
return #{self}.sort();
|
934
|
-
}
|
935
|
-
end
|
936
|
-
|
937
|
-
def shuffle()
|
938
|
-
%x{
|
939
|
-
for (var i = #{self}.length - 1; i > 0; i--) {
|
940
|
-
var j = Math.floor(Math.random() * (i + 1));
|
941
|
-
var tmp = #{self}[i];
|
942
|
-
#{self}[i] = #{self}[j];
|
943
|
-
#{self}[j] = tmp;
|
944
|
-
}
|
945
|
-
|
946
|
-
return #{self};
|
947
|
-
}
|
948
|
-
end
|
949
|
-
end
|
993
|
+
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
class Boolean < `Boolean`
|
2
|
-
|
3
|
-
Boolean.prototype._isBoolean = true;
|
4
|
-
}
|
2
|
+
`def._isBoolean = true`
|
5
3
|
|
6
4
|
def &(other)
|
7
5
|
`(#{self} == true) ? (other !== false && other !== nil) : false`
|
@@ -19,6 +17,10 @@ class Boolean < `Boolean`
|
|
19
17
|
`(#{self} == true) === other.valueOf()`
|
20
18
|
end
|
21
19
|
|
20
|
+
def as_json
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
22
24
|
alias singleton_class class
|
23
25
|
|
24
26
|
def to_json
|
@@ -128,6 +128,18 @@ class Class
|
|
128
128
|
|
129
129
|
alias attr attr_accessor
|
130
130
|
|
131
|
+
def const_get(name)
|
132
|
+
%x{
|
133
|
+
var result = #{self}._scope[name];
|
134
|
+
|
135
|
+
if (result == null) {
|
136
|
+
#{ raise NameError, "uninitialized constant #{name}" }
|
137
|
+
}
|
138
|
+
|
139
|
+
return result;
|
140
|
+
}
|
141
|
+
end
|
142
|
+
|
131
143
|
def define_method(name, &block)
|
132
144
|
%x{
|
133
145
|
if (block === nil) {
|
@@ -229,8 +241,11 @@ class Class
|
|
229
241
|
alias protected public
|
230
242
|
|
231
243
|
def superclass
|
232
|
-
|
233
|
-
|
234
|
-
|
244
|
+
`#{self}._super || nil`
|
245
|
+
end
|
246
|
+
|
247
|
+
def undef_method(symbol)
|
248
|
+
`#{self}.prototype['$' + symbol] = undefined`
|
249
|
+
self
|
235
250
|
end
|
236
|
-
end
|
251
|
+
end
|