ruby-next-core 0.15.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: fc36fd395eedfde5c29e65f1f3a75c683630d5111349b3070d3b4e6d200477ad
4
- data.tar.gz: e53e28aec62f7e425a98ba1eeb9591778ca1dbab13a0390113fc7440aab9663d
3
+ metadata.gz: c392536e2de07a838a8c9818b0651a9d2eb6803471f52d1e3632bada3fb398a4
4
+ data.tar.gz: 564822b7a5c55ec7fc278bf223206f0b16a75a71a9277b247d862489c7a342cb
5
5
  SHA512:
6
- metadata.gz: 50069c2ef6b59005d7efc640e1d84a74e17e4e385aaadce3ac54c2e3e061c7f71b727943140899210af997196f0bdf5a1157b86b97ce7af3de307e68a1cffe12
7
- data.tar.gz: edf464100a254380bee320c586f48afc35782027303840fd319f32260ac5cf771c6f349d7447b9ed2f8a55bab424395664099dbd58600a05ffcd79e49080509f
6
+ metadata.gz: 33d80d8d5bfaaf75cc0cc42b79eb4758ff57c9d72f1ac21eb86770f1f039c79cebc7eabc5b4a20c42e11a9a266b8a435849b2a4ae74547acd6b9a8fb8db03f39
7
+ data.tar.gz: 1a9b048897ad763e2dd726bc0be7112337499dbb1ddad9e02f13b81a2bb98d28d6f32f2e9abe1e29222a05895433117e082a5a8e42be4101d4d4eb056bcf5c61
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
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
+
5
15
  ## 0.15.1 (2022-04-05)
6
16
 
7
17
  - Fix transpiling `rescue` within nested blocks. ([@palkan][])
@@ -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)
@@ -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
@@ -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
 
@@ -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
@@ -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
@@ -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} --min-version=#{RUBY_VERSION} > /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."
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyNext
4
- VERSION = "0.15.1"
4
+ VERSION = "0.15.2"
5
5
  end
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.15.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-04-05 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