opal 0.7.0.beta3 → 0.7.0.rc1
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.
- checksums.yaml +4 -4
- data/.gitmodules +4 -0
- data/.travis.yml +7 -3
- data/.yardopts +6 -0
- data/CHANGELOG.md +28 -0
- data/Gemfile +1 -1
- data/README.md +3 -12
- data/Rakefile +4 -150
- data/bin/opal-mspec +1 -1
- data/docs/compiler_directives.md +127 -0
- data/examples/rack/.gitignore +1 -0
- data/examples/rack/app/user.rb +1 -0
- data/lib/mspec/opal/special_calls.rb +15 -2
- data/lib/opal/builder.rb +15 -8
- data/lib/opal/compiler.rb +75 -4
- data/lib/opal/erb.rb +22 -2
- data/lib/opal/fragment.rb +17 -5
- data/lib/opal/nodes/def.rb +174 -53
- data/lib/opal/nodes/if.rb +14 -0
- data/lib/opal/nodes/module.rb +0 -1
- data/lib/opal/nodes/rescue.rb +10 -2
- data/lib/opal/nodes/scope.rb +0 -17
- data/lib/opal/parser.rb +83 -19
- data/lib/opal/parser/grammar.rb +2511 -2414
- data/lib/opal/parser/grammar.y +71 -9
- data/lib/opal/parser/lexer.rb +44 -12
- data/lib/opal/parser/parser_scope.rb +3 -0
- data/lib/opal/parser/sexp.rb +7 -1
- data/lib/opal/paths.rb +5 -5
- data/lib/opal/sprockets/environment.rb +2 -10
- data/lib/opal/sprockets/path_reader.rb +1 -1
- data/lib/opal/sprockets/processor.rb +1 -0
- data/lib/opal/sprockets/server.rb +2 -0
- data/lib/opal/util.rb +7 -2
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +1 -0
- data/opal/README.md +1 -1
- data/opal/corelib/dir.rb +1 -1
- data/opal/corelib/enumerable.rb +3 -1
- data/opal/corelib/error.rb +3 -0
- data/opal/corelib/file.rb +2 -0
- data/opal/corelib/hash.rb +3 -0
- data/opal/corelib/io.rb +15 -1
- data/opal/corelib/kernel.rb +8 -0
- data/opal/corelib/module.rb +42 -17
- data/opal/corelib/runtime.js +223 -49
- data/opal/corelib/string.rb +1 -1
- data/opal/corelib/struct.rb +1 -7
- data/spec/README.md +8 -0
- data/spec/filters/bugs/language.rb +1 -0
- data/spec/filters/bugs/module.rb +4 -0
- data/spec/filters/unsupported/frozen.rb +2 -0
- data/spec/lib/compiler/pre_processed_conditionals_spec.rb +87 -0
- data/spec/lib/compiler_spec.rb +1 -67
- data/spec/lib/fixtures/file_with_directives.js +2 -0
- data/spec/lib/fixtures/required_file.js +1 -0
- data/spec/lib/parser/def_spec.rb +29 -16
- data/spec/lib/parser/variables_spec.rb +5 -5
- data/spec/lib/sprockets/path_reader_spec.rb +24 -8
- data/spec/lib/sprockets/server_spec.rb +10 -3
- data/spec/opal/core/date_spec.rb +14 -0
- data/spec/opal/core/language/versions/def_2_0_spec.rb +62 -0
- data/spec/opal/core/language_spec.rb +23 -0
- data/spec/opal/core/runtime/donate_spec.rb +53 -0
- data/spec/opal/stdlib/native/native_alias_spec.rb +19 -0
- data/spec/opal/stdlib/native/native_class_spec.rb +18 -0
- data/spec/opal/stdlib/native/native_module_spec.rb +13 -0
- data/spec/rubyspecs +2 -0
- data/stdlib/buffer.rb +1 -0
- data/stdlib/date.rb +18 -0
- data/stdlib/encoding.rb +3 -2
- data/stdlib/minitest.rb +780 -0
- data/stdlib/minitest/assertions.rb +662 -0
- data/stdlib/minitest/autorun.rb +12 -0
- data/stdlib/minitest/benchmark.rb +426 -0
- data/stdlib/minitest/expectations.rb +281 -0
- data/stdlib/minitest/hell.rb +11 -0
- data/stdlib/minitest/mock.rb +220 -0
- data/stdlib/minitest/parallel.rb +65 -0
- data/stdlib/minitest/pride.rb +4 -0
- data/stdlib/minitest/pride_plugin.rb +142 -0
- data/stdlib/minitest/spec.rb +310 -0
- data/stdlib/minitest/test.rb +293 -0
- data/stdlib/minitest/unit.rb +45 -0
- data/stdlib/native.rb +12 -3
- data/stdlib/nodejs/process.rb +16 -2
- data/stdlib/promise.rb +99 -0
- data/stdlib/test/unit.rb +10 -0
- data/stdlib/thread.rb +4 -0
- data/tasks/building.rake +58 -0
- data/tasks/documentation.rake +38 -0
- data/tasks/documenting.rake +37 -0
- data/tasks/testing.rake +102 -0
- metadata +57 -2
data/lib/opal/parser/grammar.y
CHANGED
@@ -15,7 +15,7 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
|
|
15
15
|
tLCURLY tRCURLY tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
|
16
16
|
tWORDS_BEG tAWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END tSTRING
|
17
17
|
tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG
|
18
|
-
tLBRACK2 tLBRACK
|
18
|
+
tLBRACK2 tLBRACK tDSTAR
|
19
19
|
|
20
20
|
prechigh
|
21
21
|
right tBANG tTILDE tUPLUS
|
@@ -1458,35 +1458,97 @@ xstring_contents: none
|
|
1458
1458
|
result = val[0]
|
1459
1459
|
}
|
1460
1460
|
|
1461
|
-
|
1461
|
+
kwrest_mark: tPOW
|
1462
|
+
| tDSTAR
|
1463
|
+
|
1464
|
+
f_kwrest: kwrest_mark tIDENTIFIER
|
1465
|
+
{
|
1466
|
+
result = new_kwrestarg(val[1])
|
1467
|
+
}
|
1468
|
+
| kwrest_mark
|
1469
|
+
{
|
1470
|
+
result = new_kwrestarg()
|
1471
|
+
}
|
1472
|
+
|
1473
|
+
f_label: tLABEL
|
1474
|
+
{
|
1475
|
+
result = new_sym(val[0])
|
1476
|
+
}
|
1477
|
+
|
1478
|
+
f_kw: f_label arg_value
|
1479
|
+
{
|
1480
|
+
result = new_kwoptarg(val[0], val[1])
|
1481
|
+
}
|
1482
|
+
| f_label
|
1483
|
+
{
|
1484
|
+
result = new_kwarg(val[0])
|
1485
|
+
}
|
1486
|
+
|
1487
|
+
f_kwarg: f_kw
|
1488
|
+
{
|
1489
|
+
result = [val[0]]
|
1490
|
+
}
|
1491
|
+
| f_kwarg tCOMMA f_kw
|
1492
|
+
{
|
1493
|
+
result = val[0]
|
1494
|
+
result << val[2]
|
1495
|
+
}
|
1496
|
+
|
1497
|
+
args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
|
1498
|
+
{
|
1499
|
+
result = new_args_tail(val[0], val[2], val[3])
|
1500
|
+
}
|
1501
|
+
| f_kwarg opt_f_block_arg
|
1502
|
+
{
|
1503
|
+
result = new_args_tail(val[0], nil, val[1])
|
1504
|
+
}
|
1505
|
+
| f_kwrest opt_f_block_arg
|
1506
|
+
{
|
1507
|
+
result = new_args_tail(nil, val[0], val[1])
|
1508
|
+
}
|
1509
|
+
| f_block_arg
|
1510
|
+
{
|
1511
|
+
result = new_args_tail(nil, nil, val[0])
|
1512
|
+
}
|
1513
|
+
|
1514
|
+
opt_args_tail: tCOMMA args_tail
|
1515
|
+
{
|
1516
|
+
result = val[1]
|
1517
|
+
}
|
1518
|
+
| # none
|
1519
|
+
{
|
1520
|
+
result = new_args_tail(nil, nil, nil)
|
1521
|
+
}
|
1522
|
+
|
1523
|
+
f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
|
1462
1524
|
{
|
1463
1525
|
result = new_args(val[0], val[2], val[4], val[5])
|
1464
1526
|
}
|
1465
|
-
| f_arg tCOMMA f_optarg
|
1527
|
+
| f_arg tCOMMA f_optarg opt_args_tail
|
1466
1528
|
{
|
1467
1529
|
result = new_args(val[0], val[2], nil, val[3])
|
1468
1530
|
}
|
1469
|
-
| f_arg tCOMMA f_rest_arg
|
1531
|
+
| f_arg tCOMMA f_rest_arg opt_args_tail
|
1470
1532
|
{
|
1471
1533
|
result = new_args(val[0], nil, val[2], val[3])
|
1472
1534
|
}
|
1473
|
-
| f_arg
|
1535
|
+
| f_arg opt_args_tail
|
1474
1536
|
{
|
1475
1537
|
result = new_args(val[0], nil, nil, val[1])
|
1476
1538
|
}
|
1477
|
-
| f_optarg tCOMMA f_rest_arg
|
1539
|
+
| f_optarg tCOMMA f_rest_arg opt_args_tail
|
1478
1540
|
{
|
1479
1541
|
result = new_args(nil, val[0], val[2], val[3])
|
1480
1542
|
}
|
1481
|
-
| f_optarg
|
1543
|
+
| f_optarg opt_args_tail
|
1482
1544
|
{
|
1483
1545
|
result = new_args(nil, val[0], nil, val[1])
|
1484
1546
|
}
|
1485
|
-
| f_rest_arg
|
1547
|
+
| f_rest_arg opt_args_tail
|
1486
1548
|
{
|
1487
1549
|
result = new_args(nil, nil, val[0], val[1])
|
1488
1550
|
}
|
1489
|
-
|
|
1551
|
+
| args_tail
|
1490
1552
|
{
|
1491
1553
|
result = new_args(nil, nil, nil, val[0])
|
1492
1554
|
}
|
data/lib/opal/parser/lexer.rb
CHANGED
@@ -2,6 +2,23 @@ require 'strscan'
|
|
2
2
|
require 'opal/parser/keywords'
|
3
3
|
|
4
4
|
module Opal
|
5
|
+
# {Opal::Lexer} is used by {Opal::Parser} to step through ruby code, and
|
6
|
+
# returning tokens representing each chunk of ruby code.
|
7
|
+
#
|
8
|
+
# Tokens are in the form:
|
9
|
+
#
|
10
|
+
# [token, [value, location]]
|
11
|
+
#
|
12
|
+
# where `location` is in the form `[line_number, column_number]`. The location
|
13
|
+
# data can be used to produce source maps in the compiler. Tokens are
|
14
|
+
# generally ruby symbols, and the value will always be a string value.
|
15
|
+
#
|
16
|
+
# The main method used by the parser is {#next_token}, which is called
|
17
|
+
# repeatedly until a token of value `false` is returned, which indicated the
|
18
|
+
# EOF has been reached.
|
19
|
+
#
|
20
|
+
# Generally this class is only used by {Opal::Parser} directly.
|
21
|
+
#
|
5
22
|
class Lexer
|
6
23
|
|
7
24
|
STR_FUNC_ESCAPE = 0x01
|
@@ -31,6 +48,13 @@ module Opal
|
|
31
48
|
attr_accessor :yylval
|
32
49
|
attr_accessor :parser
|
33
50
|
|
51
|
+
# Create a new instance using the given ruby code and filename for
|
52
|
+
# reference.
|
53
|
+
#
|
54
|
+
# Opal::Lexer.new("ruby code", "my_file.rb")
|
55
|
+
#
|
56
|
+
# @param source [String] ruby code to lex
|
57
|
+
# @param file [String] filename of given ruby code
|
34
58
|
def initialize(source, file)
|
35
59
|
@lex_state = :expr_beg
|
36
60
|
@cond = 0
|
@@ -48,6 +72,25 @@ module Opal
|
|
48
72
|
@start_of_lambda = nil
|
49
73
|
end
|
50
74
|
|
75
|
+
# Returns next token from source input stream.
|
76
|
+
#
|
77
|
+
# Token in form:
|
78
|
+
#
|
79
|
+
# [token, [value, [source_line, source_column]]]
|
80
|
+
#
|
81
|
+
# @return [Array]
|
82
|
+
def next_token
|
83
|
+
token = self.yylex
|
84
|
+
value = self.yylval
|
85
|
+
location = [@tok_line, @tok_column]
|
86
|
+
|
87
|
+
# once location is stored, ensure next token starts in correct place
|
88
|
+
@tok_column = @column
|
89
|
+
@tok_line = @line
|
90
|
+
|
91
|
+
[token, [value, location]]
|
92
|
+
end
|
93
|
+
|
51
94
|
def has_local?(local)
|
52
95
|
parser.scope.has_local?(local.to_sym)
|
53
96
|
end
|
@@ -151,18 +194,6 @@ module Opal
|
|
151
194
|
@line = @tok_line = line
|
152
195
|
end
|
153
196
|
|
154
|
-
def next_token
|
155
|
-
token = self.yylex
|
156
|
-
value = self.yylval
|
157
|
-
location = [@tok_line, @tok_column]
|
158
|
-
|
159
|
-
# once location is stored, ensure next token starts in correct place
|
160
|
-
@tok_column = @column
|
161
|
-
@tok_line = @line
|
162
|
-
|
163
|
-
[token, [value, location]]
|
164
|
-
end
|
165
|
-
|
166
197
|
def new_strterm(func, term, paren)
|
167
198
|
{ :type => :string, :func => func, :term => term, :paren => paren }
|
168
199
|
end
|
@@ -600,6 +631,7 @@ module Opal
|
|
600
631
|
return matched =~ /^[A-Z]/ ? :tCONSTANT : :tIDENTIFIER
|
601
632
|
end
|
602
633
|
|
634
|
+
# Does the heavy lifting for `next_token`.
|
603
635
|
def yylex
|
604
636
|
@yylval = ''
|
605
637
|
@space_seen = false
|
data/lib/opal/parser/sexp.rb
CHANGED
@@ -1,4 +1,11 @@
|
|
1
1
|
module Opal
|
2
|
+
# [Opal::Sexp] is used to build up the syntax tree inside [Opal::Parser]. The
|
3
|
+
# compiler then steps through the sexp trees to generate the javascript code.
|
4
|
+
#
|
5
|
+
# For example, an array of integers `[1, 2]` might be represented by:
|
6
|
+
#
|
7
|
+
# s(:array, s(:int, 1), s(:int, 2))
|
8
|
+
#
|
2
9
|
class Sexp
|
3
10
|
|
4
11
|
attr_reader :array
|
@@ -72,4 +79,3 @@ module Opal
|
|
72
79
|
alias to_s inspect
|
73
80
|
end
|
74
81
|
end
|
75
|
-
|
data/lib/opal/paths.rb
CHANGED
@@ -19,19 +19,19 @@ module Opal
|
|
19
19
|
paths << path
|
20
20
|
end
|
21
21
|
|
22
|
-
def self.use_gem(gem_name,
|
23
|
-
require_paths_for_gem(gem_name,
|
22
|
+
def self.use_gem(gem_name, include_dependencies = true)
|
23
|
+
require_paths_for_gem(gem_name, include_dependencies).each do |path|
|
24
24
|
append_path path
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
def self.require_paths_for_gem(gem_name,
|
28
|
+
def self.require_paths_for_gem(gem_name, include_dependencies)
|
29
29
|
paths = []
|
30
30
|
spec = Gem::Specification.find_by_name(gem_name)
|
31
31
|
|
32
32
|
spec.runtime_dependencies.each do |dependency|
|
33
|
-
paths += require_paths_for_gem(dependency.name,
|
34
|
-
end if
|
33
|
+
paths += require_paths_for_gem(dependency.name, include_dependencies)
|
34
|
+
end if include_dependencies
|
35
35
|
|
36
36
|
gem_dir = spec.gem_dir
|
37
37
|
spec.require_paths.map do |path|
|
@@ -3,20 +3,12 @@ require 'opal/sprockets/processor'
|
|
3
3
|
require 'opal/sprockets/erb'
|
4
4
|
|
5
5
|
module Opal
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# Opal.process('opal-jquery') # => String
|
6
|
+
# @deprecated
|
9
7
|
def self.process asset
|
10
8
|
Environment.new[asset].to_s
|
11
9
|
end
|
12
10
|
|
13
|
-
#
|
14
|
-
# load paths loaded. This makes it easy for stand-alone rack apps, or test runners
|
15
|
-
# that have opal load paths ready to use. You can also add an existing gem's lib
|
16
|
-
# directory to our load path to use real gems inside your opal environment.
|
17
|
-
#
|
18
|
-
# If you are running rails, then you just need opal-rails instead, which will
|
19
|
-
# do this for you.
|
11
|
+
# @deprecated
|
20
12
|
class Environment < ::Sprockets::Environment
|
21
13
|
def initialize *args
|
22
14
|
warn "WARNING: Opal::Sprockets::Environment is deprecated. "\
|
@@ -36,6 +36,8 @@ module Opal
|
|
36
36
|
|
37
37
|
# "logical_name" of a BundledAsset keeps the .js extension
|
38
38
|
source = register[asset.logical_path.sub(/\.js$/, '')]
|
39
|
+
return not_found(asset) if source.nil?
|
40
|
+
|
39
41
|
map = JSON.parse(source)
|
40
42
|
map['sources'] = map['sources'].map {|s| "#{prefix}/#{s}"}
|
41
43
|
source = map.to_json
|
data/lib/opal/util.rb
CHANGED
@@ -2,13 +2,18 @@ module Opal
|
|
2
2
|
module Util
|
3
3
|
extend self
|
4
4
|
|
5
|
-
# Used for uglifying source to minify
|
5
|
+
# Used for uglifying source to minify.
|
6
|
+
#
|
7
|
+
# Opal::Util.uglify("javascript contents")
|
8
|
+
#
|
9
|
+
# @param str [String] string to minify
|
10
|
+
# @return [String]
|
6
11
|
def uglify(str)
|
7
12
|
uglifyjs = DigestSourceCommand.new(:uglifyjs, nil, ' (install with: "npm install -g uglify-js")')
|
8
13
|
uglifyjs.digest(str)
|
9
14
|
end
|
10
15
|
|
11
|
-
# Gzip code to check file size
|
16
|
+
# Gzip code to check file size.
|
12
17
|
def gzip(str)
|
13
18
|
gzip = DigestSourceCommand.new(:gzip, '-f', ', it is required to produce the .gz version')
|
14
19
|
gzip.digest(str)
|
data/lib/opal/version.rb
CHANGED
data/opal.gemspec
CHANGED
data/opal/README.md
CHANGED
data/opal/corelib/dir.rb
CHANGED
data/opal/corelib/enumerable.rb
CHANGED
data/opal/corelib/error.rb
CHANGED
@@ -48,6 +48,9 @@ class LoadError < ScriptError; end
|
|
48
48
|
class NotImplementedError < ScriptError; end
|
49
49
|
|
50
50
|
class SystemExit < Exception; end
|
51
|
+
class NoMemoryError < Exception; end
|
52
|
+
class SignalException < Exception; end
|
53
|
+
class Interrupt < Exception; end
|
51
54
|
|
52
55
|
class StandardError < Exception; end
|
53
56
|
class NameError < StandardError; end
|
data/opal/corelib/file.rb
CHANGED
data/opal/corelib/hash.rb
CHANGED
data/opal/corelib/io.rb
CHANGED
@@ -3,6 +3,14 @@ class IO
|
|
3
3
|
SEEK_CUR = 1
|
4
4
|
SEEK_END = 2
|
5
5
|
|
6
|
+
def tty?
|
7
|
+
@tty
|
8
|
+
end
|
9
|
+
|
10
|
+
def closed?
|
11
|
+
@closed
|
12
|
+
end
|
13
|
+
|
6
14
|
attr_accessor :write_proc
|
7
15
|
|
8
16
|
def write(string)
|
@@ -10,6 +18,8 @@ class IO
|
|
10
18
|
string.size
|
11
19
|
end
|
12
20
|
|
21
|
+
attr_accessor :sync
|
22
|
+
|
13
23
|
module Writable
|
14
24
|
def <<(string)
|
15
25
|
write(string)
|
@@ -23,7 +33,11 @@ class IO
|
|
23
33
|
|
24
34
|
def puts(*args)
|
25
35
|
newline = $/
|
26
|
-
|
36
|
+
if args.empty?
|
37
|
+
write $/
|
38
|
+
else
|
39
|
+
write args.map { |arg| String(arg).chomp }.concat([nil]).join(newline)
|
40
|
+
end
|
27
41
|
nil
|
28
42
|
end
|
29
43
|
end
|
data/opal/corelib/kernel.rb
CHANGED
@@ -71,6 +71,11 @@ module Kernel
|
|
71
71
|
}
|
72
72
|
end
|
73
73
|
|
74
|
+
def at_exit(&block)
|
75
|
+
$__at_exit__ ||= []
|
76
|
+
$__at_exit__ << block
|
77
|
+
end
|
78
|
+
|
74
79
|
# Opal does not support #caller, but we stub it as an empty array to not
|
75
80
|
# break dependant libs
|
76
81
|
def caller
|
@@ -405,6 +410,7 @@ module Kernel
|
|
405
410
|
end
|
406
411
|
|
407
412
|
def load(file)
|
413
|
+
file = Opal.coerce_to!(file, String, :to_str)
|
408
414
|
`Opal.load(Opal.normalize_loadable_path(#{file}))`
|
409
415
|
end
|
410
416
|
|
@@ -521,10 +527,12 @@ module Kernel
|
|
521
527
|
end
|
522
528
|
|
523
529
|
def require(file)
|
530
|
+
file = Opal.coerce_to!(file, String, :to_str)
|
524
531
|
`Opal.require(Opal.normalize_loadable_path(#{file}))`
|
525
532
|
end
|
526
533
|
|
527
534
|
def require_relative(file)
|
535
|
+
Opal.try_convert!(file, String, :to_str)
|
528
536
|
file = File.expand_path File.join(`Opal.current_file`, '..', file)
|
529
537
|
|
530
538
|
`Opal.require(Opal.normalize_loadable_path(#{file}))`
|