ruby-next-core 0.15.1 → 0.15.2

Sign up to get free protection for your applications and to get access to all the features.
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