ruby-next-core 0.9.0.pre → 0.9.0
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 +6 -0
- data/README.md +12 -5
- data/bin/transform +9 -1
- data/lib/ruby-next/commands/core_ext.rb +1 -1
- data/lib/ruby-next/commands/nextify.rb +23 -12
- data/lib/ruby-next/core.rb +5 -0
- data/lib/ruby-next/core/time/ceil.rb +2 -1
- data/lib/ruby-next/language.rb +2 -0
- data/lib/ruby-next/language/eval.rb +10 -8
- data/lib/ruby-next/language/rewriters/base.rb +1 -1
- data/lib/ruby-next/language/rewriters/pattern_matching.rb +2 -1
- data/lib/ruby-next/language/rewriters/runtime.rb +6 -0
- data/lib/ruby-next/language/rewriters/runtime/dir.rb +32 -0
- data/lib/ruby-next/language/runtime.rb +3 -2
- data/lib/ruby-next/utils.rb +30 -0
- data/lib/ruby-next/version.rb +1 -1
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79dd9f615898df70de6648be3805f3c0da92c80e22cd8e2cffc109958ec0811b
|
4
|
+
data.tar.gz: 7ed7e923ca5f2b3f6eaf27135a722f2a23e868fe65bce32f6700e74867e6d62c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e16c8585ed3e8b5b23ccc5a7b79b80d6da6e96f539c008bc9e781e523c8451fec954b6f0e0948056de9feb231b30dd62989c26aea77890afc2037d91c0a4028a
|
7
|
+
data.tar.gz: b2d0d3891032b51a22ffccc600410d250da89d34332cc4797fc4e216f13ab82024520c262e43788660e041937c081a254ae7597e93e686fc23fcbd2d9df37e0c
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.9.0 (2020-06-04)
|
6
|
+
|
7
|
+
- Add Ruby 2.3 support. ([@palkan][])
|
8
|
+
|
9
|
+
- Remove stale transpiled files when running `ruby-next nextify`. ([@palkan][])
|
10
|
+
|
5
11
|
- Add Ruby 2.4 support. ([@palkan][])
|
6
12
|
|
7
13
|
APIs for <2.5 must be backported via [backports][] gem. Refinements are not supported.
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
[](https://rubygems.org/gems/ruby-next) [](https://github.com/ruby-next/ruby-next/actions)
|
2
|
-
[](https://github.com/ruby-next/ruby-next/actions)
|
2
|
+
[](https://github.com/ruby-next/ruby-next/actions?query=workflow%3A%22TruffleRuby+Build%22)
|
3
|
+
[](https://github.com/ruby-next/ruby-next/actions?query=workflow%3A%22TruffleRuby+Build%22)
|
3
4
|
|
4
5
|
# Ruby Next
|
5
6
|
|
@@ -66,7 +67,7 @@ Core provides **polyfills** for Ruby core classes APIs via Refinements (default
|
|
66
67
|
Language is responsible for **transpiling** edge Ruby syntax into older versions. It could be done
|
67
68
|
programmatically or via CLI. It also could be done in runtime.
|
68
69
|
|
69
|
-
Currently, Ruby Next supports Ruby versions 2.
|
70
|
+
Currently, Ruby Next supports Ruby versions 2.3+, including JRuby 9.2.8+ and TruffleRuby 20.1+ (with some limitations). Support for EOL versions (<2.5) slightly differs though ([see below](#using-with-eol-rubies)).
|
70
71
|
|
71
72
|
Please, [open an issue](https://github.com/ruby-next/ruby-next/issues/new/choose) or join the discussion in the existing ones if you would like us to support older Ruby versions.
|
72
73
|
|
@@ -137,6 +138,8 @@ The following _rule of thumb_ is recommended when choosing between refinements a
|
|
137
138
|
- Using core extensions could be considered for application development (no need to think about `using RubyNext`); this approach could potentially lead to conflicts with dependencies (if these dependencies are not using refinements 🙂)
|
138
139
|
- Use core extensions if refinements are not supported by your platform
|
139
140
|
|
141
|
+
**NOTE:** TruffleRuby doesn't fully support refinements (refining modules is not supported as of v20.1.0).
|
142
|
+
|
140
143
|
[**The list of supported APIs.**][features_core]
|
141
144
|
|
142
145
|
## Transpiling
|
@@ -390,6 +393,12 @@ RUBYOPT="-ruby-next" ruby my_ruby_script.rb
|
|
390
393
|
ruby -ruby-next -e "puts [2, 4, 5].tally"
|
391
394
|
```
|
392
395
|
|
396
|
+
**NOTE:** running Ruby scripts directly or executing code via `-e` option is not supported in TruffleRuby. You can still use `-ruby-next` to transpile required files, e.g.:
|
397
|
+
|
398
|
+
```sh
|
399
|
+
ruby -ruby-next -r my_ruby_script.rb -e "puts my_method"
|
400
|
+
```
|
401
|
+
|
393
402
|
## Logging and debugging
|
394
403
|
|
395
404
|
Ruby Next prints some debugging information when fails to load a file in the runtime mode (and fallbacks to the built-in loading mechanism).
|
@@ -426,9 +435,7 @@ AllCops:
|
|
426
435
|
|
427
436
|
## Using with EOL Rubies
|
428
437
|
|
429
|
-
|
430
|
-
|
431
|
-
We currently provide experimental support for Ruby 2.4. Work on older Rubies (down to 2.2) is in progress.
|
438
|
+
We currently provide support for Ruby 2.3 and 2.4. Work on 2.2 is in progress.
|
432
439
|
|
433
440
|
Ruby Next itself relies on 2.5 features and contains polyfills only for version 2.5+ (and that won't change).
|
434
441
|
Thus, to make it work with <2.5 we need to backport some APIs ourselves.
|
data/bin/transform
CHANGED
@@ -9,6 +9,7 @@ ENV["RUBY_NEXT_EDGE"] = "1"
|
|
9
9
|
ENV["RUBY_NEXT_PROPOSED"] = "1"
|
10
10
|
|
11
11
|
require "ruby-next/language"
|
12
|
+
require "ruby-next/language/rewriters/runtime"
|
12
13
|
|
13
14
|
contents =
|
14
15
|
if File.exist?(ARGV[0])
|
@@ -17,4 +18,11 @@ contents =
|
|
17
18
|
ARGV[0]
|
18
19
|
end
|
19
20
|
|
20
|
-
|
21
|
+
opts =
|
22
|
+
if ARGV[1] && ARGV[1] == "--current"
|
23
|
+
{rewriters: RubyNext::Language.current_rewriters}
|
24
|
+
else
|
25
|
+
{}
|
26
|
+
end
|
27
|
+
|
28
|
+
puts RubyNext::Language.transform(contents, **opts)
|
@@ -16,6 +16,8 @@ module RubyNext
|
|
16
16
|
log "RubyNext core strategy: #{RubyNext::Core.strategy}"
|
17
17
|
log "RubyNext transpile mode: #{RubyNext::Language.mode}"
|
18
18
|
|
19
|
+
remove_rbnext!
|
20
|
+
|
19
21
|
paths.each do |path|
|
20
22
|
contents = File.read(path)
|
21
23
|
transpile path, contents
|
@@ -120,25 +122,17 @@ module RubyNext
|
|
120
122
|
end
|
121
123
|
|
122
124
|
def save(contents, path, version)
|
123
|
-
return $stdout.puts(contents) if
|
125
|
+
return $stdout.puts(contents) if stdout?
|
124
126
|
|
125
127
|
paths = [Pathname.new(path).relative_path_from(Pathname.new(lib_path))]
|
126
128
|
|
127
129
|
paths.unshift(version.segments[0..1].join(".")) unless single_version?
|
128
130
|
|
129
131
|
next_path =
|
130
|
-
if
|
131
|
-
|
132
|
-
out_path
|
133
|
-
else
|
134
|
-
File.join(out_path, *paths)
|
135
|
-
end
|
132
|
+
if next_dir_path.end_with?(".rb")
|
133
|
+
out_path
|
136
134
|
else
|
137
|
-
File.join(
|
138
|
-
lib_path,
|
139
|
-
RUBY_NEXT_DIR,
|
140
|
-
*paths
|
141
|
-
)
|
135
|
+
File.join(next_dir_path, *paths)
|
142
136
|
end
|
143
137
|
|
144
138
|
unless CLI.dry_run?
|
@@ -150,6 +144,23 @@ module RubyNext
|
|
150
144
|
log "Generated: #{next_path}"
|
151
145
|
end
|
152
146
|
|
147
|
+
def remove_rbnext!
|
148
|
+
return if CLI.dry_run? || stdout?
|
149
|
+
|
150
|
+
return unless File.directory?(next_dir_path)
|
151
|
+
|
152
|
+
log "Remove old files: #{next_dir_path}"
|
153
|
+
FileUtils.rm_r(next_dir_path)
|
154
|
+
end
|
155
|
+
|
156
|
+
def next_dir_path
|
157
|
+
@next_dir_path ||= (out_path || File.join(lib_path, RUBY_NEXT_DIR))
|
158
|
+
end
|
159
|
+
|
160
|
+
def stdout?
|
161
|
+
out_path == "stdout"
|
162
|
+
end
|
163
|
+
|
153
164
|
alias single_version? single_version
|
154
165
|
end
|
155
166
|
end
|
data/lib/ruby-next/core.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
require "set"
|
4
4
|
|
5
|
+
require_relative "utils"
|
6
|
+
|
5
7
|
module RubyNext
|
6
8
|
module Core
|
7
9
|
# Patch contains the extension implementation
|
@@ -182,6 +184,9 @@ require_relative "core/struct/deconstruct_keys"
|
|
182
184
|
# Generate refinements
|
183
185
|
RubyNext.module_eval do
|
184
186
|
RubyNext::Core.patches.refined.each do |mod, patches|
|
187
|
+
# Only refine modules when supported
|
188
|
+
next unless mod.is_a?(Class) || RubyNext::Utils.refine_modules?
|
189
|
+
|
185
190
|
refine mod do
|
186
191
|
patches.each do |patch|
|
187
192
|
module_eval(patch.body, *patch.location)
|
data/lib/ruby-next/language.rb
CHANGED
@@ -83,6 +83,8 @@ module RubyNext
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def runtime!
|
86
|
+
require "ruby-next/language/rewriters/runtime"
|
87
|
+
|
86
88
|
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.7.0") && !defined?(Unparser::Emitter::CaseMatch)
|
87
89
|
RubyNext.warn "Ruby Next fallbacks to \"rewrite\" transpiling mode since Unparser doesn't support 2.7 AST yet.\n" \
|
88
90
|
"See https://github.com/mbj/unparser/pull/142"
|
@@ -3,14 +3,16 @@
|
|
3
3
|
module RubyNext
|
4
4
|
module Language
|
5
5
|
module KernelEval
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
if Utils.refine_modules?
|
7
|
+
refine Kernel do
|
8
|
+
def eval(source, bind = nil, *args)
|
9
|
+
new_source = ::RubyNext::Language::Runtime.transform(
|
10
|
+
source,
|
11
|
+
using: bind&.receiver == TOPLEVEL_BINDING.receiver || bind&.receiver&.is_a?(Module)
|
12
|
+
)
|
13
|
+
RubyNext.debug_source(new_source, "(#{caller_locations(1, 1).first})")
|
14
|
+
super new_source, bind, *args
|
15
|
+
end
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
@@ -59,7 +59,7 @@ module RubyNext
|
|
59
59
|
def unsupported_syntax?
|
60
60
|
save_verbose, $VERBOSE = $VERBOSE, nil
|
61
61
|
eval_mid = Kernel.respond_to?(:eval_without_ruby_next) ? :eval_without_ruby_next : :eval
|
62
|
-
Kernel.send eval_mid, self::SYNTAX_PROBE
|
62
|
+
Kernel.send eval_mid, self::SYNTAX_PROBE, nil, __FILE__, __LINE__
|
63
63
|
false
|
64
64
|
rescue SyntaxError, NameError
|
65
65
|
true
|
@@ -816,11 +816,12 @@ module RubyNext
|
|
816
816
|
end
|
817
817
|
|
818
818
|
def respond_to_missing?(mid, *)
|
819
|
-
return true if mid.match?(/_(clause|array_element)/)
|
819
|
+
return true if mid.to_s.match?(/_(clause|array_element)/)
|
820
820
|
super
|
821
821
|
end
|
822
822
|
|
823
823
|
def method_missing(mid, *args, &block)
|
824
|
+
mid = mid.to_s
|
824
825
|
return case_eq_clause(*args) if mid.match?(/_clause$/)
|
825
826
|
return case_eq_array_element(*args) if mid.match?(/_array_element$/)
|
826
827
|
return case_eq_hash_element(*args) if mid.match?(/_hash_element$/)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyNext
|
4
|
+
module Language
|
5
|
+
module Rewriters
|
6
|
+
# Special rewriter for Ruby <=2.3, which doesn't support __dir__ in iseq.eval
|
7
|
+
class Dir < Base
|
8
|
+
SYNTAX_PROBE = "defined?(RubyVM::InstructionSequence) && RubyVM::InstructionSequence.compile('raise SyntaxError if __dir__.nil?', 'test.rb').eval"
|
9
|
+
MIN_SUPPORTED_VERSION = Gem::Version.new("2.4.0")
|
10
|
+
|
11
|
+
def on_send(node)
|
12
|
+
return super(node) unless node.children[1] == :__dir__
|
13
|
+
|
14
|
+
context.track! self
|
15
|
+
|
16
|
+
replace(node.loc.expression, "File.dirname(__FILE__)")
|
17
|
+
|
18
|
+
process(
|
19
|
+
node.updated(
|
20
|
+
nil,
|
21
|
+
[
|
22
|
+
s(:const, nil, :File),
|
23
|
+
:dirname,
|
24
|
+
s(:send, nil, "__FILE__")
|
25
|
+
]
|
26
|
+
)
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -42,7 +42,7 @@ module RubyNext
|
|
42
42
|
path
|
43
43
|
end
|
44
44
|
|
45
|
-
if defined?(JRUBY_VERSION)
|
45
|
+
if defined?(JRUBY_VERSION) || defined?(TruffleRuby)
|
46
46
|
def evaluate(code, filepath)
|
47
47
|
new_toplevel.eval(code, filepath)
|
48
48
|
end
|
@@ -89,7 +89,8 @@ module Kernel
|
|
89
89
|
|
90
90
|
alias_method :require_relative_without_ruby_next, :require_relative
|
91
91
|
def require_relative(path)
|
92
|
-
|
92
|
+
loc = caller_locations(1..1).first
|
93
|
+
from = loc.absolute_path || loc.path || File.join(Dir.pwd, "main")
|
93
94
|
realpath = File.absolute_path(
|
94
95
|
File.join(
|
95
96
|
File.dirname(File.absolute_path(from)),
|
data/lib/ruby-next/utils.rb
CHANGED
@@ -33,5 +33,35 @@ module RubyNext
|
|
33
33
|
lines.unshift " 0: # source: #{path}"
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
37
|
+
# Returns true if modules refinement is supported in current version
|
38
|
+
def refine_modules?
|
39
|
+
@refine_modules ||=
|
40
|
+
begin
|
41
|
+
# Make sure that including modules within refinements works
|
42
|
+
# See https://github.com/oracle/truffleruby/issues/2026
|
43
|
+
eval <<~RUBY, TOPLEVEL_BINDING, __FILE__, __LINE__ + 1
|
44
|
+
module RubyNext::Utils::A; end
|
45
|
+
class RubyNext::Utils::B
|
46
|
+
include RubyNext::Utils::A
|
47
|
+
end
|
48
|
+
|
49
|
+
using(Module.new do
|
50
|
+
refine RubyNext::Utils::A do
|
51
|
+
include(Module.new do
|
52
|
+
def i_am_refinement
|
53
|
+
"yes, you are!"
|
54
|
+
end
|
55
|
+
end)
|
56
|
+
end
|
57
|
+
end)
|
58
|
+
|
59
|
+
RubyNext::Utils::B.new.i_am_refinement
|
60
|
+
RUBY
|
61
|
+
true
|
62
|
+
rescue TypeError, NoMethodError
|
63
|
+
false
|
64
|
+
end
|
65
|
+
end
|
36
66
|
end
|
37
67
|
end
|
data/lib/ruby-next/version.rb
CHANGED
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.9.0
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-next-parser
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.8.0.
|
19
|
+
version: 2.8.0.6
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.8.0.
|
26
|
+
version: 2.8.0.6
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: unparser
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -96,6 +96,8 @@ files:
|
|
96
96
|
- lib/ruby-next/language/rewriters/numbered_params.rb
|
97
97
|
- lib/ruby-next/language/rewriters/pattern_matching.rb
|
98
98
|
- lib/ruby-next/language/rewriters/right_hand_assignment.rb
|
99
|
+
- lib/ruby-next/language/rewriters/runtime.rb
|
100
|
+
- lib/ruby-next/language/rewriters/runtime/dir.rb
|
99
101
|
- lib/ruby-next/language/runtime.rb
|
100
102
|
- lib/ruby-next/language/setup.rb
|
101
103
|
- lib/ruby-next/language/unparser.rb
|
@@ -121,12 +123,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
121
123
|
requirements:
|
122
124
|
- - ">="
|
123
125
|
- !ruby/object:Gem::Version
|
124
|
-
version: 2.
|
126
|
+
version: 2.3.0
|
125
127
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
128
|
requirements:
|
127
|
-
- - "
|
129
|
+
- - ">="
|
128
130
|
- !ruby/object:Gem::Version
|
129
|
-
version:
|
131
|
+
version: '0'
|
130
132
|
requirements: []
|
131
133
|
rubygems_version: 3.0.6
|
132
134
|
signing_key:
|