opal 1.4.0.alpha1 → 1.5.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +5 -3
  3. data/.github/workflows/build.yml +20 -18
  4. data/.rubocop.yml +1 -0
  5. data/CHANGELOG.md +98 -7
  6. data/UNRELEASED.md +31 -59
  7. data/benchmark-ips/bm_js_symbols_vs_strings.rb +39 -14
  8. data/docs/releasing.md +11 -4
  9. data/lib/opal/ast/matcher.rb +77 -0
  10. data/lib/opal/cache.rb +1 -1
  11. data/lib/opal/cli_runners/applescript.rb +2 -0
  12. data/lib/opal/compiler.rb +18 -9
  13. data/lib/opal/nodes/call.rb +73 -28
  14. data/lib/opal/nodes/def.rb +31 -27
  15. data/lib/opal/nodes/definitions.rb +2 -0
  16. data/lib/opal/nodes/helpers.rb +4 -23
  17. data/lib/opal/nodes/if.rb +226 -0
  18. data/lib/opal/nodes/iter.rb +41 -37
  19. data/lib/opal/nodes/literal.rb +2 -2
  20. data/lib/opal/nodes/masgn.rb +15 -17
  21. data/lib/opal/nodes/node_with_args/shortcuts.rb +100 -0
  22. data/lib/opal/nodes/node_with_args.rb +1 -0
  23. data/lib/opal/nodes/super.rb +9 -9
  24. data/lib/opal/nodes/top.rb +26 -10
  25. data/lib/opal/nodes/x_string.rb +27 -28
  26. data/lib/opal/nodes.rb +0 -1
  27. data/lib/opal/parser/default_config.rb +3 -2
  28. data/lib/opal/repl.rb +1 -1
  29. data/lib/opal/rewriter.rb +13 -6
  30. data/lib/opal/rewriters/base.rb +12 -1
  31. data/lib/opal/rewriters/rubyspec/filters_rewriter.rb +1 -0
  32. data/lib/opal/version.rb +1 -1
  33. data/opal/corelib/array.rb +23 -28
  34. data/opal/corelib/binding.rb +14 -4
  35. data/opal/corelib/constants.rb +3 -3
  36. data/opal/corelib/hash.rb +2 -2
  37. data/opal/corelib/irb.rb +192 -0
  38. data/opal/corelib/math/polyfills.rb +127 -0
  39. data/opal/corelib/math.rb +14 -194
  40. data/opal/corelib/module.rb +25 -40
  41. data/opal/corelib/number.rb +63 -14
  42. data/opal/corelib/regexp.rb +2 -0
  43. data/opal/corelib/runtime.js +56 -20
  44. data/opal/corelib/string.rb +38 -59
  45. data/opal/corelib/time.rb +106 -68
  46. data/opal/opal/full.rb +0 -1
  47. data/opal/opal.rb +4 -1
  48. data/spec/filters/bugs/date.rb +0 -3
  49. data/spec/filters/bugs/datetime.rb +65 -0
  50. data/spec/filters/bugs/float.rb +0 -18
  51. data/spec/filters/bugs/hash.rb +0 -2
  52. data/spec/filters/bugs/language.rb +0 -3
  53. data/spec/filters/bugs/marshal.rb +0 -1
  54. data/spec/filters/bugs/string.rb +0 -30
  55. data/spec/filters/bugs/time.rb +18 -8
  56. data/spec/lib/cli_spec.rb +2 -2
  57. data/spec/lib/compiler_spec.rb +8 -8
  58. data/spec/lib/rewriters/base_spec.rb +1 -1
  59. data/spec/lib/rewriters/binary_operator_assignment_spec.rb +34 -59
  60. data/spec/lib/rewriters/block_to_iter_spec.rb +3 -6
  61. data/spec/lib/rewriters/dot_js_syntax_spec.rb +2 -5
  62. data/spec/lib/rewriters/for_rewriter_spec.rb +0 -1
  63. data/spec/lib/rewriters/forward_args_spec.rb +2 -3
  64. data/spec/lib/rewriters/js_reserved_words_spec.rb +2 -15
  65. data/spec/lib/rewriters/logical_operator_assignment_spec.rb +64 -89
  66. data/spec/lib/rewriters/numblocks_spec.rb +3 -5
  67. data/spec/lib/rewriters/opal_engine_check_spec.rb +2 -14
  68. data/spec/lib/rewriters/rubyspec/filters_rewriter_spec.rb +10 -2
  69. data/spec/opal/compiler/irb_spec.rb +4 -0
  70. data/spec/opal/core/language/super_spec.rb +40 -17
  71. data/spec/opal/core/language/xstring_spec.rb +13 -0
  72. data/spec/opal/core/regexp/assertions_spec.rb +19 -0
  73. data/spec/opal/core/string/to_proc_spec.rb +19 -0
  74. data/spec/ruby_specs +4 -0
  75. data/spec/support/rewriters_helper.rb +43 -23
  76. data/stdlib/date/date_time.rb +71 -0
  77. data/stdlib/date/formatters.rb +28 -0
  78. data/stdlib/date/infinity.rb +73 -0
  79. data/stdlib/date.rb +77 -214
  80. data/stdlib/opal/repl_js.rb +1 -1
  81. data/stdlib/{opal/replutils.rb → opal-replutils.rb} +3 -3
  82. data/stdlib/promise/v2.rb +0 -7
  83. data/stdlib/time.rb +39 -2
  84. data/stdlib/uri.rb +53 -0
  85. data/tasks/performance/asciidoctor_test.rb.erb +3 -1
  86. data/tasks/performance/optimization_status.rb +3 -2
  87. data/tasks/performance.rake +69 -35
  88. data/tasks/testing.rake +1 -0
  89. data/test/opal/test_uri.rb +35 -0
  90. data/yarn.lock +27 -5
  91. metadata +30 -16
  92. data/lib/opal/nodes/csend.rb +0 -24
  93. data/lib/opal/rewriters/explicit_writer_return.rb +0 -59
  94. data/spec/lib/rewriters/explicit_writer_return_spec.rb +0 -186
  95. data/stdlib/nodejs/irb.rb +0 -43
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a891400c1e60680daab2289df6be2148d87aaf7e007210797a963c68af671e82
4
- data.tar.gz: 4315f9771bd13282d378ae1ec2b564864945cf94e780c17288d53af8f38dfc91
3
+ metadata.gz: 6ac3c5ae91f1f31b94c292f0aed320bdba76511abd34bb6dc45294c11958e802
4
+ data.tar.gz: 473ca0893f427b05c88c64805dc0f64668816b263b136863b903f5262aba7aef
5
5
  SHA512:
