ruby-next-core 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: []