opal 0.10.0.beta2 → 0.10.0.beta3
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/CHANGELOG.md +9 -1
- data/lib/opal/compiler.rb +15 -9
- data/lib/opal/fragment.rb +8 -1
- data/lib/opal/nodes/args/restarg.rb +6 -1
- data/lib/opal/nodes/base.rb +1 -1
- data/lib/opal/nodes/call.rb +4 -0
- data/lib/opal/nodes/def.rb +20 -25
- data/lib/opal/nodes/hash.rb +89 -17
- data/lib/opal/nodes/iter.rb +30 -2
- data/lib/opal/nodes/logic.rb +54 -4
- data/lib/opal/nodes/node_with_args.rb +72 -0
- data/lib/opal/parser.rb +16 -0
- data/lib/opal/parser/grammar.rb +2555 -2562
- data/lib/opal/parser/grammar.y +28 -20
- data/lib/opal/parser/lexer.rb +4 -4
- data/lib/opal/regexp_anchors.rb +13 -5
- data/lib/opal/source_map.rb +2 -1
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/array.rb +4 -0
- data/opal/corelib/basic_object.rb +3 -1
- data/opal/corelib/constants.rb +1 -1
- data/opal/corelib/file.rb +196 -4
- data/opal/corelib/hash.rb +7 -7
- data/opal/corelib/kernel.rb +7 -4
- data/opal/corelib/marshal.rb +31 -0
- data/opal/corelib/marshal/read_buffer.rb +427 -0
- data/opal/corelib/marshal/write_buffer.rb +383 -0
- data/opal/corelib/method.rb +8 -0
- data/opal/corelib/module.rb +21 -0
- data/opal/corelib/number.rb +19 -5
- data/opal/corelib/proc.rb +33 -6
- data/opal/corelib/range.rb +6 -0
- data/opal/corelib/regexp.rb +5 -1
- data/opal/corelib/runtime.js +69 -17
- data/opal/corelib/string.rb +8 -0
- data/opal/corelib/string/inheritance.rb +4 -0
- data/opal/corelib/struct.rb +5 -0
- data/opal/corelib/unsupported.rb +0 -18
- data/opal/opal/full.rb +1 -0
- data/spec/filters/bugs/basicobject.rb +0 -2
- data/spec/filters/bugs/compiler_opal.rb +5 -0
- data/spec/filters/bugs/enumerable.rb +1 -0
- data/spec/filters/bugs/enumerator.rb +0 -2
- data/spec/filters/bugs/exception.rb +0 -1
- data/spec/filters/bugs/kernel.rb +0 -5
- data/spec/filters/bugs/language.rb +7 -27
- data/spec/filters/bugs/marshal.rb +43 -0
- data/spec/filters/bugs/method.rb +0 -56
- data/spec/filters/bugs/module.rb +0 -1
- data/spec/filters/bugs/proc.rb +0 -46
- data/spec/filters/bugs/regexp.rb +1 -0
- data/spec/filters/bugs/unboundmethod.rb +0 -13
- data/spec/filters/unsupported/bignum.rb +5 -0
- data/spec/filters/unsupported/freeze.rb +2 -0
- data/spec/filters/unsupported/marshal.rb +46 -0
- data/spec/filters/unsupported/symbol.rb +5 -0
- data/spec/lib/compiler/call_spec.rb +29 -29
- data/spec/lib/compiler_spec.rb +7 -1
- data/spec/opal/core/kernel/instance_variables_spec.rb +40 -0
- data/spec/opal/core/language/ternary_operator_spec.rb +6 -0
- data/spec/opal/core/marshal/dump_spec.rb +53 -0
- data/spec/opal/core/marshal/load_spec.rb +7 -0
- data/spec/opal/core/source_map_spec.rb +35 -1
- data/spec/opal/javascript_api_spec.rb +16 -0
- data/spec/opal/stdlib/source_map_spec.rb +8 -0
- data/spec/ruby_specs +7 -4
- data/spec/support/match_helpers.rb +57 -0
- data/spec/support/mspec_rspec_adapter.rb +1 -1
- data/stdlib/opal-parser.rb +3 -1
- data/stdlib/pathname.rb +105 -7
- data/stdlib/racc/parser.rb +551 -138
- data/stdlib/source_map/vlq.rb +3 -2
- data/tasks/testing.rake +4 -2
- metadata +22 -2
data/lib/opal/parser/grammar.y
CHANGED
@@ -225,16 +225,25 @@ rule
|
|
225
225
|
result = new_js_call(val[0], val[2], val[3])
|
226
226
|
}
|
227
227
|
| primary_value tJSDOT operation2 command_args cmd_brace_block
|
228
|
+
{
|
229
|
+
result = new_js_call(val[0], val[2], val[3]) << val[4]
|
230
|
+
}
|
228
231
|
| primary_value tDOT operation2 command_args =tLOWEST
|
229
232
|
{
|
230
233
|
result = new_call(val[0], val[2], val[3])
|
231
234
|
}
|
232
235
|
| primary_value tDOT operation2 command_args cmd_brace_block
|
236
|
+
{
|
237
|
+
result = new_call(val[0], val[2], val[3]) << val[4]
|
238
|
+
}
|
233
239
|
| primary_value tCOLON2 operation2 command_args =tLOWEST
|
234
|
-
|
235
|
-
|
236
|
-
|
240
|
+
{
|
241
|
+
result = new_call(val[0], val[2], val[3])
|
242
|
+
}
|
237
243
|
| primary_value tCOLON2 operation2 command_args cmd_brace_block
|
244
|
+
{
|
245
|
+
result = new_call(val[0], val[2], val[3]) << val[4]
|
246
|
+
}
|
238
247
|
| kSUPER command_args
|
239
248
|
{
|
240
249
|
result = new_super(val[0], val[1])
|
@@ -714,28 +723,15 @@ rule
|
|
714
723
|
add_block_pass result, val[0]
|
715
724
|
}
|
716
725
|
|
717
|
-
call_args2: arg_value tCOMMA args opt_block_arg
|
718
|
-
| block_arg
|
719
|
-
|
720
726
|
command_args: {
|
721
727
|
lexer.cmdarg_push 1
|
722
728
|
}
|
723
|
-
|
729
|
+
call_args
|
724
730
|
{
|
725
731
|
lexer.cmdarg_pop
|
726
732
|
result = val[1]
|
727
733
|
}
|
728
734
|
|
729
|
-
open_args: call_args
|
730
|
-
| tLPAREN_ARG tRPAREN
|
731
|
-
{
|
732
|
-
result = nil
|
733
|
-
}
|
734
|
-
| tLPAREN_ARG call_args2 tRPAREN
|
735
|
-
{
|
736
|
-
result = val[1]
|
737
|
-
}
|
738
|
-
|
739
735
|
block_arg: tAMPER arg_value
|
740
736
|
{
|
741
737
|
result = new_block_pass(val[0], val[1])
|
@@ -799,10 +795,22 @@ rule
|
|
799
795
|
{
|
800
796
|
result = s(:begin, val[2])
|
801
797
|
}
|
802
|
-
| tLPAREN_ARG expr
|
798
|
+
| tLPAREN_ARG expr
|
799
|
+
{
|
800
|
+
lexer.lex_state = :expr_endarg
|
801
|
+
}
|
802
|
+
opt_nl tRPAREN
|
803
803
|
{
|
804
804
|
result = val[1]
|
805
805
|
}
|
806
|
+
| tLPAREN_ARG
|
807
|
+
{
|
808
|
+
lexer.lex_state = :expr_endarg
|
809
|
+
}
|
810
|
+
opt_nl tRPAREN
|
811
|
+
{
|
812
|
+
result = new_nil(val[0])
|
813
|
+
}
|
806
814
|
| tLPAREN compstmt tRPAREN
|
807
815
|
{
|
808
816
|
result = new_paren(val[0], val[1], val[2])
|
@@ -867,8 +875,7 @@ rule
|
|
867
875
|
| method_call
|
868
876
|
| method_call brace_block
|
869
877
|
{
|
870
|
-
val[0]
|
871
|
-
result = val[0]
|
878
|
+
result = new_method_call_with_block(val[0], val[1])
|
872
879
|
}
|
873
880
|
| tLAMBDA lambda
|
874
881
|
{
|
@@ -1168,6 +1175,7 @@ opt_block_args_tail: tCOMMA block_args_tail
|
|
1168
1175
|
}
|
1169
1176
|
| f_arg tCOMMA
|
1170
1177
|
{
|
1178
|
+
val[0] << nil
|
1171
1179
|
result = [val[0], nil]
|
1172
1180
|
}
|
1173
1181
|
| f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
|
data/lib/opal/parser/lexer.rb
CHANGED
@@ -653,7 +653,7 @@ module Opal
|
|
653
653
|
elsif cmdarg? && @lex_state != :expr_cmdarg
|
654
654
|
@lex_state = :expr_beg
|
655
655
|
return :kDO_BLOCK
|
656
|
-
elsif
|
656
|
+
elsif last_state == :expr_endarg
|
657
657
|
return :kDO_BLOCK
|
658
658
|
else
|
659
659
|
@lex_state = :expr_beg
|
@@ -997,7 +997,6 @@ module Opal
|
|
997
997
|
|
998
998
|
elsif scan(/\(/)
|
999
999
|
result = scanner.matched
|
1000
|
-
@lparen_arg_seen = false
|
1001
1000
|
|
1002
1001
|
if beg?
|
1003
1002
|
result = :tLPAREN
|
@@ -1018,6 +1017,7 @@ module Opal
|
|
1018
1017
|
cond_lexpop
|
1019
1018
|
cmdarg_lexpop
|
1020
1019
|
@lex_state = :expr_end
|
1020
|
+
@lparen_arg_seen = false
|
1021
1021
|
return :tRPAREN
|
1022
1022
|
|
1023
1023
|
elsif scan(/\[/)
|
@@ -1304,7 +1304,7 @@ module Opal
|
|
1304
1304
|
result = :tLCURLY
|
1305
1305
|
end
|
1306
1306
|
elsif @lex_state == :expr_endarg
|
1307
|
-
result = :
|
1307
|
+
result = :tLBRACE_ARG
|
1308
1308
|
else
|
1309
1309
|
result = :tLBRACE
|
1310
1310
|
end
|
@@ -1328,7 +1328,7 @@ module Opal
|
|
1328
1328
|
elsif check(/[0-9]/)
|
1329
1329
|
return process_numeric
|
1330
1330
|
|
1331
|
-
elsif scan(
|
1331
|
+
elsif scan(INLINE_IDENTIFIER_REGEXP)
|
1332
1332
|
return process_identifier scanner.matched, cmd_start
|
1333
1333
|
end
|
1334
1334
|
|
data/lib/opal/regexp_anchors.rb
CHANGED
@@ -2,6 +2,15 @@ module Opal
|
|
2
2
|
REGEXP_START = RUBY_ENGINE == 'opal' ? '^' : '\A'.freeze
|
3
3
|
REGEXP_END = RUBY_ENGINE == 'opal' ? '$' : '\z'.freeze
|
4
4
|
|
5
|
+
# Unicode characters in ranges
|
6
|
+
# \u0001 - \u002F (blank unicode characters + space + !"#$%&'()*+,-./ chars)
|
7
|
+
# \u003A - \u0040 (:;<=>?@ chars)
|
8
|
+
# \u005B - \u005E ([\]^ chars)
|
9
|
+
# \u0060 (` char)
|
10
|
+
# \u007B - \u007F ({|}~ chars})
|
11
|
+
# are not allowed to be used in identifier in the beggining or middle of its name
|
12
|
+
FORBIDDEN_STARTING_IDENTIFIER_CHARS = "\\u0001-\\u002F\\u003A-\\u0040\\u005B-\\u005E\\u0060\\u007B-\\u007F"
|
13
|
+
|
5
14
|
# Unicode characters in ranges
|
6
15
|
# \u0001 - \u0020 (blank unicode characters + space)
|
7
16
|
# \u0022 - \u002F ("#$%&'()*+,-./ chars)
|
@@ -10,14 +19,13 @@ module Opal
|
|
10
19
|
# \u005B - \u005E ([\]^ chars)
|
11
20
|
# \u0060 (` char)
|
12
21
|
# \u007B - \u007F ({|}~ chars})
|
13
|
-
# are not allowed to be used in identifier in
|
14
|
-
#
|
15
|
-
|
16
|
-
|
22
|
+
# are not allowed to be used in identifier in the end of its name
|
23
|
+
# In fact, FORBIDDEN_STARTING_IDENTIFIER_CHARS = FORBIDDEN_ENDING_IDENTIFIER_CHARS + \u0021 ('?') + \u003F ('!')
|
24
|
+
FORBIDDEN_ENDING_IDENTIFIER_CHARS = "\\u0001-\\u0020\\u0022-\\u002F\\u003A-\\u003E\\u0040\\u005B-\\u005E\\u0060\\u007B-\\u007F"
|
25
|
+
INLINE_IDENTIFIER_REGEXP = Regexp.new("[^#{FORBIDDEN_STARTING_IDENTIFIER_CHARS}]*[^#{FORBIDDEN_ENDING_IDENTIFIER_CHARS}]")
|
17
26
|
|
18
27
|
# For constants rules are pretty much the same, but ':' is allowed and '?!' are not.
|
19
28
|
# Plus it may start with a '::' which indicates that the constant comes from toplevel.
|
20
29
|
FORBIDDEN_CONST_NAME_CHARS = "\\u0001-\\u0020\\u0021-\\u002F\\u003B-\\u003F\\u0040\\u005B-\\u005E\\u0060\\u007B-\\u007F"
|
21
30
|
CONST_NAME_REGEXP = Regexp.new("#{REGEXP_START}(::)?[A-Z][^#{FORBIDDEN_CONST_NAME_CHARS}]*#{REGEXP_END}")
|
22
31
|
end
|
23
|
-
|
data/lib/opal/source_map.rb
CHANGED
data/lib/opal/version.rb
CHANGED
data/opal/corelib/array.rb
CHANGED
@@ -51,7 +51,9 @@ class BasicObject
|
|
51
51
|
Kernel.raise ArgumentError, "wrong number of arguments (0 for 1..3)" unless (1..3).cover? args.size
|
52
52
|
|
53
53
|
string, file, _lineno = *args
|
54
|
-
|
54
|
+
default_eval_options = { file: (file || '(eval)'), eval: true }
|
55
|
+
compiling_options = __OPAL_COMPILER_CONFIG__.merge(default_eval_options)
|
56
|
+
compiled = Opal.compile string, compiling_options
|
55
57
|
block = Kernel.lambda do
|
56
58
|
%x{
|
57
59
|
return (function(self) {
|
data/opal/corelib/constants.rb
CHANGED
data/opal/corelib/file.rb
CHANGED
@@ -22,12 +22,204 @@ class File < IO
|
|
22
22
|
end
|
23
23
|
alias realpath expand_path
|
24
24
|
|
25
|
+
%x{
|
26
|
+
function chompdirsep(path) {
|
27
|
+
var last;
|
28
|
+
|
29
|
+
while (path.length > 0) {
|
30
|
+
if (isDirSep(path)) {
|
31
|
+
last = path;
|
32
|
+
path = path.substring(1, path.length);
|
33
|
+
while (path.length > 0 && isDirSep(path)) {
|
34
|
+
path = inc(path);
|
35
|
+
}
|
36
|
+
if (path.length == 0) {
|
37
|
+
return last;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
else {
|
41
|
+
path = inc(path);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
return path;
|
45
|
+
}
|
46
|
+
|
47
|
+
function inc(a) {
|
48
|
+
return a.substring(1, a.length);
|
49
|
+
}
|
50
|
+
|
51
|
+
function skipprefix(path) {
|
52
|
+
return path;
|
53
|
+
}
|
54
|
+
|
55
|
+
function lastSeparator(path) {
|
56
|
+
var tmp, last;
|
57
|
+
|
58
|
+
while (path.length > 0) {
|
59
|
+
if (isDirSep(path)) {
|
60
|
+
tmp = path;
|
61
|
+
path = inc(path);
|
62
|
+
|
63
|
+
while (path.length > 0 && isDirSep(path)) {
|
64
|
+
path = inc(path);
|
65
|
+
}
|
66
|
+
if (!path) {
|
67
|
+
break;
|
68
|
+
}
|
69
|
+
last = tmp;
|
70
|
+
}
|
71
|
+
else {
|
72
|
+
path = inc(path);
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
return last;
|
77
|
+
}
|
78
|
+
|
79
|
+
function isDirSep(sep) {
|
80
|
+
return sep.charAt(0) === #{SEPARATOR};
|
81
|
+
}
|
82
|
+
|
83
|
+
function skipRoot(path) {
|
84
|
+
while (path.length > 0 && isDirSep(path)) {
|
85
|
+
path = inc(path);
|
86
|
+
}
|
87
|
+
return path;
|
88
|
+
}
|
89
|
+
|
90
|
+
function pointerSubtract(a, b) {
|
91
|
+
if (a.length == 0) {
|
92
|
+
return b.length;
|
93
|
+
}
|
94
|
+
return b.indexOf(a);
|
95
|
+
}
|
96
|
+
|
97
|
+
function handleSuffix(n, f, p, suffix, name, origName) {
|
98
|
+
var suffixMatch;
|
99
|
+
|
100
|
+
if (n >= 0) {
|
101
|
+
if (suffix === nil) {
|
102
|
+
f = n;
|
103
|
+
}
|
104
|
+
else {
|
105
|
+
suffixMatch = suffix === '.*' ? '\\.\\w+' : suffix.replace(/\?/g, '\\?');
|
106
|
+
suffixMatch = new RegExp(suffixMatch + #{Separator} + '*$').exec(p);
|
107
|
+
if (suffixMatch) {
|
108
|
+
f = suffixMatch.index;
|
109
|
+
}
|
110
|
+
else {
|
111
|
+
f = n;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
if (f === origName.length) {
|
116
|
+
return name;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
return p.substring(0, f);
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
25
124
|
def dirname(path)
|
26
|
-
|
125
|
+
%x{
|
126
|
+
if (path === nil) {
|
127
|
+
#{raise TypeError, 'no implicit conversion of nil into String'}
|
128
|
+
}
|
129
|
+
if (#{path.respond_to?(:to_path)}) {
|
130
|
+
path = #{path.to_path};
|
131
|
+
}
|
132
|
+
if (!path.$$is_string) {
|
133
|
+
#{raise TypeError, "no implicit conversion of #{path.class} into String"}
|
134
|
+
}
|
135
|
+
|
136
|
+
var root, p;
|
137
|
+
|
138
|
+
root = skipRoot(path);
|
139
|
+
|
140
|
+
// if (root > name + 1) in the C code
|
141
|
+
if (root.length == 0) {
|
142
|
+
path = path.substring(path.length - 1, path.length);
|
143
|
+
}
|
144
|
+
else if (root.length - path.length < 0) {
|
145
|
+
path = path.substring(path.indexOf(root)-1, path.length);
|
146
|
+
}
|
147
|
+
|
148
|
+
p = lastSeparator(root);
|
149
|
+
if (!p) {
|
150
|
+
p = root;
|
151
|
+
}
|
152
|
+
if (p === path) {
|
153
|
+
return '.';
|
154
|
+
}
|
155
|
+
return path.substring(0, path.length - p.length);
|
156
|
+
}
|
27
157
|
end
|
28
158
|
|
29
|
-
def basename(
|
30
|
-
|
159
|
+
def basename(name, suffix=nil)
|
160
|
+
%x{
|
161
|
+
var p, q, e, f = 0, n = -1, tmp, pointerMath, origName;
|
162
|
+
|
163
|
+
if (name === nil) {
|
164
|
+
#{raise TypeError, 'no implicit conversion of nil into String'}
|
165
|
+
}
|
166
|
+
if (#{name.respond_to?(:to_path)}) {
|
167
|
+
name = #{name.to_path};
|
168
|
+
}
|
169
|
+
if (!name.$$is_string) {
|
170
|
+
#{raise TypeError, "no implicit conversion of #{name.class} into String"}
|
171
|
+
}
|
172
|
+
if (suffix !== nil && !suffix.$$is_string) {
|
173
|
+
#{raise TypeError, "no implicit conversion of #{suffix.class} into String"}
|
174
|
+
}
|
175
|
+
|
176
|
+
if (name.length == 0) {
|
177
|
+
return name;
|
178
|
+
}
|
179
|
+
|
180
|
+
origName = name;
|
181
|
+
name = skipprefix(name);
|
182
|
+
|
183
|
+
while (isDirSep(name)) {
|
184
|
+
tmp = name;
|
185
|
+
name = inc(name);
|
186
|
+
}
|
187
|
+
|
188
|
+
if (!name) {
|
189
|
+
p = tmp;
|
190
|
+
f = 1;
|
191
|
+
}
|
192
|
+
else {
|
193
|
+
if (!(p = lastSeparator(name))) {
|
194
|
+
p = name;
|
195
|
+
}
|
196
|
+
else {
|
197
|
+
while (isDirSep(p)) {
|
198
|
+
p = inc(p);
|
199
|
+
}
|
200
|
+
}
|
201
|
+
|
202
|
+
n = pointerSubtract(chompdirsep(p), p);
|
203
|
+
|
204
|
+
for (q = p; pointerSubtract(q, p) < n && q.charAt(0) === '.'; q = inc(q)) {
|
205
|
+
}
|
206
|
+
|
207
|
+
for (e = null; pointerSubtract(q, p) < n; q = inc(q)) {
|
208
|
+
if (q.charAt(0) === '.') {
|
209
|
+
e = q;
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
213
|
+
if (e) {
|
214
|
+
f = pointerSubtract(e, p);
|
215
|
+
}
|
216
|
+
else {
|
217
|
+
f = n;
|
218
|
+
}
|
219
|
+
}
|
220
|
+
|
221
|
+
return handleSuffix(n, f, p, suffix, name, origName);
|
222
|
+
}
|
31
223
|
end
|
32
224
|
|
33
225
|
def extname(path)
|
@@ -35,7 +227,7 @@ class File < IO
|
|
35
227
|
path = path.to_path if path.respond_to?(:to_path)
|
36
228
|
raise TypeError, "no implicit conversion of #{path.class} into String" unless path.is_a?(String)
|
37
229
|
filename = basename(path)
|
38
|
-
return '' if filename.
|
230
|
+
return '' if filename.empty?
|
39
231
|
last_dot_idx = filename[1..-1].rindex('.')
|
40
232
|
# extension name must contains at least one character .(something)
|
41
233
|
(last_dot_idx.nil? || last_dot_idx + 1 == filename.length - 1) ? '' : filename[(last_dot_idx + 1)..-1]
|
data/opal/corelib/hash.rb
CHANGED
@@ -175,7 +175,7 @@ class Hash
|
|
175
175
|
end
|
176
176
|
|
177
177
|
def default(key = undefined)
|
178
|
-
|
178
|
+
%x{
|
179
179
|
if (key !== undefined && self.$$proc !== nil && self.$$proc !== undefined) {
|
180
180
|
return self.$$proc.$call(self, key);
|
181
181
|
}
|
@@ -196,12 +196,12 @@ class Hash
|
|
196
196
|
end
|
197
197
|
|
198
198
|
def default_proc
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
199
|
+
%x{
|
200
|
+
if (self.$$proc !== undefined) {
|
201
|
+
return self.$$proc;
|
202
|
+
}
|
203
|
+
return nil;
|
204
|
+
}
|
205
205
|
end
|
206
206
|
|
207
207
|
def default_proc=(proc)
|