ruby-next-core 0.5.3 → 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 +65 -0
- data/README.md +153 -40
- data/bin/transform +12 -5
- data/lib/ruby-next.rb +3 -2
- data/lib/ruby-next/cli.rb +17 -2
- data/lib/ruby-next/commands/base.rb +15 -2
- data/lib/ruby-next/commands/core_ext.rb +5 -3
- data/lib/ruby-next/commands/nextify.rb +47 -20
- data/lib/ruby-next/core.rb +13 -2
- data/lib/ruby-next/core/time/ceil.rb +2 -1
- data/lib/ruby-next/core_ext.rb +1 -1
- data/lib/ruby-next/language.rb +15 -4
- data/lib/ruby-next/language/edge.rb +9 -0
- data/lib/ruby-next/language/eval.rb +10 -8
- data/lib/ruby-next/language/parser.rb +6 -2
- data/lib/ruby-next/language/proposed.rb +6 -0
- data/lib/ruby-next/language/rewriters/args_forward.rb +10 -8
- data/lib/ruby-next/language/rewriters/base.rb +1 -5
- data/lib/ruby-next/language/rewriters/endless_method.rb +40 -0
- data/lib/ruby-next/language/rewriters/method_reference.rb +0 -6
- data/lib/ruby-next/language/rewriters/pattern_matching.rb +2 -1
- data/lib/ruby-next/language/rewriters/right_hand_assignment.rb +44 -0
- 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/language/setup.rb +21 -2
- data/lib/ruby-next/logging.rb +1 -1
- data/lib/ruby-next/rubocop.rb +70 -1
- data/lib/ruby-next/utils.rb +30 -0
- data/lib/ruby-next/version.rb +1 -1
- data/lib/uby-next.rb +4 -0
- metadata +12 -6
@@ -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
|
@@ -78,10 +78,6 @@ module RubyNext
|
|
78
78
|
def transform(source)
|
79
79
|
Language.transform(source, rewriters: [self], using: false)
|
80
80
|
end
|
81
|
-
|
82
|
-
def warn_custom_parser_required_for(feature)
|
83
|
-
RubyNext.warn(CUSTOM_PARSER_REQUIRED % feature)
|
84
|
-
end
|
85
81
|
end
|
86
82
|
|
87
83
|
attr_reader :locals
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyNext
|
4
|
+
module Language
|
5
|
+
module Rewriters
|
6
|
+
class EndlessMethod < Base
|
7
|
+
SYNTAX_PROBE = "obj = Object.new; def obj.foo() = 42"
|
8
|
+
MIN_SUPPORTED_VERSION = Gem::Version.new("2.8.0")
|
9
|
+
|
10
|
+
def on_def_e(node)
|
11
|
+
context.track! self
|
12
|
+
|
13
|
+
replace(node.loc.assignment, "; ")
|
14
|
+
insert_after(node.loc.expression, "; end")
|
15
|
+
|
16
|
+
process(
|
17
|
+
node.updated(
|
18
|
+
:def,
|
19
|
+
node.children
|
20
|
+
)
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_defs_e(node)
|
25
|
+
context.track! self
|
26
|
+
|
27
|
+
replace(node.loc.assignment, "; ")
|
28
|
+
insert_after(node.loc.expression, "; end")
|
29
|
+
|
30
|
+
process(
|
31
|
+
node.updated(
|
32
|
+
:defs,
|
33
|
+
node.children
|
34
|
+
)
|
35
|
+
)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -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,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyNext
|
4
|
+
module Language
|
5
|
+
module Rewriters
|
6
|
+
class RightHandAssignment < Base
|
7
|
+
SYNTAX_PROBE = "1 + 2 => a"
|
8
|
+
MIN_SUPPORTED_VERSION = Gem::Version.new("2.8.0")
|
9
|
+
|
10
|
+
def on_rasgn(node)
|
11
|
+
context.track! self
|
12
|
+
|
13
|
+
val_node, asgn_node = *node
|
14
|
+
|
15
|
+
remove(val_node.loc.expression.end.join(asgn_node.loc.expression))
|
16
|
+
insert_before(val_node.loc.expression, "#{asgn_node.loc.expression.source} = ")
|
17
|
+
|
18
|
+
process(
|
19
|
+
asgn_node.updated(
|
20
|
+
nil,
|
21
|
+
asgn_node.children + [val_node]
|
22
|
+
)
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def on_mrasgn(node)
|
27
|
+
context.track! self
|
28
|
+
|
29
|
+
lhs, rhs = *node
|
30
|
+
|
31
|
+
replace(lhs.loc.expression.end.join(rhs.loc.expression), ")")
|
32
|
+
insert_before(lhs.loc.expression, "#{rhs.loc.expression.source} = (")
|
33
|
+
|
34
|
+
process(
|
35
|
+
node.updated(
|
36
|
+
:masgn,
|
37
|
+
[rhs, lhs]
|
38
|
+
)
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -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)),
|
@@ -5,6 +5,21 @@ require "ruby-next"
|
|
5
5
|
|
6
6
|
module RubyNext
|
7
7
|
module Language
|
8
|
+
# Module responsible for transpiling a library at load time
|
9
|
+
module GemTranspiler
|
10
|
+
def self.maybe_transpile(root_dir, lib_dir, target_dir)
|
11
|
+
return if File.directory?(target_dir)
|
12
|
+
|
13
|
+
Dir.chdir(root_dir) do
|
14
|
+
unless system("bundle exec ruby-next nextify ./#{lib_dir} -o #{target_dir} > /dev/null 2>&1")
|
15
|
+
RubyNext.warn "Traspiled files are missing in: #{target_dir}. \n" \
|
16
|
+
"Make sure you have gem 'ruby-next' in your Gemfile to auto-transpile the required files from source on load. " \
|
17
|
+
"Otherwise the code from #{root_dir} may not work correctly."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
8
23
|
class << self
|
9
24
|
unless method_defined?(:runtime?)
|
10
25
|
def runtime?
|
@@ -12,7 +27,7 @@ module RubyNext
|
|
12
27
|
end
|
13
28
|
end
|
14
29
|
|
15
|
-
def setup_gem_load_path(lib_dir = "lib", rbnext_dir: RUBY_NEXT_DIR)
|
30
|
+
def setup_gem_load_path(lib_dir = "lib", rbnext_dir: RUBY_NEXT_DIR, transpile: false)
|
16
31
|
called_from = caller_locations(1, 1).first.path
|
17
32
|
dirname = File.dirname(called_from)
|
18
33
|
|
@@ -29,6 +44,10 @@ module RubyNext
|
|
29
44
|
|
30
45
|
return if Language.runtime? && Language.watch_dirs.include?(dirname)
|
31
46
|
|
47
|
+
next_dirname = File.join(dirname, rbnext_dir)
|
48
|
+
|
49
|
+
GemTranspiler.maybe_transpile(File.dirname(dirname), lib_dir, next_dirname) if transpile
|
50
|
+
|
32
51
|
current_index = $LOAD_PATH.index(dirname)
|
33
52
|
|
34
53
|
raise "Gem's lib is not in the $LOAD_PATH: #{dirname}" if current_index.nil?
|
@@ -38,7 +57,7 @@ module RubyNext
|
|
38
57
|
loop do
|
39
58
|
break unless version
|
40
59
|
|
41
|
-
version_dir = File.join(
|
60
|
+
version_dir = File.join(next_dirname, version.segments[0..1].join("."))
|
42
61
|
|
43
62
|
if File.exist?(version_dir)
|
44
63
|
$LOAD_PATH.insert current_index, version_dir
|
data/lib/ruby-next/logging.rb
CHANGED
data/lib/ruby-next/rubocop.rb
CHANGED
@@ -1,7 +1,50 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file contains patches to RuboCop to support
|
4
|
-
# edge features and fix some bugs with 2.7 syntax
|
4
|
+
# edge features and fix some bugs with 2.7+ syntax
|
5
|
+
|
6
|
+
require "parser/ruby-next/version"
|
7
|
+
|
8
|
+
module RuboCop
|
9
|
+
# Transform Ruby Next parser version to a float, e.g.: "2.8.0.1" => 2.801
|
10
|
+
RUBY_NEXT_VERSION = Parser::NEXT_VERSION.match(/(^\d+)\.(.+)$/)[1..-1].map { |part| part.delete(".") }.join(".").to_f
|
11
|
+
|
12
|
+
class TargetRuby
|
13
|
+
class RuboCopNextConfig < RuboCopConfig
|
14
|
+
private
|
15
|
+
|
16
|
+
def find_version
|
17
|
+
version = @config.for_all_cops["TargetRubyVersion"]
|
18
|
+
return unless version == "next"
|
19
|
+
|
20
|
+
RUBY_NEXT_VERSION
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
new_rubies = KNOWN_RUBIES + [RUBY_NEXT_VERSION]
|
25
|
+
remove_const :KNOWN_RUBIES
|
26
|
+
const_set :KNOWN_RUBIES, new_rubies
|
27
|
+
|
28
|
+
new_sources = [RuboCopNextConfig] + SOURCES
|
29
|
+
remove_const :SOURCES
|
30
|
+
const_set :SOURCES, new_sources
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module RuboCop
|
35
|
+
class ProcessedSource
|
36
|
+
module ParserClassExt
|
37
|
+
def parser_class(version)
|
38
|
+
return super unless version == RUBY_NEXT_VERSION
|
39
|
+
|
40
|
+
require "parser/rubynext"
|
41
|
+
Parser::RubyNext
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
prepend ParserClassExt
|
46
|
+
end
|
47
|
+
end
|
5
48
|
|
6
49
|
module RuboCop
|
7
50
|
module AST
|
@@ -41,6 +84,32 @@ module RuboCop
|
|
41
84
|
send(:"on_#{child.type}", child)
|
42
85
|
end
|
43
86
|
end
|
87
|
+
|
88
|
+
unless method_defined?(:on_def_e)
|
89
|
+
def on_def_e(node)
|
90
|
+
_name, _args_node, body_node = *node
|
91
|
+
send(:"on_#{body_node.type}", body_node)
|
92
|
+
end
|
93
|
+
|
94
|
+
def on_defs_e(node)
|
95
|
+
_definee_node, _name, _args_node, body_node = *node
|
96
|
+
send(:"on_#{body_node.type}", body_node)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
unless method_defined?(:on_rasgn)
|
101
|
+
def on_rasgn(node)
|
102
|
+
val_node, asgn_node = *node
|
103
|
+
send(:"on_#{asgn_node.type}", asgn_node)
|
104
|
+
send(:"on_#{val_node.type}", val_node)
|
105
|
+
end
|
106
|
+
|
107
|
+
def on_mrasgn(node)
|
108
|
+
lhs, rhs = *node
|
109
|
+
send(:"on_#{lhs.type}", lhs)
|
110
|
+
send(:"on_#{rhs.type}", rhs)
|
111
|
+
end
|
112
|
+
end
|
44
113
|
end
|
45
114
|
end
|
46
115
|
end
|
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
data/lib/uby-next.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
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.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
|
-
name: parser
|
14
|
+
name: ruby-next-parser
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.
|
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.
|
26
|
+
version: 2.8.0.6
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: unparser
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,14 +84,20 @@ files:
|
|
84
84
|
- lib/ruby-next/core_ext.rb
|
85
85
|
- lib/ruby-next/language.rb
|
86
86
|
- lib/ruby-next/language/bootsnap.rb
|
87
|
+
- lib/ruby-next/language/edge.rb
|
87
88
|
- lib/ruby-next/language/eval.rb
|
88
89
|
- lib/ruby-next/language/parser.rb
|
90
|
+
- lib/ruby-next/language/proposed.rb
|
89
91
|
- lib/ruby-next/language/rewriters/args_forward.rb
|
90
92
|
- lib/ruby-next/language/rewriters/base.rb
|
93
|
+
- lib/ruby-next/language/rewriters/endless_method.rb
|
91
94
|
- lib/ruby-next/language/rewriters/endless_range.rb
|
92
95
|
- lib/ruby-next/language/rewriters/method_reference.rb
|
93
96
|
- lib/ruby-next/language/rewriters/numbered_params.rb
|
94
97
|
- lib/ruby-next/language/rewriters/pattern_matching.rb
|
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
|
95
101
|
- lib/ruby-next/language/runtime.rb
|
96
102
|
- lib/ruby-next/language/setup.rb
|
97
103
|
- lib/ruby-next/language/unparser.rb
|
@@ -117,7 +123,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
117
123
|
requirements:
|
118
124
|
- - ">="
|
119
125
|
- !ruby/object:Gem::Version
|
120
|
-
version: 2.
|
126
|
+
version: 2.3.0
|
121
127
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
128
|
requirements:
|
123
129
|
- - ">="
|