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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/lib/opal/compiler.rb +15 -9
  4. data/lib/opal/fragment.rb +8 -1
  5. data/lib/opal/nodes/args/restarg.rb +6 -1
  6. data/lib/opal/nodes/base.rb +1 -1
  7. data/lib/opal/nodes/call.rb +4 -0
  8. data/lib/opal/nodes/def.rb +20 -25
  9. data/lib/opal/nodes/hash.rb +89 -17
  10. data/lib/opal/nodes/iter.rb +30 -2
  11. data/lib/opal/nodes/logic.rb +54 -4
  12. data/lib/opal/nodes/node_with_args.rb +72 -0
  13. data/lib/opal/parser.rb +16 -0
  14. data/lib/opal/parser/grammar.rb +2555 -2562
  15. data/lib/opal/parser/grammar.y +28 -20
  16. data/lib/opal/parser/lexer.rb +4 -4
  17. data/lib/opal/regexp_anchors.rb +13 -5
  18. data/lib/opal/source_map.rb +2 -1
  19. data/lib/opal/version.rb +1 -1
  20. data/opal/corelib/array.rb +4 -0
  21. data/opal/corelib/basic_object.rb +3 -1
  22. data/opal/corelib/constants.rb +1 -1
  23. data/opal/corelib/file.rb +196 -4
  24. data/opal/corelib/hash.rb +7 -7
  25. data/opal/corelib/kernel.rb +7 -4
  26. data/opal/corelib/marshal.rb +31 -0
  27. data/opal/corelib/marshal/read_buffer.rb +427 -0
  28. data/opal/corelib/marshal/write_buffer.rb +383 -0
  29. data/opal/corelib/method.rb +8 -0
  30. data/opal/corelib/module.rb +21 -0
  31. data/opal/corelib/number.rb +19 -5
  32. data/opal/corelib/proc.rb +33 -6
  33. data/opal/corelib/range.rb +6 -0
  34. data/opal/corelib/regexp.rb +5 -1
  35. data/opal/corelib/runtime.js +69 -17
  36. data/opal/corelib/string.rb +8 -0
  37. data/opal/corelib/string/inheritance.rb +4 -0
  38. data/opal/corelib/struct.rb +5 -0
  39. data/opal/corelib/unsupported.rb +0 -18
  40. data/opal/opal/full.rb +1 -0
  41. data/spec/filters/bugs/basicobject.rb +0 -2
  42. data/spec/filters/bugs/compiler_opal.rb +5 -0
  43. data/spec/filters/bugs/enumerable.rb +1 -0
  44. data/spec/filters/bugs/enumerator.rb +0 -2
  45. data/spec/filters/bugs/exception.rb +0 -1
  46. data/spec/filters/bugs/kernel.rb +0 -5
  47. data/spec/filters/bugs/language.rb +7 -27
  48. data/spec/filters/bugs/marshal.rb +43 -0
  49. data/spec/filters/bugs/method.rb +0 -56
  50. data/spec/filters/bugs/module.rb +0 -1
  51. data/spec/filters/bugs/proc.rb +0 -46
  52. data/spec/filters/bugs/regexp.rb +1 -0
  53. data/spec/filters/bugs/unboundmethod.rb +0 -13
  54. data/spec/filters/unsupported/bignum.rb +5 -0
  55. data/spec/filters/unsupported/freeze.rb +2 -0
  56. data/spec/filters/unsupported/marshal.rb +46 -0
  57. data/spec/filters/unsupported/symbol.rb +5 -0
  58. data/spec/lib/compiler/call_spec.rb +29 -29
  59. data/spec/lib/compiler_spec.rb +7 -1
  60. data/spec/opal/core/kernel/instance_variables_spec.rb +40 -0
  61. data/spec/opal/core/language/ternary_operator_spec.rb +6 -0
  62. data/spec/opal/core/marshal/dump_spec.rb +53 -0
  63. data/spec/opal/core/marshal/load_spec.rb +7 -0
  64. data/spec/opal/core/source_map_spec.rb +35 -1
  65. data/spec/opal/javascript_api_spec.rb +16 -0
  66. data/spec/opal/stdlib/source_map_spec.rb +8 -0
  67. data/spec/ruby_specs +7 -4
  68. data/spec/support/match_helpers.rb +57 -0
  69. data/spec/support/mspec_rspec_adapter.rb +1 -1
  70. data/stdlib/opal-parser.rb +3 -1
  71. data/stdlib/pathname.rb +105 -7
  72. data/stdlib/racc/parser.rb +551 -138
  73. data/stdlib/source_map/vlq.rb +3 -2
  74. data/tasks/testing.rake +4 -2
  75. metadata +22 -2
@@ -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
- result = new_call(val[0], val[2], val[3])
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
- open_args
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 opt_nl tRPAREN
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] << val[1]
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
@@ -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 @lex_state == :expr_endarg
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 = :LBRACE_ARG
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(IDENTIFIER_REGEXP)
1331
+ elsif scan(INLINE_IDENTIFIER_REGEXP)
1332
1332
  return process_identifier scanner.matched, cmd_start
1333
1333
  end
1334
1334
 
@@ -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 any form
14
- # This regexp contains a common rule for filtering Ruby identifiers
15
- FORBIDDEN_IDENTIFIER_CHARS = "\\u0001-\\u0020\\u0022-\\u002F\\u003A-\\u003E\\u0040\\u005B-\\u005E\\u0060\\u007B-\\u007F"
16
- IDENTIFIER_REGEXP = Regexp.new("[^#{FORBIDDEN_IDENTIFIER_CHARS}]+")
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
-
@@ -29,7 +29,8 @@ module Opal
29
29
  mapping = ::SourceMap::Mapping.new(
30
30
  source_file,
31
31
  generated_offset,
32
- source_offset
32
+ source_offset,
33
+ fragment.source_map_name
33
34
  )
34
35
  end
35
36
 
@@ -1,5 +1,5 @@
1
1
  module Opal
2
2
  # WHEN RELEASING:
3
3
  # Remember to update RUBY_ENGINE_VERSION in opal/corelib/constants.rb too!
4
- VERSION = '0.10.0.beta2'
4
+ VERSION = '0.10.0.beta3'
5
5
  end
@@ -2227,4 +2227,8 @@ class Array < `Array`
2227
2227
  }
2228
2228
  }
2229
2229
  end
2230
+
2231
+ def instance_variables
2232
+ super.reject { |ivar| `/^@\d+$/.test(#{ivar})` || ivar == '@length' }
2233
+ end
2230
2234
  end
@@ -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
- compiled = Opal.compile string, file: (file || '(eval)'), eval: true
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) {
@@ -1,7 +1,7 @@
1
1
  RUBY_PLATFORM = 'opal'
2
2
  RUBY_ENGINE = 'opal'
3
3
  RUBY_VERSION = '2.2.3'
4
- RUBY_ENGINE_VERSION = '0.10.0.beta2'
4
+ RUBY_ENGINE_VERSION = '0.10.0.beta3'
5
5
  RUBY_RELEASE_DATE = '2015-12-20'
6
6
  RUBY_PATCHLEVEL = 0
7
7
  RUBY_REVISION = 0
@@ -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
- split(path)[0..-2].join(SEPARATOR)
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(path)
30
- split(path)[-1]
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.nil?
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]
@@ -175,7 +175,7 @@ class Hash
175
175
  end
176
176
 
177
177
  def default(key = undefined)
178
- %x{
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
- %x{
200
- if (self.$$proc !== undefined) {
201
- return self.$$proc;
202
- }
203
- return nil;
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)