ruby-next-core 0.14.1 → 0.15.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/README.md +36 -2
- data/lib/.rbnext/2.1/ruby-next/core.rb +2 -2
- data/lib/.rbnext/2.1/ruby-next/language.rb +3 -0
- data/lib/.rbnext/2.3/ruby-next/commands/nextify.rb +14 -0
- data/lib/.rbnext/2.3/ruby-next/language/rewriters/2.7/args_forward.rb +134 -0
- data/lib/.rbnext/2.3/ruby-next/language/rewriters/2.7/pattern_matching.rb +0 -1
- data/lib/.rbnext/2.3/ruby-next/language/rewriters/base.rb +1 -1
- data/lib/.rbnext/2.7/ruby-next/core.rb +2 -2
- data/lib/.rbnext/2.7/ruby-next/language/rewriters/2.7/pattern_matching.rb +0 -1
- data/lib/ruby-next/cli.rb +10 -15
- data/lib/ruby-next/commands/nextify.rb +14 -0
- data/lib/ruby-next/config.rb +2 -2
- data/lib/ruby-next/core/proc/compose.rb +0 -1
- data/lib/ruby-next/core/refinement/import.rb +1 -1
- data/lib/ruby-next/core.rb +1 -1
- data/lib/ruby-next/irb.rb +24 -0
- data/lib/ruby-next/language/rewriters/2.5/rescue_within_block.rb +41 -0
- data/lib/ruby-next/language/rewriters/2.7/args_forward.rb +57 -0
- data/lib/ruby-next/language/rewriters/2.7/pattern_matching.rb +0 -1
- data/lib/ruby-next/language/rewriters/base.rb +1 -1
- data/lib/ruby-next/language/runtime.rb +1 -1
- data/lib/ruby-next/language/setup.rb +1 -1
- data/lib/ruby-next/language.rb +3 -0
- data/lib/ruby-next/pry.rb +90 -0
- data/lib/ruby-next/version.rb +1 -1
- data/lib/uby-next/irb.rb +3 -0
- data/lib/uby-next/pry.rb +3 -0
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c392536e2de07a838a8c9818b0651a9d2eb6803471f52d1e3632bada3fb398a4
|
4
|
+
data.tar.gz: 564822b7a5c55ec7fc278bf223206f0b16a75a71a9277b247d862489c7a342cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33d80d8d5bfaaf75cc0cc42b79eb4758ff57c9d72f1ac21eb86770f1f039c79cebc7eabc5b4a20c42e11a9a266b8a435849b2a4ae74547acd6b9a8fb8db03f39
|
7
|
+
data.tar.gz: 1a9b048897ad763e2dd726bc0be7112337499dbb1ddad9e02f13b81a2bb98d28d6f32f2e9abe1e29222a05895433117e082a5a8e42be4101d4d4eb056bcf5c61
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,34 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.15.2 (2022-08-02)
|
6
|
+
|
7
|
+
- Fix loading transpiled in TruffleRuby. ([@palkan][])
|
8
|
+
|
9
|
+
TruffleRuby doesn't support all Ruby 3.0 features yet, so we should treat as an older Ruby.
|
10
|
+
|
11
|
+
- Use `ruby2_keywords` when transpiling arguments forwarding. ([@palkan][])
|
12
|
+
|
13
|
+
That makes transpiled code forward compatible with the modern Ruby versions.
|
14
|
+
|
15
|
+
## 0.15.1 (2022-04-05)
|
16
|
+
|
17
|
+
- Fix transpiling `rescue` within nested blocks. ([@palkan][])
|
18
|
+
|
19
|
+
## 0.15.0 (2022-03-21)
|
20
|
+
|
21
|
+
- Support IRB ([@palkan][])
|
22
|
+
|
23
|
+
- Create empty `.rbnext` folder during `nextify` if nothing to transpile. ([@palkan][])
|
24
|
+
|
25
|
+
This would prevent from auto-transpiling a library every time when no files should be transpiled.
|
26
|
+
|
27
|
+
- Auto-transpile using the current Ruby version. ([@palkan][])
|
28
|
+
|
29
|
+
- Support Pry. ([@baygeldin][])
|
30
|
+
|
31
|
+
- Add `rescue/ensure/else` within block rewriter for Ruby < 2.5. ([@fargelus][])
|
32
|
+
|
5
33
|
## 0.14.1 (2022-01-21)
|
6
34
|
|
7
35
|
- Fix nested find patterns transpiling. ([@palkan][])
|
data/README.md
CHANGED
@@ -71,6 +71,8 @@ _Please, submit a PR to add your project to the list!_
|
|
71
71
|
- [`ruby -ruby-next`](#uby-next)
|
72
72
|
- [Logging & Debugging](#logging-and-debugging)
|
73
73
|
- [RuboCop](#rubocop)
|
74
|
+
- [Using with IRB](#irb)
|
75
|
+
- [Using with Pry](#pry)
|
74
76
|
- [Using with EOL Rubies](#using-with-eol-rubies)
|
75
77
|
- [Proposed & edge features](#proposed-and-edge-features)
|
76
78
|
- [Known limitations](#known-limitations)
|
@@ -454,6 +456,38 @@ AllCops:
|
|
454
456
|
|
455
457
|
**NOTE:** you need `ruby-next` gem available in the environment where you run RuboCop (having `ruby-next-core` is not enough).
|
456
458
|
|
459
|
+
## IRB
|
460
|
+
|
461
|
+
Ruby Next supports IRB. In order to enable edge Ruby features for your REPL, add the following line to your `.irbrc`:
|
462
|
+
|
463
|
+
```ruby
|
464
|
+
require "ruby-next/irb"
|
465
|
+
```
|
466
|
+
|
467
|
+
Alternatively, you can require it at startup:
|
468
|
+
|
469
|
+
```sh
|
470
|
+
irb -r ruby-next/irb
|
471
|
+
# or
|
472
|
+
irb -ruby-next/irb
|
473
|
+
```
|
474
|
+
|
475
|
+
## Pry
|
476
|
+
|
477
|
+
Ruby Next supports Pry. In order to enable edge Ruby features for your REPL, add the following line to your `.pryrc`:
|
478
|
+
|
479
|
+
```ruby
|
480
|
+
require "ruby-next/pry"
|
481
|
+
```
|
482
|
+
|
483
|
+
Alternatively, you can require it at startup:
|
484
|
+
|
485
|
+
```sh
|
486
|
+
pry -r ruby-next/pry
|
487
|
+
# or
|
488
|
+
pry -ruby-next/pry
|
489
|
+
```
|
490
|
+
|
457
491
|
## Using with EOL Rubies
|
458
492
|
|
459
493
|
We currently provide support for Ruby 2.2, 2.3 and 2.4.
|
@@ -510,9 +544,9 @@ These features are disabled by default, you must opt-in in one of the following
|
|
510
544
|
# It's important to load language module first
|
511
545
|
require "ruby-next/language"
|
512
546
|
|
513
|
-
require "ruby-next/language/edge"
|
547
|
+
require "ruby-next/language/rewriters/edge"
|
514
548
|
# or
|
515
|
-
require "ruby-next/language/proposed"
|
549
|
+
require "ruby-next/language/rewriters/proposed"
|
516
550
|
|
517
551
|
# and then activate the runtime mode
|
518
552
|
require "ruby-next/language/runtime"
|
@@ -62,7 +62,7 @@ module RubyNext
|
|
62
62
|
mod_name = singleton? ? singleton.name : mod.name
|
63
63
|
camelized_method_name = method_name.to_s.split("_").map(&:capitalize).join
|
64
64
|
|
65
|
-
"#{mod_name}#{camelized_method_name}".gsub(/\W/, "")
|
65
|
+
"#{mod_name}#{camelized_method_name}".gsub(/\W/, "")
|
66
66
|
end
|
67
67
|
|
68
68
|
def build_location(trace_locations)
|
@@ -125,7 +125,7 @@ module RubyNext
|
|
125
125
|
|
126
126
|
def patch(*__rest__, &__block__)
|
127
127
|
patches << Patch.new(*__rest__, &__block__)
|
128
|
-
end
|
128
|
+
end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :patch)
|
129
129
|
|
130
130
|
# Inject `using RubyNext` at the top of the source code
|
131
131
|
def inject!(contents)
|
@@ -186,6 +186,9 @@ module RubyNext
|
|
186
186
|
require "ruby-next/language/rewriters/2.3/safe_navigation"
|
187
187
|
rewriters << Rewriters::SafeNavigation
|
188
188
|
|
189
|
+
require "ruby-next/language/rewriters/2.5/rescue_within_block"
|
190
|
+
rewriters << Rewriters::RescueWithinBlock
|
191
|
+
|
189
192
|
require "ruby-next/language/rewriters/2.7/args_forward"
|
190
193
|
rewriters << Rewriters::ArgsForward
|
191
194
|
|
@@ -24,6 +24,8 @@ module RubyNext
|
|
24
24
|
contents = File.read(path)
|
25
25
|
transpile path, contents
|
26
26
|
end
|
27
|
+
|
28
|
+
ensure_rbnext!
|
27
29
|
end
|
28
30
|
|
29
31
|
def parse!(args)
|
@@ -150,6 +152,7 @@ module RubyNext
|
|
150
152
|
transpile path, contents, version: version
|
151
153
|
rescue SyntaxError, StandardError => e
|
152
154
|
warn "Failed to transpile #{path}: #{e.class} — #{e.message}"
|
155
|
+
warn e.backtrace.take(10).join("\n") if ENV["RUBY_NEXT_DEBUG"] == "1"
|
153
156
|
exit 1
|
154
157
|
end
|
155
158
|
|
@@ -185,6 +188,17 @@ module RubyNext
|
|
185
188
|
FileUtils.rm_r(next_dir_path)
|
186
189
|
end
|
187
190
|
|
191
|
+
def ensure_rbnext!
|
192
|
+
return if CLI.dry_run? || stdout?
|
193
|
+
|
194
|
+
return if File.directory?(next_dir_path)
|
195
|
+
|
196
|
+
return if next_dir_path.end_with?(".rb")
|
197
|
+
|
198
|
+
FileUtils.mkdir_p next_dir_path
|
199
|
+
File.write(File.join(next_dir_path, ".keep"), "")
|
200
|
+
end
|
201
|
+
|
188
202
|
def next_dir_path
|
189
203
|
@next_dir_path ||= (out_path || File.join(lib_path, RUBY_NEXT_DIR))
|
190
204
|
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyNext
|
4
|
+
module Language
|
5
|
+
module Rewriters
|
6
|
+
class ArgsForward < Base
|
7
|
+
NAME = "args-forward"
|
8
|
+
SYNTAX_PROBE = "obj = Object.new; def obj.foo(...) super(...); end"
|
9
|
+
MIN_SUPPORTED_VERSION = Gem::Version.new("2.7.0")
|
10
|
+
|
11
|
+
REST = :__rest__
|
12
|
+
BLOCK = :__block__
|
13
|
+
|
14
|
+
def on_args(node)
|
15
|
+
farg = node.children.find { |child| child.is_a?(::Parser::AST::Node) && child.type == :forward_arg }
|
16
|
+
return unless farg
|
17
|
+
|
18
|
+
context.track! self
|
19
|
+
|
20
|
+
node = super(node)
|
21
|
+
|
22
|
+
replace(farg.loc.expression, "*#{REST}, &#{BLOCK}")
|
23
|
+
|
24
|
+
node.updated(
|
25
|
+
:args,
|
26
|
+
[
|
27
|
+
*node.children.slice(0, node.children.index(farg)),
|
28
|
+
s(:restarg, REST),
|
29
|
+
s(:blockarg, BLOCK)
|
30
|
+
]
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
def on_send(node)
|
35
|
+
fargs = extract_fargs(node)
|
36
|
+
return super(node) unless fargs
|
37
|
+
|
38
|
+
process_fargs(node, fargs)
|
39
|
+
end
|
40
|
+
|
41
|
+
def on_super(node)
|
42
|
+
fargs = extract_fargs(node)
|
43
|
+
return super(node) unless fargs
|
44
|
+
|
45
|
+
process_fargs(node, fargs)
|
46
|
+
end
|
47
|
+
|
48
|
+
def on_def(node)
|
49
|
+
return super unless forward_arg?(node.children[1])
|
50
|
+
|
51
|
+
new_node = super
|
52
|
+
|
53
|
+
name = node.children[0]
|
54
|
+
|
55
|
+
insert_after(node.loc.expression, "; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :#{name})")
|
56
|
+
|
57
|
+
s(:begin,
|
58
|
+
new_node,
|
59
|
+
ruby2_keywords_node(nil, name))
|
60
|
+
end
|
61
|
+
|
62
|
+
def on_defs(node)
|
63
|
+
return super unless forward_arg?(node.children[2])
|
64
|
+
|
65
|
+
new_node = super
|
66
|
+
|
67
|
+
receiver = node.children[0]
|
68
|
+
name = node.children[1]
|
69
|
+
|
70
|
+
# Using self.ruby2_keywords :name results in undefined method error,
|
71
|
+
# singleton_class works as expected
|
72
|
+
receiver = s(:send, nil, :singleton_class) if receiver.type == :self
|
73
|
+
|
74
|
+
receiver_name =
|
75
|
+
case receiver.type
|
76
|
+
when :send
|
77
|
+
receiver.children[1]
|
78
|
+
when :const
|
79
|
+
receiver.children[1]
|
80
|
+
end
|
81
|
+
|
82
|
+
insert_after(node.loc.expression, "; #{receiver_name}.respond_to?(:ruby2_keywords, true) && (#{receiver_name}.send(:ruby2_keywords, :#{name}))")
|
83
|
+
|
84
|
+
s(:begin,
|
85
|
+
new_node,
|
86
|
+
ruby2_keywords_node(receiver, name))
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def ruby2_keywords_node(receiver, name)
|
92
|
+
s(:and,
|
93
|
+
s(:send, receiver, :respond_to?,
|
94
|
+
s(:sym, :ruby2_keywords), s(:true)),
|
95
|
+
s(:begin,
|
96
|
+
s(:send, receiver, :send,
|
97
|
+
s(:sym, :ruby2_keywords),
|
98
|
+
s(:sym, name))))
|
99
|
+
end
|
100
|
+
|
101
|
+
def forward_arg?(args)
|
102
|
+
return false unless ((((__safe_lvar__ = args) || true) && (!__safe_lvar__.nil? || nil)) && __safe_lvar__.children)
|
103
|
+
|
104
|
+
args.children.any? { |arg| arg.type == :forward_arg }
|
105
|
+
end
|
106
|
+
|
107
|
+
def extract_fargs(node)
|
108
|
+
node.children.find { |child| child.is_a?(::Parser::AST::Node) && child.type == :forwarded_args }
|
109
|
+
end
|
110
|
+
|
111
|
+
def process_fargs(node, fargs)
|
112
|
+
replace(fargs.loc.expression, "*#{REST}, &#{BLOCK}")
|
113
|
+
|
114
|
+
process(
|
115
|
+
node.updated(
|
116
|
+
nil,
|
117
|
+
[
|
118
|
+
*node.children.take(node.children.index(fargs)),
|
119
|
+
*forwarded_args
|
120
|
+
]
|
121
|
+
)
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
def forwarded_args
|
126
|
+
[
|
127
|
+
s(:splat, s(:lvar, REST)),
|
128
|
+
s(:block_pass, s(:lvar, BLOCK))
|
129
|
+
]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -65,7 +65,7 @@ module RubyNext
|
|
65
65
|
end
|
66
66
|
|
67
67
|
class << self
|
68
|
-
# Returns true if the syntax is supported
|
68
|
+
# Returns true if the syntax is not supported
|
69
69
|
# by the current Ruby (performs syntax check, not version check)
|
70
70
|
def unsupported_syntax?
|
71
71
|
save_verbose, $VERBOSE = $VERBOSE, nil
|
@@ -62,7 +62,7 @@ module RubyNext
|
|
62
62
|
mod_name = singleton? ? singleton.name : mod.name
|
63
63
|
camelized_method_name = method_name.to_s.split("_").map(&:capitalize).join
|
64
64
|
|
65
|
-
"#{mod_name}#{camelized_method_name}".gsub(/\W/, "")
|
65
|
+
"#{mod_name}#{camelized_method_name}".gsub(/\W/, "")
|
66
66
|
end
|
67
67
|
|
68
68
|
def build_location(trace_locations)
|
@@ -125,7 +125,7 @@ module RubyNext
|
|
125
125
|
|
126
126
|
def patch(*__rest__, &__block__)
|
127
127
|
patches << Patch.new(*__rest__, &__block__)
|
128
|
-
end
|
128
|
+
end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :patch)
|
129
129
|
|
130
130
|
# Inject `using RubyNext` at the top of the source code
|
131
131
|
def inject!(contents)
|
data/lib/ruby-next/cli.rb
CHANGED
@@ -24,9 +24,6 @@ module RubyNext
|
|
24
24
|
"core_ext" => Commands::CoreExt
|
25
25
|
}.freeze
|
26
26
|
|
27
|
-
def initialize
|
28
|
-
end
|
29
|
-
|
30
27
|
def run(args = ARGV)
|
31
28
|
maybe_print_version(args)
|
32
29
|
|
@@ -80,18 +77,16 @@ module RubyNext
|
|
80
77
|
end
|
81
78
|
|
82
79
|
def optparser
|
83
|
-
@optparser ||=
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
@print_help = true
|
94
|
-
end
|
80
|
+
@optparser ||= OptionParser.new do |opts|
|
81
|
+
opts.banner = "Usage: ruby-next COMMAND [options]"
|
82
|
+
|
83
|
+
opts.on("-v", "--version", "Print version") do
|
84
|
+
$stdout.puts RubyNext::VERSION
|
85
|
+
exit 0
|
86
|
+
end
|
87
|
+
|
88
|
+
opts.on("-h", "--help", "Print help") do
|
89
|
+
@print_help = true
|
95
90
|
end
|
96
91
|
end
|
97
92
|
end
|
@@ -24,6 +24,8 @@ module RubyNext
|
|
24
24
|
contents = File.read(path)
|
25
25
|
transpile path, contents
|
26
26
|
end
|
27
|
+
|
28
|
+
ensure_rbnext!
|
27
29
|
end
|
28
30
|
|
29
31
|
def parse!(args)
|
@@ -150,6 +152,7 @@ module RubyNext
|
|
150
152
|
transpile path, contents, version: version
|
151
153
|
rescue SyntaxError, StandardError => e
|
152
154
|
warn "Failed to transpile #{path}: #{e.class} — #{e.message}"
|
155
|
+
warn e.backtrace.take(10).join("\n") if ENV["RUBY_NEXT_DEBUG"] == "1"
|
153
156
|
exit 1
|
154
157
|
end
|
155
158
|
|
@@ -185,6 +188,17 @@ module RubyNext
|
|
185
188
|
FileUtils.rm_r(next_dir_path)
|
186
189
|
end
|
187
190
|
|
191
|
+
def ensure_rbnext!
|
192
|
+
return if CLI.dry_run? || stdout?
|
193
|
+
|
194
|
+
return if File.directory?(next_dir_path)
|
195
|
+
|
196
|
+
return if next_dir_path.end_with?(".rb")
|
197
|
+
|
198
|
+
FileUtils.mkdir_p next_dir_path
|
199
|
+
File.write(File.join(next_dir_path, ".keep"), "")
|
200
|
+
end
|
201
|
+
|
188
202
|
def next_dir_path
|
189
203
|
@next_dir_path ||= (out_path || File.join(lib_path, RUBY_NEXT_DIR))
|
190
204
|
end
|
data/lib/ruby-next/config.rb
CHANGED
@@ -19,8 +19,8 @@ module RubyNext
|
|
19
19
|
NEXT_VERSION = "1995.next.0"
|
20
20
|
|
21
21
|
class << self
|
22
|
-
# TruffleRuby claims
|
23
|
-
if defined?(TruffleRuby)
|
22
|
+
# TruffleRuby claims its RUBY_VERSION to be X.Y while not supporting all the features
|
23
|
+
if defined?(TruffleRuby)
|
24
24
|
def current_ruby_version
|
25
25
|
"2.6.5"
|
26
26
|
end
|
@@ -54,7 +54,7 @@ RubyNext::Core.singleton_class.module_eval do
|
|
54
54
|
|
55
55
|
# Copy constants (they could be accessed from methods)
|
56
56
|
other.constants.each do |name|
|
57
|
-
Kernel.eval "#{name} = #{other}::#{name}", bind
|
57
|
+
Kernel.eval "#{name} = #{other}::#{name}", bind # rubocop:disable Style/EvalWithLocation
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
data/lib/ruby-next/core.rb
CHANGED
@@ -62,7 +62,7 @@ module RubyNext
|
|
62
62
|
mod_name = singleton? ? singleton.name : mod.name
|
63
63
|
camelized_method_name = method_name.to_s.split("_").map(&:capitalize).join
|
64
64
|
|
65
|
-
"#{mod_name}#{camelized_method_name}".gsub(/\W/, "")
|
65
|
+
"#{mod_name}#{camelized_method_name}".gsub(/\W/, "")
|
66
66
|
end
|
67
67
|
|
68
68
|
def build_location(trace_locations)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ruby-next"
|
4
|
+
# Include RubyNext into TOPLEVEL_BINDING for polyfills to work
|
5
|
+
eval("using RubyNext", TOPLEVEL_BINDING, __FILE__, __LINE__)
|
6
|
+
|
7
|
+
require "ruby-next/language"
|
8
|
+
|
9
|
+
# IRB extension to transpile code before evaluating
|
10
|
+
module RubyNext
|
11
|
+
module IRBExt
|
12
|
+
def evaluate(context, statements, *args)
|
13
|
+
new_statements = ::RubyNext::Language.transform(
|
14
|
+
statements,
|
15
|
+
rewriters: ::RubyNext::Language.current_rewriters,
|
16
|
+
using: false
|
17
|
+
)
|
18
|
+
|
19
|
+
super(context, new_statements, *args)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
IRB::WorkSpace.prepend(RubyNext::IRBExt)
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyNext
|
4
|
+
module Language
|
5
|
+
module Rewriters
|
6
|
+
class RescueWithinBlock < Base
|
7
|
+
NAME = "rescue-within-block"
|
8
|
+
SYNTAX_PROBE = "lambda do
|
9
|
+
raise 'err'
|
10
|
+
rescue
|
11
|
+
$! # => #<RuntimeError: err>
|
12
|
+
end.call"
|
13
|
+
|
14
|
+
MIN_SUPPORTED_VERSION = Gem::Version.new("2.5.0")
|
15
|
+
|
16
|
+
def on_block(block_node)
|
17
|
+
exception_node = block_node.children.find do |node|
|
18
|
+
node && (node.type == :rescue || node.type == :ensure)
|
19
|
+
end
|
20
|
+
|
21
|
+
return super(block_node) unless exception_node
|
22
|
+
|
23
|
+
context.track! self
|
24
|
+
|
25
|
+
insert_before(exception_node.loc.expression, "begin;")
|
26
|
+
insert_after(exception_node.loc.expression, ";end")
|
27
|
+
|
28
|
+
new_children = block_node.children.map do |child|
|
29
|
+
next s(:kwbegin, exception_node) if child == exception_node
|
30
|
+
|
31
|
+
child
|
32
|
+
end
|
33
|
+
|
34
|
+
process(
|
35
|
+
block_node.updated(:block, new_children)
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -45,8 +45,65 @@ module RubyNext
|
|
45
45
|
process_fargs(node, fargs)
|
46
46
|
end
|
47
47
|
|
48
|
+
def on_def(node)
|
49
|
+
return super unless forward_arg?(node.children[1])
|
50
|
+
|
51
|
+
new_node = super
|
52
|
+
|
53
|
+
name = node.children[0]
|
54
|
+
|
55
|
+
insert_after(node.loc.expression, "; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :#{name})")
|
56
|
+
|
57
|
+
s(:begin,
|
58
|
+
new_node,
|
59
|
+
ruby2_keywords_node(nil, name))
|
60
|
+
end
|
61
|
+
|
62
|
+
def on_defs(node)
|
63
|
+
return super unless forward_arg?(node.children[2])
|
64
|
+
|
65
|
+
new_node = super
|
66
|
+
|
67
|
+
receiver = node.children[0]
|
68
|
+
name = node.children[1]
|
69
|
+
|
70
|
+
# Using self.ruby2_keywords :name results in undefined method error,
|
71
|
+
# singleton_class works as expected
|
72
|
+
receiver = s(:send, nil, :singleton_class) if receiver.type == :self
|
73
|
+
|
74
|
+
receiver_name =
|
75
|
+
case receiver.type
|
76
|
+
when :send
|
77
|
+
receiver.children[1]
|
78
|
+
when :const
|
79
|
+
receiver.children[1]
|
80
|
+
end
|
81
|
+
|
82
|
+
insert_after(node.loc.expression, "; #{receiver_name}.respond_to?(:ruby2_keywords, true) && (#{receiver_name}.send(:ruby2_keywords, :#{name}))")
|
83
|
+
|
84
|
+
s(:begin,
|
85
|
+
new_node,
|
86
|
+
ruby2_keywords_node(receiver, name))
|
87
|
+
end
|
88
|
+
|
48
89
|
private
|
49
90
|
|
91
|
+
def ruby2_keywords_node(receiver, name)
|
92
|
+
s(:and,
|
93
|
+
s(:send, receiver, :respond_to?,
|
94
|
+
s(:sym, :ruby2_keywords), s(:true)),
|
95
|
+
s(:begin,
|
96
|
+
s(:send, receiver, :send,
|
97
|
+
s(:sym, :ruby2_keywords),
|
98
|
+
s(:sym, name))))
|
99
|
+
end
|
100
|
+
|
101
|
+
def forward_arg?(args)
|
102
|
+
return false unless args&.children
|
103
|
+
|
104
|
+
args.children.any? { |arg| arg.type == :forward_arg }
|
105
|
+
end
|
106
|
+
|
50
107
|
def extract_fargs(node)
|
51
108
|
node.children.find { |child| child.is_a?(::Parser::AST::Node) && child.type == :forwarded_args }
|
52
109
|
end
|
@@ -66,7 +66,7 @@ module RubyNext
|
|
66
66
|
end
|
67
67
|
|
68
68
|
class << self
|
69
|
-
# Returns true if the syntax is supported
|
69
|
+
# Returns true if the syntax is not supported
|
70
70
|
# by the current Ruby (performs syntax check, not version check)
|
71
71
|
def unsupported_syntax?
|
72
72
|
save_verbose, $VERBOSE = $VERBOSE, nil
|
@@ -12,7 +12,7 @@ module RubyNext
|
|
12
12
|
return if File.directory?(target_dir)
|
13
13
|
|
14
14
|
Dir.chdir(root_dir) do
|
15
|
-
unless system("bundle exec ruby-next nextify ./#{lib_dir} -o #{target_dir} > /dev/null 2>&1")
|
15
|
+
unless system("bundle exec ruby-next nextify ./#{lib_dir} -o #{target_dir} --min-version=#{RubyNext.current_ruby_version} > /dev/null 2>&1")
|
16
16
|
RubyNext.warn "Traspiled files are missing in: #{target_dir}. \n" \
|
17
17
|
"Make sure you have gem 'ruby-next' in your Gemfile to auto-transpile the required files from source on load. " \
|
18
18
|
"Otherwise the code from #{root_dir} may not work correctly."
|
data/lib/ruby-next/language.rb
CHANGED
@@ -186,6 +186,9 @@ module RubyNext
|
|
186
186
|
require "ruby-next/language/rewriters/2.3/safe_navigation"
|
187
187
|
rewriters << Rewriters::SafeNavigation
|
188
188
|
|
189
|
+
require "ruby-next/language/rewriters/2.5/rescue_within_block"
|
190
|
+
rewriters << Rewriters::RescueWithinBlock
|
191
|
+
|
189
192
|
require "ruby-next/language/rewriters/2.7/args_forward"
|
190
193
|
rewriters << Rewriters::ArgsForward
|
191
194
|
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file contains patches for Pry integration.
|
4
|
+
# It's supposed to be required inside .pryrc files.
|
5
|
+
|
6
|
+
require "ruby-next/language/setup"
|
7
|
+
require "ruby-next/language/runtime"
|
8
|
+
|
9
|
+
# Enables refinements by injecting "using RubyNext"
|
10
|
+
# before Pry copies and memorizes the TOPLEVEL_BINDING.
|
11
|
+
Pry.singleton_class.prepend(Module.new do
|
12
|
+
def toplevel_binding
|
13
|
+
unless defined?(@_using_injected) && @_using_injected
|
14
|
+
orig_binding = super
|
15
|
+
|
16
|
+
# Copy TOPLEVEL_BINDING without local variables.
|
17
|
+
TOPLEVEL_BINDING.eval <<-RUBY
|
18
|
+
using RubyNext
|
19
|
+
|
20
|
+
def self.__pry__
|
21
|
+
binding
|
22
|
+
end
|
23
|
+
|
24
|
+
Pry.toplevel_binding = __pry__
|
25
|
+
|
26
|
+
class << self; undef __pry__; end
|
27
|
+
RUBY
|
28
|
+
|
29
|
+
# Inject local variables from the original binding.
|
30
|
+
orig_binding.local_variables.each do |var|
|
31
|
+
value = orig_binding.local_variable_get(var)
|
32
|
+
@toplevel_binding.local_variable_set(var, value)
|
33
|
+
end
|
34
|
+
|
35
|
+
@_using_injected = true
|
36
|
+
end
|
37
|
+
|
38
|
+
super
|
39
|
+
end
|
40
|
+
end)
|
41
|
+
|
42
|
+
# Enables edge Ruby syntax by transpiling the code
|
43
|
+
# before it's evaluated in the context of a binding.
|
44
|
+
Pry.prepend(Module.new do
|
45
|
+
def current_binding
|
46
|
+
super.tap do |obj|
|
47
|
+
next if obj.respond_to?(:__nextified__)
|
48
|
+
|
49
|
+
obj.instance_eval do
|
50
|
+
def eval(code, *args)
|
51
|
+
new_code = ::RubyNext::Language::Runtime.transform(code, using: false)
|
52
|
+
|
53
|
+
super(new_code, *args)
|
54
|
+
end
|
55
|
+
|
56
|
+
def __nextified__
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end)
|
62
|
+
|
63
|
+
# Enables edge Ruby syntax for multi-line input.
|
64
|
+
Pry::Code.singleton_class.prepend(Module.new do
|
65
|
+
def complete_expression?(str)
|
66
|
+
silence_stderr do
|
67
|
+
::Parser::RubyNext.parse(str)
|
68
|
+
end
|
69
|
+
|
70
|
+
true
|
71
|
+
rescue Parser::SyntaxError => ex
|
72
|
+
case ex.message
|
73
|
+
when /unexpected token \$end/
|
74
|
+
false
|
75
|
+
else
|
76
|
+
true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def silence_stderr
|
83
|
+
stderr = StringIO.new
|
84
|
+
orig_stderr, $stderr = $stderr, stderr
|
85
|
+
|
86
|
+
yield
|
87
|
+
|
88
|
+
$stderr = orig_stderr
|
89
|
+
end
|
90
|
+
end)
|
data/lib/ruby-next/version.rb
CHANGED
data/lib/uby-next/irb.rb
ADDED
data/lib/uby-next/pry.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-next-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-08-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-next-parser
|
@@ -62,6 +62,7 @@ files:
|
|
62
62
|
- lib/.rbnext/2.3/ruby-next/commands/nextify.rb
|
63
63
|
- lib/.rbnext/2.3/ruby-next/language/eval.rb
|
64
64
|
- lib/.rbnext/2.3/ruby-next/language/rewriters/2.6/endless_range.rb
|
65
|
+
- lib/.rbnext/2.3/ruby-next/language/rewriters/2.7/args_forward.rb
|
65
66
|
- lib/.rbnext/2.3/ruby-next/language/rewriters/2.7/pattern_matching.rb
|
66
67
|
- lib/.rbnext/2.3/ruby-next/language/rewriters/3.1/anonymous_block.rb
|
67
68
|
- lib/.rbnext/2.3/ruby-next/language/rewriters/base.rb
|
@@ -103,6 +104,7 @@ files:
|
|
103
104
|
- lib/ruby-next/core/time/floor.rb
|
104
105
|
- lib/ruby-next/core/unboundmethod/bind_call.rb
|
105
106
|
- lib/ruby-next/core_ext.rb
|
107
|
+
- lib/ruby-next/irb.rb
|
106
108
|
- lib/ruby-next/language.rb
|
107
109
|
- lib/ruby-next/language/bootsnap.rb
|
108
110
|
- lib/ruby-next/language/eval.rb
|
@@ -112,6 +114,7 @@ files:
|
|
112
114
|
- lib/ruby-next/language/rewriters/2.3/safe_navigation.rb
|
113
115
|
- lib/ruby-next/language/rewriters/2.3/squiggly_heredoc.rb
|
114
116
|
- lib/ruby-next/language/rewriters/2.4/dir.rb
|
117
|
+
- lib/ruby-next/language/rewriters/2.5/rescue_within_block.rb
|
115
118
|
- lib/ruby-next/language/rewriters/2.6/endless_range.rb
|
116
119
|
- lib/ruby-next/language/rewriters/2.7/args_forward.rb
|
117
120
|
- lib/ruby-next/language/rewriters/2.7/numbered_params.rb
|
@@ -136,11 +139,14 @@ files:
|
|
136
139
|
- lib/ruby-next/language/setup.rb
|
137
140
|
- lib/ruby-next/language/unparser.rb
|
138
141
|
- lib/ruby-next/logging.rb
|
142
|
+
- lib/ruby-next/pry.rb
|
139
143
|
- lib/ruby-next/rubocop.rb
|
140
144
|
- lib/ruby-next/setup_self.rb
|
141
145
|
- lib/ruby-next/utils.rb
|
142
146
|
- lib/ruby-next/version.rb
|
143
147
|
- lib/uby-next.rb
|
148
|
+
- lib/uby-next/irb.rb
|
149
|
+
- lib/uby-next/pry.rb
|
144
150
|
homepage: http://github.com/palkan/ruby-next
|
145
151
|
licenses:
|
146
152
|
- MIT
|
@@ -165,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
171
|
- !ruby/object:Gem::Version
|
166
172
|
version: '0'
|
167
173
|
requirements: []
|
168
|
-
rubygems_version: 3.
|
174
|
+
rubygems_version: 3.3.7
|
169
175
|
signing_key:
|
170
176
|
specification_version: 4
|
171
177
|
summary: Ruby Next core functionality
|