opal 1.6.0.alpha1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 799fb70bbdbc0be33af9c9757287797702fd8752f29e3beb4b3515f3dc0e7a66
4
- data.tar.gz: 757ec0cb6cc3a5bb24e7a6e6e2aec81fa70d5f05f98025ee00528d00b0779d48
3
+ metadata.gz: 849fd3ee9a34f471ea70ff0069aedfc41b66471e846b81c59e6fd17370e881a6
4
+ data.tar.gz: 71220b09662aef06681fadb4e0841eb110afa4a3e15b14e77de9a6e0666f0564
5
5
  SHA512:
6
- metadata.gz: f3024674d274a45c92bbb5094416074ef754802a78c0484a71d68a7b03815867a8ac42f8499e23a9f2d05587212afeafb752c0894cfabc4a6ace63faf0da4098
7
- data.tar.gz: f1d8ec6f6ac95d89233d4af4a26ab4eaed8d275edd86b154dd06d6fea5477c9aa869dc644f571a2c95737bf674703f03db9b8bed7b43a8af322d5dad6e3a0516
6
+ metadata.gz: 62c5c2f184630d3fc92ec3792e5022434668d33023b89c36a49e128991a7aeea26d61f7ed7559e57e9def93577a94d784f6308c65a78c3ac83726d50942e3435
7
+ data.tar.gz: b7ede6f69220d31c0b8dc0f8350b3699c428d50471ef8d9df47a1a6c9b197116994d1b682681ee37a83b2a0c8547b93e059295c555074a093403ebe9d6ccf84a
data/.gitattributes CHANGED
@@ -1 +1,5 @@
1
1
  UNRELEASED.md merge=union
2
+ spec/opal/core/language/DATA/characters_support_crlf_spec.rb text eol=crlf
3
+ spec/opal/core/language/DATA/characters_support_spec.rb text eol=lf
4
+ spec/opal/core/language/DATA/multiple___END___crlf_spec.rb text eol=crlf
5
+ spec/opal/core/language/DATA/multiple___END___spec.rb text eol=lf
@@ -45,9 +45,20 @@ jobs:
45
45
  - name: smoke-test
46
46
  ruby: '3.0'
47
47
  command: bin/rake smoke_test
48
+ - name: windows-mspec-nodejs
49
+ command: bundle exec rake mspec_nodejs
50
+ ruby: '3.0'
51
+ os: windows-latest
52
+ - name: windows-mspec-chrome
53
+ command: bundle exec rake mspec_chrome
54
+ ruby: '3.0'
55
+ os: windows-latest
56
+ - name: windows-minitest
57
+ command: bundle exec rake minitest
58
+ ruby: '3.0'
59
+ os: windows-latest
48
60
  - name: windows
49
- # These two fail because of broken stacktraces on windows: minitest_node_nodejs mspec_nodejs
50
- command: bundle exec rake rspec minitest_nodejs
61
+ command: bundle exec rake rspec
51
62
  ruby: '3.0'
52
63
  os: windows-latest
53
64
  - name: lint
data/CHANGELOG.md CHANGED
@@ -10,11 +10,76 @@ Changes are grouped as follows:
10
10
  - **Removed** for deprecated features removed in this release.
11
11
  - **Fixed** for any bug fixes.
12
12
  - **Security** to invite users to upgrade in case of vulnerabilities.
13
+ - **Performance** changes related to speed and efficiency.
13
14
 
14
15
 
15
16
 
16
17
 
17
18
 
