opal 0.3.44 → 0.4.0

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.
Files changed (109) hide show
  1. data/.travis.yml +0 -1
  2. data/CHANGELOG.md +52 -0
  3. data/README.md +3 -3
  4. data/Rakefile +32 -8
  5. data/bin/opal +69 -16
  6. data/config.ru +1 -1
  7. data/examples/native/app/app.rb +28 -9
  8. data/examples/rack/app/app.rb +1 -1
  9. data/lib/opal.rb +0 -1
  10. data/lib/opal/cli.rb +106 -0
  11. data/lib/opal/lexer.rb +4 -2
  12. data/lib/opal/parser.rb +603 -360
  13. data/lib/opal/processor.rb +20 -8
  14. data/lib/opal/server.rb +47 -0
  15. data/lib/opal/source_map.rb +63 -0
  16. data/lib/opal/sprockets_parser.rb +77 -0
  17. data/lib/opal/sprockets_source_map_header.rb +21 -0
  18. data/lib/opal/target_scope.rb +14 -7
  19. data/lib/opal/version.rb +1 -1
  20. data/opal.gemspec +2 -0
  21. data/opal/opal-browser/script_loader.rb +7 -7
  22. data/opal/opal-parser.js.erb +2 -2
  23. data/opal/opal-source-maps.js.erb +2 -0
  24. data/opal/opal.rb +3 -4
  25. data/opal/opal/array.rb +31 -28
  26. data/opal/opal/boolean.rb +4 -0
  27. data/opal/opal/class.rb +14 -5
  28. data/opal/opal/enumerable.rb +68 -8
  29. data/opal/opal/error.rb +1 -1
  30. data/opal/opal/hash.rb +15 -18
  31. data/opal/opal/kernel.rb +24 -10
  32. data/opal/opal/native.rb +31 -0
  33. data/opal/opal/nil_class.rb +7 -2
  34. data/opal/opal/numeric.rb +10 -1
  35. data/opal/opal/proc.rb +4 -0
  36. data/opal/opal/range.rb +1 -1
  37. data/opal/opal/regexp.rb +13 -3
  38. data/opal/opal/runtime.js +134 -51
  39. data/opal/opal/string.rb +45 -22
  40. data/opal/opal/time.rb +25 -7
  41. data/opal/source_map.rb +63 -0
  42. data/opal/source_map/generator.rb +251 -0
  43. data/opal/source_map/parser.rb +102 -0
  44. data/opal/source_map/vlq.rb +122 -0
  45. data/opal/strscan.rb +30 -12
  46. data/spec/opal/class/_inherited_spec.rb +1 -1
  47. data/spec/{rubyspec/core → opal}/class/bridge_class_spec.rb +5 -3
  48. data/spec/{rubyspec/core → opal}/class/extend_spec.rb +0 -0
  49. data/spec/{rubyspec/core → opal}/class/instance_methods_spec.rb +0 -0
  50. data/spec/{rubyspec/core → opal}/class/last_value_spec.rb +0 -1
  51. data/spec/{rubyspec/core → opal}/json/parse_spec.rb +0 -0
  52. data/spec/{rubyspec/core/kernel/block_given.rb → opal/kernel/block_given_spec.rb} +0 -0
  53. data/spec/{rubyspec/core → opal}/kernel/class_spec.rb +0 -0
  54. data/spec/{rubyspec/core → opal}/kernel/extend_spec.rb +0 -0
  55. data/spec/{rubyspec/core → opal}/kernel/format_spec.rb +0 -0
  56. data/spec/opal/kernel/freeze_spec.rb +15 -0
  57. data/spec/{rubyspec/core → opal}/kernel/match_spec.rb +0 -0
  58. data/spec/{rubyspec/core → opal}/kernel/method_spec.rb +0 -0
  59. data/spec/{rubyspec/core → opal}/kernel/methods_spec.rb +0 -0
  60. data/spec/{rubyspec/core → opal}/kernel/nil_spec.rb +0 -0
  61. data/spec/{rubyspec/core → opal}/kernel/p_spec.rb +0 -0
  62. data/spec/{rubyspec/core → opal}/kernel/printf_spec.rb +0 -0
  63. data/spec/{rubyspec/core → opal}/kernel/proc_spec.rb +0 -0
  64. data/spec/{rubyspec/core → opal}/kernel/rand_spec.rb +0 -0
  65. data/spec/{rubyspec/core → opal}/kernel/respond_to_spec.rb +0 -0
  66. data/spec/{rubyspec/core → opal}/kernel/sprintf_spec.rb +0 -0
  67. data/spec/{rubyspec/core → opal}/kernel/to_json_spec.rb +0 -0
  68. data/spec/{rubyspec/core → opal}/module/alias_method_spec.rb +0 -0
  69. data/spec/{rubyspec/core → opal}/module/ancestors_spec.rb +0 -0
  70. data/spec/{rubyspec/core → opal}/module/append_features_spec.rb +0 -0
  71. data/spec/{rubyspec/core → opal}/module/constants_spec.rb +0 -0
  72. data/spec/{rubyspec/core → opal}/module/module_function_spec.rb +0 -1
  73. data/spec/opal/native_spec.rb +85 -3
  74. data/spec/opal/numeric/equal_spec.rb +9 -0
  75. data/spec/opal/parser/irb_spec.rb +43 -0
  76. data/spec/{rubyspec/core → opal}/proc/proc_tricks_spec.rb +0 -0
  77. data/spec/opal/runtime/block_send_spec.rb +28 -0
  78. data/spec/{rubyspec/core/runtime → opal/runtime2}/call_spec.rb +0 -0
  79. data/spec/{rubyspec/core/runtime → opal/runtime2}/class_hierarchy_spec.rb +0 -0
  80. data/spec/{rubyspec/core/runtime → opal/runtime2}/def_spec.rb +0 -0
  81. data/spec/{rubyspec/core/runtime → opal/runtime2}/defined_spec.rb +0 -0
  82. data/spec/{rubyspec/core/runtime → opal/runtime2}/super_spec.rb +0 -0
  83. data/spec/opal/source_map_spec.rb +19 -0
  84. data/spec/opal/string/freeze_spec.rb +15 -0
  85. data/spec/{rubyspec/core → opal}/string/to_json_spec.rb +0 -0
  86. data/spec/ospec/runner.rb +3 -0
  87. data/spec/parser/str_spec.rb +4 -0
  88. data/spec/rubyspec/core/enumerable/fixtures/classes.rb +2 -2
  89. data/spec/rubyspec/core/enumerable/none_spec.rb +68 -0
  90. data/spec/rubyspec/core/enumerable/sort_by_spec.rb +31 -0
  91. data/spec/rubyspec/core/hash/size_spec.rb +1 -1
  92. data/spec/rubyspec/core/hash/to_native_spec.rb +3 -3
  93. data/spec/rubyspec/core/string/fixtures/classes.rb +49 -0
  94. data/spec/rubyspec/core/string/index_spec.rb +405 -0
  95. data/spec/rubyspec/filters/bugs/language/class.rb +0 -2
  96. data/spec/rubyspec/filters/bugs/language/module.rb +3 -0
  97. data/spec/rubyspec/language/array_spec.rb +1 -1
  98. data/spec/rubyspec/language/block_spec.rb +1 -1
  99. data/spec/rubyspec/language/module_spec.rb +5 -5
  100. data/spec/rubyspec/language/predefined_spec.rb +1 -2
  101. data/spec/rubyspec/library/stringscanner/element_reference_spec.rb +29 -0
  102. data/spec/rubyspec/spec_helper.rb +31 -0
  103. metadata +130 -76
  104. data/lib/opal/erb.rb +0 -41
  105. data/opal/erb.rb +0 -19
  106. data/spec/opal/erb/erb_spec.rb +0 -31
  107. data/spec/simple_erb_template.opalerb +0 -1
  108. data/spec/templates/foo/bar.opalerb +0 -1
  109. data/spec/templates/prefixed.opalerb +0 -1
