opal 0.3.37 → 0.3.38
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/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
|