opal 1.8.0.beta1 → 1.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +150 -1
- data/UNRELEASED.md +1 -92
- data/lib/opal/nodes/args/parameters.rb +18 -11
- data/lib/opal/nodes/args.rb +0 -28
- data/lib/opal/nodes/super.rb +0 -9
- data/lib/opal/rewriter.rb +2 -0
- data/lib/opal/rewriters/deduplicate_arg_name.rb +48 -0
- data/lib/opal/rewriters/inline_args.rb +1 -13
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/array.rb +26 -22
- data/opal/corelib/constants.rb +2 -2
- data/opal/corelib/hash.rb +6 -2
- data/opal/corelib/kernel.rb +11 -14
- data/opal/corelib/method.rb +1 -0
- data/opal/corelib/module.rb +43 -22
- data/opal/corelib/proc.rb +4 -6
- data/opal/corelib/range.rb +54 -10
- data/opal/corelib/runtime.js +40 -31
- data/spec/filters/bugs/array.rb +0 -36
- data/spec/filters/bugs/cgi.rb +40 -0
- data/spec/filters/bugs/enumerable.rb +1 -3
- data/spec/filters/bugs/kernel.rb +6 -9
- data/spec/filters/bugs/method.rb +0 -3
- data/spec/filters/bugs/module.rb +1 -10
- data/spec/filters/bugs/range.rb +2 -16
- data/spec/filters/bugs/ruby-32.rb +2 -2
- data/spec/filters/unsupported/kernel.rb +0 -4
- data/spec/opal/core/language/arguments/underscore_arg_spec.rb +89 -0
- data/spec/opal/core/module/define_method_spec.rb +29 -0
- data/spec/ruby_specs +1 -0
- data/stdlib/cgi/util.rb +89 -0
- data/stdlib/cgi.rb +1 -14
- metadata +15 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8af8b2b4d485065e48d45e66e00075cf3b2f3d58c358355f5cbf5c97c46cd607
|
4
|
+
data.tar.gz: 87b7e4d8443eeb45953d48ca6ebb321b27269d9e7bbe2c4770c5189bcd44bcf9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 615891333955fa65566ccad7f18d7a2a65905076db6268775bb5e9f06604b56e4ebfcb8fc05d181353c1bcfbba64c195c2eb4f71b37f805e9f7984f990e56a41
|
7
|
+
data.tar.gz: 1566eb09bf04acbcb49c7386ab9259cd13f8d94810e9dfecadf109b57ad2eaf479d1df419359a4a776b11aba2c7cc97d7df761c9ade46a2b8512d2718503ab69
|
data/CHANGELOG.md
CHANGED
@@ -16,7 +16,7 @@ Changes are grouped as follows:
|
|
16
16
|
|
17
17
|
|
18
18
|
|
19
|
-
## [1.
|
19
|
+
## [1.8.1](https://github.com/opal/opal/compare/v1.8.0...v1.8.1) - 2023-11-09
|
20
20
|
|
21
21
|
|
22
22
|
<!--
|
@@ -26,8 +26,157 @@ Changes are grouped as follows:
|
|
26
26
|
### Removed
|
27
27
|
### Deprecated
|
28
28
|
### Performance
|
29
|
+
### Fixed
|
30
|
+
-->
|
31
|
+
|
32
|
+
|
33
|
+
### Fixed
|
34
|
+
|
35
|
+
- `Array` methods should handle elements inserted during the iteration ([#2602](https://github.com/opal/opal/pull/2602))
|
36
|
+
- Assign correct values to duplicated underscore parameters ([#2606](https://github.com/opal/opal/pull/2606))
|
37
|
+
|
38
|
+
|
39
|
+
### Added
|
40
|
+
|
41
|
+
- Support an `IO` argument of `Kernel.printf` ([#2605](https://github.com/opal/opal/pull/2605))
|
42
|
+
|
43
|
+
|
44
|
+
### Performance
|
45
|
+
|
46
|
+
- Fix a performance regression introduced by freezing support ([#2609](https://github.com/opal/opal/pull/2609))
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
## [1.8.0](https://github.com/opal/opal/compare/v1.7.4...v1.8.0) - 2023-10-26
|
52
|
+
|
53
|
+
|
54
|
+
<!--
|
55
|
+
### Internal
|
56
|
+
### Added
|
57
|
+
### Removed
|
58
|
+
### Deprecated
|
59
|
+
### Performance
|
60
|
+
### Fixed
|
61
|
+
### Documentation
|
29
62
|
-->
|
30
63
|
|
64
|
+
## Highlights
|
65
|
+
|
66
|
+
### `Hash` is now bridged to JavaScript `Map`
|
67
|
+
|
68
|
+
This change brings a lot of benefits, but also some incompatibilities. The main benefit is that `Hash` now is both more performant and relies on native JavaScript capabilities.
|
69
|
+
This improves interoperability with JavaScript. As a downside, applications reaching for internal `Hash` data structures will need to be updated.
|
70
|
+
|
71
|
+
Interacting with `Hash` from `JavaScript` is easier than ever:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
hash = `new Map([['a', 1], ['b', 2]])`
|
75
|
+
hash # => {a: 1, b: 2}
|
76
|
+
`console.log(hash)` # => Map(2) {"a" => 1, "b" => 2}
|
77
|
+
`hash.get('a')` # => 1
|
78
|
+
`hash.set('c', 3)`
|
79
|
+
hash # => {a: 1, b: 2, c: 3}
|
80
|
+
hash.keys # => ["a", "b", "c"]
|
81
|
+
hash.values # => [1, 2, 3]
|
82
|
+
```
|
83
|
+
|
84
|
+
### Performance improvements
|
85
|
+
|
86
|
+
This release brings a lot of performance improvements, our tests on Asciidoctor show a 25% improvement in performance, but we've seen up to 66% performance improvement on some applications.
|
87
|
+
|
88
|
+
## Changelog
|
89
|
+
|
90
|
+
### Deprecated
|
91
|
+
|
92
|
+
- Deprecate using x-string to access JavaScript without an explicit magic-comment ([#2543](https://github.com/opal/opal/pull/2543))
|
93
|
+
|
94
|
+
### Compatibility
|
95
|
+
|
96
|
+
- Add a magic-comment that will disable x-string compilation to JavaScript ([#2543](https://github.com/opal/opal/pull/2543))
|
97
|
+
- Pass value in `PromiseV2#always` just like `PromiseV1#always` does it ([#2579](https://github.com/opal/opal/pull/2579))
|
98
|
+
- `#hash` now returns integers ([#2582](https://github.com/opal/opal/pull/2582))
|
99
|
+
- Improve `Range#include?`/`member?`/`cover?`/`===` ([#2598](https://github.com/opal/opal/pull/2598))
|
100
|
+
- Make `Module#define_method` more compatible with CRuby ([#2593](https://github.com/opal/opal/pull/2593))
|
101
|
+
- `Hash#clone` must freeze clone if original is frozen, but `Hash#dup` must not ([#2603](https://github.com/opal/opal/pull/2603))
|
102
|
+
|
103
|
+
### Fixed
|
104
|
+
|
105
|
+
- Fix `Kernel#Float` with `exception:` option ([#2532](https://github.com/opal/opal/pull/2532))
|
106
|
+
- Fix `Kernel#Integer` with `exception:` option ([#2531](https://github.com/opal/opal/pull/2531))
|
107
|
+
- Fix `String#split` with limit and capturing regexp ([#2544](https://github.com/opal/opal/pull/2544))
|
108
|
+
- Fix `switch` with Object-wrapped values ([#2542](https://github.com/opal/opal/pull/2542))
|
109
|
+
- Fix non-direct subclasses of bridged classes not calling the original constructor ([#2546](https://github.com/opal/opal/pull/2546))
|
110
|
+
- Regexp.escape: Cast to String or drop exception ([#2552](https://github.com/opal/opal/pull/2552))
|
111
|
+
- Propagate removal of method from included/prepended modules ([#2553](https://github.com/opal/opal/pull/2553))
|
112
|
+
- Restore `nodejs/yaml` functionality ([#2551](https://github.com/opal/opal/pull/2551))
|
113
|
+
- Fix sine `Range#size` edge cases ([#2541](https://github.com/opal/opal/pull/2541))
|
114
|
+
- Use a Map instead of a POJO for the jsid_cache ([#2584](https://github.com/opal/opal/pull/2584))
|
115
|
+
- Fix `String#object_id`, `String#__id__`, `String#hash` to match CRuby's behavior ([#2576](https://github.com/opal/opal/pull/2576))
|
116
|
+
- Lowercase response headers in `SimpleServer` for rack 3.0 compatibility ([#2578](https://github.com/opal/opal/pull/2578))
|
117
|
+
- Fix `Module#clone` and `Module#dup` to properly copy methods ([#2572](https://github.com/opal/opal/pull/2572))
|
118
|
+
- Chrome runner fix: support code that contains `</script>` ([#2581](https://github.com/opal/opal/pull/2581))
|
119
|
+
- Do not skip `$truthy` when left hand side of a comparison is `self` ([#2596](https://github.com/opal/opal/pull/2596))
|
120
|
+
- Unexpected `return`/`break` should raise `LocalJumpError` ([#2591](https://github.com/opal/opal/pull/2591))
|
121
|
+
|
122
|
+
### Added
|
123
|
+
|
124
|
+
- SourceMap support for `Kernel#eval` ([#2534](https://github.com/opal/opal/pull/2534))
|
125
|
+
- Add `CGI::Util#escapeURIComponent` and `CGI::Util#unescapeURIComponent` ([#2566](https://github.com/opal/opal/pull/2566))
|
126
|
+
- `CGI::Util` implement additional methods ([#2601](https://github.com/opal/opal/pull/2601))
|
127
|
+
|
128
|
+
### Changed
|
129
|
+
|
130
|
+
- Change compilation of Regexp nodes that may contain advanced features, so if invalid that they would raise at runtime, not parse-time ([#2548](https://github.com/opal/opal/pull/2548))
|
131
|
+
- `Hash` is now bridged to JavaScript `Map` and support for non-symbol keys in keyword arguments ([#2568](https://github.com/opal/opal/pull/2568))
|
132
|
+
|
133
|
+
### Documentation
|
134
|
+
|
135
|
+
- Bridging documentation ([#2541](https://github.com/opal/opal/pull/2541))
|
136
|
+
- Fix Typo in Running tests Section of README.md File ([#2580](https://github.com/opal/opal/pull/2580))
|
137
|
+
|
138
|
+
### Performance
|
139
|
+
|
140
|
+
- Improve performance of `Array#intersect?` and `#intersection` ([#2533](https://github.com/opal/opal/pull/2533))
|
141
|
+
- `Proc#call`: Refactor for performance ([#2541](https://github.com/opal/opal/pull/2541))
|
142
|
+
- Opal.stub_for: optimize ([#2541](https://github.com/opal/opal/pull/2541))
|
143
|
+
- Hash: Optimize `#to_a` ([#2541](https://github.com/opal/opal/pull/2541))
|
144
|
+
- Array: Optimize `#collect`/`#map` ([#2541](https://github.com/opal/opal/pull/2541))
|
145
|
+
- Optimize argument slicing in runtime for performance ([#2555](https://github.com/opal/opal/pull/2555))
|
146
|
+
- Closure: Generate a JavaScript object, not an Error, gain up to 15% on Asciidoctor ([#2556](https://github.com/opal/opal/pull/2556))
|
147
|
+
- Optimize `String#split` and `String#start_with` ([#2560](https://github.com/opal/opal/pull/2560))
|
148
|
+
- Compute `$@` dynamically ([#2592](https://github.com/opal/opal/pull/2592))
|
149
|
+
- Optimize the `$prop` helper ([#2597](https://github.com/opal/opal/pull/2597))
|
150
|
+
- Improve `Array.push()` performance when pushing many items ([#2565](https://github.com/opal/opal/pull/2565))
|
151
|
+
- Optimize `Opal.instance_methods` ([#2600](https://github.com/opal/opal/pull/2600))
|
152
|
+
|
153
|
+
### Internal
|
154
|
+
|
155
|
+
- Update rubocop ([#2535](https://github.com/opal/opal/pull/2535))
|
156
|
+
- Match3Node Cleanup ([#2541](https://github.com/opal/opal/pull/2541))
|
157
|
+
- IFlipFlop/EFlipFlop: Refactor for readability ([#2541](https://github.com/opal/opal/pull/2541))
|
158
|
+
- ForRewriter: Refactor for readability ([#2541](https://github.com/opal/opal/pull/2541))
|
159
|
+
|
160
|
+
|
161
|
+
|
162
|
+
|
163
|
+
## [1.7.4](https://github.com/opal/opal/compare/v1.7.3...v1.7.4) - 2023-09-14
|
164
|
+
|
165
|
+
|
166
|
+
### Fixed
|
167
|
+
|
168
|
+
- Use a Map instead of a POJO for the jsid_cache ([#2584](https://github.com/opal/opal/pull/2584))
|
169
|
+
- Lowercase response headers in `SimpleServer` for rack 3.0 compatibility ([#2578](https://github.com/opal/opal/pull/2578))
|
170
|
+
- Fix `switch` with Object-wrapped values ([#2542](https://github.com/opal/opal/pull/2542))
|
171
|
+
- Regexp.escape: Cast to String or drop exception ([#2552](https://github.com/opal/opal/pull/2552))
|
172
|
+
- Chrome runner fix: support code that contains `</script>` ([#2581](https://github.com/opal/opal/pull/2581))
|
173
|
+
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
## [1.7.3](https://github.com/opal/opal/compare/v1.7.2...v1.7.3) - 2023-03-23
|
178
|
+
|
179
|
+
|
31
180
|
### Fixed
|
32
181
|
|
33
182
|
- Disallow to define a singleton class for Number ([#2521](https://github.com/opal/opal/pull/2521))
|
data/UNRELEASED.md
CHANGED
@@ -1,101 +1,10 @@
|
|
1
1
|
<!--
|
2
2
|
### Internal
|
3
|
+
### Changed
|
3
4
|
### Added
|
4
5
|
### Removed
|
5
6
|
### Deprecated
|
6
7
|
### Performance
|
7
8
|
### Fixed
|
8
|
-
### Documentation
|
9
9
|
-->
|
10
10
|
|
11
|
-
## Highlights
|
12
|
-
|
13
|
-
### `Hash` is now bridged to JavaScript `Map`
|
14
|
-
|
15
|
-
This change brings a lot of benefits, but also some incompatibilities. The main benefit is that `Hash` now is both more performant and relies on native JavaScript capabilities.
|
16
|
-
This improves interoperability with JavaScript. As a downside, applications reaching for internal `Hash` data structures will need to be updated.
|
17
|
-
|
18
|
-
Interacting with `Hash` from `JavaScript` is easier than ever:
|
19
|
-
|
20
|
-
```ruby
|
21
|
-
hash = `new Map([['a', 1], ['b', 2]])`
|
22
|
-
hash # => {a: 1, b: 2}
|
23
|
-
`console.log(hash)` # => Map(2) {"a" => 1, "b" => 2}
|
24
|
-
`hash.get('a')` # => 1
|
25
|
-
`hash.set('c', 3)`
|
26
|
-
hash # => {a: 1, b: 2, c: 3}
|
27
|
-
hash.keys # => ["a", "b", "c"]
|
28
|
-
hash.values # => [1, 2, 3]
|
29
|
-
```
|
30
|
-
|
31
|
-
### Performance improvements
|
32
|
-
|
33
|
-
This release brings a lot of performance improvements, our tests on Asciidoctor show a 25% improvement in performance, but we've seen up to 66% performance improvement on some applications.
|
34
|
-
|
35
|
-
## Changelog
|
36
|
-
|
37
|
-
### Deprecated
|
38
|
-
|
39
|
-
- Deprecate using x-string to access JavaScript without an explicit magic-comment (#2543)
|
40
|
-
|
41
|
-
### Compatibility
|
42
|
-
|
43
|
-
- Add a magic-comment that will disable x-string compilation to JavaScript (#2543)
|
44
|
-
- Pass value in `PromiseV2#always` just like `PromiseV1#always` does it (#2579)
|
45
|
-
- `#hash` now returns integers #2582)
|
46
|
-
|
47
|
-
### Fixed
|
48
|
-
|
49
|
-
- Fix `Kernel#Float` with `exception:` option (#2532)
|
50
|
-
- Fix `Kernel#Integer` with `exception:` option (#2531)
|
51
|
-
- Fix `String#split` with limit and capturing regexp (#2544)
|
52
|
-
- Fix `switch` with Object-wrapped values (#2542)
|
53
|
-
- Fix non-direct subclasses of bridged classes not calling the original constructor (#2546)
|
54
|
-
- Regexp.escape: Cast to String or drop exception (#2552)
|
55
|
-
- Propagate removal of method from included/prepended modules (#2553)
|
56
|
-
- Restore `nodejs/yaml` functionality (#2551)
|
57
|
-
- Fix sine `Range#size` edge cases (#2541)
|
58
|
-
- Use a Map instead of a POJO for the jsid_cache (#2584)
|
59
|
-
- Fix `String#object_id`, `String#__id__`, `String#hash` to match CRuby's behavior (#2576)
|
60
|
-
- Lowercase response headers in `SimpleServer` for rack 3.0 compatibility (#2578)
|
61
|
-
- Fix `Module#clone` and `Module#dup` to properly copy methods (#2572)
|
62
|
-
- Chrome runner fix: support code that contains `</script>` (#2581)
|
63
|
-
- Do not skip `$truthy` when left hand side of a comparison is `self` (#2596)
|
64
|
-
- Unexpected `return`/`break` should raise `LocalJumpError` (#2591)
|
65
|
-
|
66
|
-
### Added
|
67
|
-
|
68
|
-
- SourceMap support for `Kernel#eval` (#2534)
|
69
|
-
- Add `CGI::Util#escapeURIComponent` and `CGI::Util#unescapeURIComponent` (#2566)
|
70
|
-
|
71
|
-
### Changed
|
72
|
-
|
73
|
-
- Change compilation of Regexp nodes that may contain advanced features, so if invalid that they would raise at runtime, not parse-time (#2548)
|
74
|
-
- `Hash` is now bridged to JavaScript `Map` and support for non-symbol keys in keyword arguments (#2568)
|
75
|
-
|
76
|
-
### Documentation
|
77
|
-
|
78
|
-
- Bridging documentation (#2541)
|
79
|
-
- Fix Typo in Running tests Section of README.md File (#2580)
|
80
|
-
|
81
|
-
### Performance
|
82
|
-
|
83
|
-
- Improve performance of `Array#intersect?` and `#intersection` (#2533)
|
84
|
-
- `Proc#call`: Refactor for performance (#2541)
|
85
|
-
- Opal.stub_for: optimize (#2541)
|
86
|
-
- Hash: Optimize `#to_a` (#2541)
|
87
|
-
- Array: Optimize `#collect`/`#map` (#2541)
|
88
|
-
- Optimize argument slicing in runtime for performance (#2555)
|
89
|
-
- Closure: Generate a JavaScript object, not an Error, gain up to 15% on Asciidoctor (#2556)
|
90
|
-
- Optimize `String#split` and `String#start_with` (#2560)
|
91
|
-
- Compute `$@` dynamically (#2592)
|
92
|
-
- Optimize the `$prop` helper (#2597)
|
93
|
-
- Improve `Array.push()` performance when pushing many items (#2565)
|
94
|
-
-
|
95
|
-
|
96
|
-
### Internal
|
97
|
-
|
98
|
-
- Update rubocop (#2535)
|
99
|
-
- Match3Node Cleanup (#2541)
|
100
|
-
- IFlipFlop/EFlipFlop: Refactor for readability (#2541)
|
101
|
-
- ForRewriter: Refactor for readability (#2541)
|
@@ -10,25 +10,28 @@ module Opal
|
|
10
10
|
|
11
11
|
def to_code
|
12
12
|
stringified_parameters = @args.map do |arg|
|
13
|
-
public_send(:"on_#{arg.type}",
|
13
|
+
public_send(:"on_#{arg.type}", arg)
|
14
14
|
end
|
15
15
|
|
16
16
|
"[#{stringified_parameters.compact.join(', ')}]"
|
17
17
|
end
|
18
18
|
|
19
|
-
def on_arg(
|
19
|
+
def on_arg(arg)
|
20
|
+
arg_name = arg.meta[:arg_name]
|
20
21
|
%{['req', '#{arg_name}']}
|
21
22
|
end
|
22
23
|
|
23
|
-
def on_mlhs(
|
24
|
+
def on_mlhs(_arg)
|
24
25
|
%{['req']}
|
25
26
|
end
|
26
27
|
|
27
|
-
def on_optarg(
|
28
|
+
def on_optarg(arg)
|
29
|
+
arg_name = arg.meta[:arg_name]
|
28
30
|
%{['opt', '#{arg_name}']}
|
29
31
|
end
|
30
32
|
|
31
|
-
def on_restarg(
|
33
|
+
def on_restarg(arg)
|
34
|
+
arg_name = arg.meta[:arg_name]
|
32
35
|
if arg_name
|
33
36
|
arg_name = :* if arg_name == :fwd_rest_arg
|
34
37
|
%{['rest', '#{arg_name}']}
|
@@ -37,15 +40,18 @@ module Opal
|
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
40
|
-
def on_kwarg(
|
43
|
+
def on_kwarg(arg)
|
44
|
+
arg_name = arg.meta[:arg_name]
|
41
45
|
%{['keyreq', '#{arg_name}']}
|
42
46
|
end
|
43
47
|
|
44
|
-
def on_kwoptarg(
|
48
|
+
def on_kwoptarg(arg)
|
49
|
+
arg_name = arg.meta[:arg_name]
|
45
50
|
%{['key', '#{arg_name}']}
|
46
51
|
end
|
47
52
|
|
48
|
-
def on_kwrestarg(
|
53
|
+
def on_kwrestarg(arg)
|
54
|
+
arg_name = arg.meta[:arg_name]
|
49
55
|
if arg_name
|
50
56
|
%{['keyrest', '#{arg_name}']}
|
51
57
|
else
|
@@ -53,16 +59,17 @@ module Opal
|
|
53
59
|
end
|
54
60
|
end
|
55
61
|
|
56
|
-
def on_blockarg(
|
62
|
+
def on_blockarg(arg)
|
63
|
+
arg_name = arg.meta[:arg_name]
|
57
64
|
arg_name = :& if arg_name == :fwd_block_arg
|
58
65
|
%{['block', '#{arg_name}']}
|
59
66
|
end
|
60
67
|
|
61
|
-
def on_kwnilarg
|
68
|
+
def on_kwnilarg(_arg)
|
62
69
|
%{['nokey']}
|
63
70
|
end
|
64
71
|
|
65
|
-
def on_shadowarg(
|
72
|
+
def on_shadowarg(_arg); end
|
66
73
|
end
|
67
74
|
end
|
68
75
|
end
|
data/lib/opal/nodes/args.rb
CHANGED
@@ -25,40 +25,12 @@ module Opal
|
|
25
25
|
class ArgsNode < Base
|
26
26
|
handle :args
|
27
27
|
|
28
|
-
# ruby allows for args with the same name, if the arg starts with a '_', like:
|
29
|
-
# def funny_method_name(_, _)
|
30
|
-
# puts _
|
31
|
-
# end
|
32
|
-
# but javascript in strict mode does not allow for args with the same name
|
33
|
-
# ruby assigns the value of the first arg given
|
34
|
-
# funny_method_name(1, 2) => 1
|
35
|
-
# 1. check for args starting with '_' and check if they appear multiple times
|
36
|
-
# 2. leave the first appearance as it is and rename the other ones
|
37
|
-
# compiler result:
|
38
|
-
# function $$funny_method_name(_, __$2)
|
39
|
-
|
40
28
|
def compile
|
41
|
-
same_arg_counter = {}
|
42
29
|
children.each_with_index do |arg, idx|
|
43
|
-
if multiple_underscore?(arg)
|
44
|
-
same_arg_counter[arg] ||= 0
|
45
|
-
same_arg_counter[arg] += 1
|
46
|
-
if same_arg_counter[arg] > 1
|
47
|
-
arg = s(arg.type, :"#{arg.children[0]}_$#{same_arg_counter[arg]}")
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
30
|
push ', ' if idx != 0
|
52
31
|
push process(arg)
|
53
32
|
end
|
54
33
|
end
|
55
|
-
|
56
|
-
def multiple_underscore?(arg)
|
57
|
-
arg.type == :arg &&
|
58
|
-
arg.children.count == 1 &&
|
59
|
-
arg.children.first.to_s.start_with?('_') &&
|
60
|
-
children.count(arg) > 1
|
61
|
-
end
|
62
34
|
end
|
63
35
|
end
|
64
36
|
end
|
data/lib/opal/nodes/super.rb
CHANGED
@@ -176,7 +176,6 @@ module Opal
|
|
176
176
|
def implicit_arglist
|
177
177
|
args = []
|
178
178
|
kwargs = []
|
179
|
-
same_arg_counter = Hash.new(0)
|
180
179
|
|
181
180
|
def_scope.original_args.children.each do |sexp|
|
182
181
|
lvar_name = sexp.children[0]
|
@@ -184,14 +183,6 @@ module Opal
|
|
184
183
|
case sexp.type
|
185
184
|
when :arg, :optarg
|
186
185
|
arg_node = s(:lvar, lvar_name)
|
187
|
-
# def m(_, _)
|
188
|
-
# is compiled to
|
189
|
-
# function $$m(_, __$2)
|
190
|
-
# See Opal::Node::ArgsNode
|
191
|
-
if lvar_name[0] == '_'
|
192
|
-
same_arg_counter[lvar_name] += 1
|
193
|
-
arg_node = s(:js_tmp, "#{lvar_name}_$#{same_arg_counter[lvar_name]}") if same_arg_counter[lvar_name] > 1
|
194
|
-
end
|
195
186
|
args << arg_node
|
196
187
|
when :restarg
|
197
188
|
arg_node = lvar_name ? s(:lvar, lvar_name) : s(:js_tmp, '$rest_arg')
|
data/lib/opal/rewriter.rb
CHANGED
@@ -11,6 +11,7 @@ require 'opal/rewriters/logical_operator_assignment'
|
|
11
11
|
require 'opal/rewriters/binary_operator_assignment'
|
12
12
|
require 'opal/rewriters/hashes/key_duplicates_rewriter'
|
13
13
|
require 'opal/rewriters/dump_args'
|
14
|
+
require 'opal/rewriters/deduplicate_arg_name'
|
14
15
|
require 'opal/rewriters/mlhs_args'
|
15
16
|
require 'opal/rewriters/inline_args'
|
16
17
|
require 'opal/rewriters/numblocks'
|
@@ -66,6 +67,7 @@ module Opal
|
|
66
67
|
use Rewriters::BinaryOperatorAssignment
|
67
68
|
use Rewriters::Hashes::KeyDuplicatesRewriter
|
68
69
|
use Rewriters::ReturnableLogic
|
70
|
+
use Rewriters::DeduplicateArgName
|
69
71
|
use Rewriters::DumpArgs
|
70
72
|
use Rewriters::MlhsArgs
|
71
73
|
use Rewriters::InlineArgs
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Opal
|
4
|
+
module Rewriters
|
5
|
+
# Ruby allows for args with the same name, if the arg starts with a '_', like:
|
6
|
+
# def funny_method_name(_, _)
|
7
|
+
# puts _
|
8
|
+
# end
|
9
|
+
# but JavaScript in strict mode does not allow for args with the same name
|
10
|
+
# Ruby assigns the value of the first arg given
|
11
|
+
# funny_method_name(1, 2) => 1
|
12
|
+
# leave the first appearance as it is and rename the other ones
|
13
|
+
# compiler result:
|
14
|
+
# function $$funny_method_name(_, __$2)
|
15
|
+
class DeduplicateArgName < Base
|
16
|
+
def on_args(node)
|
17
|
+
@arg_name_count = Hash.new(0)
|
18
|
+
|
19
|
+
children = node.children.map do |arg|
|
20
|
+
rename_arg(arg)
|
21
|
+
end
|
22
|
+
|
23
|
+
super(node.updated(nil, children))
|
24
|
+
end
|
25
|
+
|
26
|
+
def rename_arg(arg)
|
27
|
+
case arg.type
|
28
|
+
when :arg, :restarg, :kwarg, :kwrestarg, :blockarg
|
29
|
+
name = arg.children[0]
|
30
|
+
name ? arg.updated(nil, [unique_name(name)]) : arg
|
31
|
+
when :optarg, :kwoptarg
|
32
|
+
name, value = arg.children
|
33
|
+
arg.updated(nil, [unique_name(name), value])
|
34
|
+
when :mlhs
|
35
|
+
new_children = arg.children.map { |child| rename_arg(child) }
|
36
|
+
arg.updated(nil, new_children)
|
37
|
+
else
|
38
|
+
arg
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def unique_name(name)
|
43
|
+
count = (@arg_name_count[name] += 1)
|
44
|
+
count > 1 ? :"#{name}_$#{count}" : name
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -91,7 +91,6 @@ module Opal
|
|
91
91
|
@initialization = []
|
92
92
|
|
93
93
|
@type = type
|
94
|
-
@underscore_found = false
|
95
94
|
|
96
95
|
STEPS.each do |step|
|
97
96
|
send(step)
|
@@ -120,20 +119,9 @@ module Opal
|
|
120
119
|
@args.args.each do |arg|
|
121
120
|
if @type == :iter
|
122
121
|
# block args are not required,
|
123
|
-
# so we
|
122
|
+
# so we need to tell compiler that required args
|
124
123
|
# must be initialized with nil-s
|
125
124
|
@initialization << arg.updated(:initialize_iter_arg)
|
126
|
-
|
127
|
-
if arg.children[0] == :_
|
128
|
-
if @underscore_found
|
129
|
-
# for proc { |_, _| _ }.call(1, 2) result must be 1
|
130
|
-
# here we convert all underscore args starting from the 2nd
|
131
|
-
# to a "fake" arg
|
132
|
-
arg = s(:fake_arg)
|
133
|
-
end
|
134
|
-
|
135
|
-
@underscore_found = true
|
136
|
-
end
|
137
125
|
else
|
138
126
|
# required inline def argument like 'def m(req)'
|
139
127
|
# no initialization is required
|
data/lib/opal/version.rb
CHANGED
data/opal/corelib/array.rb
CHANGED
@@ -47,7 +47,7 @@ class ::Array < `Array`
|
|
47
47
|
function filterIf(self, filter, block) {
|
48
48
|
var value, raised = null, updated = new Array(self.length);
|
49
49
|
|
50
|
-
for (var i = 0, i2 = 0
|
50
|
+
for (var i = 0, i2 = 0; i < self.length; i++) {
|
51
51
|
if (!raised) {
|
52
52
|
try {
|
53
53
|
value = $yield1(block, self[i])
|
@@ -708,10 +708,9 @@ class ::Array < `Array`
|
|
708
708
|
return enum_for(:collect) { size } unless block_given?
|
709
709
|
|
710
710
|
%x{
|
711
|
-
var
|
712
|
-
var result = new Array(length);
|
711
|
+
var result = [];
|
713
712
|
|
714
|
-
for (var i = 0; i < length; i++) {
|
713
|
+
for (var i = 0; i < self.length; i++) {
|
715
714
|
var value = $yield1(block, self[i]);
|
716
715
|
result[i] = value;
|
717
716
|
}
|
@@ -726,7 +725,7 @@ class ::Array < `Array`
|
|
726
725
|
%x{
|
727
726
|
$deny_frozen_access(self);
|
728
727
|
|
729
|
-
for (var i = 0
|
728
|
+
for (var i = 0; i < self.length; i++) {
|
730
729
|
var value = $yield1(block, self[i]);
|
731
730
|
self[i] = value;
|
732
731
|
}
|
@@ -988,8 +987,8 @@ class ::Array < `Array`
|
|
988
987
|
return enum_for(:each) { size } unless block_given?
|
989
988
|
|
990
989
|
%x{
|
991
|
-
for (var i = 0
|
992
|
-
|
990
|
+
for (var i = 0; i < self.length; i++) {
|
991
|
+
$yield1(block, self[i]);
|
993
992
|
}
|
994
993
|
}
|
995
994
|
|
@@ -1000,8 +999,8 @@ class ::Array < `Array`
|
|
1000
999
|
return enum_for(:each_index) { size } unless block_given?
|
1001
1000
|
|
1002
1001
|
%x{
|
1003
|
-
for (var i = 0
|
1004
|
-
|
1002
|
+
for (var i = 0; i < self.length; i++) {
|
1003
|
+
$yield1(block, i);
|
1005
1004
|
}
|
1006
1005
|
}
|
1007
1006
|
|
@@ -1348,7 +1347,7 @@ class ::Array < `Array`
|
|
1348
1347
|
}
|
1349
1348
|
}
|
1350
1349
|
else if (block !== nil) {
|
1351
|
-
for (i = 0
|
1350
|
+
for (i = 0; i < self.length; i++) {
|
1352
1351
|
value = block(self[i]);
|
1353
1352
|
|
1354
1353
|
if (value !== false && value !== nil) {
|
@@ -1789,7 +1788,7 @@ class ::Array < `Array`
|
|
1789
1788
|
%x{
|
1790
1789
|
var result = [];
|
1791
1790
|
|
1792
|
-
for (var i = 0,
|
1791
|
+
for (var i = 0, value; i < self.length; i++) {
|
1793
1792
|
value = block(self[i]);
|
1794
1793
|
|
1795
1794
|
if (value === false || value === nil) {
|
@@ -1839,7 +1838,11 @@ class ::Array < `Array`
|
|
1839
1838
|
def reverse_each(&block)
|
1840
1839
|
return enum_for(:reverse_each) { size } unless block_given?
|
1841
1840
|
|
1842
|
-
|
1841
|
+
%x{
|
1842
|
+
for (var i = self.length - 1; i >= 0; i--) {
|
1843
|
+
$yield1(block, self[i]);
|
1844
|
+
}
|
1845
|
+
}
|
1843
1846
|
self
|
1844
1847
|
end
|
1845
1848
|
|
@@ -2048,7 +2051,7 @@ class ::Array < `Array`
|
|
2048
2051
|
%x{
|
2049
2052
|
var result = [];
|
2050
2053
|
|
2051
|
-
for (var i = 0,
|
2054
|
+
for (var i = 0, item, value; i < self.length; i++) {
|
2052
2055
|
item = self[i];
|
2053
2056
|
|
2054
2057
|
value = $yield1(block, item);
|
@@ -2293,7 +2296,7 @@ class ::Array < `Array`
|
|
2293
2296
|
%x{
|
2294
2297
|
var result = [];
|
2295
2298
|
|
2296
|
-
for (var i = 0,
|
2299
|
+
for (var i = 0, item, value; i < self.length; i++) {
|
2297
2300
|
item = self[i];
|
2298
2301
|
|
2299
2302
|
value = block(item);
|
@@ -2389,7 +2392,7 @@ class ::Array < `Array`
|
|
2389
2392
|
}
|
2390
2393
|
}
|
2391
2394
|
else {
|
2392
|
-
for (i = 0
|
2395
|
+
for (i = 0; i < self.length; i++) {
|
2393
2396
|
item = self[i];
|
2394
2397
|
key = $yield1(block, item);
|
2395
2398
|
if ($hash_get(hash, key) === undefined) {
|
@@ -2406,23 +2409,24 @@ class ::Array < `Array`
|
|
2406
2409
|
%x{
|
2407
2410
|
$deny_frozen_access(self);
|
2408
2411
|
|
2409
|
-
var
|
2412
|
+
var hash = #{{}}, i, item, key, delete_indexes = [];
|
2410
2413
|
|
2411
|
-
for (i = 0
|
2414
|
+
for (i = 0; i < self.length; i++) {
|
2412
2415
|
item = self[i];
|
2413
2416
|
key = (block === nil ? item : $yield1(block, item));
|
2414
2417
|
|
2415
2418
|
if ($hash_get(hash, key) === undefined) {
|
2416
2419
|
$hash_put(hash, key, item);
|
2417
|
-
|
2420
|
+
} else {
|
2421
|
+
delete_indexes.push(i);
|
2418
2422
|
}
|
2423
|
+
}
|
2419
2424
|
|
2420
|
-
|
2421
|
-
|
2422
|
-
i--;
|
2425
|
+
for (i = delete_indexes.length - 1; i >= 0; i--) {
|
2426
|
+
self.splice(delete_indexes[i], 1);
|
2423
2427
|
}
|
2424
2428
|
|
2425
|
-
return
|
2429
|
+
return delete_indexes.length === 0 ? nil : self;
|
2426
2430
|
}
|
2427
2431
|
end
|
2428
2432
|
|
data/opal/corelib/constants.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
::RUBY_PLATFORM = 'opal'
|
2
2
|
::RUBY_ENGINE = 'opal'
|
3
3
|
::RUBY_VERSION = '3.2.0'
|
4
|
-
::RUBY_ENGINE_VERSION = '1.8.
|
5
|
-
::RUBY_RELEASE_DATE = '2023-
|
4
|
+
::RUBY_ENGINE_VERSION = '1.8.1'
|
5
|
+
::RUBY_RELEASE_DATE = '2023-11-09'
|
6
6
|
::RUBY_PATCHLEVEL = 0
|
7
7
|
::RUBY_REVISION = '0'
|
8
8
|
::RUBY_COPYRIGHT = 'opal - Copyright (C) 2011-2023 Adam Beynon and the Opal contributors'
|