@@ -1,4 +1,5 @@
1
1
  require 'sprockets'
2
+ require 'opal/sprockets_parser'
2
3
 
3
4
  module Opal
4
5
  # Proccess using Sprockets
@@ -13,9 +14,13 @@ module Opal
13
14
  # ruby source file to build. There are some options you can override globally
14
15
  # which effect how certain ruby features are handled:
15
16
  #
16
- # * method_missing_enabled [true by default]
17
+ # * method_missing_enabled [true by default]
17
18
  # * optimized_operators_enabled [true by default]
18
- # * arity_check_enabled [false by default]
19
+ # * arity_check_enabled [false by default]
20
+ # * const_missing_enabled [true by default]
21
+ # * dynamic_require_severity [true by default]
22
+ # * source_map_enabled [true by default]
23
+ # * irb_enabled [false by default]
19
24
  #
20
25
  class Processor < Tilt::Template
21
26
  self.default_mime_type = 'application/javascript'
@@ -30,13 +35,17 @@ module Opal
30
35
  attr_accessor :arity_check_enabled
31
36
  attr_accessor :const_missing_enabled
32
37
  attr_accessor :dynamic_require_severity
38
+ attr_accessor :source_map_enabled
39
+ attr_accessor :irb_enabled
33
40
  end
34
41
 