19
+ ## [1.6.0](https://github.com/opal/opal/compare/v1.5.1...v1.6.0) - 2022-11-24
20
+
21
+
22
+ <!--
23
+ ### Internal
24
+ ### Changed
25
+ ### Added
26
+ ### Removed
27
+ ### Deprecated
28
+ ### Performance
29
+ ### Fixed
30
+ -->
31
+
32
+ ### Changed
33
+
34
+ - No longer truncate stacktraces to 15 lines ([#2440](https://github.com/opal/opal/pull/2440))
35
+ - Mark async/await as non-experimental ([#2477](https://github.com/opal/opal/pull/2477))
36
+
37
+ ### Performance
38
+
39
+ - Improve method block performance for runtime ([#2449](https://github.com/opal/opal/pull/2449))
40
+ - Uninline non-typical argument handling ([#2419](https://github.com/opal/opal/pull/2419))
41
+ - Logic optimization of runtime.js ([#2415](https://github.com/opal/opal/pull/2415))
42
+ - Windows support for `performance:compare` CI check ([#2450](https://github.com/opal/opal/pull/2450))
43
+ - Improve block performance for even more cases ([#2465](https://github.com/opal/opal/pull/2465))
44
+
45
+ ### Added
46
+
47
+ - Added support for `#freeze` and `#frozen?` (#2444, #2468)
48
+ - Add CLI support for ESM, at least for Chrome, NodeJS, QuickJS and GJS ([#2435](https://github.com/opal/opal/pull/2435))
49
+ - Support exit in Chrome CLI Runner, both sync and async ([#2439](https://github.com/opal/opal/pull/2439))
50
+ - Make sure the Server CLI Runner can pick up changes in sources ([#2436](https://github.com/opal/opal/pull/2436))
51
+ - Delegate and ruby2_keywords ([#2446](https://github.com/opal/opal/pull/2446))
52
+ - Source code can now be embedded in the compiled file to improve development/debugging, e.g. RSpec reports, `Proc#source_location` ([#2440](https://github.com/opal/opal/pull/2440))
53
+ - Added `Kernel#caller_locations` ([#2440](https://github.com/opal/opal/pull/2440))
54
+ - `Opal::Builder::Prefork` for blazingly fast multicore compilation times (#2263, #2462, #2454, #2469, #2475)
55
+ - Add `Opal::BuilderProcessors::RubyERBProcessor` ([#2470](https://github.com/opal/opal/pull/2470))
56
+
57
+ ### Fixed
58
+
59
+ - Closure tracking support fixes a whole array of bugs handling `break` / `next` / `retry` / … ([#2357](https://github.com/opal/opal/pull/2357))
60
+ - Fix an edge case of if in the most complex form not returning ([#2433](https://github.com/opal/opal/pull/2433))
61
+ - `String#length` is now available when using `opal/mini` ([#2438](https://github.com/opal/opal/pull/2438))
62
+ - Auto-await produced invalid code ([#2440](https://github.com/opal/opal/pull/2440))
63
+ - Fix `Enumerable#collect_concat` and `#flat_map` implementation ([#2440](https://github.com/opal/opal/pull/2440))
64
+ - Improved await support for PromiseV1 ([#2440](https://github.com/opal/opal/pull/2440))
65
+ - Compilation error occurs while compiling `being/end` returning a `case/when` ([#2459](https://github.com/opal/opal/pull/2459))
66
+ - Ensure UTF-8 encoding of `.sourcesContent` of source maps ([#2451](https://github.com/opal/opal/pull/2451))
67
+ - Benchmarks require string/unpack ([#2453](https://github.com/opal/opal/pull/2453))
68
+ - Fix compilation of a call: `gets&.chomp` ([#2473](https://github.com/opal/opal/pull/2473))
69
+ - Fix specs on Windows ([#2460](https://github.com/opal/opal/pull/2460))
70
+ - Make opal CLI tool work again with pipes ([#2474](https://github.com/opal/opal/pull/2474))
71
+
72
+ ### Internal
73
+
74
+ - GitHub Workflows security hardening ([#2432](https://github.com/opal/opal/pull/2432))
75
+ - Retry if file cache write operation exits with Zlib::BufError ([#2463](https://github.com/opal/opal/pull/2463))
76
+ - Eliminate redundant `var constructor` in `allocate_class` ([#2452](https://github.com/opal/opal/pull/2452))
77
+ - Fix `performance:compare` asset size calculation ([#2457](https://github.com/opal/opal/pull/2457))
78
+ - Fix a few specs after the Opal RSpec 1.0 (alpha) release (#2471, #2472)
79
+
80
+
81
+
82
+
18
83
  ## [1.5.1](https://github.com/opal/opal/compare/v1.5.0...v1.5.1) - 2022-07-20
19
84
 
20
85
 
@@ -24,6 +89,11 @@ Changes are grouped as follows:
24
89
  - Fix exception during `Hash#each_value` if keys get deleted during loop ([#2427](https://github.com/opal/opal/pull/2427))
25
90
  - Fix scan_until and check_until implementation of StringScanner ([#2420](https://github.com/opal/opal/pull/2420))
26
91
 
92
+ ## New Contributors
93
+ * @Leon0402 made their first contribution in https://github.com/opal/opal/pull/2420
94
+
95
+ **Full Changelog**: https://github.com/opal/opal/compare/v1.5.0...v1.5.1
96
+
27
97
 
28
98
 
29
99
 
data/README.md CHANGED
@@ -18,14 +18,14 @@
18
18
  <a href="#sponsors"><img src="https://opencollective.com/opal/sponsors/badge.svg" alt="Sponsors on Open Collective" title="" /></a>
19
19
  <a href="https://slack.opalrb.com/"><img src="https://img.shields.io/badge/slack-join%20chat-46BC99?logo=slack&style=flat" alt="Slack" title="Join Chat" /></a>
20
20
  <a href="https://opalrb.com/docs"><img src="https://img.shields.io/badge/docs-updated-blue.svg" alt="Documentation" title="" /></a>
21
-
21
+
22
22
  <br>
23
23
  <strong>Code:</strong><br>
24
24
  <a href="https://badge.fury.io/rb/opal"><img src="https://img.shields.io/gem/v/opal.svg?style=flat" alt="Gem Version" title="" /></a>
25
25
  <a href="https://github.com/opal/opal/actions?query=workflow%3Abuild"><img src="https://github.com/opal/opal/workflows/build/badge.svg" alt="Build Status" /></a>
26
26
  <a href="https://codeclimate.com/github/opal/opal"><img src="https://img.shields.io/codeclimate/maintainability-percentage/opal/opal.svg" alt="Code Climate" title="" /></a>
27
27
  <a href="https://coveralls.io/github/opal/opal?branch=master"><img src="https://coveralls.io/repos/opal/opal/badge.svg?branch=master&amp;service=github" alt="Coverage Status" title="" /></a>
28
-
28
+
29
29
  <br>
30
30
  <strong>Sponsors:</strong>
31
31
  <br/><a href="https://nebulab.it?utm_source=github&utm_medium=badge"><img src="https://img.shields.io/static/v1?label=Nebulab&message=Open+Source+Fridays&color=%235dbefd&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMQSURBVHgBrZZNTxNRFIbfczsgIMQiLBCRFDaGhUr9A9iiIa5EEneIwE/AlRsNv8KlIKwFl35RTUBX8rFBdiVKAgqmXSCY0M71nJl+zJTOdKh9k6Yzc8/cZ86555x7CQE0mji5hSyGlQoNaOgIPwrnhtIArWszu4EQFudjdR8rzUV+gw8/ZMZB9IwvIwimJJGafhmjWZwFOJ7QkYzWCwTdj+qUDJGKz8Rou3RAlT4YS+hHWW2u/QdM1MNzrI6+zwyXDrg8FANStIDaSXOIJ5whLgAljOIZiglRK6U4vDfz4S2ElGGJWsEaQkCTUbhtNbV+lb+xgFY2Bs9ET0h/GzBxlfAkqnCUKY5xKfVLbsi1/R126lcF6WgCYp2ES42EBp6tvQFY+alLTUlrUxizJEVNWiVwBkVagGg7oe+CDclLYOfrgMdfTBz8PfWa1lkzbsDEsH/5FyF9YUK0zQ1xwpoZtsm9pwxMRLyA9wyi0A2Jcjl1NNqeeEFEimxYPkmWd014ikIDnDTeBb53DOweaRxnvWGyhnmYfPZWGt487sNi6lsK67/lZ1oZGOtUaD3nhtU7etXXfe0VzrzCBgLKCR68rNDX6oaJlvd0xXnklbSfgSTL/QghXF8EP980cVKyVL/Ys9UDVFJa8Tdt+1lYmcmJM3Vd4UEvWeslRf32h9ubrVRl77gBrCto85OfUU+LXTMGx+JuN2Hoin3/Zkfjj6ObBAknV+KG4jpc9BqXMEpiCMz6Z9ZQ12kvJZxb6co4Zr1W83esY8F2OYsIe+eEyfTiVXczCl7uM2wliHfMEJaRc3Wa++mLUotrF4EW7h6f94Dvh6aVFM60Fy8Xkya+BfBOjh5yUWhqY0vmKi9q1GnVxZ7sHKIWSs7FQ71yUagkRTTCfymnVY1gsgHHC5z8hbUjaz0Fr8ZanXhX0pPOw5SrV8wNGjNscMrTKpXKaj05f9twVYHnMZGPHEuwTwEBNi+3NGiNt6GRcsfEIAfhp2cAV3cQLtXoOz7q8+ZJRLx3kmxn4dy7aas1SrfiBpKraV/9A+PSJLDAXLUvAAAAAElFTkSuQmCC" alt="Nebulab: Open Source Fridays" /></a>
@@ -99,7 +99,7 @@ or to build an entire app including dependencies declared with `require`:
99
99
  ```ruby
100
100
  builder = Opal::Builder.new
101
101
  builder.build_str('require "opal"; puts "wow"', '(inline)')
102
- File.write 'app.js', builder.to_s
102
+ File.binwrite 'app.js', builder.to_s # must use binary mode for writing
103
103
  ```
104
104
 
105
105
 
data/UNRELEASED.md CHANGED
@@ -8,44 +8,3 @@
8
8
  ### Fixed
9
9
  -->
10
10
 
11
- ### Changed
12
-
13
- - No longer truncate stacktraces to 15 lines (#2440)
14
-
15
- ### Performance
16
-
17
- - Improve method block performance for runtime (#2449)
18
- - Uninline non-typical argument handling (#2419)
19
- - Logic optimization of runtime.js (#2415)
20
- - Windows support for `performance:compare` CI check (#2450)
21
- - Improve block performance for even more cases (#2465)
22
-
23
- ### Added
24
-
25
- - Added support for `#freeze` and `#frozen?` (#2444, #2468)
26
- - Add CLI support for ESM, at least for Chrome, NodeJS, QuickJS and GJS (#2435)
27
- - Support exit in Chrome CLI Runner, both sync and async (#2439)
28
- - Make sure the Server CLI Runner can pick up changes in sources (#2436)
29
- - Delegate and ruby2_keywords (#2446)
30
- - Source code can now be embedded in the compiled file to improve development/debugging, e.g. RSpec reports, `Proc#source_location` (#2440)
31
- - Added `Kernel#caller_locations` (#2440)
32
- - `Opal::Builder::Prefork` for blazingly fast multicore compilation times (#2263, #2462, #2454)
33
-
34
- ### Fixed
35
-
36
- - Closure tracking support fixes a whole array of bugs handling `break` / `next` / `retry` / … (#2357)
37
- - Fix an edge case of if in the most complex form not returning (#2433)
38
- - `String#length` is now available when using `opal/mini` (#2438)
39
- - Auto-await produced invalid code (#2440)
40
- - Fix `Enumerable#collect_concat` and `#flat_map` implementation (#2440)
41
- - Improved await support for PromiseV1 (#2440)
42
- - Compilation error occurs while compiling `being/end` returning a `case/when` (#2459)
43
- - Ensure UTF-8 encoding of `.sourcesContent` of source maps (#2451)
44
- - Benchmarks require string/unpack (#2453)
45
-
46
- ### Internal
47
-
48
- - GitHub Workflows security hardening (#2432)
49
- - Retry if file cache write operation exits with Zlib::BufError (#2463)
50
- - Eliminate redundant `var constructor` in `allocate_class` (#2452)
51
- - Fix `performance:compare` asset size calculation (#2457)
data/docs/async.md CHANGED
@@ -1,16 +1,5 @@
1
1
  # Asynchronous code (PromiseV2 / async / await)
2
2
 
3
- Please be aware that this functionality is marked as experimental and may change
4
- in the future.
5
-
6
- In order to disable the warnings that will be shown if you use those experimental
7
- features, add the following line before requiring `promise/v2` or `await` and after
8
- requiring `opal`.
9
-
10
- ```ruby
11
- `Opal.config.experimental_features_severity = 'ignore'`
12
- ```
13
-
14
3
  ## PromiseV2
15
4
 
16
5
  In Opal 1.2 we introduced PromiseV2 which is to replace the default Promise in Opal 2.0
@@ -52,7 +41,7 @@ require "await"
52
41
 
53
42
  def wait_5_seconds
54
43
  puts "Let's wait 5 seconds..."
55
- sleep(5).await
44
+ sleep(5).__await__
56
45
  puts "Done!"
57
46
  end
58
47
 
@@ -60,14 +49,11 @@ wait_5_seconds.__await__
60
49
  ```
61
50
 
62
51
  It's important to understand what happens under the hood: every scope in which `#__await__` is
63
- encountered will become async, which means that it will return a Promise that will resolve
52
+ encountered will become async, which means that it will return a PromiseV2 that will resolve
64
53
  to a value. This includes methods, blocks and the top scope. This means, that `#__await__` is
65
54
  infectious and you need to remember to `#__await__` everything along the way, otherwise
66
55
  a program will finish too early and the values may be incorrect.
67
56
 
68
- [You can take a look at how we ported Minitest to support asynchronous tests.](https://github.com/opal/opal/pull/2221/commits/8383c7b45a94fe4628778f429508b9c08c8948b0) Take note, that
69
- it was ported to use `#await` while the finally accepted version uses `#__await__`.
70
-
71
57
  It is certainly correct to `#__await__` any value, including non-Promises, for instance
72
58
  `5.__await__` will correctly resolve to `5` (except that it will make the scope an async
73
59
  function, with all the limitations described above).
@@ -76,6 +62,8 @@ The `await` stdlib module includes a few useful functions, like async-aware `eac
76
62
  function and `sleep` that doesn't block the thread. It also includes a method `#await`
77
63
  which is an alias of `#itself` - it makes sense to auto-await that method.
78
64
 
65
+ [You can take a look at how we ported Minitest to support asynchronous tests.](https://github.com/opal/opal/pull/2221/files#diff-bdc8868ad4476bff7b25475f1b19059ac684d64c6531a645b3ba0aef0c466d0f).
66
+
79
67
  This approach is certainly incompatible with what Ruby does, but due to a dynamic nature
80
68
  of Ruby and a different model of JavaScript this was the least invasive way to catch up
81
69
  with the latest JavaScript trends and support `Promise` heavy APIs and asynchronous code.
@@ -106,4 +94,4 @@ require "await"
106
94
  p i
107
95
  sleep i
108
96
  end
109
- ```
97
+ ```
data/docs/jquery.md CHANGED
@@ -58,7 +58,7 @@ builder.build('opal')
58
58
  builder.build('opal-jquery')
59
59
  builder.build('./app/application.rb')
60
60
 
61
- File.write('application.js', builder.to_s)
61
+ File.binwrite('application.js', builder.to_s) # must use binary mode for writing
62
62
  ```
63
63
 
64
64
  then simply load the compiled file in your html:
@@ -67,7 +67,7 @@ then simply load the compiled file in your html:
67
67
  <!DOCTYPE html>
68
68
  <html>
69
69
  <head>
70
- <script src='https://code.jquery.com/jquery-3.3.1.min.js' integrity='sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=' crossorigin='anonymous'></script>
70
+ <script src='https://code.jquery.com/jquery-3.3.1.min.js' integrity='sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=' crossorigin='anonymous'></script>
71
71
  <script type='text/javascript' src='./application.js'></script>
72
72
  </head>
73
73
  <body></body>
@@ -75,11 +75,11 @@ then simply load the compiled file in your html:
75
75
  ```
76
76
 
77
77
  NOTE: opal-jquery expects a jquery library to be loaded. This example loads it
78
- remotely from jquery.com, but a locally downloaded copy works just as well, or-
78
+ remotely from jquery.com, but a locally downloaded copy works just as well, or-
79
79
  if you're using rails- jquery may be included automatically.
80
80
 
81
- This example builds opal, opal-jquery and the application into a single `.js` file,
82
- but you may build them separately, if you so choose. Just remember to include
81
+ This example builds opal, opal-jquery and the application into a single `.js` file,
82
+ but you may build them separately, if you so choose. Just remember to include
83
83
  each respective script in your html!
84
84
 
85
85
  ### How does opal-jquery work
data/docs/releasing.md CHANGED
@@ -18,14 +18,14 @@ _This guide is a work-in-progress._
18
18
  - Commit the updated changelog along with the version bump using this commit message:
19
19
  "Release v1.2.3"
20
20
  - Push the commit and run `bin/rake release` to release the new version to Rubygems
21
- - Go to GitHub releases and create a new release from the latest tag pasting the contents from CHANGELOG.md
21
+ - Go to GitHub releases and create a new release from the latest tag pasting the contents from CHANGELOG.md (or UNRELEASED.md for pre-releases)
22
22
 
23
23
  ## Opal docs
24
24
 
25
25
  - Open `opal-docs` and run `bin/build v1.2.3`
26
26
  - Then run `bin/deploy`
27
27
 
28
- ## Opal site
28
+ ## [skip for pre-releases] Opal site
29
29
 
30
30
  - Open `opal.github.io` and update the opal version in the `Gemfile`
31
31
  - run `bin/build`
@@ -35,9 +35,8 @@ _This guide is a work-in-progress._
35
35
 
36
36
  - Run `bin/release v1.2.3`
37
37
 
38
- ## Prepare for the next release
38
+ ## [skip for minor-releases] Prepare for the next release
39
39
 
40
- - Skip this step if releasing a stable release
41
40
  - Create a new pull request that:
42
41
  - Updates a version to `v1.x.0.dev` in both `lib/opal/version.rb` and `opal/corelib/constants.rb`
43
42
  - Remember to merge that PR before merging anything else next once we decide to not release any more point releases from `master`.
@@ -114,6 +114,12 @@ module Opal
114
114
  end
115
115
  end
116
116
 
117
+ # This handler is for files named ".opalerb", which ought to
118
+ # first get compiled to Ruby code using ERB, then with Opal.
119
+ # Unlike below processors, OpalERBProcessor can be used to
120
+ # compile templates, which will in turn output HTML. Take
121
+ # a look at docs/templates.md to understand this subsystem
122
+ # better.
117
123
  class OpalERBProcessor < RubyProcessor
118
124
  handles :opalerb
119
125
 
@@ -133,6 +139,24 @@ module Opal
133
139
  end
134
140
  end
135
141
 
142
+ # This handler is for files named ".rb.erb", which ought to
143
+ # first get preprocessed via ERB, then via Opal.
144
+ class RubyERBProcessor < RubyProcessor
145
+ handles :"rb.erb"
146
+
147
+ def compiled
148
+ @compiled ||= begin
149
+ @source = ::ERB.new(@source.to_s).result
150
+
151
+ compiler = compiler_for(@source, file: @filename)
152
+ compiler.compile
153
+ compiler
154
+ end
155
+ end
156
+ end
157
+
158
+ # This handler is for files named ".js.erb", which ought to
159
+ # first get preprocessed via ERB, then served verbatim as JS.
136
160
  class ERBProcessor < Processor
137
161
  handles :erb
138
162
 
@@ -161,6 +161,9 @@ module Opal
161
161
  end
162
162
 
163
163
  def fork_entrypoint(io)
164
+ # Ensure we can work with our forks async...
165
+ Fiber.set_scheduler(nil) if Fiber.respond_to? :set_scheduler
166
+
164
167
  @in_fork = io
165
168
 
166
169
  until io.eof?
@@ -19,15 +19,21 @@ module Opal
19
19
 
20
20
  def set(key, data)
21
21
  file = cache_filename_for(key)
22
-
23
22
  out = Marshal.dump(data)
24
- out = Zlib.gzip(out, level: 9)
23
+
24
+ # Sometimes `Zlib::BufError` gets raised, unsure why, makes no sense, possibly
25
+ # some race condition (see https://github.com/ruby/zlib/issues/49).
26
+ # Limit the number of retries to avoid infinite loops.
27
+ retries = 5
28
+ begin
29
+ out = Zlib.gzip(out, level: 9)
30
+ rescue Zlib::BufError
31
+ warn "\n[Opal]: Zlib::BufError; retrying (#{retries} retries left)"
32
+ retries -= 1
33
+ retry if retries > 0
34
+ end
35
+
25
36
  File.binwrite(file, out)
26
- rescue Zlib::BufError
27
- # This sometimes happens, unsure why, makes no sense, possibly
28
- # some race condition
29
- warn '[Opal]: Zlib::BufError; retrying'
30
- retry
31
37
  end
32
38
 
33
39
  def get(key)
data/lib/opal/cli.rb CHANGED
@@ -184,8 +184,21 @@ module Opal
184
184
  if evals.any?
185
185
  yield evals.join("\n"), '-e'
186
186
  elsif file && (filename != '-' || evals.empty?)
187
- file.rewind
188
- yield file.read, filename
187
+ return @content if @content
188
+
189
+ if file.tty?
190
+ save = true
191
+ else
192
+ begin
193
+ file.rewind
194
+ rescue Errno::ESPIPE
195
+ save = true
196
+ end
197
+ end
198
+
199
+ content = yield(file.read, filename)
200
+ @content = content if save
201
+ content
189
202
  end
190
203
  end
191
204
  end
@@ -66,7 +66,7 @@ module Opal
66
66
  def prepare_files_in(dir)
67
67
  js = builder.to_s
68
68
  map = builder.source_map.to_json
69
- stack = File.read("#{__dir__}/source-map-support-browser.js")
69
+ stack = File.binread("#{__dir__}/source-map-support-browser.js")
70
70
 
71
71
  ext = builder.output_extension
72
72
  module_type = ' type="module"' if builder.esm?
@@ -74,9 +74,9 @@ module Opal
74
74
  # Chrome can't handle huge data passed to `addScriptToEvaluateOnLoad`
75
75
  # https://groups.google.com/a/chromium.org/forum/#!topic/chromium-discuss/U5qyeX_ydBo
76
76
  # The only way is to create temporary files and pass them to chrome.
77
- File.write("#{dir}/index.#{ext}", js)
78
- File.write("#{dir}/source-map-support.js", stack)
79
- File.write("#{dir}/index.html", <<~HTML)
77
+ File.binwrite("#{dir}/index.#{ext}", js)
78
+ File.binwrite("#{dir}/source-map-support.js", stack)
79
+ File.binwrite("#{dir}/index.html", <<~HTML)
80
80
  <html><head>
81
81
  <meta charset='utf-8'>
82
82
  <script src='./source-map-support.js'></script>
@@ -124,7 +124,7 @@ module Opal
124
124
 
125
125
  chrome_pid = Process.spawn(chrome_server_cmd)
126
126
 
127
- Timeout.timeout(10) do
127
+ Timeout.timeout(30) do
128
128
  loop do
129
129
  break if chrome_server_running?
130
130
  sleep 0.5
@@ -137,7 +137,7 @@ module Opal
137
137
  puts 'Make sure that you have it installed and that its version is > 59'
138
138
  exit(1)
139
139
  ensure
140
- if windows? && chrome_pid
140
+ if OS.windows? && chrome_pid
141
141
  Process.kill('KILL', chrome_pid) unless system("taskkill /f /t /pid #{chrome_pid} >NUL 2>NUL")
142
142
  elsif chrome_pid
143
143
  Process.kill('HUP', chrome_pid)
@@ -27,9 +27,9 @@ SystemRunner = ->(data, &block) {
27
27
 
28
28
  tempfile =
29
29
  if debug
30
- File.new("opal-nodejs-runner.#{ext}", 'w')
30
+ File.new("opal-nodejs-runner.#{ext}", 'wb')
31
31
  else
32
- Tempfile.new(['opal-system-runner', ".#{ext}"])
32
+ Tempfile.new(['opal-system-runner', ".#{ext}"], mode: File::BINARY)
33
33
  end
34
34
 
35
35
  tempfile.write code
@@ -15,9 +15,12 @@ module Opal
15
15
  eof_content = @source[last_token_position..-1]
16
16
  return nil unless eof_content
17
17
 
18
- eof_content = eof_content.lines.drop_while { |line| line == "\n" }
18
+ # On Windows token position is off a bit, because Parser does not seem to compensate for \r\n
19
+ # The first eof_content line on Windows may be for example "end\r\n"
20
+ # Must match for it and \r\n and \n
21
+ eof_content = eof_content.lines.drop_while { |line| /\A.*\r?\n?\z/.match?(line) && !line.start_with?('__END__') }
19
22
 
20
- if eof_content[0] == "__END__\n"
23
+ if /\A__END__\r?\n?\z/.match?(eof_content[0])
21
24
  eof_content = eof_content[1..-1] || []
22
25
  eof_content.join
23
26
  elsif eof_content == ['__END__']
@@ -186,7 +186,8 @@ module Opal
186
186
  end
187
187
 
188
188
  def compile_simple_call_chain
189
- push recv(receiver_sexp), method_jsid, '(', expr(arglist), ')'
189
+ compile_receiver
190
+ push method_jsid, '(', expr(arglist), ')'
190
191
  end
191
192
 
192
193
  def splat?
@@ -469,7 +470,7 @@ module Opal
469
470
  def handle_conditional_send
470
471
  # temporary variable that stores method receiver
471
472
  receiver_temp = scope.new_temp
472
- push "#{receiver_temp} = ", expr(recvr)
473
+ push "#{receiver_temp} = ", expr(receiver_sexp)
473
474
 
474
475
  # execute the sexp only if the receiver isn't nil
475
476
  push ", (#{receiver_temp} === nil || #{receiver_temp} == null) ? nil : "
@@ -182,8 +182,9 @@ class Opal::SourceMap::File
182
182
  def fragments_by_line
183
183
  raw_mappings = [[]]
184
184
  fragments.flat_map do |fragment|
185
- fragment_code = fragment.code
186
- fragment_lines = fragment_code.split("\n", -1) # a negative limit won't suppress trailing null values
185
+ fragment_code = fragment.code
186
+ splitter = /\r/.match?(fragment_code) ? /\r?\n/ : "\n"
187
+ fragment_lines = fragment_code.split(splitter, -1) # a negative limit won't suppress trailing null values
187
188
  fragment_lines.each.with_index do |fragment_line, index|
188
189
  raw_segment = [fragment_line, fragment]
189
190
  if index.zero? && !fragment_line.size.zero?
data/lib/opal/version.rb CHANGED
@@ -3,5 +3,5 @@
3
3
  module Opal
4
4
  # WHEN RELEASING:
5
5
  # Remember to update RUBY_ENGINE_VERSION in opal/corelib/constants.rb too!
6
- VERSION = '1.6.0.alpha1'
6
+ VERSION = '1.6.0'
7
7
  end
@@ -1,8 +1,8 @@
1
1
  ::RUBY_PLATFORM = 'opal'
2
2
  ::RUBY_ENGINE = 'opal'
3
3
  ::RUBY_VERSION = '3.1.0'
4
- ::RUBY_ENGINE_VERSION = '1.6.0.alpha1'
5
- ::RUBY_RELEASE_DATE = '2022-11-11'
4
+ ::RUBY_ENGINE_VERSION = '1.6.0'
5
+ ::RUBY_RELEASE_DATE = '2022-11-24'
6
6
  ::RUBY_PATCHLEVEL = 0
7
7
  ::RUBY_REVISION = '0'
8
8
  ::RUBY_COPYRIGHT = 'opal - Copyright (C) 2013-2022 Adam Beynon and the Opal contributors'
@@ -4,6 +4,7 @@ module ::Errno
4
4
  [:EEXIST, 'File exists', 17],
5
5
  [:EISDIR, 'Is a directory', 21],
6
6
  [:EMFILE, 'Too many open files', 24],
7
+ [:ESPIPE, 'Illegal seek', 29],
7
8
  [:EACCES, 'Permission denied', 13],
8
9
  [:EPERM, 'Operation not permitted', 1],
9
10
  [:ENOENT, 'No such file or directory', 2],
data/opal/corelib/io.rb CHANGED
@@ -89,7 +89,7 @@ class ::IO
89
89
  parts = ''
90
90
 
91
91
  # Will execure at most twice - one time reading from a buffer
92
- # second time
92
+ # second time executing read proc
93
93
  begin
94
94
  @read_buffer += parts
95
95
  if @read_buffer != ''
data/opal.gemspec CHANGED
@@ -44,9 +44,9 @@ Gem::Specification.new do |spec|
44
44
  spec.add_development_dependency 'rack-test'
45
45
  spec.add_development_dependency 'selenium-webdriver'
46
46
  spec.add_development_dependency 'benchmark-ips', '< 2.8'
47
- spec.add_development_dependency 'sinatra'
47
+ spec.add_development_dependency 'sinatra', '~> 3.0'
48
48
  spec.add_development_dependency 'rubocop', '~> 0.67.0'
49
49
  spec.add_development_dependency 'rubocop-performance', '~> 1.1.0'
50
- spec.add_development_dependency 'rack'
50
+ spec.add_development_dependency 'rack', '~> 2.2'
51
51
  spec.add_development_dependency 'webrick'
52
52
  end
data/spec/lib/cli_spec.rb CHANGED
@@ -236,6 +236,20 @@ RSpec.describe Opal::CLI do
236
236
  end
237
237
  end
238
238
 
239
+ context 'using pipes' do
240
+ it 'runs the provided source' do
241
+ # `echo` on windows will output double-quotes along with the contents, that's why we print with ruby
242
+ expect(`ruby -e"puts 'foo'" | ruby bin/opal -ropal/platform -e "puts gets.reverse"`.strip).to eq("oof")
243
+ end
244
+
245
+ it 'compiles the provided source' do
246
+ # `echo` on windows will output double-quotes along with the contents, that's why we print with ruby
247
+ expect(`ruby -e"puts 'puts 123'" | ruby bin/opal -cEO`.strip).to include("self.$puts(123)")
248
+ end
249
+
250
+ # TODO: test refreshes with the server runner (only way to ensure we correctly rewind or cache the eval contents)
251
+ end
252
+
239
253
  private
240
254
 
241
255
  def expect_output_of
@@ -0,0 +1,9 @@
1
+ describe "characters support of the DATA contstant" do
2
+ it "supports all characters" do
3
+ DATA.read.should == "azAZ09`~!@#$%^&*(\r\n)_+{}\\|;:'\",<.>/?\r\n"
4
+ end
5
+ end
6
+
7
+ __END__
8
+ azAZ09`~!@#$%^&*(
9
+ )_+{}\|;:'",<.>/?
@@ -0,0 +1,10 @@
1
+ describe "DATA constant with multiple __END__ sections" do
2
+ it "returns everything after first __END__" do
3
+ DATA.read.should == "1\r\n__END__\r\n2\r\n"
4
+ end
5
+ end
6
+
7
+ __END__
8
+ 1
9
+ __END__
10
+ 2
@@ -4,4 +4,14 @@ describe 'Safe navigator' do
4
4
  value&.unknown.should == nil
5
5
  end
6
6
  end
7
+
8
+ it "calls a receiver exactly once" do
9
+ def receiver
10
+ @calls += 1
11
+ end
12
+ @calls = 0
13
+ receiver&.itself.should == 1
14
+ @calls = 0
15
+ receiver&.itself{}.should == 1
16
+ end
7
17
  end
data/stdlib/await.rb CHANGED
@@ -1,13 +1,6 @@
1
1
  # helpers: coerce_to
2
2
  # await: await
3
3
 
4
- if `Opal.config.experimental_features_severity == 'warning'`
5
- warn 'Await functionality is a technology preview, which means it may change its behavior ' \
6
- 'in the future unless this warning is removed. If you are interested in this part, ' \
7
- 'please make sure you track the async/await/promises tag on Opal issues: ' \
8
- 'https://github.com/opal/opal/issues?q=label%3Aasync%2Fawait%2Fpromises'
9
- end
10
-
11
4
  %x{
12
5
  var AsyncFunction = Object.getPrototypeOf(async function() {}).constructor;
13
6
  }
data/tasks/testing.rake CHANGED
@@ -427,14 +427,15 @@ task :smoke_test do
427
427
  extend RSpec::Matchers
428
428
  expect(actual_output.lines[0]).to eq("..\n")
429
429
  expect(actual_output.lines[1]).to eq("\n")
430
- expect(actual_output.lines[2]).to match(%r{^Finished in \d+\.\d+ seconds \(files took \d+\.\d+ seconds to load\)\n$})
431
- expect(actual_output.lines[3]).to eq("2 examples, 0 failures\n")
432
- expect(actual_output.lines[4]).to eq("\n")
433
- expect(actual_output.lines[5]).to match(%r{Top 2 slowest examples \(\d+\.\d+ seconds, \d+\.\d+% of total time\):\n})
434
- expect(actual_output.lines[7]).to match(%r{ \[1m\d+\.\d+\[0m \[1mseconds\[0m \n})
430
+ expect(actual_output.lines[2]).to match(%r{Top 2 slowest examples \(\d+\.\d+ seconds, \d+\.\d+% of total time\):\n})
431
+ expect(actual_output.lines[4]).to match(%r{ \[1m\d+\.\d+\[0m \[1mseconds\[0m .*deprecations_spec\.rb:7\n})
432
+ expect(actual_output.lines[6]).to match(%r{ \[1m\d+\.\d+\[0m \[1mseconds\[0m .*deprecations_spec\.rb:12\n})
433
+ expect(actual_output.lines[7]).to eq("\n")
434
+ expect(actual_output.lines[8]).to match(%r{^Finished in \d+\.\d+ seconds \(files took \d+\.\d+ seconds to load\)\n$})
435
+ expect(actual_output.lines[9]).to eq("2 examples, 0 failures\n")
435
436
  expect([
436
- actual_output.lines[6],
437
- actual_output.lines[8],
437
+ actual_output.lines[3],
438
+ actual_output.lines[5],
438
439
  ]).to contain_exactly(
439
440
  " Opal::Deprecations defaults to warn\n",
440
441
  " Opal::Deprecations can be set to raise\n",
@@ -175,6 +175,7 @@ class TestNodejsFile < Test::Unit::TestCase
175
175
  end if windows_platform?
176
176
 
177
177
  def test_windows_file_expand_path
178
+ # do not use d: because its a symlink in github actions fs, leading to unexpected results
178
179
  drive_letter = Dir.pwd.slice(0, 2)
179
180
  assert_equal(Dir.pwd + '/foo/bar.js', File.expand_path('./foo/bar.js'))
180
181
  assert_equal(drive_letter + '/foo/bar.js', File.expand_path('/foo/bar.js'))
@@ -186,8 +187,8 @@ class TestNodejsFile < Test::Unit::TestCase
186
187
  assert_equal('c:/bar.js', File.expand_path('\\..\\bar.js', 'c:\\foo\\baz\\'))
187
188
  assert_equal('c:/foo/baz/bar.js', File.expand_path('baz\\bar.js', 'c:\\foo'))
188
189
  assert_equal('c:/baz/bar.js', File.expand_path('baz\\bar.js', 'c:\\foo\\..'))
189
- assert_equal('d:/', File.expand_path('d:'), 'should add a trailing slash when the path is d:')
190
- assert_equal('d:/', File.expand_path('d:/'), 'should preserve the trailing slash when the path d:/')
190
+ assert_equal('f:/', File.expand_path('f:'), 'should add a trailing slash when the path is d:')
191
+ assert_equal('g:/', File.expand_path('g:/'), 'should preserve the trailing slash when the path d:/')
191
192
  assert_equal(Dir.pwd, File.expand_path(drive_letter), 'should expand to the current directory when the path is c: (and the current directory is located in the c drive)')
192
193
  assert_equal(drive_letter + '/', drive_letter + '/', 'should return c:/ when the path is c:/ because the path is absolute')
193
194
  end if windows_platform?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0.alpha1
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elia Schito
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2022-11-11 00:00:00.000000000 Z
13
+ date: 2022-11-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: ast
@@ -162,16 +162,16 @@ dependencies:
162
162
  name: sinatra
163
163
  requirement: !ruby/object:Gem::Requirement
164
164
  requirements:
165
- - - ">="
165
+ - - "~>"
166
166
  - !ruby/object:Gem::Version
167
- version: '0'
167
+ version: '3.0'
168
168
  type: :development
169
169
  prerelease: false
170
170
  version_requirements: !ruby/object:Gem::Requirement
171
171
  requirements:
172
- - - ">="
172
+ - - "~>"
173
173
  - !ruby/object:Gem::Version
174
- version: '0'
174
+ version: '3.0'
175
175
  - !ruby/object:Gem::Dependency
176
176
  name: rubocop
177
177
  requirement: !ruby/object:Gem::Requirement
@@ -204,16 +204,16 @@ dependencies:
204
204
  name: rack
205
205
  requirement: !ruby/object:Gem::Requirement
206
206
  requirements:
207
- - - ">="
207
+ - - "~>"
208
208
  - !ruby/object:Gem::Version
209
- version: '0'
209
+ version: '2.2'
210
210
  type: :development
211
211
  prerelease: false
212
212
  version_requirements: !ruby/object:Gem::Requirement
213
213
  requirements:
214
- - - ">="
214
+ - - "~>"
215
215
  - !ruby/object:Gem::Version
216
- version: '0'
216
+ version: '2.2'
217
217
  - !ruby/object:Gem::Dependency
218
218
  name: webrick
219
219
  requirement: !ruby/object:Gem::Requirement
@@ -856,8 +856,10 @@ files:
856
856
  - spec/opal/core/kernel/puts_spec.rb
857
857
  - spec/opal/core/kernel/require_tree_spec.rb
858
858
  - spec/opal/core/kernel/respond_to_spec.rb
859
+ - spec/opal/core/language/DATA/characters_support_crlf_spec.rb
859
860
  - spec/opal/core/language/DATA/characters_support_spec.rb
860
861
  - spec/opal/core/language/DATA/empty___END___spec.rb
862
+ - spec/opal/core/language/DATA/multiple___END___crlf_spec.rb
861
863
  - spec/opal/core/language/DATA/multiple___END___spec.rb
862
864
  - spec/opal/core/language/arguments/mlhs_arg_spec.rb
863
865
  - spec/opal/core/language/forward_args_spec.rb
@@ -1167,10 +1169,10 @@ licenses:
1167
1169
  metadata:
1168
1170
  homepage_uri: https://opalrb.com/
1169
1171
  bug_tracker_uri: https://github.com/opal/opal/issues
1170
- changelog_uri: https://github.com/opal/opal/blob/v1.6.0.alpha1/CHANGELOG.md
1171
- readme_uri: https://github.com/opal/opal/blob/v1.6.0.alpha1/README.md
1172
- api_documentation_uri: http://opalrb.com/docs/api/v1.6.0.alpha1/index.html
1173
- guides_uri: http://opalrb.com/docs/guides/v1.6.0.alpha1/index.html
1172
+ changelog_uri: https://github.com/opal/opal/blob/v1.6.0/CHANGELOG.md
1173
+ readme_uri: https://github.com/opal/opal/blob/v1.6.0/README.md
1174
+ api_documentation_uri: http://opalrb.com/docs/api/v1.6.0/index.html
1175
+ guides_uri: http://opalrb.com/docs/guides/v1.6.0/index.html
1174
1176
  chat_uri: https://gitter.im/opal/opal
1175
1177
  source_code_uri: https://github.com/opal/opal
1176
1178
  post_install_message:
@@ -1184,9 +1186,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
1184
1186
  version: '2.3'
1185
1187
  required_rubygems_version: !ruby/object:Gem::Requirement
1186
1188
  requirements:
1187
- - - ">"
1189
+ - - ">="
1188
1190
  - !ruby/object:Gem::Version
1189
- version: 1.3.1
1191
+ version: '0'
1190
1192
  requirements: []
1191
1193
  rubygems_version: 3.3.22
1192
1194
  signing_key: