ruby-next-core 0.2.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 (39) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +68 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +279 -0
  5. data/bin/parse +19 -0
  6. data/bin/ruby-next +16 -0
  7. data/bin/transform +21 -0
  8. data/lib/ruby-next.rb +37 -0
  9. data/lib/ruby-next/cli.rb +55 -0
  10. data/lib/ruby-next/commands/base.rb +42 -0
  11. data/lib/ruby-next/commands/nextify.rb +118 -0
  12. data/lib/ruby-next/core.rb +34 -0
  13. data/lib/ruby-next/core/array/difference_union_intersection.rb +31 -0
  14. data/lib/ruby-next/core/enumerable/filter.rb +23 -0
  15. data/lib/ruby-next/core/enumerable/filter_map.rb +50 -0
  16. data/lib/ruby-next/core/enumerable/tally.rb +28 -0
  17. data/lib/ruby-next/core/enumerator/produce.rb +22 -0
  18. data/lib/ruby-next/core/hash/merge.rb +16 -0
  19. data/lib/ruby-next/core/kernel/then.rb +12 -0
  20. data/lib/ruby-next/core/pattern_matching.rb +37 -0
  21. data/lib/ruby-next/core/proc/compose.rb +21 -0
  22. data/lib/ruby-next/core/runtime.rb +10 -0
  23. data/lib/ruby-next/language.rb +117 -0
  24. data/lib/ruby-next/language/bootsnap.rb +26 -0
  25. data/lib/ruby-next/language/eval.rb +64 -0
  26. data/lib/ruby-next/language/parser.rb +24 -0
  27. data/lib/ruby-next/language/rewriters/args_forward.rb +57 -0
  28. data/lib/ruby-next/language/rewriters/base.rb +105 -0
  29. data/lib/ruby-next/language/rewriters/endless_range.rb +60 -0
  30. data/lib/ruby-next/language/rewriters/method_reference.rb +31 -0
  31. data/lib/ruby-next/language/rewriters/numbered_params.rb +41 -0
  32. data/lib/ruby-next/language/rewriters/pattern_matching.rb +522 -0
  33. data/lib/ruby-next/language/runtime.rb +96 -0
  34. data/lib/ruby-next/language/setup.rb +43 -0
  35. data/lib/ruby-next/language/unparser.rb +8 -0
  36. data/lib/ruby-next/utils.rb +36 -0
  37. data/lib/ruby-next/version.rb +5 -0
  38. data/lib/uby-next.rb +68 -0
  39. metadata +117 -0
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+
5
+ require "ruby-next"
6
+ require "ruby-next/utils"
7
+ require "ruby-next/language"
8
+ require "ruby-next/language/eval"
9
+
10
+ using RubyNext
11
+
12
+ module RubyNext
13
+ module Language
14
+ # Module responsible for runtime transformations
15
+
16
+ module Runtime
17
+ class << self
18
+ include Utils
19
+
20
+ def load(path, wrap: false)
21
+ raise "RubyNext cannot handle `load(smth, wrap: true)`" if wrap
22
+
23
+ contents = File.read(path)
24
+ new_contents = transform contents
25
+
26
+ $stdout.puts source_with_lines(new_contents, path) if ENV["RUBY_NEXT_DEBUG"] == "1"
27
+
28
+ TOPLEVEL_BINDING.eval(new_contents, path)
29
+ true
30
+ end
31
+
32
+ def transform(contents, **options)
33
+ Language.transform(contents, rewriters: Language.current_rewriters, **options)
34
+ end
35
+
36
+ def feature_path(path)
37
+ path = resolve_feature_path(path)
38
+ return if path.nil?
39
+ return if File.extname(path) != ".rb"
40
+ return unless Language.transformable?(path)
41
+ path
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ # Patch Kernel to hijack require/require_relative/load/eval
49
+ module Kernel
50
+ module_function # rubocop:disable Style/ModuleFunction
51
+
52
+ alias_method :require_without_ruby_next, :require
53
+ def require(path)
54
+ realpath = RubyNext::Language::Runtime.feature_path(path)
55
+ return require_without_ruby_next(path) unless realpath
56
+
57
+ return false if $LOADED_FEATURES.include?(realpath)
58
+
59
+ $LOADED_FEATURES << realpath
60
+
61
+ RubyNext::Language::Runtime.load(realpath)
62
+
63
+ true
64
+ rescue => e
65
+ $LOADED_FEATURES.delete realpath
66
+ warn "RubyNext failed to require '#{path}': #{e.message}"
67
+ require_without_ruby_next(path)
68
+ end
69
+
70
+ alias_method :require_relative_without_ruby_next, :require_relative
71
+ def require_relative(path)
72
+ from = caller_locations(1..1).first.absolute_path || File.join(Dir.pwd, "main")
73
+ realpath = File.absolute_path(
74
+ File.join(
75
+ File.dirname(File.absolute_path(from)),
76
+ path
77
+ )
78
+ )
79
+ require(realpath)
80
+ rescue => e
81
+ warn "RubyNext failed to require relative '#{path}' from #{from}: #{e.message}"
82
+ require_relative_without_ruby_next(path)
83
+ end
84
+
85
+ alias_method :load_without_ruby_next, :load
86
+ def load(path, wrap = false)
87
+ realpath = RubyNext::Language::Runtime.feature_path(path)
88
+
89
+ return load_without_ruby_next(path, wrap) unless realpath
90
+
91
+ RubyNext::Language::Runtime.load(realpath, wrap: wrap)
92
+ rescue => e
93
+ warn "RubyNext failed to load '#{path}': #{e.message}"
94
+ load_without_ruby_next(path)
95
+ end
96
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Make sure Core is loaded
4
+ require "ruby-next"
5
+
6
+ module RubyNext
7
+ module Language
8
+ class << self
9
+ def setup_gem_load_path(lib_dir = "lib", rbnext_dir: RUBY_NEXT_DIR)
10
+ called_from = caller_locations(1, 1).first.path
11
+ dirname = File.dirname(called_from)
12
+
13
+ loop do
14
+ basename = File.basename(dirname)
15
+ raise "Couldn't find gem's load dir: #{lib_dir}" if basename == dirname
16
+
17
+ break if basename == lib_dir
18
+
19
+ dirname = File.dirname(basename)
20
+ end
21
+
22
+ current_index = $LOAD_PATH.index(dirname)
23
+
24
+ raise "Gem's lib is not in the $LOAD_PATH: #{dirname}" if current_index.nil?
25
+
26
+ version = RubyNext.next_version
27
+
28
+ loop do
29
+ break unless version
30
+
31
+ version_dir = File.join(dirname, rbnext_dir, version.segments[0..1].join("."))
32
+
33
+ if File.exist?(version_dir)
34
+ $LOAD_PATH.insert current_index, version_dir
35
+ current_index += 1
36
+ end
37
+
38
+ version = RubyNext.next_version(version)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Require current parser without warnings
4
+ save_verbose, $VERBOSE = $VERBOSE, nil
5
+ require "parser/current"
6
+ $VERBOSE = save_verbose
7
+
8
+ require "unparser"
@@ -0,0 +1,36 @@
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
+ return path if Pathname.new(path).absolute?
20
+
21
+ $LOAD_PATH.find do |lp|
22
+ lpath = File.join(lp, path)
23
+ return lpath if File.file?(lpath)
24
+ end
25
+ end
26
+ end
27
+
28
+ def source_with_lines(source, path)
29
+ source.lines.map.with_index do |line, i|
30
+ "#{(i + 1).to_s.rjust(4)}: #{line}"
31
+ end.tap do |lines|
32
+ lines.unshift " 0: # source: #{path}"
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyNext
4
+ VERSION = "0.2.0"
5
+ end
data/lib/uby-next.rb ADDED
@@ -0,0 +1,68 @@
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.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\s*#{$$}/] }.then do |command|
43
+ next unless command
44
+ command.tr! '\012', "\n"
45
+ command.tr! "\\", "\n"
46
+ command.match(/\-e(.*)/m)
47
+ end.then do |matches|
48
+ next unless matches
49
+
50
+ args = ["-e", matches[1]]
51
+ require "optparse"
52
+ OptionParser.new do |o|
53
+ o.on("-e SOURCE") do |v|
54
+ e_script = v
55
+ end
56
+ end.parse!(args)
57
+ end
58
+ end
59
+
60
+ if e_script
61
+ new_e_script = RubyNext::Language::Runtime.transform(e_script)
62
+ TOPLEVEL_BINDING.eval(new_e_script, $0)
63
+ exit!(0)
64
+ end
65
+ end
66
+
67
+ puts(stderr.tap(&:rewind).read)
68
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-next-core
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Vladimir Dementyev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-01-13 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.7.0.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.7.0.0
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.7
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.7
41
+ description: "\n Ruby Next Core is a zero deps version of Ruby Next meant to be
42
+ used\n as as dependency in your gems.\n\n It contains all the polyfills and
43
+ utility files but doesn't require transpiler\n dependencies to be install.\n
44
+ \ "
45
+ email:
46
+ - dementiev.vm@gmail.com
47
+ executables:
48
+ - ruby-next
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - CHANGELOG.md
53
+ - LICENSE.txt
54
+ - README.md
55
+ - bin/parse
56
+ - bin/ruby-next
57
+ - bin/transform
58
+ - lib/ruby-next.rb
59
+ - lib/ruby-next/cli.rb
60
+ - lib/ruby-next/commands/base.rb
61
+ - lib/ruby-next/commands/nextify.rb
62
+ - lib/ruby-next/core.rb
63
+ - lib/ruby-next/core/array/difference_union_intersection.rb
64
+ - lib/ruby-next/core/enumerable/filter.rb
65
+ - lib/ruby-next/core/enumerable/filter_map.rb
66
+ - lib/ruby-next/core/enumerable/tally.rb
67
+ - lib/ruby-next/core/enumerator/produce.rb
68
+ - lib/ruby-next/core/hash/merge.rb
69
+ - lib/ruby-next/core/kernel/then.rb
70
+ - lib/ruby-next/core/pattern_matching.rb
71
+ - lib/ruby-next/core/proc/compose.rb
72
+ - lib/ruby-next/core/runtime.rb
73
+ - lib/ruby-next/language.rb
74
+ - lib/ruby-next/language/bootsnap.rb
75
+ - lib/ruby-next/language/eval.rb
76
+ - lib/ruby-next/language/parser.rb
77
+ - lib/ruby-next/language/rewriters/args_forward.rb
78
+ - lib/ruby-next/language/rewriters/base.rb
79
+ - lib/ruby-next/language/rewriters/endless_range.rb
80
+ - lib/ruby-next/language/rewriters/method_reference.rb
81
+ - lib/ruby-next/language/rewriters/numbered_params.rb
82
+ - lib/ruby-next/language/rewriters/pattern_matching.rb
83
+ - lib/ruby-next/language/runtime.rb
84
+ - lib/ruby-next/language/setup.rb
85
+ - lib/ruby-next/language/unparser.rb
86
+ - lib/ruby-next/utils.rb
87
+ - lib/ruby-next/version.rb
88
+ - lib/uby-next.rb
89
+ homepage: http://github.com/palkan/ruby-next
90
+ licenses:
91
+ - MIT
92
+ metadata:
93
+ bug_tracker_uri: http://github.com/ruby-next/ruby-next/issues
94
+ changelog_uri: https://github.com/ruby-next/ruby-next/blob/master/CHANGELOG.md
95
+ documentation_uri: http://github.com/ruby-next/ruby-next/blob/master/README.md
96
+ homepage_uri: http://github.com/ruby-next/ruby-next
97
+ source_code_uri: http://github.com/ruby-next/ruby-next
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: 2.5.0
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubygems_version: 3.0.6
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Ruby Next core functionality
117
+ test_files: []