35
- self.method_missing_enabled = true
42
+ self.method_missing_enabled = true
36
43
  self.optimized_operators_enabled = true
37
- self.arity_check_enabled = false
38
- self.const_missing_enabled = true
39
- self.dynamic_require_severity = :error # :error, :warning or :ignore
44
+ self.arity_check_enabled = false
45
+ self.const_missing_enabled = true
46
+ self.dynamic_require_severity = :error # :error, :warning or :ignore
47
+ self.source_map_enabled = true
48
+ self.irb_enabled = false
40
49
 
41
50
  def initialize_engine
42
51
  require_template_library 'opal'
@@ -52,10 +61,13 @@ module Opal
52
61
  :arity_check => self.class.arity_check_enabled,
53
62
  :const_missing => self.class.const_missing_enabled,
54
63
  :dynamic_require_severity => self.class.dynamic_require_severity,
55
- :file => context.logical_path
64
+ :source_map_enabled => self.class.source_map_enabled,
65
+ :irb => self.class.irb_enabled,
66
+ :file => context.logical_path,
67
+ :source_file => context.pathname.to_s,
56
68
  }
57
69
 
58
- parser = Opal::Parser.new
70
+ parser = Opal::SprocketsParser.new
59
71
  result = parser.parse data, options
60
72
 
61
73
  parser.requires.each { |r| context.require_asset r }
@@ -1,4 +1,8 @@
1
1
  require 'erb'
2
+ require 'rack'
3
+ require 'rack/showexceptions'
4
+ require 'opal/sprockets_source_map_header'
5
+ require 'opal/source_map'
2
6
 
3
7
  module Opal
4
8
  class Environment < ::Sprockets::Environment
@@ -6,6 +10,39 @@ module Opal
6
10
  super
7
11
  Opal.paths.each { |p| append_path p }
8
12
  end
13
+
14
+ def use_gem gem_name
15
+ append_path File.join(Gem::Specification.find_by_name(gem_name).gem_dir, 'lib')
16
+ end
17
+ end
18
+
19
+ class SourceMapServer
20
+ def initialize sprockets
21
+ @sprockets = sprockets
22
+ end
23
+
24
+ attr_reader :sprockets
25
+
26
+ attr_writer :prefix
27
+
28
+ def prefix
29
+ @prefix ||= '/__opal_source_maps__'
30
+ end
31
+
32
+ def inspect
33
+ "#<#{self.class}:#{object_id}>"
34
+ end
35
+
36
+ def call(env)
37
+ path = env['PATH_INFO'].gsub(/^\/|\.js\.map$/, '')
38
+ asset = sprockets[path]
39
+ return [404, {}, []] if asset.nil?
40
+
41
+ source = asset.to_s
42
+ map = Opal::SourceMap.new(source, asset.pathname.to_s)
43
+
44
+ return [200, {"Content-Type" => "text/json"}, [map.to_s]]
45
+ end
9
46
  end
10
47
 
11
48
  class Server
@@ -25,16 +62,26 @@ module Opal
25
62
  @sprockets.append_path path
26
63
  end
27
64
 
65
+ def use_gem gem_name
66
+ @sprockets.use_gem gem_name
67
+ end
68
+
28
69
  def create_app
