opal 1.2.0 → 1.3.0.alpha1

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 (159) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.await.js +6 -0
  3. data/.eslintrc.js +34 -0
  4. data/.github/workflows/build.yml +8 -0
  5. data/.rubocop.yml +9 -0
  6. data/CHANGELOG.md +4 -0
  7. data/README.md +1 -1
  8. data/Rakefile +1 -0
  9. data/UNRELEASED.md +64 -38
  10. data/docs/async.md +109 -0
  11. data/docs/roda-sprockets.md +0 -2
  12. data/exe/opal +2 -0
  13. data/exe/opal-repl +2 -2
  14. data/lib/opal/builder.rb +5 -1
  15. data/lib/opal/builder_processors.rb +7 -2
  16. data/lib/opal/cache/file_cache.rb +119 -0
  17. data/lib/opal/cache.rb +71 -0
  18. data/lib/opal/cli.rb +35 -1
  19. data/lib/opal/cli_options.rb +21 -0
  20. data/lib/opal/cli_runners/chrome.rb +21 -14
  21. data/lib/opal/cli_runners/chrome_cdp_interface.js +30285 -0
  22. data/lib/opal/cli_runners/{chrome.js → chrome_cdp_interface.rb} +27 -6
  23. data/lib/opal/cli_runners/compiler.rb +2 -1
  24. data/lib/opal/cli_runners/gjs.rb +27 -0
  25. data/lib/opal/cli_runners/mini_racer.rb +36 -0
  26. data/lib/opal/cli_runners/source-map-support-browser.js +276 -91
  27. data/lib/opal/cli_runners/source-map-support-node.js +276 -91
  28. data/lib/opal/cli_runners/source-map-support.js +60 -18
  29. data/lib/opal/cli_runners.rb +2 -0
  30. data/lib/opal/compiler.rb +99 -10
  31. data/lib/opal/fragment.rb +77 -14
  32. data/lib/opal/nodes/args/extract_kwrestarg.rb +6 -4
  33. data/lib/opal/nodes/args/extract_restarg.rb +10 -12
  34. data/lib/opal/nodes/args.rb +28 -0
  35. data/lib/opal/nodes/base.rb +29 -5
  36. data/lib/opal/nodes/call.rb +123 -2
  37. data/lib/opal/nodes/case.rb +7 -1
  38. data/lib/opal/nodes/class.rb +12 -2
  39. data/lib/opal/nodes/def.rb +3 -23
  40. data/lib/opal/nodes/definitions.rb +21 -4
  41. data/lib/opal/nodes/helpers.rb +2 -2
  42. data/lib/opal/nodes/if.rb +39 -9
  43. data/lib/opal/nodes/iter.rb +15 -3
  44. data/lib/opal/nodes/lambda.rb +3 -1
  45. data/lib/opal/nodes/literal.rb +13 -7
  46. data/lib/opal/nodes/logic.rb +2 -2
  47. data/lib/opal/nodes/module.rb +12 -2
  48. data/lib/opal/nodes/rescue.rb +59 -34
  49. data/lib/opal/nodes/scope.rb +88 -6
  50. data/lib/opal/nodes/super.rb +52 -25
  51. data/lib/opal/nodes/top.rb +13 -7
  52. data/lib/opal/nodes/while.rb +7 -1
  53. data/lib/opal/parser/patch.rb +2 -1
  54. data/lib/opal/repl.rb +137 -49
  55. data/lib/opal/rewriters/binary_operator_assignment.rb +10 -10
  56. data/lib/opal/rewriters/block_to_iter.rb +3 -3
  57. data/lib/opal/rewriters/for_rewriter.rb +7 -7
  58. data/lib/opal/rewriters/js_reserved_words.rb +5 -3
  59. data/lib/opal/source_map/file.rb +7 -4
  60. data/lib/opal/source_map/map.rb +17 -3
  61. data/lib/opal/version.rb +1 -1
  62. data/opal/corelib/array.rb +2 -2
  63. data/opal/corelib/binding.rb +46 -0
  64. data/opal/corelib/boolean.rb +54 -4
  65. data/opal/corelib/class.rb +2 -0
  66. data/opal/corelib/constants.rb +2 -2
  67. data/opal/corelib/error.rb +98 -12
  68. data/opal/corelib/io.rb +250 -38
  69. data/opal/corelib/kernel/format.rb +5 -2
  70. data/opal/corelib/kernel.rb +44 -23
  71. data/opal/corelib/main.rb +5 -0
  72. data/opal/corelib/method.rb +1 -0
  73. data/opal/corelib/module.rb +28 -0
  74. data/opal/corelib/number.rb +12 -1
  75. data/opal/corelib/random/seedrandom.js.rb +2 -2
  76. data/opal/corelib/regexp.rb +47 -3
  77. data/opal/corelib/runtime.js +152 -12
  78. data/opal/corelib/string/encoding.rb +17 -17
  79. data/opal/corelib/string.rb +2 -0
  80. data/opal/corelib/struct.rb +10 -3
  81. data/opal/corelib/trace_point.rb +57 -0
  82. data/opal/opal/full.rb +2 -0
  83. data/package.json +3 -2
  84. data/spec/filters/bugs/array.rb +0 -1
  85. data/spec/filters/bugs/basicobject.rb +0 -1
  86. data/spec/filters/bugs/binding.rb +27 -0
  87. data/spec/filters/bugs/enumerator.rb +132 -0
  88. data/spec/filters/bugs/exception.rb +70 -93
  89. data/spec/filters/bugs/float.rb +0 -1
  90. data/spec/filters/bugs/kernel.rb +3 -9
  91. data/spec/filters/bugs/language.rb +15 -58
  92. data/spec/filters/bugs/main.rb +16 -0
  93. data/spec/filters/bugs/matrix.rb +39 -0
  94. data/spec/filters/bugs/method.rb +0 -2
  95. data/spec/filters/bugs/module.rb +36 -79
  96. data/spec/filters/bugs/proc.rb +0 -1
  97. data/spec/filters/bugs/regexp.rb +0 -16
  98. data/spec/filters/bugs/trace_point.rb +12 -0
  99. data/spec/filters/bugs/warnings.rb +0 -4
  100. data/spec/filters/unsupported/freeze.rb +2 -0
  101. data/spec/filters/unsupported/privacy.rb +4 -0
  102. data/spec/lib/compiler_spec.rb +7 -1
  103. data/spec/lib/repl_spec.rb +4 -2
  104. data/spec/lib/source_map/file_spec.rb +1 -1
  105. data/spec/mspec-opal/formatters.rb +18 -4
  106. data/spec/mspec-opal/runner.rb +2 -2
  107. data/spec/opal/core/boolean_spec.rb +44 -0
  108. data/spec/opal/core/hash_spec.rb +8 -0
  109. data/spec/opal/core/number/to_s_spec.rb +11 -0
  110. data/spec/opal/stdlib/json/ext_spec.rb +3 -3
  111. data/spec/opal/stdlib/logger/logger_spec.rb +10 -1
  112. data/spec/ruby_specs +18 -0
  113. data/stdlib/await.rb +83 -0
  114. data/stdlib/base64.rb +4 -4
  115. data/stdlib/bigdecimal/bignumber.js.rb +4 -2
  116. data/stdlib/bigdecimal.rb +1 -0
  117. data/stdlib/gjs/io.rb +33 -0
  118. data/stdlib/gjs/kernel.rb +5 -0
  119. data/stdlib/gjs.rb +2 -0
  120. data/stdlib/js.rb +4 -0
  121. data/stdlib/json.rb +3 -3
  122. data/stdlib/logger.rb +1 -1
  123. data/stdlib/nashorn/file.rb +2 -0
  124. data/stdlib/nodejs/env.rb +7 -0
  125. data/stdlib/nodejs/file.rb +6 -41
  126. data/stdlib/nodejs/io.rb +21 -5
  127. data/stdlib/nodejs/js-yaml-3-6-1.js +2 -2
  128. data/stdlib/opal/miniracer.rb +6 -0
  129. data/stdlib/opal/platform.rb +4 -0
  130. data/stdlib/opal/repl_js.rb +5 -0
  131. data/stdlib/opal/replutils.rb +271 -0
  132. data/stdlib/opal-parser.rb +24 -11
  133. data/stdlib/opal-platform.rb +8 -0
  134. data/stdlib/promise/v2.rb +16 -4
  135. data/stdlib/promise.rb +14 -0
  136. data/stdlib/stringio.rb +13 -110
  137. data/stdlib/thread.rb +29 -0
  138. data/tasks/building.rake +10 -4
  139. data/tasks/linting-parse-eslint-results.js +39 -0
  140. data/tasks/linting.rake +38 -28
  141. data/tasks/performance/asciidoctor_test.rb.erb +6 -0
  142. data/tasks/performance/optimization_status.rb +77 -0
  143. data/tasks/performance.rake +149 -0
  144. data/tasks/testing.rake +9 -1
  145. data/test/nodejs/test_await.rb +169 -0
  146. data/test/opal/promisev2/test_error.rb +9 -3
  147. data/test/opal/unsupported_and_bugs.rb +5 -0
  148. data/vendored-minitest/minitest/benchmark.rb +9 -7
  149. data/vendored-minitest/minitest/test.rb +14 -12
  150. data/vendored-minitest/minitest.rb +19 -16
  151. data/yarn.lock +686 -117
  152. metadata +60 -23
  153. data/.jshintrc +0 -41
  154. data/spec/filters/unsupported/refinements.rb +0 -8
  155. data/vendored-minitest/minitest/hell.rb +0 -11
  156. data/vendored-minitest/minitest/parallel.rb +0 -65
  157. data/vendored-minitest/minitest/pride.rb +0 -4
  158. data/vendored-minitest/minitest/pride_plugin.rb +0 -142
  159. data/vendored-minitest/minitest/unit.rb +0 -45
