ruby-next 0.0.1.26 → 0.1.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 +38 -0
- data/LICENSE.txt +21 -0
- data/README.md +201 -11
- data/bin/parse +19 -0
- data/bin/ruby-next +16 -0
- data/bin/transform +18 -0
- data/lib/ruby-next/cli.rb +55 -0
- data/lib/ruby-next/commands/base.rb +42 -0
- data/lib/ruby-next/commands/nextify.rb +113 -0
- data/lib/ruby-next/core/array/difference_union_intersection.rb +31 -0
- data/lib/ruby-next/core/enumerable/filter.rb +23 -0
- data/lib/ruby-next/core/enumerable/filter_map.rb +50 -0
- data/lib/ruby-next/core/enumerable/tally.rb +28 -0
- data/lib/ruby-next/core/hash/merge.rb +16 -0
- data/lib/ruby-next/core/kernel/then.rb +12 -0
- data/lib/ruby-next/core/pattern_matching.rb +37 -0
- data/lib/ruby-next/core/proc/compose.rb +21 -0
- data/lib/ruby-next/core/runtime.rb +10 -0
- data/lib/ruby-next/core.rb +28 -0
- data/lib/ruby-next/language/parser.rb +23 -0
- data/lib/ruby-next/language/rewriters/args_forward.rb +57 -0
- data/lib/ruby-next/language/rewriters/base.rb +87 -0
- data/lib/ruby-next/language/rewriters/endless_range.rb +60 -0
- data/lib/ruby-next/language/rewriters/method_reference.rb +27 -0
- data/lib/ruby-next/language/rewriters/numbered_params.rb +41 -0
- data/lib/ruby-next/language/rewriters/pattern_matching.rb +464 -0
- data/lib/ruby-next/language/runtime.rb +149 -0
- data/lib/ruby-next/language/setup.rb +43 -0
- data/lib/ruby-next/language/unparser.rb +23 -0
- data/lib/ruby-next/language.rb +100 -0
- data/lib/ruby-next/utils.rb +39 -0
- data/lib/ruby-next/version.rb +5 -0
- data/lib/ruby-next.rb +37 -0
- data/lib/uby-next.rb +66 -0
- metadata +69 -7
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
gem "parser", "~> 2.6.3.102"
|
4
|
+
gem "unparser", "~> 0.4.5"
|
5
|
+
|
6
|
+
require "set"
|
7
|
+
|
8
|
+
require "ruby-next"
|
9
|
+
using RubyNext
|
10
|
+
|
11
|
+
module RubyNext
|
12
|
+
# Language module contains tools to transpile newer Ruby syntax
|
13
|
+
# into an older one.
|
14
|
+
#
|
15
|
+
# It works the following way:
|
16
|
+
# - Takes a Ruby source code as input
|
17
|
+
# - Generates the AST using the edge parser (via the `parser` gem)
|
18
|
+
# - Pass this AST through the list of processors (one feature = one processor)
|
19
|
+
# - Each processor may modify the AST
|
20
|
+
# - Generates a transpiled source code from the transformed AST (via the `unparser` gem)
|
21
|
+
module Language
|
22
|
+
require "ruby-next/language/parser"
|
23
|
+
require "ruby-next/language/unparser"
|
24
|
+
|
25
|
+
class TransformContext
|
26
|
+
attr_reader :versions, :use_ruby_next
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
# Minimum supported RubyNext version
|
30
|
+
@min_version = MIN_SUPPORTED_VERSION
|
31
|
+
@dirty = false
|
32
|
+
@versions = Set.new
|
33
|
+
@use_ruby_next = false
|
34
|
+
end
|
35
|
+
|
36
|
+
# Called by rewriter when it performs transfomrations
|
37
|
+
def track!(rewriter)
|
38
|
+
@dirty = true
|
39
|
+
versions << rewriter.class::MIN_SUPPORTED_VERSION
|
40
|
+
end
|
41
|
+
|
42
|
+
def use_ruby_next!
|
43
|
+
@use_ruby_next = true
|
44
|
+
end
|
45
|
+
|
46
|
+
alias use_ruby_next? use_ruby_next
|
47
|
+
|
48
|
+
def dirty?
|
49
|
+
@dirty == true
|
50
|
+
end
|
51
|
+
|
52
|
+
def min_version
|
53
|
+
versions.min
|
54
|
+
end
|
55
|
+
|
56
|
+
def sorted_versions
|
57
|
+
versions.to_a.sort
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class << self
|
62
|
+
attr_accessor :rewriters
|
63
|
+
|
64
|
+
def transform(source, rewriters: self.rewriters, eval: false, context: TransformContext.new)
|
65
|
+
Parser.parse(source).then do |ast|
|
66
|
+
rewriters.inject(ast) do |tree, rewriter|
|
67
|
+
rewriter.new(context).process(tree)
|
68
|
+
end.then do |new_ast|
|
69
|
+
next source unless context.dirty?
|
70
|
+
|
71
|
+
Unparser.unparse(new_ast)
|
72
|
+
end.then do |source|
|
73
|
+
next source if eval || !context.use_ruby_next?
|
74
|
+
|
75
|
+
Core.inject! source.dup
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
self.rewriters = []
|
82
|
+
|
83
|
+
require "ruby-next/language/rewriters/base"
|
84
|
+
|
85
|
+
require "ruby-next/language/rewriters/endless_range"
|
86
|
+
rewriters << Rewriters::EndlessRange
|
87
|
+
|
88
|
+
require "ruby-next/language/rewriters/pattern_matching"
|
89
|
+
rewriters << Rewriters::PatternMatching
|
90
|
+
|
91
|
+
require "ruby-next/language/rewriters/method_reference"
|
92
|
+
rewriters << Rewriters::MethodReference
|
93
|
+
|
94
|
+
require "ruby-next/language/rewriters/args_forward"
|
95
|
+
rewriters << Rewriters::ArgsForward
|
96
|
+
|
97
|
+
require "ruby-next/language/rewriters/numbered_params"
|
98
|
+
rewriters << Rewriters::NumberedParams
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyNext
|
4
|
+
module Utils
|
5
|
+
module_function
|
6
|
+
|
7
|
+
if $LOAD_PATH.respond_to?(:resolve_feature_path)
|
8
|
+
def resolve_feature_path(feature)
|
9
|
+
$LOAD_PATH.resolve_feature_path(feature)&.last
|
10
|
+
end
|
11
|
+
else
|
12
|
+
def resolve_feature_path(path)
|
13
|
+
if File.file?(relative = File.expand_path(path))
|
14
|
+
path = relative
|
15
|
+
end
|
16
|
+
|
17
|
+
path = "#{path}.rb" if File.extname(path).empty?
|
18
|
+
|
19
|
+
unless Pathname.new(path).absolute?
|
20
|
+
loadpath = $LOAD_PATH.find do |lp|
|
21
|
+
File.file?(File.join(lp, path))
|
22
|
+
end
|
23
|
+
|
24
|
+
return if loadpath.nil?
|
25
|
+
|
26
|
+
path = File.join(loadpath, path)
|
27
|
+
end
|
28
|
+
|
29
|
+
path
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def source_with_lines(source)
|
34
|
+
source.lines.map.with_index do |line, i|
|
35
|
+
"#{i.to_s.rjust(3)}: #{line}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/ruby-next.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ruby-next/version"
|
4
|
+
|
5
|
+
module RubyNext
|
6
|
+
# Mininum Ruby version supported by RubyNext
|
7
|
+
MIN_SUPPORTED_VERSION = Gem::Version.new("2.5.0")
|
8
|
+
|
9
|
+
# Where to store transpiled files (relative from the project LOAD_PATH, usually `lib/`)
|
10
|
+
RUBY_NEXT_DIR = ".rbnext"
|
11
|
+
|
12
|
+
# Defines last minor version for every major version
|
13
|
+
LAST_MINOR_VERSIONS = {
|
14
|
+
2 => 7
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
LATEST_VERSION = [2, 7].freeze
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def next_version(version = RUBY_VERSION)
|
21
|
+
major, minor = Gem::Version.new(version).segments.map(&:to_i)
|
22
|
+
|
23
|
+
return if major >= LATEST_VERSION.first && minor >= LATEST_VERSION.last
|
24
|
+
|
25
|
+
nxt =
|
26
|
+
if LAST_MINOR_VERSIONS[major] == minor
|
27
|
+
"#{major + 1}.0.0"
|
28
|
+
else
|
29
|
+
"#{major}.#{minor + 1}.0"
|
30
|
+
end
|
31
|
+
|
32
|
+
Gem::Version.new(nxt)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
require_relative "ruby-next/core"
|
37
|
+
end
|
data/lib/uby-next.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ruby-next/language/runtime"
|
4
|
+
require "ruby-next/core/runtime"
|
5
|
+
|
6
|
+
using RubyNext
|
7
|
+
|
8
|
+
RubyNext::Language::Runtime.watch_dirs << Dir.pwd
|
9
|
+
|
10
|
+
require "stringio"
|
11
|
+
|
12
|
+
# Hijack stderr to avoid printing exceptions while executing ruby files
|
13
|
+
stderr = StringIO.new
|
14
|
+
|
15
|
+
orig_stderr, $stderr = $stderr, stderr
|
16
|
+
|
17
|
+
# Capture source code passed via `-e` option
|
18
|
+
e_script = nil
|
19
|
+
|
20
|
+
if $0 == "-e"
|
21
|
+
begin
|
22
|
+
TracePoint.new(:script_compiled) do |tp|
|
23
|
+
next unless tp.path == "-e"
|
24
|
+
e_script = tp.eval_script
|
25
|
+
tp.disable
|
26
|
+
end.enable
|
27
|
+
rescue ArgumentError
|
28
|
+
# script_compiled event is not supported
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
at_exit do
|
33
|
+
$stderr = orig_stderr
|
34
|
+
|
35
|
+
if NoMethodError === $! || SyntaxError === $!
|
36
|
+
if $0 && File.exist?($0)
|
37
|
+
load($0)
|
38
|
+
exit!(0)
|
39
|
+
end
|
40
|
+
|
41
|
+
if $0 == "-e" && e_script.nil?
|
42
|
+
`ps axw`.split("\n").find { |ps| ps[/\A#{$$}/] }.then do |command|
|
43
|
+
next unless command
|
44
|
+
command.match(/\-e(.*$)/)
|
45
|
+
end.then do |matches|
|
46
|
+
next unless matches
|
47
|
+
|
48
|
+
args = ["-e", matches[1]]
|
49
|
+
require "optparse"
|
50
|
+
OptionParser.new do |o|
|
51
|
+
o.on("-e SOURCE") do |v|
|
52
|
+
e_script = v
|
53
|
+
end
|
54
|
+
end.parse!(args)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
if e_script
|
59
|
+
new_e_script = RubyNext::Language::Runtime.transform(e_script)
|
60
|
+
TOPLEVEL_BINDING.eval(new_e_script, $0)
|
61
|
+
exit!(0)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
puts(stderr.tap(&:rewind).read)
|
66
|
+
end
|
metadata
CHANGED
@@ -1,23 +1,85 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-next
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.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: 2019-
|
12
|
-
dependencies:
|
11
|
+
date: 2019-11-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: parser
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.6.3.102
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.6.3.102
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: unparser
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.4.5
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.4.5
|
13
41
|
description: "\n Coming soon.\n "
|
14
42
|
email:
|
15
43
|
- dementiev.vm@gmail.com
|
16
|
-
executables:
|
44
|
+
executables:
|
45
|
+
- ruby-next
|
17
46
|
extensions: []
|
18
47
|
extra_rdoc_files: []
|
19
48
|
files:
|
49
|
+
- CHANGELOG.md
|
50
|
+
- LICENSE.txt
|
20
51
|
- README.md
|
52
|
+
- bin/parse
|
53
|
+
- bin/ruby-next
|
54
|
+
- bin/transform
|
55
|
+
- lib/ruby-next.rb
|
56
|
+
- lib/ruby-next/cli.rb
|
57
|
+
- lib/ruby-next/commands/base.rb
|
58
|
+
- lib/ruby-next/commands/nextify.rb
|
59
|
+
- lib/ruby-next/core.rb
|
60
|
+
- lib/ruby-next/core/array/difference_union_intersection.rb
|
61
|
+
- lib/ruby-next/core/enumerable/filter.rb
|
62
|
+
- lib/ruby-next/core/enumerable/filter_map.rb
|
63
|
+
- lib/ruby-next/core/enumerable/tally.rb
|
64
|
+
- lib/ruby-next/core/hash/merge.rb
|
65
|
+
- lib/ruby-next/core/kernel/then.rb
|
66
|
+
- lib/ruby-next/core/pattern_matching.rb
|
67
|
+
- lib/ruby-next/core/proc/compose.rb
|
68
|
+
- lib/ruby-next/core/runtime.rb
|
69
|
+
- lib/ruby-next/language.rb
|
70
|
+
- lib/ruby-next/language/parser.rb
|
71
|
+
- lib/ruby-next/language/rewriters/args_forward.rb
|
72
|
+
- lib/ruby-next/language/rewriters/base.rb
|
73
|
+
- lib/ruby-next/language/rewriters/endless_range.rb
|
74
|
+
- lib/ruby-next/language/rewriters/method_reference.rb
|
75
|
+
- lib/ruby-next/language/rewriters/numbered_params.rb
|
76
|
+
- lib/ruby-next/language/rewriters/pattern_matching.rb
|
77
|
+
- lib/ruby-next/language/runtime.rb
|
78
|
+
- lib/ruby-next/language/setup.rb
|
79
|
+
- lib/ruby-next/language/unparser.rb
|
80
|
+
- lib/ruby-next/utils.rb
|
81
|
+
- lib/ruby-next/version.rb
|
82
|
+
- lib/uby-next.rb
|
21
83
|
homepage: http://github.com/palkan/ruby-next
|
22
84
|
licenses:
|
23
85
|
- MIT
|
@@ -28,16 +90,16 @@ require_paths:
|
|
28
90
|
- lib
|
29
91
|
required_ruby_version: !ruby/object:Gem::Requirement
|
30
92
|
requirements:
|
31
|
-
- - "
|
93
|
+
- - ">="
|
32
94
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.
|
95
|
+
version: 2.5.0
|
34
96
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
35
97
|
requirements:
|
36
98
|
- - ">="
|
37
99
|
- !ruby/object:Gem::Version
|
38
100
|
version: '0'
|
39
101
|
requirements: []
|
40
|
-
rubygems_version: 3.0.
|
102
|
+
rubygems_version: 3.0.6
|
41
103
|
signing_key:
|
42
104
|
specification_version: 4
|
43
105
|
summary: Make older Rubies quack like edge Ruby
|