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
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
require 'pp'
|
|
2
|
+
require 'stringio'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
module REPLUtils
|
|
6
|
+
module_function
|
|
7
|
+
|
|
8
|
+
def ls(object, colorize)
|
|
9
|
+
methods = imethods = object.methods
|
|
10
|
+
ancestors = object.class.ancestors
|
|
11
|
+
constants = []
|
|
12
|
+
ivs = object.instance_variables
|
|
13
|
+
cvs = []
|
|
14
|
+
|
|
15
|
+
if [Class, Module].include? object.class
|
|
16
|
+
imethods = object.instance_methods
|
|
17
|
+
ancestors = object.ancestors
|
|
18
|
+
constants = object.constants
|
|
19
|
+
cvs = object.class_variables
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
if colorize
|
|
23
|
+
blue = ->(i) { "\e[1;34m#{i}\e[0m" }
|
|
24
|
+
dark_blue = ->(i) { "\e[34m#{i}\e[0m" }
|
|
25
|
+
else
|
|
26
|
+
blue = dark_blue = ->(i) { i }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
out = ''
|
|
30
|
+
out = "#{blue['class variables']}: #{cvs.map { |i| dark_blue[i] }.sort.join(' ')}\n" + out unless cvs.empty?
|
|
31
|
+
out = "#{blue['instance variables']}: #{ivs.map { |i| dark_blue[i] }.sort.join(' ')}\n" + out unless ivs.empty?
|
|
32
|
+
ancestors.each do |a|
|
|
33
|
+
im = a.instance_methods(false)
|
|
34
|
+
meths = (im & imethods)
|
|
35
|
+
methods -= meths
|
|
36
|
+
imethods -= meths
|
|
37
|
+
next if meths.empty? || [Object, BasicObject, Kernel, PP::ObjectMixin].include?(a)
|
|
38
|
+
out = "#{blue["#{a.name}#methods"]}: #{meths.sort.join(' ')}\n" + out
|
|
39
|
+
end
|
|
40
|
+
methods &= object.methods(false)
|
|
41
|
+
out = "#{blue['self.methods']}: #{methods.sort.join(' ')}\n" + out unless methods.empty?
|
|
42
|
+
out = "#{blue['constants']}: #{constants.map { |i| dark_blue[i] }.sort.join(' ')}\n" + out unless constants.empty?
|
|
43
|
+
out
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def eval_and_print(func, mode, colorize)
|
|
47
|
+
printer = if colorize
|
|
48
|
+
->(i) { ColorPrinter.default(i) }
|
|
49
|
+
else
|
|
50
|
+
->(i) { out = []; PP.pp(i, out); out.join }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
%x{
|
|
54
|
+
var $_result = eval(func);
|
|
55
|
+
|
|
56
|
+
if (mode == 'silent') return nil;
|
|
57
|
+
|
|
58
|
+
if (typeof $_result === 'null') {
|
|
59
|
+
return "=> null";
|
|
60
|
+
}
|
|
61
|
+
else if (typeof $_result === 'undefined') {
|
|
62
|
+
return "=> undefined";
|
|
63
|
+
}
|
|
64
|
+
else if (typeof $_result.$$class === 'undefined') {
|
|
65
|
+
try {
|
|
66
|
+
var json = JSON.stringify($_result, null, 2);
|
|
67
|
+
if (!colorize) json = #{ColorPrinter.colorize(`json`)}
|
|
68
|
+
return "=> " + $_result.toString() + " => " + json;
|
|
69
|
+
}
|
|
70
|
+
catch(e) {
|
|
71
|
+
return "=> " + $_result.toString();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
if (mode == 'ls') {
|
|
76
|
+
return #{ls(`$_result`, colorize)};
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
var pretty = #{printer.call(`$_result`)};
|
|
80
|
+
// Is it multiline? If yes, add a linebreak
|
|
81
|
+
if (pretty.match(/\n.*?\n/)) pretty = "\n" + pretty;
|
|
82
|
+
return "=> " + pretty;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
87
|
+
e.full_message(highlight: true)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def js_repl
|
|
91
|
+
while (line = gets)
|
|
92
|
+
input = JSON.parse(line)
|
|
93
|
+
|
|
94
|
+
out = eval_and_print(input[:code], input[:mode], input[:colors])
|
|
95
|
+
puts out if out
|
|
96
|
+
puts '<<<ready>>>'
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Slightly based on Pry's implementation
|
|
101
|
+
class ColorPrinter < ::PP
|
|
102
|
+
# Taken from CodeRay
|
|
103
|
+
TOKEN_COLORS = {
|
|
104
|
+
debug: "\e[1;37;44m",
|
|
105
|
+
|
|
106
|
+
annotation: "\e[34m",
|
|
107
|
+
attribute_name: "\e[35m",
|
|
108
|
+
attribute_value: "\e[31m",
|
|
109
|
+
binary: {
|
|
110
|
+
self: "\e[31m",
|
|
111
|
+
char: "\e[1;31m",
|
|
112
|
+
delimiter: "\e[1;31m",
|
|
113
|
+
},
|
|
114
|
+
char: {
|
|
115
|
+
self: "\e[35m",
|
|
116
|
+
delimiter: "\e[1;35m"
|
|
117
|
+
},
|
|
118
|
+
class: "\e[1;35;4m",
|
|
119
|
+
class_variable: "\e[36m",
|
|
120
|
+
color: "\e[32m",
|
|
121
|
+
comment: {
|
|
122
|
+
self: "\e[1;30m",
|
|
123
|
+
char: "\e[37m",
|
|
124
|
+
delimiter: "\e[37m",
|
|
125
|
+
},
|
|
126
|
+
constant: "\e[1;34;4m",
|
|
127
|
+
decorator: "\e[35m",
|
|
128
|
+
definition: "\e[1;33m",
|
|
129
|
+
directive: "\e[33m",
|
|
130
|
+
docstring: "\e[31m",
|
|
131
|
+
doctype: "\e[1;34m",
|
|
132
|
+
done: "\e[1;30;2m",
|
|
133
|
+
entity: "\e[31m",
|
|
134
|
+
error: "\e[1;37;41m",
|
|
135
|
+
exception: "\e[1;31m",
|
|
136
|
+
float: "\e[1;35m",
|
|
137
|
+
function: "\e[1;34m",
|
|
138
|
+
global_variable: "\e[1;32m",
|
|
139
|
+
hex: "\e[1;36m",
|
|
140
|
+
id: "\e[1;34m",
|
|
141
|
+
include: "\e[31m",
|
|
142
|
+
integer: "\e[1;34m",
|
|
143
|
+
imaginary: "\e[1;34m",
|
|
144
|
+
important: "\e[1;31m",
|
|
145
|
+
key: {
|
|
146
|
+
self: "\e[35m",
|
|
147
|
+
char: "\e[1;35m",
|
|
148
|
+
delimiter: "\e[1;35m",
|
|
149
|
+
},
|
|
150
|
+
keyword: "\e[32m",
|
|
151
|
+
label: "\e[1;33m",
|
|
152
|
+
local_variable: "\e[33m",
|
|
153
|
+
namespace: "\e[1;35m",
|
|
154
|
+
octal: "\e[1;34m",
|
|
155
|
+
predefined: "\e[36m",
|
|
156
|
+
predefined_constant: "\e[1;36m",
|
|
157
|
+
predefined_type: "\e[1;32m",
|
|
158
|
+
preprocessor: "\e[1;36m",
|
|
159
|
+
pseudo_class: "\e[1;34m",
|
|
160
|
+
regexp: {
|
|
161
|
+
self: "\e[35m",
|
|
162
|
+
delimiter: "\e[1;35m",
|
|
163
|
+
modifier: "\e[35m",
|
|
164
|
+
char: "\e[1;35m",
|
|
165
|
+
},
|
|
166
|
+
reserved: "\e[32m",
|
|
167
|
+
shell: {
|
|
168
|
+
self: "\e[33m",
|
|
169
|
+
char: "\e[1;33m",
|
|
170
|
+
delimiter: "\e[1;33m",
|
|
171
|
+
escape: "\e[1;33m",
|
|
172
|
+
},
|
|
173
|
+
string: {
|
|
174
|
+
self: "\e[31m",
|
|
175
|
+
modifier: "\e[1;31m",
|
|
176
|
+
char: "\e[1;35m",
|
|
177
|
+
delimiter: "\e[1;31m",
|
|
178
|
+
escape: "\e[1;31m",
|
|
179
|
+
},
|
|
180
|
+
symbol: {
|
|
181
|
+
self: "\e[33m",
|
|
182
|
+
delimiter: "\e[1;33m",
|
|
183
|
+
},
|
|
184
|
+
tag: "\e[32m",
|
|
185
|
+
type: "\e[1;34m",
|
|
186
|
+
value: "\e[36m",
|
|
187
|
+
variable: "\e[34m",
|
|
188
|
+
|
|
189
|
+
insert: {
|
|
190
|
+
self: "\e[42m",
|
|
191
|
+
insert: "\e[1;32;42m",
|
|
192
|
+
eyecatcher: "\e[102m",
|
|
193
|
+
},
|
|
194
|
+
delete: {
|
|
195
|
+
self: "\e[41m",
|
|
196
|
+
delete: "\e[1;31;41m",
|
|
197
|
+
eyecatcher: "\e[101m",
|
|
198
|
+
},
|
|
199
|
+
change: {
|
|
200
|
+
self: "\e[44m",
|
|
201
|
+
change: "\e[37;44m",
|
|
202
|
+
},
|
|
203
|
+
head: {
|
|
204
|
+
self: "\e[45m",
|
|
205
|
+
filename: "\e[37;45m"
|
|
206
|
+
},
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
TOKEN_COLORS[:keyword] = TOKEN_COLORS[:reserved]
|
|
210
|
+
TOKEN_COLORS[:method] = TOKEN_COLORS[:function]
|
|
211
|
+
TOKEN_COLORS[:escape] = TOKEN_COLORS[:delimiter]
|
|
212
|
+
|
|
213
|
+
def self.default(obj, width = 79)
|
|
214
|
+
pager = StringIO.new
|
|
215
|
+
pp(obj, pager, width)
|
|
216
|
+
pager.string
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def self.pp(obj, output = $DEFAULT_OUTPUT, max_width = 79)
|
|
220
|
+
queue = ColorPrinter.new(output, max_width, "\n")
|
|
221
|
+
queue.guard_inspect_key { queue.pp(obj) }
|
|
222
|
+
queue.flush
|
|
223
|
+
output << "\n"
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def text(str, max_width = str.length)
|
|
227
|
+
super(ColorPrinter.colorize(str), max_width)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def self.token(string, *name)
|
|
231
|
+
TOKEN_COLORS.dig(*name) + string + "\e[0m"
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
NUMBER = '[+-]?[0-9.]+(?:e[+-][0-9]+|i)?'
|
|
235
|
+
REGEXP = '/.*?/[iesu]*'
|
|
236
|
+
TOKEN_REGEXP = /(\s+|=>|[@$:]?[a-z]\w+|[A-Z]\w+|#{NUMBER}|#{REGEXP}|".*?"|#<.*?[> ]|.)/
|
|
237
|
+
|
|
238
|
+
def self.tokenize(str)
|
|
239
|
+
str.scan(TOKEN_REGEXP).map(&:first)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def self.colorize(str)
|
|
243
|
+
tokens = tokenize(str)
|
|
244
|
+
|
|
245
|
+
tokens.map do |tok|
|
|
246
|
+
case tok
|
|
247
|
+
when /^[0-9+-]/
|
|
248
|
+
if /[.e]/ =~ tok
|
|
249
|
+
token(tok, :float)
|
|
250
|
+
else
|
|
251
|
+
token(tok, :integer)
|
|
252
|
+
end
|
|
253
|
+
when /^"/
|
|
254
|
+
token(tok, :string, :self)
|
|
255
|
+
when /^:/
|
|
256
|
+
token(tok, :symbol, :self)
|
|
257
|
+
when /^[A-Z]/
|
|
258
|
+
token(tok, :constant)
|
|
259
|
+
when /^#</, '=', '>'
|
|
260
|
+
token(tok, :keyword)
|
|
261
|
+
when /^\/./
|
|
262
|
+
token(tok, :regexp, :self)
|
|
263
|
+
when 'true', 'false', 'nil'
|
|
264
|
+
token(tok, :predefined_constant)
|
|
265
|
+
else
|
|
266
|
+
tok
|
|
267
|
+
end
|
|
268
|
+
end.join
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
data/stdlib/opal-parser.rb
CHANGED
|
@@ -6,16 +6,20 @@ require 'opal/erb'
|
|
|
6
6
|
require 'opal/version'
|
|
7
7
|
|
|
8
8
|
module Kernel
|
|
9
|
-
def eval(str)
|
|
9
|
+
def eval(str, binding = nil, file = nil, line = nil)
|
|
10
10
|
str = Opal.coerce_to!(str, String, :to_str)
|
|
11
|
-
default_eval_options = { file: '(eval)', eval: true }
|
|
11
|
+
default_eval_options = { file: file || '(eval)', eval: true }
|
|
12
12
|
compiling_options = __OPAL_COMPILER_CONFIG__.merge(default_eval_options)
|
|
13
|
-
code = Opal.compile
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
code = `Opal.compile(str, compiling_options)`
|
|
14
|
+
if binding
|
|
15
|
+
binding.js_eval(code)
|
|
16
|
+
else
|
|
17
|
+
%x{
|
|
18
|
+
return (function(self) {
|
|
19
|
+
return eval(#{code});
|
|
20
|
+
})(self)
|
|
21
|
+
}
|
|
22
|
+
end
|
|
19
23
|
end
|
|
20
24
|
|
|
21
25
|
def require_remote(url)
|
|
@@ -30,10 +34,19 @@ end
|
|
|
30
34
|
|
|
31
35
|
%x{
|
|
32
36
|
Opal.compile = function(str, options) {
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
try {
|
|
38
|
+
str = #{Opal.coerce_to!(`str`, String, :to_str)}
|
|
39
|
+
if (options) options = Opal.hash(options);
|
|
40
|
+
return Opal.Opal.$compile(str, options);
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
if (e.$$class === Opal.Opal.SyntaxError) {
|
|
44
|
+
var err = Opal.SyntaxError.$new(e.message);
|
|
45
|
+
err.$set_backtrace(e.$backtrace());
|
|
46
|
+
throw(err);
|
|
47
|
+
}
|
|
48
|
+
else { throw e; }
|
|
35
49
|
}
|
|
36
|
-
return Opal.Opal.$compile(str, options);
|
|
37
50
|
};
|
|
38
51
|
|
|
39
52
|
Opal['eval'] = function(str, options) {
|
data/stdlib/opal-platform.rb
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
`/* global Java, GjsFileImporter */`
|
|
2
|
+
|
|
1
3
|
browser = `typeof(document) !== "undefined"`
|
|
2
4
|
node = `typeof(process) !== "undefined" && process.versions && process.versions.node`
|
|
3
5
|
nashorn = `typeof(Java) !== "undefined" && Java.type`
|
|
4
6
|
headless_chrome = `typeof(navigator) !== "undefined" && /\bHeadlessChrome\//.test(navigator.userAgent)`
|
|
7
|
+
gjs = `typeof(window) !== "undefined" && typeof(GjsFileImporter) !== 'undefined'`
|
|
8
|
+
opalminiracer = `typeof(opalminiracer) !== 'undefined'`
|
|
5
9
|
|
|
6
10
|
OPAL_PLATFORM = if nashorn
|
|
7
11
|
'nashorn'
|
|
@@ -9,5 +13,9 @@ OPAL_PLATFORM = if nashorn
|
|
|
9
13
|
'nodejs'
|
|
10
14
|
elsif headless_chrome
|
|
11
15
|
'headless-chrome'
|
|
16
|
+
elsif gjs
|
|
17
|
+
'gjs'
|
|
18
|
+
elsif opalminiracer
|
|
19
|
+
'opal-miniracer'
|
|
12
20
|
else # possibly browser, which is the primary target
|
|
13
21
|
end
|
data/stdlib/promise/v2.rb
CHANGED
|
@@ -98,10 +98,12 @@
|
|
|
98
98
|
# end
|
|
99
99
|
#
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
101
|
+
if `Opal.config.experimental_features_severity == 'warning'`
|
|
102
|
+
warn 'PromiseV2 is a technology preview, which means it may change its behavior ' \
|
|
103
|
+
'in the future until this warning is removed. If you are interested in this part, ' \
|
|
104
|
+
'please make sure you track the async/await/promises tag on Opal issues: ' \
|
|
105
|
+
'https://github.com/opal/opal/issues?q=label%3Aasync%2Fawait%2Fpromises'
|
|
106
|
+
end
|
|
105
107
|
|
|
106
108
|
class PromiseV2 < `Promise`
|
|
107
109
|
class << self
|
|
@@ -360,6 +362,16 @@ class PromiseV2 < `Promise`
|
|
|
360
362
|
yield self if block_given?
|
|
361
363
|
end
|
|
362
364
|
|
|
365
|
+
alias to_v2 itself
|
|
366
|
+
|
|
367
|
+
def to_v1
|
|
368
|
+
v1 = PromiseV1.new
|
|
369
|
+
|
|
370
|
+
self.then { |i| v1.resolve(i) }.rescue { |i| v1.reject(i) }
|
|
371
|
+
|
|
372
|
+
v1
|
|
373
|
+
end
|
|
374
|
+
|
|
363
375
|
alias to_n itself
|
|
364
376
|
|
|
365
377
|
def inspect
|
data/stdlib/promise.rb
CHANGED
|
@@ -337,6 +337,18 @@ class Promise
|
|
|
337
337
|
result
|
|
338
338
|
end
|
|
339
339
|
|
|
340
|
+
alias to_v1 itself
|
|
341
|
+
|
|
342
|
+
def to_v2
|
|
343
|
+
v2 = PromiseV2.new
|
|
344
|
+
|
|
345
|
+
self.then { |i| v2.resolve(i) }.rescue { |i| v2.reject(i) }
|
|
346
|
+
|
|
347
|
+
v2
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
alias to_n to_v2
|
|
351
|
+
|
|
340
352
|
class Trace < self
|
|
341
353
|
def self.it(promise)
|
|
342
354
|
current = []
|
|
@@ -444,3 +456,5 @@ class Promise
|
|
|
444
456
|
end
|
|
445
457
|
end
|
|
446
458
|
end
|
|
459
|
+
|
|
460
|
+
PromiseV1 = Promise
|
data/stdlib/stringio.rb
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
class StringIO < IO
|
|
2
|
-
include IO::Readable
|
|
3
|
-
include IO::Writable
|
|
4
|
-
|
|
5
2
|
def self.open(string = "", mode = nil, &block)
|
|
6
3
|
io = new(string, mode)
|
|
7
4
|
res = block.call(io)
|
|
@@ -14,13 +11,9 @@ class StringIO < IO
|
|
|
14
11
|
|
|
15
12
|
def initialize(string = "", mode = 'rw')
|
|
16
13
|
@string = string
|
|
17
|
-
@position =
|
|
14
|
+
@position = 0
|
|
18
15
|
|
|
19
|
-
|
|
20
|
-
@closed = :write
|
|
21
|
-
elsif mode.include?('w') and not mode.include?('r')
|
|
22
|
-
@closed = :read
|
|
23
|
-
end
|
|
16
|
+
super(nil, mode)
|
|
24
17
|
end
|
|
25
18
|
|
|
26
19
|
def eof?
|
|
@@ -32,6 +25,9 @@ class StringIO < IO
|
|
|
32
25
|
alias eof eof?
|
|
33
26
|
|
|
34
27
|
def seek(pos, whence = IO::SEEK_SET)
|
|
28
|
+
# Let's reset the read buffer, because it will be most likely wrong
|
|
29
|
+
@read_buffer = ''
|
|
30
|
+
|
|
35
31
|
case whence
|
|
36
32
|
when IO::SEEK_SET
|
|
37
33
|
raise Errno::EINVAL unless pos >= 0
|
|
@@ -68,70 +64,12 @@ class StringIO < IO
|
|
|
68
64
|
seek 0
|
|
69
65
|
end
|
|
70
66
|
|
|
71
|
-
def each_byte(&block)
|
|
72
|
-
return enum_for :each_byte unless block
|
|
73
|
-
|
|
74
|
-
check_readable
|
|
75
|
-
|
|
76
|
-
i = @position
|
|
77
|
-
until eof?
|
|
78
|
-
block.call(@string[i].ord)
|
|
79
|
-
i += 1
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
self
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def each_char(&block)
|
|
86
|
-
return enum_for :each_char unless block
|
|
87
|
-
|
|
88
|
-
check_readable
|
|
89
|
-
|
|
90
|
-
i = @position
|
|
91
|
-
until eof?
|
|
92
|
-
block.call(@string[i])
|
|
93
|
-
i += 1
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
self
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def each(separator = $/)
|
|
100
|
-
return enum_for :each_line unless block_given?
|
|
101
|
-
check_readable
|
|
102
|
-
chomp_lines = false
|
|
103
|
-
if ::Hash === separator
|
|
104
|
-
separator = (chomp_lines = separator[:chomp]) ? /\r?\n/ : $/
|
|
105
|
-
elsif separator
|
|
106
|
-
separator = separator.to_str
|
|
107
|
-
else
|
|
108
|
-
separator = `undefined`
|
|
109
|
-
end
|
|
110
|
-
%x{
|
|
111
|
-
var str = self.string, stringLength = str.length;
|
|
112
|
-
if (self.position < stringLength) str = str.substr(self.position);
|
|
113
|
-
if (separator) {
|
|
114
|
-
var chomped = #{`str`.chomp}, trailing = str.length !== chomped.length, splitted = chomped.split(separator);
|
|
115
|
-
for (var i = 0, len = splitted.length; i < len; i++) {
|
|
116
|
-
var line = chomp_lines ? splitted[i] : (i < len - 1 || trailing ? splitted[i] + separator : splitted[i]);
|
|
117
|
-
#{yield `line`};
|
|
118
|
-
}
|
|
119
|
-
} else if (separator === undefined) {
|
|
120
|
-
#{yield `str`};
|
|
121
|
-
} else {
|
|
122
|
-
var m, re = /(.+(?:\n\n|$))\n*/g;
|
|
123
|
-
while ((m = re.exec(str))) #{yield `m[1]`};
|
|
124
|
-
}
|
|
125
|
-
self.position = stringLength;
|
|
126
|
-
}
|
|
127
|
-
self
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
alias each_line each
|
|
131
|
-
|
|
132
67
|
def write(string)
|
|
133
68
|
check_writable
|
|
134
69
|
|
|
70
|
+
# Let's reset the read buffer, because it will be most likely wrong
|
|
71
|
+
@read_buffer = ''
|
|
72
|
+
|
|
135
73
|
string = String(string)
|
|
136
74
|
|
|
137
75
|
if @string.length == @position
|
|
@@ -154,6 +92,7 @@ class StringIO < IO
|
|
|
154
92
|
string = if length
|
|
155
93
|
str = @string[@position, length]
|
|
156
94
|
@position += length
|
|
95
|
+
@position = @string.length if @position > @string.length
|
|
157
96
|
str
|
|
158
97
|
else
|
|
159
98
|
str = @string[@position .. -1]
|
|
@@ -168,47 +107,11 @@ class StringIO < IO
|
|
|
168
107
|
end
|
|
169
108
|
end
|
|
170
109
|
|
|
171
|
-
def
|
|
172
|
-
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def close_read
|
|
176
|
-
if @closed == :write
|
|
177
|
-
@closed = :both
|
|
178
|
-
else
|
|
179
|
-
@closed = :read
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
def close_write
|
|
184
|
-
if @closed == :read
|
|
185
|
-
@closed = :both
|
|
186
|
-
else
|
|
187
|
-
@closed = :write
|
|
188
|
-
end
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
def closed?
|
|
192
|
-
@closed == :both
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
def closed_read?
|
|
196
|
-
@closed == :read || @closed == :both
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
def closed_write?
|
|
200
|
-
@closed == :write || @closed == :both
|
|
201
|
-
end
|
|
110
|
+
def sysread(length)
|
|
111
|
+
check_readable
|
|
202
112
|
|
|
203
|
-
|
|
204
|
-
if closed_write?
|
|
205
|
-
raise IOError, "not opened for writing"
|
|
206
|
-
end
|
|
113
|
+
read(length)
|
|
207
114
|
end
|
|
208
115
|
|
|
209
|
-
|
|
210
|
-
if closed_read?
|
|
211
|
-
raise IOError, "not opened for reading"
|
|
212
|
-
end
|
|
213
|
-
end
|
|
116
|
+
alias readpartial read
|
|
214
117
|
end
|
data/stdlib/thread.rb
CHANGED
|
@@ -111,6 +111,35 @@ class Thread
|
|
|
111
111
|
@storage.each(&block)
|
|
112
112
|
end
|
|
113
113
|
end
|
|
114
|
+
|
|
115
|
+
class Backtrace
|
|
116
|
+
class Location
|
|
117
|
+
def initialize(str)
|
|
118
|
+
@str = str
|
|
119
|
+
|
|
120
|
+
str =~ /^(.*?):(\d+):(\d+):in `(.*?)'$/
|
|
121
|
+
@path = Regexp.last_match(1)
|
|
122
|
+
@label = Regexp.last_match(4)
|
|
123
|
+
@lineno = Regexp.last_match(2).to_i
|
|
124
|
+
|
|
125
|
+
@label =~ /(\w+)$/
|
|
126
|
+
@base_label = Regexp.last_match(1) || @label
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def to_s
|
|
130
|
+
@str
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def inspect
|
|
134
|
+
@str.inspect
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
attr_reader :base_label, :label, :lineno, :path
|
|
138
|
+
|
|
139
|
+
# TODO: Make it somehow provide the absolute path.
|
|
140
|
+
alias absolute_path path
|
|
141
|
+
end
|
|
142
|
+
end
|
|
114
143
|
end
|
|
115
144
|
|
|
116
145
|
Queue = Thread::Queue
|
data/tasks/building.rake
CHANGED
|
@@ -4,11 +4,13 @@ desc <<-DESC
|
|
|
4
4
|
Build *corelib* and *stdlib* to "build/"
|
|
5
5
|
|
|
6
6
|
You can restrict the file list with the FILES env var (comma separated)
|
|
7
|
-
and the destination dir with the DIR env var.
|
|
7
|
+
and the destination dir with the DIR env var, FORMATS to select output formats.
|
|
8
8
|
|
|
9
9
|
Example: rake dist DIR=/tmp/foo FILES='opal.rb,base64.rb'
|
|
10
10
|
Example: rake dist DIR=cdn/opal/#{Opal::VERSION}
|
|
11
11
|
Example: rake dist DIR=cdn/opal/master
|
|
12
|
+
Example: rake dist DIR=cdn/opal/master FORMATS=js,min,gz
|
|
13
|
+
Example: rake dist DIR=cdn/opal/master FORMATS=js,map
|
|
12
14
|
DESC
|
|
13
15
|
task :dist do
|
|
14
16
|
require 'opal/util'
|
|
@@ -22,6 +24,7 @@ task :dist do
|
|
|
22
24
|
build_dir = ENV['DIR'] || 'build'
|
|
23
25
|
files = ENV['FILES'] ? ENV['FILES'].split(',') :
|
|
24
26
|
Dir['{opal,stdlib}/*.rb'].map { |lib| File.basename(lib, '.rb') }
|
|
27
|
+
formats = (ENV['FORMATS'] || 'js,min,gz').split(',')
|
|
25
28
|
|
|
26
29
|
mkdir_p build_dir unless File.directory? build_dir
|
|
27
30
|
width = files.map(&:size).max
|
|
@@ -34,9 +37,12 @@ task :dist do
|
|
|
34
37
|
|
|
35
38
|
# Set requirable to true, unless building opal. This allows opal to be auto-loaded.
|
|
36
39
|
requirable = (lib != 'opal')
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
builder = Opal::Builder.build(lib, requirable: requirable)
|
|
41
|
+
|
|
42
|
+
src = builder.to_s if (formats & %w[js min gz]).any?
|
|
43
|
+
src << ";" << builder.source_map.to_data_uri_comment if (formats & %w[map]).any?
|
|
44
|
+
min = Opal::Util.uglify src if (formats & %w[min gz]).any?
|
|
45
|
+
gzp = Opal::Util.gzip min if (formats & %w[gz]).any?
|
|
40
46
|
|
|
41
47
|
File.open("#{build_dir}/#{lib}.js", 'w+') { |f| f << src }
|
|
42
48
|
File.open("#{build_dir}/#{lib}.min.js", 'w+') { |f| f << min } if min
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const SourceMapConsumer = require('source-map').SourceMapConsumer
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
const root = `${__dirname}/..`
|
|
5
|
+
const results = JSON.parse(fs.readFileSync(`${root}/tmp/lint/result.json`, 'utf8'))
|
|
6
|
+
const bufferFrom = require('buffer-from');
|
|
7
|
+
const puts = (string = '') => process.stdout.write(`${string}\n`)
|
|
8
|
+
const retrieveSourceMapURL = (fileData) => {
|
|
9
|
+
var re = /(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg;
|
|
10
|
+
var matches = fileData.match(re);
|
|
11
|
+
return matches[matches.length - 1];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let count = 0
|
|
15
|
+
|
|
16
|
+
results.forEach(
|
|
17
|
+
({filePath, messages}) => {
|
|
18
|
+
if (messages.length === 0) {return}
|
|
19
|
+
|
|
20
|
+
const sourceMappingURL = retrieveSourceMapURL(fs.readFileSync(filePath, 'utf8'))
|
|
21
|
+
const rawData = sourceMappingURL.split(',', 2)[1]
|
|
22
|
+
const sourceMapData = bufferFrom(rawData, "base64").toString();
|
|
23
|
+
const consumer = new SourceMapConsumer(sourceMapData);
|
|
24
|
+
|
|
25
|
+
messages.forEach((error) => {
|
|
26
|
+
const original = consumer.originalPositionFor({ line: error.line, column: error.column })
|
|
27
|
+
count++
|
|
28
|
+
|
|
29
|
+
puts()
|
|
30
|
+
puts(`* ${error.message}`)
|
|
31
|
+
if (error.ruleId) puts(` - Read more: https://eslint.org/docs/rules/${error.ruleId}`)
|
|
32
|
+
;(error.suggestions || []).forEach((suggestion) => puts(` - Suggestion: ${suggestion.desc}`))
|
|
33
|
+
puts(` - Compiled: ${path.relative(root, filePath)}:${error.line}:${error.column}`)
|
|
34
|
+
puts(` - Original: ${original.source}:${original.line}:${original.column}`)
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
puts(`\nFailed with ${count} error${count === 1 ? '' : 's'}.`)
|