@@ -1,5 +1,5 @@
1
1
  class Exception < `Error`
2
- # `var Kernel$raise = #{Kernel}.$raise`
2
+ `Opal.defineProperty(self.$$prototype, '$$is_exception', true)`
3
3
  `var stack_trace_limit`
4
4
 
5
5
  def self.new(*args)
@@ -8,6 +8,7 @@ class Exception < `Error`
8
8
  var error = new self.$$constructor(message);
9
9
  error.name = self.$$name;
10
10
  error.message = message;
11
+ error.cause = #{$!};
11
12
  Opal.send(error, error.$initialize, args);
12
13
 
13
14
  // Error.captureStackTrace() will use .name and .toString to build the
@@ -33,6 +34,37 @@ class Exception < `Error`
33
34
  `self.message = (args.length > 0) ? args[0] : nil`
34
35
  end
35
36
 
37
+ %x{
38
+ // Convert backtrace from any format to Ruby format
39
+ function correct_backtrace(backtrace) {
40
+ var new_bt = [], m;
41
+
42
+ for (var i = 0; i < backtrace.length; i++) {
43
+ var loc = backtrace[i];
44
+ if (!loc || !loc.$$is_string) {
45
+ /* Do nothing */
46
+ }
47
+ /* Chromium format */
48
+ else if ((m = loc.match(/^ at (.*?) \((.*?)\)$/))) {
49
+ new_bt.push(m[2] + ":in `" + m[1] + "'");
50
+ }
51
+ else if ((m = loc.match(/^ at (.*?)$/))) {
52
+ new_bt.push(m[1] + ":in `undefined'");
53
+ }
54
+ /* Node format */
55
+ else if ((m = loc.match(/^ from (.*?)$/))) {
56
+ new_bt.push(m[1]);
57
+ }
58
+ /* Mozilla/Apple format */
59
+ else if ((m = loc.match(/^(.*?)@(.*?)$/))) {
60
+ new_bt.push(m[2] + ':in `' + m[1] + "'");
61
+ }
62
+ }
63
+
64
+ return new_bt;
65
+ }
66
+ }
67
+
36
68
  def backtrace
