opal 0.3.37 → 0.3.38

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/CHANGELOG.md +11 -0
  2. data/Gemfile +0 -8
  3. data/README.md +7 -6
  4. data/bin/opal +18 -10
  5. data/config.ru +8 -21
  6. data/lib/assets/javascripts/opal-parser.js.erb +3 -60
  7. data/lib/assets/javascripts/opal/array.rb +87 -43
  8. data/lib/assets/javascripts/opal/basic_object.rb +4 -0
  9. data/lib/assets/javascripts/opal/boolean.rb +5 -3
  10. data/lib/assets/javascripts/opal/class.rb +19 -4
  11. data/lib/assets/javascripts/opal/comparable.rb +1 -1
  12. data/lib/assets/javascripts/opal/enumerable.rb +32 -0
  13. data/lib/assets/javascripts/opal/error.rb +1 -1
  14. data/lib/assets/javascripts/opal/hash.rb +166 -103
  15. data/lib/assets/javascripts/opal/json.rb +3 -2
  16. data/lib/assets/javascripts/opal/kernel.rb +9 -1
  17. data/lib/assets/javascripts/opal/native.rb +29 -0
  18. data/lib/assets/javascripts/opal/nil_class.rb +9 -1
  19. data/lib/assets/javascripts/opal/numeric.rb +6 -4
  20. data/lib/assets/javascripts/opal/parser.js +57 -0
  21. data/lib/assets/javascripts/opal/proc.rb +5 -5
  22. data/lib/assets/javascripts/opal/regexp.rb +1 -1
  23. data/lib/assets/javascripts/opal/runtime.js +13 -0
  24. data/lib/assets/javascripts/opal/string.rb +14 -3
  25. data/lib/assets/javascripts/opal/time.rb +1 -1
  26. data/lib/opal.rb +1 -1
  27. data/lib/opal/parser.rb +39 -13
  28. data/lib/opal/processor.rb +13 -2
  29. data/lib/opal/version.rb +1 -1
  30. data/opal.gemspec +3 -0
  31. data/spec/core/array/fill_spec.rb +26 -0
  32. data/spec/core/array/try_convert_spec.rb +15 -0
  33. data/spec/core/enumerable/each_slice_spec.rb +24 -0
  34. data/spec/core/enumerable/group_by_spec.rb +16 -0
  35. data/spec/core/module/const_get_spec.rb +34 -0
  36. data/spec/core/module/undef_method_spec.rb +67 -0
  37. data/spec/core/nil/to_h_spec.rb +10 -0
  38. data/spec/core/proc/element_reference_spec.rb +21 -0
  39. data/spec/{core → core_ext}/array/to_json_spec.rb +0 -0
  40. data/spec/core_ext/method_missing_spec.rb +43 -0
  41. data/spec/core_ext/native/fixtures/classes.rb +5 -0
  42. data/spec/core_ext/native/initialize_spec.rb +8 -0
  43. data/spec/core_ext/native/method_missing_spec.rb +7 -0
  44. data/spec/core_ext/native/to_native_spec.rb +7 -0
  45. data/spec/grammar/parser_spec.rb +1 -1
  46. data/spec/language/super_spec.rb +20 -0
  47. data/spec/language/variables_spec.rb +69 -0
  48. data/spec/spec_helper.rb +9 -5
  49. metadata +66 -8
  50. data/lib/assets/javascripts/opal/core.rb +0 -36
  51. 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
@@ -2,11 +2,3 @@ source :rubygems
2
2
  gemspec
3
3
 
4
4
  gem 'rake'
5
-
6
- gem 'sprockets'
7
- gem 'opal-spec', '~> 0.2.8'
8
-
9
- # for rebuilding grammar.rb from grammar.y
10
- group :grammar do
11
- gem 'racc'
12
- end
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 opal`, as above.
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
- * **opal** tests for extra methods/features in opal not found in standard ruby
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
- #! /usr/bin/env ruby
1
+ #!/usr/bin/env ruby
2
2
 
3
+ require 'optparse'
3
4
  require 'opal'
4
5
 
5
- first = ARGV.first
6
+ options = {}
7
+ parser = OptionParser.new do |opts|
8
+ opts.banner = "Usage: opal [options] file.rb"
6
9
 
7
- if first.nil?
8
- puts "Usage: opal path/to/file.rb"
9
- puts 'Usage: opal "code to compile"'
10
- elsif first == '-v' or first == '--version'
11
- puts Opal::VERSION
12
- elsif File.exist? first
13
- puts Opal.parse File.read(first)
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
- puts Opal.parse(first)
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
- html = <<HTML
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
- map '/assets' do
17
- env = Opal::Environment.new
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
- map '/' do
23
- run lambda { |env|
24
- [200, {'Content-Type' => 'text/html'}, [html]]
25
- }
26
- end
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
- //= require opal/racc
2
- //= require opal/strscan
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
- %x{
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
@@ -46,4 +46,8 @@ class BasicObject
46
46
  return result;
47
47
  }
48
48
  end
49
+
50
+ def method_missing(symbol, *args, &block)
51
+ Kernel.raise NoMethodError, "undefined method `#{symbol}' for BasicObject instance"
52
+ end
49
53
  end
@@ -1,7 +1,5 @@
1
1
  class Boolean < `Boolean`
2
- %x{
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
- %x{
233
- return #{self}._super || nil;
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
@@ -22,4 +22,4 @@ module Comparable
22
22
  def between?(min, max)
23
23
  self > min && self < max
24
24
  end
25
- end
25
+ end