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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +38 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +201 -11
  5. data/bin/parse +19 -0
  6. data/bin/ruby-next +16 -0
  7. data/bin/transform +18 -0
  8. data/lib/ruby-next/cli.rb +55 -0
  9. data/lib/ruby-next/commands/base.rb +42 -0
  10. data/lib/ruby-next/commands/nextify.rb +113 -0
  11. data/lib/ruby-next/core/array/difference_union_intersection.rb +31 -0
  12. data/lib/ruby-next/core/enumerable/filter.rb +23 -0
  13. data/lib/ruby-next/core/enumerable/filter_map.rb +50 -0
  14. data/lib/ruby-next/core/enumerable/tally.rb +28 -0
  15. data/lib/ruby-next/core/hash/merge.rb +16 -0
  16. data/lib/ruby-next/core/kernel/then.rb +12 -0
  17. data/lib/ruby-next/core/pattern_matching.rb +37 -0
  18. data/lib/ruby-next/core/proc/compose.rb +21 -0
  19. data/lib/ruby-next/core/runtime.rb +10 -0
  20. data/lib/ruby-next/core.rb +28 -0
  21. data/lib/ruby-next/language/parser.rb +23 -0
  22. data/lib/ruby-next/language/rewriters/args_forward.rb +57 -0
  23. data/lib/ruby-next/language/rewriters/base.rb +87 -0
  24. data/lib/ruby-next/language/rewriters/endless_range.rb +60 -0
  25. data/lib/ruby-next/language/rewriters/method_reference.rb +27 -0
  26. data/lib/ruby-next/language/rewriters/numbered_params.rb +41 -0
  27. data/lib/ruby-next/language/rewriters/pattern_matching.rb +464 -0
  28. data/lib/ruby-next/language/runtime.rb +149 -0
  29. data/lib/ruby-next/language/setup.rb +43 -0
  30. data/lib/ruby-next/language/unparser.rb +23 -0
  31. data/lib/ruby-next/language.rb +100 -0
  32. data/lib/ruby-next/utils.rb +39 -0
  33. data/lib/ruby-next/version.rb +5 -0
  34. data/lib/ruby-next.rb +37 -0
  35. data/lib/uby-next.rb +66 -0
  36. 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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyNext
4
+ VERSION = "0.1.0"
5
+ 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.0.1.26
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-10-13 00:00:00.000000000 Z
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.6.0
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.4
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