29
70
  server, sprockets = self, @sprockets
30
71
 
31
72
  @app = Rack::Builder.app do
73
+ use Rack::ShowExceptions
32
74
  map('/assets') { run sprockets }
75
+ map(server.source_maps.prefix) { run server.source_maps }
33
76
  use Index, server
34
77
  run Rack::Directory.new(server.public_dir)
35
78
  end
36
79
  end
37
80
 
81
+ def source_maps
82
+ @source_maps ||= SourceMapServer.new(@sprockets)
83
+ end
84
+
38
85
  def call(env)
39
86
  @app.call env
40
87
  end
@@ -0,0 +1,63 @@
1
+ require 'opal'
2
+ require 'source_map'
3
+
4
+ module Opal
5
+ class SourceMap
6
+ LINE_REGEXP = %r{/\*:(\d+)\*/}.freeze
7
+ FILE_REGEXP = %r{/\*-file:(.+?)-\*/}.freeze
8
+
9
+ attr_reader :generated, :file
10
+
11
+ def initialize generated, file
12
+ @generated = generated
13
+ @file = file
14
+ end
15
+
16
+ def map
17
+ @map ||= ::SourceMap.new.tap do |map|
18
+ source_file = file
19
+ generated.lines.each_with_index do |line, index|
20
+ generated_line = index+1
21
+ if line =~ FILE_REGEXP
22
+ source_file = "file://#{$1}"
23
+ map.add_mapping(
24
+ :generated_line => generated_line,
25
+ :generated_col => 0,
26
+ :source_line => 1,
27
+ :source_col => 0,
28
+ :source => source_file
29
+ )
30
+ end
31
+
32
+ pos = 0
33
+ while (pos = line.index(LINE_REGEXP, pos))
34
+ pos += $~.size
35
+ source_line = $1.to_i + 1
36
+ source_col = 0 # until column info will be available
37
+ generated_col = pos
38
+ map.add_mapping(
39
+ :generated_line => generated_line,
40
+ :generated_col => generated_col,
41
+ :source_line => source_line,
42
+ :source_col => source_col,
43
+ :source => source_file
44
+ )
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ def as_json
51
+ map.as_json
52
+ end
53
+
54
+ def to_s
55
+ map.to_s
56
+ end
57
+
58
+ def magic_comment map_path
59
+ "\n//@ sourceMappingURL=file://#{map_path}"
60
+ end
61
+ end
62
+
63
+ end
@@ -0,0 +1,77 @@
1
+ require 'opal/parser'
2
+
3
+ module Opal
4
+ class SprocketsParser < Parser
5
+
6
+ def self.parse source, options = {}
7
+ self.new.parse source, options
8
+ end
9
+
10
+ # Holds an array of paths which this file 'requires'.
11
+ # @return Array<String>
12
+ attr_reader :requires
13
+
14
+ def parse source, options = {}
15
+ @requires = []
16
+ @dynamic_require_severity = (options[:dynamic_require_severity] || :error)
17
+ super source, options
18
+ end
19
+
20
+ def process_call sexp, level
21
+ if sexp[1] == :require
22
+ return handle_require sexp[2][1]
23
+ end
24
+
25
+ super sexp, level
26
+ end
27
+
28
+ def handle_require(sexp)
29
+ str = handle_require_sexp sexp
30
+ @requires << str unless str.nil? if @requires
31
+ fragment("", sexp)
32
+ end
33
+
34
+ def handle_require_sexp(sexp)
35
+ type = sexp.shift
36
+
37
+ if type == :str
38
+ return sexp[0]
39
+ elsif type == :call
40
+ recv, meth, args = sexp
41
+ parts = args[1..-1].map { |s| handle_require_sexp s }
42
+
43
+ if recv == [:const, :File]
44
+ if meth == :expand_path
45
+ return handle_expand_path(*parts)
46
+ elsif meth == :join
47
+ return handle_expand_path parts.join("/")
48
+ elsif meth == :dirname
49
+ return handle_expand_path parts[0].split("/")[0...-1].join("/")
50
+ end
51
+ end
52
+ end
53
+
54
+
55
+ case @dynamic_require_severity
56
+ when :error
57
+ error "Cannot handle dynamic require"
58
+ when :warning
59
+ warning "Cannot handle dynamic require"
60
+ end
61
+ end
62
+
63
+ def handle_expand_path(path, base = '')
64
+ "#{base}/#{path}".split("/").inject([]) do |p, part|
65
+ if part == ''
66
+ # we had '//', so ignore
67
+ elsif part == '..'
68
+ p.pop
69
+ else
70
+ p << part
71
+ end
72
+
73
+ p
74
+ end.join "/"
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,21 @@
1
+ require 'sprockets/server'
2
+
3
+ module Sprockets
4
+ module Server
5
+
6
+ # Adds the source map header to all sprocket responses for assets
7
+ # with a .rb or .opal extension in the extension chain.
8
+ def headers_with_opal_source_maps(env, asset, length)
9
+ headers_without_opal_source_maps(env, asset, length).tap do |headers|
10
+ if asset.pathname.to_s =~ /\.(rb|opal)\b/
11
+ headers['X-SourceMap'] = '/__opal_source_maps__/'+asset.logical_path + '.map'
12
+ end
13
+ end
14
+ end
15
+
16
+ # Poor man's alias_method_chain :)
17
+ alias headers_without_opal_source_maps headers
18
+ alias headers headers_with_opal_source_maps
19
+
20
+ end
21
+ end
@@ -113,12 +113,12 @@ module Opal
113
113
  ##
