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
@@ -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
@@ -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 str, compiling_options
14
- %x{
15
- return (function(self) {
16
- return eval(#{code});
17
- })(self)
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
- if (options) {
34
- options = Opal.hash(options);
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) {
@@ -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
- warn 'PromiseV2 is a technology preview, which means it may change its behavior ' \
102
- 'in the future until this warning is removed. If you are interested in this part, ' \
103
- 'please make sure you track the async/await/promises tag on Opal issues: ' \
104
- 'https://github.com/opal/opal/issues?q=label%3Aasync%2Fawait%2Fpromises'
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 = string.length
14
+ @position = 0
18
15
 
19
- if mode.include?('r') and not mode.include?('w')
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 close
172
- @closed = :both
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
- def check_writable
204
- if closed_write?
205
- raise IOError, "not opened for writing"
206
- end
113
+ read(length)
207
114
  end
208
115
 
209
- def check_readable
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
- src = Opal::Builder.build(lib, requirable: requirable).to_s
38
- min = Opal::Util.uglify src
39
- gzp = Opal::Util.gzip min
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'}.`)