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.
- 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();
|