114
114
  # Vars to use inside each scope
115
115
  def to_vars
116
- vars = @locals.map { |l| "#{l} = nil" }
117
- vars.push(*@temps)
116
+ vars = @temps.dup
117
+ vars.push(*@locals.map { |l| "#{l} = nil" })
118
118
  current_self = @parser.current_self
119
119
 
120
120
  iv = ivars.map do |ivar|
121
- "if (#{current_self}#{ivar} == null) #{current_self}#{ivar} = nil;\n"
121
+ "if (#{current_self}#{ivar} == null) #{current_self}#{ivar} = nil;\n"
122
122
  end
123
123
 
124
124
  indent = @parser.parser_indent
@@ -126,19 +126,26 @@ module Opal
126
126
  str = ivars.empty? ? res : "#{res}\n#{indent}#{iv.join indent}"
127
127
 
128
128
  if class? and !@proto_ivars.empty?
129
+ #raise "FIXME to_vars"
129
130
  pvars = @proto_ivars.map { |i| "#{proto}#{i}"}.join(' = ')
130
- "%s\n%s%s = nil;" % [str, indent, pvars]
131
+ result = "%s\n%s%s = nil;" % [str, indent, pvars]
131
132
  else
132
- str
133
+ result = str
133
134
  end
135
+
136
+ fragment(result)
137
+ end
138
+
139
+ def fragment(code, sexp = nil)
140
+ @parser.fragment code
134
141
  end
135
142
 
136
143
  # Generates code for this module to donate methods
137
144
  def to_donate_methods
138
145
  if should_donate? and !@methods.empty?
139
- "%s;__opal.donate(#{@name}, [%s]);" % [@parser.parser_indent, @methods.map(&:inspect).join(', ')]
146
+ fragment("%s;__opal.donate(#{@name}, [%s]);" % [@parser.parser_indent, @methods.map(&:inspect).join(', ')])
140
147
  else
141
- ""
148
+ fragment("")
142
149
  end
143
150
  end
144
151
 
@@ -1,3 +1,3 @@
1
1
  module Opal
2
- VERSION = '0.3.44'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -17,6 +17,8 @@ Gem::Specification.new do |s|
17
17
  s.add_dependency 'rake'
18
18
  s.add_dependency 'racc'
19
19
  s.add_dependency 'sprockets'
20
+ s.add_dependency 'source_map'
20
21
 
21
22
  s.add_development_dependency 'mspec', '1.5.18'
23
+ s.add_development_dependency 'uglifier'
22
24
  end
@@ -2,10 +2,10 @@ class BrowserScriptLoader
2
2
  def run
3
3
  handler = proc { find_scripts }
4
4
 
