opal 1.2.0 → 1.3.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintrc.await.js +6 -0
- data/.eslintrc.js +34 -0
- data/.github/workflows/build.yml +8 -0
- data/.rubocop.yml +9 -0
- data/CHANGELOG.md +4 -0
- data/README.md +1 -1
- data/Rakefile +1 -0
- data/UNRELEASED.md +64 -38
- data/docs/async.md +109 -0
- data/docs/roda-sprockets.md +0 -2
- data/exe/opal +2 -0
- data/exe/opal-repl +2 -2
- data/lib/opal/builder.rb +5 -1
- data/lib/opal/builder_processors.rb +7 -2
- data/lib/opal/cache/file_cache.rb +119 -0
- data/lib/opal/cache.rb +71 -0
- data/lib/opal/cli.rb +35 -1
- data/lib/opal/cli_options.rb +21 -0
- data/lib/opal/cli_runners/chrome.rb +21 -14
- data/lib/opal/cli_runners/chrome_cdp_interface.js +30285 -0
- data/lib/opal/cli_runners/{chrome.js → chrome_cdp_interface.rb} +27 -6
- data/lib/opal/cli_runners/compiler.rb +2 -1
- data/lib/opal/cli_runners/gjs.rb +27 -0
- data/lib/opal/cli_runners/mini_racer.rb +36 -0
- data/lib/opal/cli_runners/source-map-support-browser.js +276 -91
- data/lib/opal/cli_runners/source-map-support-node.js +276 -91
- data/lib/opal/cli_runners/source-map-support.js +60 -18
- data/lib/opal/cli_runners.rb +2 -0
- data/lib/opal/compiler.rb +99 -10
- data/lib/opal/fragment.rb +77 -14
- data/lib/opal/nodes/args/extract_kwrestarg.rb +6 -4
- data/lib/opal/nodes/args/extract_restarg.rb +10 -12
- data/lib/opal/nodes/args.rb +28 -0
- data/lib/opal/nodes/base.rb +29 -5
- data/lib/opal/nodes/call.rb +123 -2
- data/lib/opal/nodes/case.rb +7 -1
- data/lib/opal/nodes/class.rb +12 -2
- data/lib/opal/nodes/def.rb +3 -23
- data/lib/opal/nodes/definitions.rb +21 -4
- data/lib/opal/nodes/helpers.rb +2 -2
- data/lib/opal/nodes/if.rb +39 -9
- data/lib/opal/nodes/iter.rb +15 -3
- data/lib/opal/nodes/lambda.rb +3 -1
- data/lib/opal/nodes/literal.rb +13 -7
- data/lib/opal/nodes/logic.rb +2 -2
- data/lib/opal/nodes/module.rb +12 -2
- data/lib/opal/nodes/rescue.rb +59 -34
- data/lib/opal/nodes/scope.rb +88 -6
- data/lib/opal/nodes/super.rb +52 -25
- data/lib/opal/nodes/top.rb +13 -7
- data/lib/opal/nodes/while.rb +7 -1
- data/lib/opal/parser/patch.rb +2 -1
- data/lib/opal/repl.rb +137 -49
- data/lib/opal/rewriters/binary_operator_assignment.rb +10 -10
- data/lib/opal/rewriters/block_to_iter.rb +3 -3
- data/lib/opal/rewriters/for_rewriter.rb +7 -7
- data/lib/opal/rewriters/js_reserved_words.rb +5 -3
- data/lib/opal/source_map/file.rb +7 -4
- data/lib/opal/source_map/map.rb +17 -3
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/array.rb +2 -2
- data/opal/corelib/binding.rb +46 -0
- data/opal/corelib/boolean.rb +54 -4
- data/opal/corelib/class.rb +2 -0
- data/opal/corelib/constants.rb +2 -2
- data/opal/corelib/error.rb +98 -12
- data/opal/corelib/io.rb +250 -38
- data/opal/corelib/kernel/format.rb +5 -2
- data/opal/corelib/kernel.rb +44 -23
- data/opal/corelib/main.rb +5 -0
- data/opal/corelib/method.rb +1 -0
- data/opal/corelib/module.rb +28 -0
- data/opal/corelib/number.rb +12 -1
- data/opal/corelib/random/seedrandom.js.rb +2 -2
- data/opal/corelib/regexp.rb +47 -3
- data/opal/corelib/runtime.js +152 -12
- data/opal/corelib/string/encoding.rb +17 -17
- data/opal/corelib/string.rb +2 -0
- data/opal/corelib/struct.rb +10 -3
- data/opal/corelib/trace_point.rb +57 -0
- data/opal/opal/full.rb +2 -0
- data/package.json +3 -2
- data/spec/filters/bugs/array.rb +0 -1
- data/spec/filters/bugs/basicobject.rb +0 -1
- data/spec/filters/bugs/binding.rb +27 -0
- data/spec/filters/bugs/enumerator.rb +132 -0
- data/spec/filters/bugs/exception.rb +70 -93
- data/spec/filters/bugs/float.rb +0 -1
- data/spec/filters/bugs/kernel.rb +3 -9
- data/spec/filters/bugs/language.rb +15 -58
- data/spec/filters/bugs/main.rb +16 -0
- data/spec/filters/bugs/matrix.rb +39 -0
- data/spec/filters/bugs/method.rb +0 -2
- data/spec/filters/bugs/module.rb +36 -79
- data/spec/filters/bugs/proc.rb +0 -1
- data/spec/filters/bugs/regexp.rb +0 -16
- data/spec/filters/bugs/trace_point.rb +12 -0
- data/spec/filters/bugs/warnings.rb +0 -4
- data/spec/filters/unsupported/freeze.rb +2 -0
- data/spec/filters/unsupported/privacy.rb +4 -0
- data/spec/lib/compiler_spec.rb +7 -1
- data/spec/lib/repl_spec.rb +4 -2
- data/spec/lib/source_map/file_spec.rb +1 -1
- data/spec/mspec-opal/formatters.rb +18 -4
- data/spec/mspec-opal/runner.rb +2 -2
- data/spec/opal/core/boolean_spec.rb +44 -0
- data/spec/opal/core/hash_spec.rb +8 -0
- data/spec/opal/core/number/to_s_spec.rb +11 -0
- data/spec/opal/stdlib/json/ext_spec.rb +3 -3
- data/spec/opal/stdlib/logger/logger_spec.rb +10 -1
- data/spec/ruby_specs +18 -0
- data/stdlib/await.rb +83 -0
- data/stdlib/base64.rb +4 -4
- data/stdlib/bigdecimal/bignumber.js.rb +4 -2
- data/stdlib/bigdecimal.rb +1 -0
- data/stdlib/gjs/io.rb +33 -0
- data/stdlib/gjs/kernel.rb +5 -0
- data/stdlib/gjs.rb +2 -0
- data/stdlib/js.rb +4 -0
- data/stdlib/json.rb +3 -3
- data/stdlib/logger.rb +1 -1
- data/stdlib/nashorn/file.rb +2 -0
- data/stdlib/nodejs/env.rb +7 -0
- data/stdlib/nodejs/file.rb +6 -41
- data/stdlib/nodejs/io.rb +21 -5
- data/stdlib/nodejs/js-yaml-3-6-1.js +2 -2
- data/stdlib/opal/miniracer.rb +6 -0
- data/stdlib/opal/platform.rb +4 -0
- data/stdlib/opal/repl_js.rb +5 -0
- data/stdlib/opal/replutils.rb +271 -0
- data/stdlib/opal-parser.rb +24 -11
- data/stdlib/opal-platform.rb +8 -0
- data/stdlib/promise/v2.rb +16 -4
- data/stdlib/promise.rb +14 -0
- data/stdlib/stringio.rb +13 -110
- data/stdlib/thread.rb +29 -0
- data/tasks/building.rake +10 -4
- data/tasks/linting-parse-eslint-results.js +39 -0
- data/tasks/linting.rake +38 -28
- data/tasks/performance/asciidoctor_test.rb.erb +6 -0
- data/tasks/performance/optimization_status.rb +77 -0
- data/tasks/performance.rake +149 -0
- data/tasks/testing.rake +9 -1
- data/test/nodejs/test_await.rb +169 -0
- data/test/opal/promisev2/test_error.rb +9 -3
- data/test/opal/unsupported_and_bugs.rb +5 -0
- data/vendored-minitest/minitest/benchmark.rb +9 -7
- data/vendored-minitest/minitest/test.rb +14 -12
- data/vendored-minitest/minitest.rb +19 -16
- data/yarn.lock +686 -117
- metadata +60 -23
- data/.jshintrc +0 -41
- data/spec/filters/unsupported/refinements.rb +0 -8
- data/vendored-minitest/minitest/hell.rb +0 -11
- data/vendored-minitest/minitest/parallel.rb +0 -65
- data/vendored-minitest/minitest/pride.rb +0 -4
- data/vendored-minitest/minitest/pride_plugin.rb +0 -142
- data/vendored-minitest/minitest/unit.rb +0 -45
data/opal/corelib/error.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Exception < `Error`
|
2
|
-
|
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 (
|
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(
|
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
|
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 :
|
246
|
+
attr_reader :tag, :value
|
161
247
|
|
162
|
-
def initialize(
|
163
|
-
@
|
164
|
-
@
|
248
|
+
def initialize(tag, value = nil)
|
249
|
+
@tag = tag
|
250
|
+
@value = value
|
165
251
|
|
166
|
-
super("uncaught throw #{@
|
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
|
-
|
7
|
-
|
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
|
11
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
44
|
+
def <<(string)
|
45
|
+
write(string)
|
46
|
+
self
|
47
|
+
end
|
32
48
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
41
|
-
|
54
|
+
self.$write(args.join(#{$,}));
|
55
|
+
}
|
56
|
+
nil
|
57
|
+
end
|
42
58
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
60
|
-
|
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
|
-
|
64
|
-
|
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
|
-
|
68
|
-
|
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
|
-
|
74
|
-
|
75
|
-
|
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
|
-
|
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();
|