37
69
  %x{
38
70
  if (self.backtrace) {
@@ -42,17 +74,31 @@ class Exception < `Error`
42
74
 
43
75
  var backtrace = self.stack;
44
76
 
45
- if (typeof(backtrace) === 'string') {
46
- return backtrace.split("\n").slice(0, 15);
77
+ if (backtrace.$$is_string) {
78
+ return self.backtrace = correct_backtrace(backtrace.split("\n").slice(0, 15));
47
79
  }
48
80
  else if (backtrace) {
49
- return backtrace.slice(0, 15);
81
+ return self.backtrace = correct_backtrace(backtrace.slice(0, 15));
50
82
  }
51
83
 
52
84
  return [];
53
85
  }
54
86
  end
55
87
 
88
+ def backtrace_locations
89
+ %x{
90
+ if (self.backtrace_locations) return self.backtrace_locations;
91
+ self.backtrace_locations = #{backtrace&.map do |loc|
92
+ ::Thread::Backtrace::Location.new(loc)
93
+ end}
94
+ return self.backtrace_locations;
95
+ }
96
+ end
97
+
98
+ def cause
99
+ `self.cause || nil`
100
+ end
101
+
56
102
  def exception(str = nil)
57
103
  %x{
58
104
  if (str === nil || self === str) {
@@ -61,7 +107,9 @@ class Exception < `Error`
61
107
 
62
108
  var cloned = #{clone};
63
109
  cloned.message = str;
110
+ if (self.backtrace) cloned.backtrace = self.backtrace.$dup();
64
111
  cloned.stack = self.stack;
112
+ cloned.cause = self.cause;
65
113
  return cloned;
66
114
  }
67
115
  end
@@ -71,6 +119,37 @@ class Exception < `Error`
71
119
  to_s
72
120
  end
73
121
 
122
+ def full_message(highlight: $stderr.tty?, order: :top)
123
+ raise ArgumentError, "expected true or false as highlight: #{highlight}" unless [true, false].include? highlight
124
+ raise ArgumentError, "expected :top or :bottom as order: #{order}" unless %i[top bottom].include? order
125
+
126
+ if highlight
127
+ bold_underline = "\e[1;4m"
128
+ bold = "\e[1m"
129
+ reset = "\e[m"
130
+ else
131
+ bold_underline = bold = reset = ''
132
+ end
133
+
134
+ bt = backtrace.dup
135
+ bt = caller if !bt || bt.empty?
136
+ first = bt.shift
137
+
138
+ msg = "#{first}: "
139
+ msg += "#{bold}#{to_s} (#{bold_underline}#{self.class}#{reset}#{bold})#{reset}\n"
140
+
141
+ msg += bt.map { |loc| "\tfrom #{loc}\n" }.join
142
+
143
+ msg += cause.full_message(highlight: highlight) if cause
144
+
145
+ if order == :bottom
146
+ msg = msg.split("\n").reverse.join("\n")
147
+ msg = "#{bold}Traceback#{reset} (most recent call last):\n" + msg
148
+ end
149
+
150
+ msg
151
+ end
152
+
74
153
  def inspect
75
154
  as_str = to_s
76
155
  as_str.empty? ? self.class.to_s : "#<#{self.class.to_s}: #{to_s}>"
@@ -85,7 +164,7 @@ class Exception < `Error`
85
164
  self.stack = '';
86
165
  } else if (backtrace.$$is_string) {
87
166
  self.backtrace = [backtrace];
88
- self.stack = backtrace;
167
+ self.stack = ' from ' + backtrace;
89
168
  } else {
90
169
  if (backtrace.$$is_array) {
91
170
  for (i = 0, ii = backtrace.length; i < ii; i++) {
@@ -103,7 +182,7 @@ class Exception < `Error`
103
182
  }
104
183
 
105
184
  self.backtrace = backtrace;
106
- self.stack = backtrace.join('\n');
185
+ self.stack = #{`backtrace`.map { |i| ' from ' + i }}.join("\n");
107
186
  }
108
187
 
109
188
  return backtrace;
@@ -125,8 +204,9 @@ class NotImplementedError < ScriptError; end
125
204
  class SystemExit < Exception; end
126
205
  class NoMemoryError < Exception; end
127
206
  class SignalException < Exception; end
128
- class Interrupt < Exception; end
207
+ class Interrupt < SignalException; end
129
208
  class SecurityError < Exception; end
209
+ class SystemStackError < Exception; end
130
210
 
131
211
  class StandardError < Exception; end
132
212
  class EncodingError < StandardError; end
@@ -138,13 +218,19 @@ class FrozenError < RuntimeError; end
138
218
  class LocalJumpError < StandardError; end
139
219
  class TypeError < StandardError; end
140
220
  class ArgumentError < StandardError; end
221
+ class UncaughtThrowError < ArgumentError; end
141
222
  class IndexError < StandardError; end
142
223
  class StopIteration < IndexError; end
224
+ class ClosedQueueError < StopIteration; end
143
225
  class KeyError < IndexError; end
144
226
  class RangeError < StandardError; end
145
227
  class FloatDomainError < RangeError; end
146
228
  class IOError < StandardError; end
229
+ class EOFError < IOError; end
147
230
  class SystemCallError < StandardError; end
231
+ class RegexpError < StandardError; end
232
+ class ThreadError < StandardError; end
233
+ class FiberError < StandardError; end
148
234
 
149
235
  module Errno
150
236
  class EINVAL < SystemCallError
@@ -157,13 +243,13 @@ module Errno
157
243
  end
158
244
 
159
245
  class UncaughtThrowError < ArgumentError
160
- attr_reader :sym, :arg
246
+ attr_reader :tag, :value
161
247
 
162
- def initialize(args)
163
- @sym = args[0]
164
- @arg = args[1] if args.length > 1
248
+ def initialize(tag, value = nil)
249
+ @tag = tag
250
+ @value = value
165
251
 
166
- super("uncaught throw #{@sym.inspect}")
252
+ super("uncaught throw #{@tag.inspect}")
167
253
  end
168
254
  end
169
255
 
data/opal/corelib/io.rb CHANGED
@@ -2,16 +2,30 @@ class IO
2
2
  SEEK_SET = 0
3
3
  SEEK_CUR = 1
4
4
  SEEK_END = 2
5
+ SEEK_DATA = 3
6
+ SEEK_HOLE = 4
5
7
 
6
- def tty?
7
- @tty
8
+ READABLE = 1
9
+ WRITABLE = 4
10
+
11
+ def initialize(fd, flags = 'r')
12
+ @fd = fd
13
+ @flags = flags
14
+ @eof = false
15
+
16
+ if flags.include?('r') && !flags.match?(/[wa+]/)
17
+ @closed = :write
18
+ elsif flags.match?(/[wa]/) && !flags.match?(/[r+]/)
19
+ @closed = :read
20
+ end
8
21
  end
9
22
 
10
- def closed?
11
- @closed
23
+ def tty?
24
+ `self.tty == true`
12
25
  end
13
26
 
14
27
  attr_accessor :write_proc
28
+ attr_accessor :read_proc
15
29
 
16
30
  def write(string)
17
31
  `self.write_proc(string)`
@@ -20,63 +34,261 @@ class IO
20
34
 
21
35
  attr_accessor :sync, :tty
22
36
 
37
+ attr_reader :eof
38
+ alias eof? eof
39
+
23
40
  def flush
24
41
  # noop
25
42
  end
26
43
 
27
- module Writable
28
- def <<(string)
29
- write(string)
30
- self
31
- end
44
+ def <<(string)
45
+ write(string)
46
+ self
47
+ end
32
48
 
33
- def print(*args)
34
- %x{
35
- for (var i = 0, ii = args.length; i < ii; i++) {
36
- args[i] = #{String(`args[i]`)}
37
- }
38
- self.$write(args.join(#{$,}));
49
+ def print(*args)
50
+ %x{
51
+ for (var i = 0, ii = args.length; i < ii; i++) {
52
+ args[i] = #{String(`args[i]`)}
39
53
  }
40
- nil
41
- end
54
+ self.$write(args.join(#{$,}));
55
+ }
56
+ nil
57
+ end
42
58
 
43
- def puts(*args)
44
- %x{
45
- for (var i = 0, ii = args.length; i < ii; i++) {
46
- args[i] = #{String(`args[i]`).chomp}
47
- }
48
- self.$write(args.concat([nil]).join(#{$/}));
59
+ def puts(*args)
60
+ %x{
61
+ for (var i = 0, ii = args.length; i < ii; i++) {
62
+ args[i] = #{String(`args[i]`).chomp}
49
63
  }
50
- nil
64
+ self.$write(args.concat([nil]).join(#{$/}));
65
+ }
66
+ nil
67
+ end
68
+
69
+ # Reading
70
+
71
+ def getc
72
+ @read_buffer ||= ''
73
+ parts = ''
74
+
75
+ # Will execure at most twice - one time reading from a buffer
76
+ # second time
77
+ begin
78
+ @read_buffer += parts
79
+ if @read_buffer != ''
80
+ ret = @read_buffer[0]
81
+ @read_buffer = @read_buffer[1..-1]
82
+ return ret
83
+ end
84
+ end while parts = sysread_noraise(1)
85
+
86
+ nil
87
+ end
88
+
89
+ def getbyte
90
+ getc&.ord
91
+ end
92
+
93
+ def readbyte
94
+ readchar.ord
95
+ end
96
+
97
+ def readchar
98
+ getc || raise(EOFError, 'end of file reached')
99
+ end
100
+
101
+ def readline(*args)
102
+ gets(*args) || raise(EOFError, 'end of file reached')
103
+ end
104
+
105
+ def gets(sep = false, limit = nil, opts = {})
106
+ if `sep.$$is_number` && !limit
107
+ sep, limit, opts = false, sep, limit
108
+ end
109
+ if `sep.$$is_hash` && !limit && opts == {}
110
+ sep, limit, opts = false, nil, sep
111
+ elsif `limit.$$is_hash` && opts == {}
112
+ sep, limit, opts = sep, nil, limit
113
+ end
114
+
115
+ orig_sep = sep
116
+
117
+ sep = $/ if sep == false
118
+ sep = /\r?\n\r?\n/ if sep == ''
119
+ sep ||= ''
120
+ sep = sep.to_str unless orig_sep == ''
121
+
122
+ # Try to deduce length of a regexp
123
+ seplen = `orig_sep == '' ? 2 : sep.length`
124
+
125
+ sep = / / if sep == ' ' # WTF is this, String#split(" ") matches all whitespaces???
126
+
127
+ @read_buffer ||= ''
128
+ data = ''
129
+ ret = nil
130
+
131
+ begin
132
+ @read_buffer += data
133
+ if sep != '' && (`sep.$$is_regexp` ? @read_buffer.match?(sep) : @read_buffer.include?(sep))
134
+ orig_buffer = @read_buffer
135
+ ret, @read_buffer = @read_buffer.split(sep, 2)
136
+ ret += orig_buffer[ret.length, seplen] if ret != orig_buffer
137
+ break
138
+ end
139
+ end while data = sysread_noraise(sep == '' ? 65_536 : 1)
140
+
141
+ unless ret
142
+ ret, @read_buffer = (@read_buffer || ''), ''
143
+ ret = nil if ret == ''
144
+ end
145
+
146
+ if ret
147
+ if limit
148
+ ret = ret[0...limit]
149
+ @read_buffer = ret[limit..-1] + @read_buffer
150
+ end
151
+ ret = ret.sub(/\r?\n\z/, '') if opts[:chomp]
152
+ ret = ret.sub(/\A[\r\n]+/, '') if orig_sep == ''
51
153
  end
154
+
155
+ $_ = ret if orig_sep == false
156
+ ret
52
157
  end
53
158
 
54
- module Readable
55
- def readbyte
56
- getbyte
159
+ # This method is to be overloaded, or read_proc can be changed
160
+ def sysread(integer)
161
+ `self.read_proc(integer)` || begin
162
+ @eof = true
163
+ raise EOFError, 'end of file reached'
57
164
  end
165
+ end
166
+
167
+ # @private
168
+ def sysread_noraise(integer)
169
+ sysread(integer)
170
+ rescue EOFError
171
+ nil
172
+ end
58
173
 
59
- def readchar
60
- getc
174
+ def readpartial(integer)
175
+ @read_buffer ||= ''
176
+ part = sysread(integer)
177
+ ret, @read_buffer = @read_buffer + (part || ''), ''
178
+ ret = nil if ret == ''
179
+ ret
180
+ end
181
+
182
+ def read(integer = nil)
183
+ @read_buffer ||= ''
184
+ parts = ''
185
+ ret = nil
186
+
187
+ begin
188
+ @read_buffer += parts
189
+ if integer && @read_buffer.length > integer
190
+ ret, @read_buffer = @read_buffer[0...integer], @read_buffer[integer..-1]
191
+ return ret
192
+ end
193
+ end while parts = sysread_noraise(integer || 65_536)
194
+
195
+ ret, @read_buffer = @read_buffer, ''
196
+ ret
197
+ end
198
+
199
+ # Eaches
200
+
201
+ def readlines(separator = $/)
202
+ each_line(separator).to_a
203
+ end
204
+
205
+ def each(sep = $/, *args, &block)
206
+ return enum_for :each, sep, *args unless block_given?
207
+
208
+ while (s = gets(sep, *args))
209
+ yield(s)
210
+ end
211
+
212
+ self
213
+ end
214
+
215
+ alias each_line each
216
+
217
+ def each_byte(&block)
218
+ return enum_for :each_byte unless block_given?
219
+
220
+ while (s = getbyte)
221
+ yield(s)
222
+ end
223
+
224
+ self
225
+ end
226
+
227
+ def each_char(&block)
228
+ return enum_for :each_char unless block_given?
229
+
230
+ while (s = getc)
231
+ yield(s)
232
+ end
233
+
234
+ self
235
+ end
236
+
237
+ # Closedness
238
+
239
+ def close
240
+ @closed = :both
241
+ end
242
+
243
+ def close_read
244
+ if @closed == :write
245
+ @closed = :both
246
+ else
247
+ @closed = :read
248
+ end
249
+ end
250
+
251
+ def close_write
252
+ if @closed == :read
253
+ @closed = :both
254
+ else
255
+ @closed = :write
61
256
  end
257
+ end
258
+
259
+ def closed?
260
+ @closed == :both
261
+ end
62
262
 
63
- def readline(sep = $/)
64
- raise NotImplementedError
263
+ def closed_read?
264
+ @closed == :read || @closed == :both
265
+ end
266
+
267
+ def closed_write?
268
+ @closed == :write || @closed == :both
269
+ end
270
+
271
+ # @private
272
+ def check_writable
273
+ if closed_write?
274
+ raise IOError, 'not opened for writing'
65
275
  end
276
+ end
66
277
 
67
- def readpartial(integer, outbuf = nil)
68
- raise NotImplementedError
278
+ # @private
279
+ def check_readable
280
+ if closed_read?
281
+ raise IOError, 'not opened for reading'
69
282
  end
70
283
  end
71
284
  end
72
285
 
73
- STDERR = $stderr = IO.new
74
- STDIN = $stdin = IO.new
75
- STDOUT = $stdout = IO.new
286
+ STDIN = $stdin = IO.new(0, 'r')
287
+ STDOUT = $stdout = IO.new(1, 'w')
288
+ STDERR = $stderr = IO.new(2, 'w')
76
289
 
77
290
  `var console = Opal.global.console`
78
291
  STDOUT.write_proc = `typeof(process) === 'object' && typeof(process.stdout) === 'object' ? function(s){process.stdout.write(s)} : function(s){console.log(s)}`
79
292
  STDERR.write_proc = `typeof(process) === 'object' && typeof(process.stderr) === 'object' ? function(s){process.stderr.write(s)} : function(s){console.warn(s)}`
80
293
 
81
- STDOUT.extend(IO::Writable)
82
- STDERR.extend(IO::Writable)
294
+ STDIN.read_proc = `function(s) { var p = prompt(); if (p !== null) return p + "\n"; return nil; }`
@@ -66,8 +66,8 @@ module Kernel
66
66
 
67
67
  function GET_NEXT_ARG() {
68
68
  switch (pos_arg_num) {
69
- case -1: #{raise ArgumentError, "unnumbered(#{`seq_arg_num`}) mixed with numbered"}
70
- case -2: #{raise ArgumentError, "unnumbered(#{`seq_arg_num`}) mixed with named"}
69
+ case -1: #{raise ArgumentError, "unnumbered(#{`seq_arg_num`}) mixed with numbered"} // raise
70
+ case -2: #{raise ArgumentError, "unnumbered(#{`seq_arg_num`}) mixed with named"} // raise
71
71
  }
72
72
  pos_arg_num = seq_arg_num++;
73
73
  return GET_NTH_ARG(pos_arg_num - 1);
@@ -135,6 +135,7 @@ module Kernel
135
135
  switch (format_string.charAt(i)) {
136
136
  case '%':
137
137
  begin_slice = i;
138
+ // no-break
138
139
  case '':
139
140
  case '\n':
140
141
  case '\0':
@@ -240,6 +241,7 @@ module Kernel
240
241
  }
241
242
  hash_parameter_key += format_string.charAt(i);
242
243
  }
244
+ // raise
243
245
 
244
246
  case '*':
245
247
  i++;
@@ -482,6 +484,7 @@ module Kernel
482
484
  case 'A':
483
485
  // Not implemented because there are no specs for this field type.
484
486
  #{raise NotImplementedError, '`A` and `a` format field types are not implemented in Opal yet'}
487
+ // raise
485
488
 
486
489
  case 'c':
487
490
  arg = GET_ARG();