5
- if $window.respond_to? :addEventListener
6
- $window.addEventListener 'DOMContentLoaded', handler, false
7
- else
8
- $window.attachEvent 'onload', handler
5
+ if $global.respond_to? :addEventListener
6
+ $global.addEventListener 'DOMContentLoaded', handler, false
7
+ elsif @global.respond_to? :attachEvent
8
+ $global.attachEvent 'onload', handler
9
9
  end
10
10
  end
11
11
 
@@ -20,16 +20,16 @@ class BrowserScriptLoader
20
20
  end
21
21
 
22
22
  def ruby_scripts
23
- $document.getElementsByTagName('script').to_a.select { |s|
23
+ $global.document.getElementsByTagName('script').to_a.select { |s|
24
24
  s.type == "text/ruby" }
25
25
  end
26
26
 
27
27
  def run_ruby str
28
- $window.Opal.eval str
28
+ $global.Opal.eval str
29
29
  end
30
30
  end
31
31
 
32
- if $window and $document
32
+ if $global.respond_to? :document
33
33
  BrowserScriptLoader.new.run
34
34
  end
35
35
 
@@ -3,8 +3,8 @@
3
3
  <% require_asset 'strscan' %>
4
4
 
5
5
  // We need (some) of the libs from our real ruby parser (not in sprockets load path)
6
- <% %w(opal/grammar opal/lexer opal/parser opal/target_scope opal/core_ext opal/lexer_scope opal/grammar_helpers opal/parser opal).each do |f| %>
7
- <%= Opal.parse File.read(File.join Opal.core_dir, '..', 'lib', "#{f}.rb") %>
6
+ <% %w(opal/version opal/grammar opal/lexer opal/parser opal/target_scope opal/core_ext opal/lexer_scope opal/grammar_helpers opal/parser opal).each do |f| %>
7
+ <%= Opal::SprocketsParser.parse File.read(File.join Opal.core_dir, '..', 'lib', "#{f}.rb") %>
8
8
  <% end %>
9
9
 
10
10
  Opal.eval = function(str) {
@@ -0,0 +1,2 @@
1
+ <% require_asset 'source_map' %>
2
+ <%= Opal::SprocketsParser.parse File.read(File.join Opal.core_dir, '..', 'lib', "opal/source_map.rb") %>
@@ -17,6 +17,7 @@ require 'opal/proc'
17
17
  require 'opal/range'
18
18
  require 'opal/time'
19
19
  require 'opal/json'
20
+ require 'opal/native'
20
21
 
21
22
  # regexp matches
22
23
  $& = $~ = $` = $' = nil
@@ -27,10 +28,8 @@ $: = []
27
28
  # split lines
28
29
  $/ = "\n"
29
30
 
30
- # native globals
31
- $global = `Opal.global`
32
- $window = $global
33
- $document = $window.document
31
+ # native global
32
+ $$ = $global = `Opal.global`
34
33
 
35
34
  ARGV = []
36
35
  ARGF = Object.new
@@ -165,22 +165,22 @@ class Array
165
165
  for (var i = 0, length = #{self}.length, tmp1, tmp2; i < length; i++) {
166
166
  tmp1 = #{self}[i];
167
167
  tmp2 = #{other}[i];
168
-
168
+
169
169
  //recursive
170
- if ((typeof(tmp1.indexOf) == "function") &&
171
- (typeof(tmp2.indexOf) == "function") &&
170
+ if (tmp1 && (typeof(tmp1.indexOf) == "function") &&
171
+ (typeof(tmp2.indexOf) == "function") && tmp2 &&
172
172
  (tmp1.indexOf(tmp2) == tmp2.indexOf(tmp1))) {
173
173
  if (tmp1.indexOf(tmp1) == tmp2.indexOf(tmp2)) {
174
174
  continue;
175
175
  }
176
176
  }
177
-
177
+
178
178
  if (!#{`#{self}[i]` == `other[i]`}) {
179
179
  return false;
180
180
  }
181
-
181
+
182
182
  }
183
-
183
+
184
184
 
185
185
  return true;
186
186
  }