6
- metadata.gz: 3342a7d52885c1cab9b7371d72a758ce0e13aa97bae741ce549111245422366d5965b36d3eeda91b56b8d0ac733e2a3492c7d6c80190b27a9528aa77f12bfc84
7
- data.tar.gz: 1f71da4662d1218e4561154cc042ac2e643f097b119b048f35fc0f6d7c566b3b9321a3d4eb0a7020c83b197a32818379a7e7662aa82684a51c4b33e870be2a9a
6
+ metadata.gz: 5ba1e5223c56695db351ede10b36872590b29701f4576c9a1962502686434548d855d71fdd147e5b34492bb70964db72bed3229cc552dfa139a2db747dd4caa1
7
+ data.tar.gz: 30e97d6c8293b918084145f15cd9f42d6495989405d97ebbccc414440c281a8297405f651560e8a65ea21dda191631d9bd20fda058d5693af1c25b8b61cc1e40
data/.eslintrc.js CHANGED
@@ -24,12 +24,14 @@ module.exports = {
24
24
  "no-control-regex": "off",
25
25
  },
26
26
  "globals": {
27
- "Opal": "readonly",
28
- "DataView": "readonly",
29
27
  "ArrayBuffer": "readonly",
28
+ "DataView": "readonly",
30
29
  "globalThis": "readonly",
31
- "Uint8Array": "readonly",
30
+ "Opal": "readonly",
32
31
  "Promise": "readonly",
32
+ "Proxy": "readonly",
33
+ "Reflect": "readonly",
34
+ "Uint8Array": "readonly",
33
35
  "WeakRef": "readonly",
34
36
  }
35
37
  };
@@ -16,41 +16,44 @@ jobs:
16
16
  matrix:
17
17
  combo:
18
18
  - name: mspec-nodejs
19
- ruby: 3.0
19
+ ruby: '3.0'
20
20
  command: bin/rake mspec_nodejs
21
21
  - name: mspec-chrome
22
- ruby: 3.0
22
+ ruby: '3.0'
23
23
  command: bin/rake mspec_chrome
24
24
  - name: minitest
25
- ruby: 3.0
25
+ ruby: '3.0'
26
26
  command: bin/rake minitest
27
27
  - name: minitest-strict-mode
28
- ruby: 3.0
28
+ ruby: '3.0'
29
29
  command: bin/rake minitest
30
30
  strict: 'true'
31
+ - name: head-ruby
32
+ ruby: head
33
+ permissive: true
31
34
  - name: current-ruby
