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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8f084701e3c87e432518f6367d883b9524dbc002d77352793b912504a63e8d0
4
- data.tar.gz: bc44011f4183dd2133f259f07dc7a40c4be5dbd4cf2f85e35efb525463011ace
3
+ metadata.gz: c392536e2de07a838a8c9818b0651a9d2eb6803471f52d1e3632bada3fb398a4
4
+ data.tar.gz: 564822b7a5c55ec7fc278bf223206f0b16a75a71a9277b247d862489c7a342cb
5
5
  SHA512:
6
- metadata.gz: eabbb2bc0ccfa86f033eabce8001d208638a3995c7f112c29ed0e5f3142597bc60d87112899e7d383b09739c7c4cbe2eff06d10c58df7577cf12f80d4cb19c4d
7
- data.tar.gz: 000c76da160d8dba1231121b7e71b335da2d9775240bfc7a9fb2201ca55d6ac366f47f1c918a3c5ebb46abdcc90857b0c3a9d221455ed6eff68965f5b8f905e9
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/, "") # rubocop:disable Performance/StringReplacement
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
@@ -182,7 +182,6 @@ module RubyNext
182
182
  end
183
183
  end
184
184
 
185
- # rubocop:disable Style/MethodMissingSuper
186
185
  # rubocop:disable Style/MissingRespondToMissing
187
186
  class Noop < Base
188
187
  # Return node itself, no memoization
@@ -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/, "") # rubocop:disable Performance/StringReplacement
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)
@@ -182,7 +182,6 @@ module RubyNext
182
182
  end
183
183
  end
184
184
 
185
- # rubocop:disable Style/MethodMissingSuper
186
185
  # rubocop:disable Style/MissingRespondToMissing
187
186
  class Noop < Base
188
187
  # Return node itself, no memoization
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 ||= begin
84
- OptionParser.new do |opts|
85
- opts.banner = "Usage: ruby-next COMMAND [options]"
86
-
87
- opts.on("-v", "--version", "Print version") do
88
- $stdout.puts RubyNext::VERSION
89
- exit 0
90
- end
91
-
92
- opts.on("-h", "--help", "Print help") do
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
@@ -19,8 +19,8 @@ module RubyNext
19
19
  NEXT_VERSION = "1995.next.0"
20
20
 
21
21
  class << self
22
- # TruffleRuby claims it's 2.7.2 compatible but...
23
- if defined?(TruffleRuby) && ::RUBY_VERSION =~ /^2\.7/
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
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Style/LambdaCall
4
3
  RubyNext::Core.patch Proc, name: "ProcCompose", method: :<<, version: "2.6" do
5
4
  <<-RUBY
6
5
  def <<(other)
@@ -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
@@ -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/, "") # rubocop:disable Performance/StringReplacement
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
@@ -182,7 +182,6 @@ module RubyNext
182
182
  end
183
183
  end
184
184
 
185
- # rubocop:disable Style/MethodMissingSuper
186
185
  # rubocop:disable Style/MissingRespondToMissing
187
186
  class Noop < Base
188
187
  # Return node itself, no memoization
@@ -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
@@ -67,7 +67,7 @@ end
67
67
 
68
68
  # Patch Kernel to hijack require/require_relative/load/eval
69
69
  module Kernel
70
- module_function # rubocop:disable Style/ModuleFunction
70
+ module_function
71
71
 
72
72
  alias_method :require_without_ruby_next, :require
73
73
  def require(path)
@@ -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."
@@ -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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyNext
4
- VERSION = "0.14.1"
4
+ VERSION = "0.15.2"
5
5
  end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ruby-next/irb"
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ruby-next/pry"
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.14.1
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-01-21 00:00:00.000000000 Z
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.2.22
174
+ rubygems_version: 3.3.7
169
175
  signing_key:
170
176
  specification_version: 4
171
177
  summary: Ruby Next core functionality