@@ -285,6 +285,7 @@ class Array
285
285
  %x{
286
286
  var result = [];
287
287
 
288
+
288
289
  for (var i = 0, length = #{self}.length, value; i < length; i++) {
289
290
  if ((value = block(#{self}[i])) === __breaker) {
290
291
  return __breaker.$v;
@@ -667,20 +668,20 @@ class Array
667
668
  def last(count = undefined)
668
669
  %x{
669
670
  var length = #{self}.length;
670
-
671
- if (count === nil || typeof(count) == 'string') {
671
+
672
+ if (count === nil || typeof(count) == 'string') {
672
673
  #{ raise TypeError, "no implicit conversion to integer" };
673
674
  }
674
-
675
+
675
676
  if (typeof(count) == 'object') {
676
677
  if (typeof(count['$to_int']) == 'function') {
677
678
  count = count['$to_int']();
678
- }
679
+ }
679
680
  else {
680
681
  #{ raise TypeError, "no implicit conversion to integer" };
681
682
  }
682
683
  }
683
-
684
+
684
685
  if (count == null) {
685
686
  return length === 0 ? nil : #{self}[length - 1];
686
687
  }
@@ -783,7 +784,9 @@ class Array
783
784
  `#{self}.slice(0).reverse()`
784
785
  end
785
786
 
786
- alias_native :reverse!, :reverse
787
+ def reverse!
788
+ `#{self}.reverse()`
789
+ end
787
790
 
788
791
  def reverse_each(&block)
789
792
  reverse.each &block
@@ -856,7 +859,7 @@ class Array
856
859
 
857
860
  alias size length
858
861
 
859
- def shuffle()
862
+ def shuffle
860
863
  %x{
861
864
  for (var i = #{self}.length - 1; i > 0; i--) {
862
865
  var j = Math.floor(Math.random() * (i + 1));
@@ -894,7 +897,7 @@ class Array
894
897
  var copy = #{self}.slice();
895
898
  var t_arg_error = false;
896
899
  var t_break = [];
897
-
900
+
898
901
  if (block !== nil) {
899
902
  var result = copy.sort(function(x, y) {
900
903
  var result = block(x, y);
@@ -902,12 +905,12 @@ class Array
902
905
  t_break.push(__breaker.$v);
903
906
  }
904
907
  if (result === nil) {
905
- t_arg_error = true;
908
+ t_arg_error = true;
906
909
  }
907
- if (result['$<=>'] && typeof(result['$<=>']) == "function") {
910
+ if ((result != null) && result['$<=>'] && typeof(result['$<=>']) == "function") {
908
911
  result = result['$<=>'](0);
909
912
  }
910
- if ([-1, 0, 1].indexOf(result) == -1) {
913
+ if (result !== -1 && result !== 0 && result !== 1) {
911
914
  t_arg_error = true;
912
915
  }
913
916
  return result;
@@ -920,26 +923,26 @@ class Array
920
923
 
921
924
  return result;
922
925
  }
923
-
924
- var result = copy.sort(function(a, b){
926
+
927
+ var result = copy.sort(function(a, b){
925
928
  if (typeof(a) !== typeof(b)) {
926
929
  t_arg_error = true;
927
930
  }
928
-
931
+
929
932
  if (a['$<=>'] && typeof(a['$<=>']) == "function") {
930
933
  var result = a['$<=>'](b);
931
934
  if (result === nil) {
932
935
  t_arg_error = true;
933
- }
934
- return result;
935
- }
936
+ }
937
+ return result;
938
+ }
936
939
  if (a > b)
937
940
  return 1;
938
941
  if (a < b)
939
942
  return -1;
940
- return 0;
943
+ return 0;
941
944
  });
942
-
945
+
943
946
  if (t_arg_error)
944
947
  #{raise ArgumentError, "Array#sort"};
945
948
 
@@ -1008,15 +1011,15 @@ class Array
1008
1011
  }
1009
1012
  end
1010
1013
 
1011
- def to_native
1014
+ def to_n
1012
1015
  %x{
1013
1016
  var result = [], obj
1014
1017
 
1015
1018
  for (var i = 0, len = #{self}.length; i < len; i++) {
1016
1019
  obj = #{self}[i];
1017
1020
 
1018
- if (obj.$to_native) {
1019
- result.push(#{ `obj`.to_native });
1021
+ if (obj.$to_n) {
1022
+ result.push(#{ `obj`.to_n });
1020
1023
  }
1021
1024
  else {
1022
1025
  result.push(obj);