32
- ruby: 3.0
35
+ ruby: 3.1
33
36
  - name: previous-ruby
34
- ruby: 2.7
37
+ ruby: '3.0'
35
38
  - name: older-ruby
39
+ ruby: 2.7
40
+ - name: near-eol-ruby
36
41
  ruby: 2.6
37
- # - name: near-eol-ruby
38
- # ruby: 2.6
39
42
  - name: smoke-test
40
- ruby: 3.0
43
+ ruby: '3.0'
41
44
  command: bin/rake smoke_test
42
45
  - name: windows
43
46
  # These two fail because of broken stacktraces on windows: minitest_node_nodejs mspec_nodejs
44
47
  command: bundle exec rake rspec minitest_nodejs
45
- ruby: 3.0
48
+ ruby: '3.0'
46
49
  os: windows-latest
47
50
  - name: lint
48
51
  command: bin/rake lint
49
- ruby: 3.0
52
+ ruby: '3.0'
50
53
  - name: timezone
51
- ruby: 3.0
54
+ ruby: '3.0'
52
55
  - name: performance
53
- ruby: 3.0
56
+ ruby: '3.0'
54
57
  permissive: true
55
58
  fetchdepth: '0'
56
59
  command: bin/rake performance:compare
@@ -59,7 +62,6 @@ jobs:
59
62
  # Currently failing:
60
63
  # - ruby: truffleruby
61
64
  # - ruby: jruby
62
- # - ruby: ruby-head
63
65
 
64
66
  runs-on: ${{ matrix.combo.os || 'ubuntu-latest' }}
65
67
  continue-on-error: ${{ matrix.combo.permissive || false }}
@@ -77,11 +79,11 @@ jobs:
77
79
  - uses: actions/cache@v2
78
80
  with:
79
81
  path: ./vendor/bundle
80
- key: ${{ runner.os }}-${{ matrix.combo.ruby }}-gems-${{ github.ref }}-${{ hashFiles('**/Gemfile.lock') }}
82
+ key: ${{ runner.os }}-${{ matrix.combo.ruby }}-gem-${{ github.ref }}-${{ hashFiles('**/Gemfile.lock') }}
81
83
  restore-keys: |
82
- ${{ runner.os }}-${{ matrix.combo.ruby }}-gems-${{ github.ref }}
83
- ${{ runner.os }}-${{ matrix.combo.ruby }}-gems-master
84
- ${{ runner.os }}-${{ matrix.combo.ruby }}-gems-
84
+ ${{ runner.os }}-${{ matrix.combo.ruby }}-gem-${{ github.ref }}
85
+ ${{ runner.os }}-${{ matrix.combo.ruby }}-gem-master
86
+ ${{ runner.os }}-${{ matrix.combo.ruby }}-gem-
85
87
  - uses: actions/cache@v2
86
88
  with:
87
89
  path: ./node_modules
data/.rubocop.yml CHANGED
@@ -365,6 +365,7 @@ Naming/FileName:
365
365
  - 'stdlib/opal-parser.rb'
366
366
  - 'stdlib/opal-platform.rb'
367
367
  - 'stdlib/opal-source-maps.rb'
368
+ - 'stdlib/opal-replutils.rb'
368
369
 
369
370
  Naming/ConstantName:
370
371
  Exclude:
data/CHANGELOG.md CHANGED
@@ -15,27 +15,118 @@ Changes are grouped as follows:
15
15
 
16
16
 
17
17
 
18
- ## [1.3.2](https://github.com/opal/opal/compare/v1.3.1...v1.3.2) - 2021-11-10
18
+ ## [1.4.1](https://github.com/opal/opal/compare/v1.4.0...v1.4.1) - 2022-01-12
19
+
20
+
21
+ ### Changed
19
22
 
23
+ - PromiseV2 is now declared a stable interface!
20
24
 
21
25
  ### Fixed
22
26
 
