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.
@@ -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
@@ -28,12 +28,6 @@ module RubyNext
28
28
  ]
29
29
  )
30
30
  end
31
-
32
- begin
33
- transform(SYNTAX_PROBE)
34
- rescue ::Parser::SyntaxError
35
- warn_custom_parser_required_for("method reference")
36
- end
37
31
  end
38
32
  end
39
33
  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,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Load rewriters only required for runtime transpiling
4
+
5
+ require "ruby-next/language/rewriters/runtime/dir"
6
+ RubyNext::Language.rewriters << RubyNext::Language::Rewriters::Dir
@@ -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
- from = caller_locations(1..1).first.absolute_path || File.join(Dir.pwd, "main")
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(dirname, rbnext_dir, version.segments[0..1].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
@@ -38,6 +38,6 @@ module RubyNext
38
38
  attr_reader :debug_filter
39
39
  end
40
40
 
41
- self.silence_warnings = ENV["RUBY_NEXT_WARN"] != "false"
41
+ self.silence_warnings = ENV["RUBY_NEXT_WARN"] == "false"
42
42
  self.debug_enabled = ENV["RUBY_NEXT_DEBUG"]
43
43
  end
@@ -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
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyNext
4
- VERSION = "0.5.3"
4
+ VERSION = "0.9.0"
5
5
  end
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Activate all features
4
+ ENV["RUBY_NEXT_EDGE"] = "1"
5
+ ENV["RUBY_NEXT_PROPOSED"] = "1"
6
+
3
7
  require "ruby-next/language/runtime"
4
8
  require "ruby-next/core/runtime"
5
9
 
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.5.3
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-03-25 00:00:00.000000000 Z
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.7.0.5
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.7.0.5
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.5.0
126
+ version: 2.3.0
121
127
  required_rubygems_version: !ruby/object:Gem::Requirement
122
128
  requirements:
123
129
  - - ">="