opal 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.gitmodules +27 -3
- data/.rspec +1 -1
- data/CHANGELOG.md +29 -5
- data/README.md +30 -3
- data/Rakefile +18 -9
- data/bin/opal +1 -1
- data/bin/opal-build +70 -7
- data/lib/mspec/opal/rake_task.rb +6 -9
- data/lib/opal/cli.rb +2 -2
- data/lib/opal/nodes/call.rb +1 -1
- data/lib/opal/nodes/def.rb +1 -1
- data/lib/opal/nodes/rescue.rb +19 -18
- data/lib/opal/parser/grammar.rb +8 -3
- data/lib/opal/parser/grammar.y +4 -0
- data/lib/opal/parser/lexer.rb +10 -5
- data/lib/opal/sprockets/environment.rb +9 -0
- data/lib/opal/sprockets/erb.rb +9 -1
- data/lib/opal/sprockets/processor.rb +10 -14
- data/lib/opal/util.rb +50 -15
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +4 -4
- data/opal/corelib/enumerable.rb +1 -1
- data/opal/corelib/enumerator.rb +7 -3
- data/opal/corelib/hash.rb +38 -14
- data/opal/corelib/kernel.rb +6 -2
- data/opal/corelib/module.rb +15 -1
- data/opal/corelib/runtime.js +32 -2
- data/opal/corelib/string.rb +103 -53
- data/opal/corelib/variables.rb +3 -3
- data/spec/cli/fixtures/sprockets_file.js.rb +3 -0
- data/spec/cli/parser/literal_spec.rb +5 -0
- data/spec/cli/sprockets/environment_spec.rb +14 -0
- data/spec/cli/sprockets/erb_spec.rb +25 -0
- data/spec/cli/sprockets/processor_spec.rb +28 -0
- data/spec/{opal/filters → filters}/bugs/array.rb +29 -9
- data/spec/{opal/filters → filters}/bugs/basic_object.rb +2 -0
- data/spec/{opal/filters → filters}/bugs/class.rb +1 -0
- data/spec/{opal/filters → filters}/bugs/enumerable.rb +6 -2
- data/spec/filters/bugs/enumerator.rb +3 -0
- data/spec/{opal/filters → filters}/bugs/hash.rb +6 -24
- data/spec/{opal/filters → filters}/bugs/kernel.rb +0 -0
- data/spec/{opal/filters → filters}/bugs/language.rb +14 -3
- data/spec/{opal/filters → filters}/bugs/math.rb +3 -1
- data/spec/{opal/filters → filters}/bugs/module.rb +0 -0
- data/spec/{opal/filters → filters}/bugs/nil.rb +0 -0
- data/spec/{opal/filters → filters}/bugs/numeric.rb +1 -1
- data/spec/{opal/filters → filters}/bugs/opal.rb +0 -0
- data/spec/filters/bugs/regexp.rb +7 -0
- data/spec/{opal/filters → filters}/bugs/set.rb +0 -0
- data/spec/{opal/filters → filters}/bugs/singleton.rb +0 -0
- data/spec/{opal/filters → filters}/bugs/string.rb +40 -13
- data/spec/{opal/filters → filters}/bugs/stringscanner.rb +1 -0
- data/spec/{opal/filters → filters}/bugs/struct.rb +7 -2
- data/spec/{opal/filters → filters}/bugs/symbol.rb +0 -0
- data/spec/{opal/filters → filters}/bugs/time.rb +23 -0
- data/spec/{opal/filters → filters}/bugs/unknown.rb +0 -0
- data/spec/{opal/filters → filters}/unsupported/encoding.rb +34 -1
- data/spec/{opal/filters → filters}/unsupported/enumerator.rb +1 -0
- data/spec/{opal/filters → filters}/unsupported/float.rb +0 -0
- data/spec/{opal/filters → filters}/unsupported/frozen.rb +3 -2
- data/spec/{opal/filters → filters}/unsupported/hash_compare_by_identity.rb +0 -0
- data/spec/{opal/filters → filters}/unsupported/integer_size.rb +0 -0
- data/spec/{opal/filters → filters}/unsupported/method_added.rb +0 -0
- data/spec/{opal/filters → filters}/unsupported/mutable_strings.rb +14 -0
- data/spec/{opal/filters → filters}/unsupported/private_constants.rb +0 -0
- data/spec/{opal/filters → filters}/unsupported/private_methods.rb +0 -0
- data/spec/{opal/filters → filters}/unsupported/random.rb +0 -0
- data/spec/{opal/filters → filters}/unsupported/ruby_exe.rb +0 -0
- data/spec/{opal/filters → filters}/unsupported/tainted.rb +11 -0
- data/spec/{opal/filters → filters}/unsupported/time.rb +0 -0
- data/spec/{opal/filters → filters}/unsupported/trusted.rb +14 -0
- data/spec/opal/core/kernel/methods_spec.rb +16 -2
- data/spec/opal/core/language/string_spec.rb +29 -1
- data/spec/opal/core/module/remove_const_spec.rb +1 -1
- data/spec/opal/stdlib/erb/erb_spec.rb +3 -3
- data/spec/opal/stdlib/native/native_reader_spec.rb +22 -0
- data/spec/opal/stdlib/native/native_writer_spec.rb +30 -0
- data/spec/rubyspecs +285 -0
- data/spec/{opal/spec_helper.rb → spec_helper.rb} +0 -0
- data/stdlib/native.rb +21 -0
- data/stdlib/opal-parser.rb +14 -3
- data/stdlib/promise.rb +2 -2
- metadata +113 -97
- data/spec/opal/filters/bugs/regexp.rb +0 -5
- data/spec/opal/rubyspecs +0 -285
data/lib/opal/parser/grammar.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# DO NOT MODIFY!!!!
|
3
|
-
# This file is automatically generated by Racc 1.4.
|
3
|
+
# This file is automatically generated by Racc 1.4.11
|
4
4
|
# from Racc grammer file "".
|
5
5
|
#
|
6
6
|
|
@@ -2217,7 +2217,7 @@ racc_reduce_table = [
|
|
2217
2217
|
3, 192, :_reduce_256,
|
2218
2218
|
4, 192, :_reduce_257,
|
2219
2219
|
3, 162, :_reduce_258,
|
2220
|
-
4, 162, :
|
2220
|
+
4, 162, :_reduce_259,
|
2221
2221
|
2, 162, :_reduce_260,
|
2222
2222
|
1, 190, :_reduce_none,
|
2223
2223
|
1, 190, :_reduce_none,
|
@@ -4004,7 +4004,12 @@ def _reduce_258(val, _values, result)
|
|
4004
4004
|
result
|
4005
4005
|
end
|
4006
4006
|
|
4007
|
-
|
4007
|
+
def _reduce_259(val, _values, result)
|
4008
|
+
val[0] << s(:splat, val[3])
|
4009
|
+
result = s(:array, *val[0])
|
4010
|
+
|
4011
|
+
result
|
4012
|
+
end
|
4008
4013
|
|
4009
4014
|
def _reduce_260(val, _values, result)
|
4010
4015
|
result = s(:splat, val[1])
|
data/lib/opal/parser/grammar.y
CHANGED
data/lib/opal/parser/lexer.rb
CHANGED
@@ -241,6 +241,9 @@ module Opal
|
|
241
241
|
eos_regx = /[ \t]*#{Regexp.escape(str_parse[:term])}(\r*\n|$)/
|
242
242
|
expand = true
|
243
243
|
|
244
|
+
# Don't escape single-quoted heredoc identifiers
|
245
|
+
escape = str_parse[:func] != STR_SQUOTE
|
246
|
+
|
244
247
|
if check(eos_regx)
|
245
248
|
scan(/[ \t]*#{Regexp.escape(str_parse[:term])}/)
|
246
249
|
|
@@ -272,7 +275,7 @@ module Opal
|
|
272
275
|
elsif expand && check(/#(?=[\$\@\{])/)
|
273
276
|
break
|
274
277
|
elsif scan(/\\/)
|
275
|
-
str_buffer << self.read_escape
|
278
|
+
str_buffer << (escape ? self.read_escape : scanner.matched)
|
276
279
|
else
|
277
280
|
reg = Regexp.new("[^\#\0\\\\\n]+|.")
|
278
281
|
|
@@ -471,9 +474,11 @@ module Opal
|
|
471
474
|
end
|
472
475
|
|
473
476
|
def heredoc_identifier
|
474
|
-
if scan(/(-?)['"]?(\w+)
|
475
|
-
|
476
|
-
|
477
|
+
if scan(/(-?)(['"])?(\w+)\2?/)
|
478
|
+
escape_method = (@scanner[2] == "'") ? STR_SQUOTE : STR_DQUOTE
|
479
|
+
heredoc = @scanner[3]
|
480
|
+
|
481
|
+
self.strterm = new_strterm(escape_method, heredoc, heredoc)
|
477
482
|
self.strterm[:type] = :heredoc
|
478
483
|
|
479
484
|
# if ruby code at end of line after heredoc, we have to store it to
|
@@ -510,7 +515,7 @@ module Opal
|
|
510
515
|
result = :tIDENTIFIER
|
511
516
|
else
|
512
517
|
if @lex_state == :expr_fname
|
513
|
-
if scan(/\=/)
|
518
|
+
if !check(/\=\>/) and scan(/\=/)
|
514
519
|
result = :tIDENTIFIER
|
515
520
|
matched += scanner.matched
|
516
521
|
end
|
@@ -1,6 +1,15 @@
|
|
1
1
|
require 'sprockets'
|
2
|
+
require 'opal/sprockets/processor'
|
3
|
+
require 'opal/sprockets/erb'
|
2
4
|
|
3
5
|
module Opal
|
6
|
+
# Proccess using Sprockets
|
7
|
+
#
|
8
|
+
# Opal.process('opal-jquery') # => String
|
9
|
+
def self.process asset
|
10
|
+
Environment.new[asset].to_s
|
11
|
+
end
|
12
|
+
|
4
13
|
# Environment is a subclass of Sprockets::Environment which already has our opal
|
5
14
|
# load paths loaded. This makes it easy for stand-alone rack apps, or test runners
|
6
15
|
# that have opal load paths ready to use. You can also add an existing gem's lib
|
data/lib/opal/sprockets/erb.rb
CHANGED
@@ -1,22 +1,30 @@
|
|
1
1
|
require 'opal'
|
2
|
-
require '
|
2
|
+
require 'tilt'
|
3
|
+
require 'opal/erb'
|
3
4
|
require 'sprockets'
|
4
5
|
|
5
6
|
module Opal
|
6
7
|
module ERB
|
7
8
|
class Processor < Tilt::Template
|
9
|
+
# vvv BOILERPLATE vvv
|
8
10
|
self.default_mime_type = 'application/javascript'
|
9
11
|
|
10
12
|
def self.engine_initialized?
|
11
13
|
true
|
12
14
|
end
|
13
15
|
|
16
|
+
def self.version
|
17
|
+
::Opal::VERSION
|
18
|
+
end
|
19
|
+
|
14
20
|
def initialize_engine
|
15
21
|
require_template_library 'opal'
|
16
22
|
end
|
17
23
|
|
18
24
|
def prepare
|
19
25
|
end
|
26
|
+
# ^^^ BOILERPLATE ^^^
|
27
|
+
|
20
28
|
|
21
29
|
def evaluate(context, locals, &block)
|
22
30
|
context.require_asset 'erb'
|
@@ -5,13 +5,6 @@ require 'opal/version'
|
|
5
5
|
$OPAL_SOURCE_MAPS = {}
|
6
6
|
|
7
7
|
module Opal
|
8
|
-
# Proccess using Sprockets
|
9
|
-
#
|
10
|
-
# Opal.process('opal-jquery') # => String
|
11
|
-
def self.process asset
|
12
|
-
Environment.new[asset].to_s
|
13
|
-
end
|
14
|
-
|
15
8
|
# The Processor class is used to make ruby files (with rb or opal extensions)
|
16
9
|
# available to any sprockets based server. Processor will then get passed any
|
17
10
|
# ruby source file to build. There are some options you can override globally
|
@@ -26,6 +19,7 @@ module Opal
|
|
26
19
|
# * irb_enabled [false by default]
|
27
20
|
#
|
28
21
|
class Processor < Tilt::Template
|
22
|
+
# vvv BOILERPLATE vvv
|
29
23
|
self.default_mime_type = 'application/javascript'
|
30
24
|
|
31
25
|
def self.engine_initialized?
|
@@ -36,6 +30,15 @@ module Opal
|
|
36
30
|
::Opal::VERSION
|
37
31
|
end
|
38
32
|
|
33
|
+
def initialize_engine
|
34
|
+
require_template_library 'opal'
|
35
|
+
end
|
36
|
+
|
37
|
+
def prepare
|
38
|
+
end
|
39
|
+
# ^^^ BOILERPLATE ^^^
|
40
|
+
|
41
|
+
|
39
42
|
class << self
|
40
43
|
attr_accessor :method_missing_enabled
|
41
44
|
attr_accessor :arity_check_enabled
|
@@ -60,13 +63,6 @@ module Opal
|
|
60
63
|
@stubbed_files ||= Set.new
|
61
64
|
end
|
62
65
|
|
63
|
-
def initialize_engine
|
64
|
-
require_template_library 'opal'
|
65
|
-
end
|
66
|
-
|
67
|
-
def prepare
|
68
|
-
end
|
69
|
-
|
70
66
|
def evaluate(context, locals, &block)
|
71
67
|
options = {
|
72
68
|
:method_missing => self.class.method_missing_enabled,
|
data/lib/opal/util.rb
CHANGED
@@ -4,26 +4,61 @@ module Opal
|
|
4
4
|
|
5
5
|
# Used for uglifying source to minify
|
6
6
|
def uglify(str)
|
7
|
-
|
8
|
-
|
9
|
-
i.close_write
|
10
|
-
return i.read
|
11
|
-
end
|
12
|
-
rescue Errno::ENOENT, Errno::EPIPE
|
13
|
-
$stderr.puts '"uglifyjs" command not found (install with: "npm install -g uglify-js")'
|
14
|
-
nil
|
7
|
+
uglifyjs = DigestSourceCommand.new(:uglifyjs, nil, ' (install with: "npm install -g uglify-js")')
|
8
|
+
uglifyjs.digest(str)
|
15
9
|
end
|
16
10
|
|
17
11
|
# Gzip code to check file size
|
18
12
|
def gzip(str)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
13
|
+
gzip = DigestSourceCommand.new(:gzip, '-f', ', it is required to produce the .gz version')
|
14
|
+
gzip.digest(str)
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
class DigestSourceCommand
|
19
|
+
def initialize(command, options, message)
|
20
|
+
@command, @options, @message = command, options, message
|
21
|
+
end
|
22
|
+
attr_reader :command, :options, :message
|
23
|
+
|
24
|
+
def digest(source)
|
25
|
+
return unless command_installed? command, message
|
26
|
+
IO.popen("#{command} #{options} #{hide_stderr}", 'r+') do |i|
|
27
|
+
i.puts source
|
28
|
+
i.close_write
|
29
|
+
i.read
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def hide_stderr
|
37
|
+
if (/mswin|mingw/ =~ RUBY_PLATFORM).nil?
|
38
|
+
'2> /dev/null'
|
39
|
+
else
|
40
|
+
'2> nul'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Code from http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
|
45
|
+
def which(cmd)
|
46
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
47
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).find do |path|
|
48
|
+
exts.find { |ext|
|
49
|
+
exe = File.join(path, "#{cmd}#{ext}")
|
50
|
+
exe if File.executable? exe
|
51
|
+
}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
INSTALLED = {}
|
56
|
+
def command_installed?(cmd, install_comment)
|
57
|
+
command_installed = INSTALLED[cmd.to_s] ||= which(cmd)
|
58
|
+
$stderr.puts %Q("#{cmd}" command not found#{install_comment}) unless command_installed
|
59
|
+
command_installed
|
23
60
|
end
|
24
|
-
rescue Errno::ENOENT, Errno::EPIPE
|
25
|
-
$stderr.puts '"gzip" command not found, it is required to produce the .gz version'
|
26
|
-
nil
|
27
61
|
end
|
62
|
+
|
28
63
|
end
|
29
64
|
end
|
data/lib/opal/version.rb
CHANGED
data/opal.gemspec
CHANGED
@@ -13,10 +13,10 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.description = 'Ruby runtime and core library for javascript.'
|
14
14
|
s.license = 'MIT'
|
15
15
|
|
16
|
-
s.files
|
17
|
-
s.executables
|
18
|
-
s.test_files
|
19
|
-
s.require_paths
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.require_paths = ['lib']
|
20
20
|
|
21
21
|
s.add_dependency 'source_map'
|
22
22
|
s.add_dependency 'sprockets'
|
data/opal/corelib/enumerable.rb
CHANGED
data/opal/corelib/enumerator.rb
CHANGED
@@ -35,10 +35,14 @@ class Enumerator
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def each(&block)
|
39
|
-
return self
|
38
|
+
def each(*args, &block)
|
39
|
+
return self if block.nil? && args.empty?
|
40
40
|
|
41
|
-
@
|
41
|
+
args = @args + args
|
42
|
+
|
43
|
+
return self.class.new(@object, @method, *args) if block.nil?
|
44
|
+
|
45
|
+
@object.__send__(@method, *args, &block)
|
42
46
|
end
|
43
47
|
|
44
48
|
def size
|
data/opal/corelib/hash.rb
CHANGED
@@ -13,6 +13,8 @@ class Hash
|
|
13
13
|
|
14
14
|
hash.map = {};
|
15
15
|
hash.keys = [];
|
16
|
+
hash.none = nil;
|
17
|
+
hash.proc = nil;
|
16
18
|
|
17
19
|
return hash;
|
18
20
|
}
|
@@ -20,14 +22,8 @@ class Hash
|
|
20
22
|
|
21
23
|
def initialize(defaults = undefined, &block)
|
22
24
|
%x{
|
23
|
-
|
24
|
-
|
25
|
-
}
|
26
|
-
else if (block !== nil) {
|
27
|
-
self.proc = block;
|
28
|
-
}
|
29
|
-
|
30
|
-
return self;
|
25
|
+
self.none = (defaults === undefined ? nil : defaults);
|
26
|
+
self.proc = block;
|
31
27
|
}
|
32
28
|
end
|
33
29
|
|
@@ -50,8 +46,7 @@ class Hash
|
|
50
46
|
|
51
47
|
for (var i = 0, length = self.keys.length; i < length; i++) {
|
52
48
|
var key = self.keys[i], obj = map[key], obj2 = map2[key];
|
53
|
-
|
54
|
-
if (#{`obj` != `obj2`}) {
|
49
|
+
if (obj2 === undefined || #{`obj` != `obj2`}) {
|
55
50
|
return false;
|
56
51
|
}
|
57
52
|
}
|
@@ -141,11 +136,19 @@ class Hash
|
|
141
136
|
end
|
142
137
|
|
143
138
|
def default(val = undefined)
|
144
|
-
|
139
|
+
%x{
|
140
|
+
if (val !== undefined && self.proc !== nil) {
|
141
|
+
return #{@proc.call(self, val)};
|
142
|
+
}
|
143
|
+
return self.none;
|
144
|
+
}
|
145
145
|
end
|
146
146
|
|
147
147
|
def default=(object)
|
148
|
-
|
148
|
+
%x{
|
149
|
+
self.proc = nil;
|
150
|
+
return (self.none = object);
|
151
|
+
}
|
149
152
|
end
|
150
153
|
|
151
154
|
def default_proc
|
@@ -153,10 +156,20 @@ class Hash
|
|
153
156
|
end
|
154
157
|
|
155
158
|
def default_proc=(proc)
|
156
|
-
|
159
|
+
%x{
|
160
|
+
if (proc !== nil) {
|
161
|
+
proc = #{Opal.coerce_to!(proc, Proc, :to_proc)};
|
162
|
+
|
163
|
+
if (#{proc.lambda?} && #{proc.arity.abs} != 2) {
|
164
|
+
#{raise TypeError, "default_proc takes two arguments"};
|
165
|
+
}
|
166
|
+
}
|
167
|
+
self.none = nil;
|
168
|
+
return (self.proc = proc);
|
169
|
+
}
|
157
170
|
end
|
158
171
|
|
159
|
-
def delete(key)
|
172
|
+
def delete(key, &block)
|
160
173
|
%x{
|
161
174
|
var map = self.map, result = map[key];
|
162
175
|
|
@@ -167,6 +180,9 @@ class Hash
|
|
167
180
|
return result;
|
168
181
|
}
|
169
182
|
|
183
|
+
if (block !== nil) {
|
184
|
+
return #{block.call(key)};
|
185
|
+
}
|
170
186
|
return nil;
|
171
187
|
}
|
172
188
|
end
|
@@ -448,6 +464,10 @@ class Hash
|
|
448
464
|
|
449
465
|
def merge(other, &block)
|
450
466
|
%x{
|
467
|
+
if (! #{Hash === other}) {
|
468
|
+
other = #{Opal.coerce_to!(other, Hash, :to_hash)};
|
469
|
+
}
|
470
|
+
|
451
471
|
var keys = self.keys, map = self.map,
|
452
472
|
result = $opal.hash(), keys2 = result.keys, map2 = result.map;
|
453
473
|
|
@@ -491,6 +511,10 @@ class Hash
|
|
491
511
|
|
492
512
|
def merge!(other, &block)
|
493
513
|
%x{
|
514
|
+
if (! #{Hash === other}) {
|
515
|
+
other = #{Opal.coerce_to!(other, Hash, :to_hash)};
|
516
|
+
}
|
517
|
+
|
494
518
|
var keys = self.keys, map = self.map,
|
495
519
|
keys2 = other.keys, map2 = other.map;
|
496
520
|
|
data/opal/corelib/kernel.rb
CHANGED
@@ -44,8 +44,9 @@ module Kernel
|
|
44
44
|
continue;
|
45
45
|
}
|
46
46
|
}
|
47
|
-
|
48
|
-
|
47
|
+
if (self[key].rb_stub === undefined) {
|
48
|
+
methods.push(key.substr(1));
|
49
|
+
}
|
49
50
|
}
|
50
51
|
}
|
51
52
|
|
@@ -139,6 +140,8 @@ module Kernel
|
|
139
140
|
Enumerator.for(self, method, *args, &block)
|
140
141
|
end
|
141
142
|
|
143
|
+
alias to_enum enum_for
|
144
|
+
|
142
145
|
def equal?(other)
|
143
146
|
`self === other`
|
144
147
|
end
|
@@ -464,6 +467,7 @@ module Kernel
|
|
464
467
|
exception = #{exception.new string};
|
465
468
|
}
|
466
469
|
|
470
|
+
#{$! = exception};
|
467
471
|
throw exception;
|
468
472
|
}
|
469
473
|
end
|