23
- - Update documentation ([#2350](https://github.com/opal/opal/pull/2350))
24
- - Fix `IO#gets` getting an extra char under some circumstances ([#2349](https://github.com/opal/opal/pull/2349))
25
- - Raise a `TypeError` instead of `UndefinedMethod` if not a string is passed to `__send__` ([#2346](https://github.com/opal/opal/pull/2346))
26
- - Do not modify `$~` when calling `String#scan` from internal methods ([#2353](https://github.com/opal/opal/pull/2353))
27
- - Stop interpreting falsey values as a missing constant in `Module#const_get` ([#2354](https://github.com/opal/opal/pull/2354))
27
+ - Args named with JS reserved words weren't always renamed when _zsuper_ was involved ([#2385](https://github.com/opal/opal/pull/2385))
28
28
 
29
29
  <!--
30
- ### Changed
30
+ ### Added
31
+ ### Removed
31
32
  ### Deprecated
33
+ ### Internal
34
+ -->
35
+
36
+
37
+
38
+
39
+ ## [1.4.0](https://github.com/opal/opal/compare/v1.3.2...v1.4.0) - 2021-12-24
40
+
41
+
42
+ ### Added
43
+
44
+ - Implement `chomp:` option for `String#each_line` and `#lines` ([#2355](https://github.com/opal/opal/pull/2355))
45
+ - Ruby 3.1 support and some older Ruby features we missed ([#2347](https://github.com/opal/opal/pull/2347))
46
+ - Use parser in 3.1 mode to support new language-level features like hashes/kwargs value omission, the pin operator for pattern matching
47
+ - `Array#intersect?`
48
+ - `String#strip` and `String#lstrip` to also remove NUL bytes
49
+ - `Integer.try_convert`
50
+ - `public`, `private`, `protected`, `module_function` now return their arguments
51
+ - `Class#descendants`, `Class#subclasses`
52
+ - (<=1.8) `Kernel#local_variables`
53
+ - (<=2.3) Set local variables for regexp named captures (`/(?<b>a)/ =~ 'a'` => `b = 'a'`)
54
+ - Remove deprecated `NIL`, `TRUE`, `FALSE` constants
55
+ - `String#unpack` and `String#unpack1` to support an `offset:` kwarg
56
+ - `MatchData#match`, `MatchData#match_length`
57
+ - Enumerable modernization
58
+ - `Enumerable#tally` to support an optional hash accumulator
59
+ - `Enumerable#each_{cons,slice}` to return self
60
+ - `Enumerable#compact`
61
+ - `Refinement` becomes its own class now
62
+ - `Struct#keyword_init?`
63
+ - (pre-3.1) Large Enumerator rework
64
+ - Introduce `Enumerator::ArithmeticSequence`
65
+ - Introduce `Enumerator::Chain`
66
+ - Introduce `Enumerator#+` to create `Enumerator::Chain`s
67
+ - `Enumerator#{rewind,peek,peek_values,next,next_values}`
68
+ - Improve corelib support for beginless/endless ranges and `ArithmeticSequences`
69
+ - `String#[]`, `Array#[]`, `Array#[]=`, `Array#fill`, `Array#values_at`
70
+ - `Range#step` and `Numeric#step` return an `ArithmeticSequence` when `Numeric` values are in play
71
+ - Introduce `Range#%`
72
+ - `Enumerator::Yielder#to_proc`
73
+ - Fix #2367
74
+ - (2.7) `UnboundMethod#bind_call`
75
+ - (Opal) `{Kernel,BasicObject}#{inspect,p,pp,method_missing}` may work with JS native values now, also they now correctly report cycles
76
+ - `Enumerable#sum` uses Kahan's summation algorithm to reduce error with floating point values
77
+ - `File.dirname` supports a new `level` argument
78
+ - Vendor in `optparse` and `shellwords` ([#2326](https://github.com/opal/opal/pull/2326))
79
+ - Preliminary support for compiling the whole `bin/opal` with Opal ([#2326](https://github.com/opal/opal/pull/2326))
80
+
81
+ ### Fixed
82
+
83
+ - Fix coertion for `Array#drop` ([#2371](https://github.com/opal/opal/pull/2371))
84
+ - Fix coertion for `File.absolute_path` ([#2372](https://github.com/opal/opal/pull/2372))
85
+ - Fix some `IO#puts` edge cases (no args, empty array, nested array, …) ([#2372](https://github.com/opal/opal/pull/2372))
86
+ - Preserve UNC path prefix on File.join ([#2366](https://github.com/opal/opal/pull/2366))
87
+ - Methods on `Kernel`, `BasicObject`, `Boolean` will never return boxed values anymore ([#2293](https://github.com/opal/opal/pull/2293))
88
+ - `false.tap{}` will now correctly return a JS value of `false`, not `Object(false)`
89
+ - opal-parser doesn't break on `<<~END` strings anymore ([#2364](https://github.com/opal/opal/pull/2364))
90
+ - Fix error reporting at the early stage of loading ([#2326](https://github.com/opal/opal/pull/2326))
91
+
92
+ ### Changed
93
+
94
+ - Various outputted code size optimizations - 19% improvement for minified unmangled AsciiDoctor bundle - see: https://opalrb.com/blog/2021/11/24/optimizing-opal-output-for-size/ ([#2356](https://github.com/opal/opal/pull/2356))
95
+ - Second round of code size optimizations - 3% improvement for AsciiDoctor bundle on top of the first round - 23% total - see: https://github.com/opal/opal/pull/2365/commits ([#2365](https://github.com/opal/opal/pull/2365))
96
+ - The calls to `==`, `!=` and `===` changed their semantics slightly: it's impossible to monkey patch those calls for `String` and `Number`, but on other classes they can now return `nil` and it will be handled correctly
97
+ - The calls to `!` changed their semantics slightly: it's impossible to monkey patch this call for `Boolean` or `NilClass`.
98
+ - Refactored the structure of the internal `stdlib/nodejs` folder ([#2374](https://github.com/opal/opal/pull/2374))
99
+ - Added `nodejs/base` with just I/O, exit, and ARGV management
100
+ - Moved `Process::Status` to corelib
101
+ - Fixed requires to be more robust
102
+
32
103
  ### Removed
104
+
105
+ - Removed `nodejs/irb` from stdlib as it's been broken for some time ([#2374](https://github.com/opal/opal/pull/2374))
106
+ - Removed `Kernel#node_require` from `nodejs/kernel` as it's been deprecated for a long time ([#2374](https://github.com/opal/opal/pull/2374))
107
+
108
+ <!--
109
+ ### Deprecated
33
110
  ### Internal
34
111
  -->
35
112
 
36
113
 
37
114
 
38
115
 
116
+ ## [1.3.2](https://github.com/opal/opal/compare/v1.3.1...v1.3.2) - 2021-11-10
117
+
118
+
119
+ ### Fixed
120
+
121
+ - Update documentation ([#2350](https://github.com/opal/opal/pull/2350))
122
+ - Fix `IO#gets` getting an extra char under some circumstances ([#2349](https://github.com/opal/opal/pull/2349))
123
+ - Raise a `TypeError` instead of `UndefinedMethod` if not a string is passed to `__send__` ([#2346](https://github.com/opal/opal/pull/2346))
124
+ - Do not modify `$~` when calling `String#scan` from internal methods ([#2353](https://github.com/opal/opal/pull/2353))
125
+ - Stop interpreting falsey values as a missing constant in `Module#const_get` ([#2354](https://github.com/opal/opal/pull/2354))
126
+
127
+
128
+
129
+
39
130
  ## [1.3.1](https://github.com/opal/opal/compare/v1.3.0...v1.3.1) - 2021-11-03
40
131
 
41
132
 
data/UNRELEASED.md CHANGED
@@ -1,71 +1,43 @@
1
1
  ### Added
2
2
 
3
- - Implement `chomp:` option for `String#each_line` and `#lines` (#2355)
4
- - Ruby 3.1 support and some older Ruby features we missed (#2347)
5
- - Use parser in 3.1 mode to support new language-level features like hashes/kwargs value omission, the pin operator for pattern matching
6
- - `Array#intersect?`
7
- - `String#strip` and `String#lstrip` to also remove NUL bytes
8
- - `Integer.try_convert`
9
- - `public`, `private`, `protected`, `module_function` now return their arguments
10
- - `Class#descendants`, `Class#subclasses`
11
- - (<=1.8) `Kernel#local_variables`
12
- - (<=2.3) Set local variables for regexp named captures (`/(?<b>a)/ =~ 'a'` => `b = 'a'`)
13
- - Remove deprecated `NIL`, `TRUE`, `FALSE` constants
14
- - `String#unpack` and `String#unpack1` to support an `offset:` kwarg
15
- - `MatchData#match`, `MatchData#match_length`
16
- - Enumerable modernization
17
- - `Enumerable#tally` to support an optional hash accumulator
18
- - `Enumerable#each_{cons,slice}` to return self
19
- - `Enumerable#compact`
20
- - `Refinement` becomes its own class now
21
- - `Struct#keyword_init?`
22
- - (pre-3.1) Large Enumerator rework
23
- - Introduce `Enumerator::ArithmeticSequence`
24
- - Introduce `Enumerator::Chain`
25
- - Introduce `Enumerator#+` to create `Enumerator::Chain`s
26
- - `Enumerator#{rewind,peek,peek_values,next,next_values}`
27
- - Improve corelib support for beginless/endless ranges and `ArithmeticSequences`
28
- - `String#[]`, `Array#[]`, `Array#[]=`, `Array#fill`, `Array#values_at`
29
- - `Range#step` and `Numeric#step` return an `ArithmeticSequence` when `Numeric` values are in play
30
- - Introduce `Range#%`
31
- - `Enumerator::Yielder#to_proc`
32
- - Fix #2367
33
- - (2.7) `UnboundMethod#bind_call`
34
- - (Opal) `{Kernel,BasicObject}#{inspect,p,pp,method_missing}` may work with JS native values now, also they now correctly report cycles
35
- - `Enumerable#sum` uses Kahan's summation algorithm to reduce error with floating point values
36
- - `File.dirname` supports a new `level` argument
37
- - Vendor in `optparse` and `shellwords` (#2326)
38
- - Preliminary support for compiling the whole `bin/opal` with Opal (#2326)
3
+ - Introduce timezone support for Time (#2394)
4
+ - DateTime and Date refactor (#2398)
5
+ - Implement `Number#prev_float`/`#next_float` (#2404)
6
+ - Support `binding.irb` anywhere in the code, for both browsers and node (#2392)
7
+ - Added `URI.decode_www_form` (#2387)
39
8
 
40
- ### Fixed
9
+ ### Changed
41
10
 
42
- - Fix defining multiple methods with the same block (#2345)
43
- - Fix coertion for `Array#drop` (#2371)
44
- - Fix coertion for `File.absolute_path` (#2372)
45
- - Fix some `IO#puts` edge cases (no args, empty array, nested array, …) (#2372)
46
- - Preserve UNC path prefix on File.join (#2366)
47
- - Methods on `Kernel`, `BasicObject`, `Boolean` will never return boxed values anymore (#2293)
48
- - `false.tap{}` will now correctly return a JS value of `false`, not `Object(false)`
49
- - opal-parser doesn't break on `<<~END` strings anymore (#2364)
50
- - Fix error reporting at the early stage of loading (#2326)
11
+ - Move Math IE11-supporting polyfills to a separate file (#2395)
12
+ - String methods always return Strings even when overloaded (#2413)
13
+ - `alias` calls will not add the "old name" method to the list of stubs for method missing (#2414)
14
+ - Optimize writer/setter methods, up to 4% performance gain (#2402)
51
15
 
52
- ### Changed
16
+ ### Performance
53
17
 
54
- - Various outputted code size optimizations - 19% improvement for minified unmangled AsciiDoctor bundle - see: https://opalrb.com/blog/2021/11/24/optimizing-opal-output-for-size/ (#2356)
55
- - Second round of code size optimizations - 3% improvement for AsciiDoctor bundle on top of the first round - 23% total - see: https://github.com/opal/opal/pull/2365/commits (#2365)
56
- - The calls to `==`, `!=` and `===` changed their semantics slightly: it's impossible to monkey patch those calls for `String` and `Number`, but on other classes they can now return `nil` and it will be handled correctly
57
- - The calls to `!` changed their semantics slightly: it's impossible to monkey patch this call for `Boolean` or `NilClass`.
58
- - Refactored the structure of the internal `stdlib/nodejs` folder (#2374)
59
- - Added `nodejs/base` with just I/O, exit, and ARGV management
60
- - Moved `Process::Status` to corelib
61
- - Fixed requires to be more robust
18
+ - Improve performance of argument coertion, fast-track `Integer`, `String`, and calling the designed coertion method (#2383)
19
+ - Optimize `Array#[]=` by moving the implementation to JavaScript and inlining type checks (#2383)
20
+ - Optimize internal runtime passing of block-options (#2383)
21
+ - Compile `case` statements as `switch` whenever possible (#2411)
22
+ - Improve performance with optimized common method/iter implementation shortcuts (#2401)
62
23
 
63
- ### Removed
24
+ ### Fixed
25
+
26
+ - Fix `Regexp.new`, previously `\A` and `\z` didn't match beginning and end of input (#2079)
27
+ - Fix exception during `Hash#each` and `Hash#each_key` if keys get deleted during the loop (#2403)
28
+ - Fix defining multiple methods with the same block (#2397)
29
+ - A few edge cases of conditional calls combined with setters, e.g. `foo&.bar = 123` (#2402)
30
+ - Correct String#to_proc and method_missing compatibility (#2418)
31
+ - Exit REPL respecting the exit status number (#2396)
64
32
 
65
- - Removed `nodejs/irb` from stdlib as it's been broken for some time (#2374)
66
- - Removed `Kernel#node_require` from `nodejs/kernel` as it's been deprecated for a long time (#2374)
33
+ ### Internal
34
+
35
+ - Rewriters refactor, fix interaction between cache and inverted runner (#2400)
67
36
 
68
37
  <!--
69
- ### Deprecated
70
38
  ### Internal
39
+ ### Changed
40
+ ### Added
41
+ ### Removed
42
+ ### Deprecated
71
43
  -->
@@ -1,33 +1,58 @@
1
1
  Benchmark.ips do |x|
2
2
  %x{
3
+ const c_foo = 'foo'
4
+ const v_foo = 'foo'
5
+ const cfoo = Symbol('foo')
6
+ var vfoo = Symbol('foo')
7
+ const cgfoo = Symbol.for('foo')
8
+ var vgfoo = Symbol.for('foo')
9
+
3
10
  var o = {}
4
- o[Symbol.for('foo')] = 123
5
- o.foo = 123
6
- var foo = Symbol('foo')
7
- var gfoo = Symbol.for('foo')
8
- o[foo] = 123
9
- var a = 0, b = 0, c = 0
11
+ o[cfoo] = 1
12
+ o[cgfoo] = 1
13
+ o[c_foo] = 1
14
+ o[vfoo] = 1
15
+
16
+ let a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0, a6 = 0, a7 = 0, a8 = 0
10
17
  }
11
18
 
19
+ x.report('const string ref') do
20
+ `a1 += o[c_foo]`
21
+ end
22
+
23
+ x.report('var string ref') do
24
+ `a2 += o[v_foo]`
25
+ end
26
+
12
27
  x.report('live global symbol') do
13
- `a += o[Symbol.for('foo')]`
28
+ `a3 += o[Symbol.for('foo')]`
14
29
  end
15
30
 
16
- x.report('stored global symbol') do
17
- `a += o[gfoo]`
31
+ x.report('const global symbol') do
32
+ `a4 += o[cgfoo]`
18
33
  end
19
34
 
20
- x.report('stored symbol') do
21
- `a += o[foo]`
35
+ x.report('var global symbol') do
36
+ `a5 += o[vgfoo]`
37
+ end
38
+
39
+ x.report('const symbol') do
40
+ `a6 += o[cfoo]`
41
+ end
42
+
43
+ x.report('var symbol') do
44
+ `a6 += o[vfoo]`
22
45
  end
23
46
 
24
47
  x.report('ident') do
25
- `b += o.foo`
48
+ `a7 += o.foo`
26
49
  end
27
50
 
28
- x.report('string') do
29
- `c += o['foo']`
51
+ x.report('live string') do
52
+ `a8 += o['foo']`
30
53
  end
31
54
 
55
+ x.time = 10
56
+
32
57
  x.compare!
33
58
  end
data/docs/releasing.md CHANGED
@@ -10,16 +10,15 @@ _This guide is a work-in-progress._
10
10
  ## Updating the changelog
11
11
 
12
12
  - Ensure all the unreleased changes are documented in UNRELEASED.md
13
- - Run `bin/rake changelog VERSION=v1.2.3` specifying the version number you're about to release
13
+ - [skip for pre-releases] Run `bin/rake changelog VERSION=v1.2.3` specifying the version number you're about to release
14
+ - [skip for pre-releases] Empty UNRELEASED.md
14
15
 
15
16
  ## The commit
16
17
 
17
18
  - Commit the updated changelog along with the version bump using this commit message:
18
19
  "Release v1.2.3"
19
20
  - Push the commit and run `bin/rake release` to release the new version to Rubygems
20
- - Go to GitHub releases and create a new release from the latest tag pasting the contents of UNRELEASED.md
21
- - Empty UNRELEASED.md and run `bin/rake changelog`
22
- - Push the updated changelog
21
+ - Go to GitHub releases and create a new release from the latest tag pasting the contents from CHANGELOG.md
23
22
 
24
23
  ## Opal docs
25
24
 
@@ -35,3 +34,11 @@ _This guide is a work-in-progress._
35
34
  ## Opal CDN
36
35
 
37
36
  - Run `bin/release v1.2.3`
37
+
38
+ ## Prepare for the next release
39
+
40
+ - Skip this step if releasing a stable release
41
+ - Create a new pull request that:
42
+ - Updates a version to `v1.x.0.dev` in both `lib/opal/version.rb` and `opal/corelib/constants.rb`
43
+ - Remember to merge that PR before merging anything else next once we decide to not release any more point releases from `master`.
44
+
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ast'
4
+ require 'parser/ast/node'
5
+
6
+ module Opal
7
+ module AST
8
+ class Matcher
9
+ def initialize(&block)
10
+ @root = instance_exec(&block)
11
+ end
12
+
13
+ def s(type, *children)
14
+ Node.new(type, children)
15
+ end
16
+
17
+ def cap(capture)
18
+ Node.new(:capture, [capture])
19
+ end
20
+
21
+ def match(ast)
22
+ @captures = []
23
+ @root.match(ast, self) || (return false)
24
+ @captures
25
+ end
26
+
27
+ def inspect
28
+ "#<Opal::AST::Matcher: #{@root.inspect}>"
29
+ end
30
+
31
+ attr_accessor :captures
32
+
33
+ Node = Struct.new(:type, :children) do
34
+ def match(ast, matcher)
35
+ return false if ast.nil?
36
+
37
+ ast_parts = [ast.type] + ast.children
38
+ self_parts = [type] + children
39
+
40
+ return false if ast_parts.length != self_parts.length
41
+
42
+ ast_parts.length.times.all? do |i|
43
+ ast_elem = ast_parts[i]
44
+ self_elem = self_parts[i]
45
+
46
+ if self_elem.is_a?(Node) && self_elem.type == :capture
47
+ capture = true
48
+ self_elem = self_elem.children.first
49
+ end
50
+
51
+ res = case self_elem
52
+ when Node
53
+ self_elem.match(ast_elem, matcher)
54
+ when Array
55
+ self_elem.include?(ast_elem)
56
+ when :*
57
+ true
58
+ else
59
+ self_elem == ast_elem
60
+ end
61
+
62
+ matcher.captures << ast_elem if capture
63
+ res
64
+ end
65
+ end
66
+
67
+ def inspect
68
+ if type == :capture
69
+ "{#{children.first.inspect}}"
70
+ else
71
+ "s(#{type.inspect}, #{children.inspect[1..-2]})"
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
data/lib/opal/cache.rb CHANGED
@@ -41,7 +41,7 @@ module Opal
41
41
 
42
42
  data || begin
43
43
  compiler = yield
44
- cache.set(key, compiler)
44
+ cache.set(key, compiler) unless compiler.dynamic_cache_result
45
45
  compiler
46
46
  end
47
47
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'opal/cli_runners/system_runner'
4
+
3
5
  module Opal
4
6
  module CliRunners
5
7
  class Applescript
data/lib/opal/compiler.rb CHANGED
@@ -217,9 +217,16 @@ module Opal
217
217
  # Comments from the source code
218
218
  attr_reader :comments
219
219
 
220
+ # Method calls made in this file
221
+ attr_reader :method_calls
222
+
220
223
  # Magic comment flags extracted from the leading comments
221
224
  attr_reader :magic_comments
222
225
 
226
+ # Set if some rewritter caused a dynamic cache result, meaning it's not
227
+ # fit to be cached
228
+ attr_accessor :dynamic_cache_result
229
+
223
230
  def initialize(source, options = {})
224
231
  @source = source
225
232
  @indent = ''
@@ -227,8 +234,10 @@ module Opal
227
234
  @options = options
228
235
  @comments = Hash.new([])
229
236
  @case_stmt = nil
237
+ @method_calls = Set.new
230
238
  @option_values = {}
231
239
  @magic_comments = {}
240
+ @dynamic_cache_result = false
232
241
  end
233
242
 
234
243
  # Compile some ruby code to a string.
@@ -260,9 +269,12 @@ module Opal
260
269
  :main
261
270
  end
262
271
 
263
- @sexp = s(:top, sexp || s(:nil)).tap { |i| i.meta[:kind] = kind }
264
- @comments = ::Parser::Source::Comment.associate_locations(sexp, comments)
265
- @magic_comments = MagicComments.parse(sexp, comments)
272
+ @sexp = sexp.tap { |i| i.meta[:kind] = kind }
273
+
274
+ first_node = sexp.children.first if sexp.children.first.location
275
+
276
+ @comments = ::Parser::Source::Comment.associate_locations(first_node, comments)
277
+ @magic_comments = MagicComments.parse(first_node, comments)
266
278
  @eof_content = EofContent.new(tokens, @source).eof
267
279
  end
268
280
 
@@ -287,9 +299,8 @@ module Opal
287
299
  )
288
300
  end
289
301
 
290
- # Method calls made in this file
291
- def method_calls
292
- @method_calls ||= Set.new
302
+ def record_method_call(mid)
303
+ @method_calls << mid
293
304
  end
294
305
 
295
306
  alias async_await_before_typecasting async_await
@@ -353,9 +364,7 @@ module Opal
353
364
  @indent
354
365
  end
355
366
 
356
- # Create a new sexp using the given parts. Even though this just
357
- # returns an array, it must be used incase the internal structure
358
- # of sexps does change.
367
+ # Create a new sexp using the given parts.
359
368
  def s(type, *children)
360
369
  ::Opal::AST::Node.new(type, children)
361
370
  end