ruby-next-core 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c248b303a7e6990efd5d93e042c4043a61a553fddf880f44d9a2f7f40e66eabb
4
- data.tar.gz: 23aa24ec51098f2a73196c2ddb3c4ae1fdeece1b5232cb5832012466080f29e9
3
+ metadata.gz: 1e73900618b0d9da915699c40c610736e19919ac0d11bce7c7dc58e7d5ddb84b
4
+ data.tar.gz: b07917f44a763467f4bed145ae1224ba8aeb03eaba7924b2787c681df4b704f8
5
5
  SHA512:
6
- metadata.gz: 1b97768e53ff0e8841fbb7d045358728dcb2208ba79cdb0636b495de3112810b3d8f8deb1cbbe34a5fe52ef79c09044d4871db05caed04b211dfbbca8e6c4238
7
- data.tar.gz: 700ad59a1f0e094bf162dc2d2e30af843b4f95b9bfc3d104c58ea2f7d8a46c57537792c507dd0189e2c93850c0cccc4b0e8bb57e10eef22041ee0dac5b4b537c
6
+ metadata.gz: fb7bc9bc3416a8b6df9e99f346fb15c2c0ae0a9d63bba739adaa6c604110eaa753a5d7b00d98443400e92d7233fba7b4fda2a43e866ce85ef04ed46cd7e89a4c
7
+ data.tar.gz: 0b6410607425aaa0afb66309fa07739e72e3b8cbf94addf85d501f136755159db968225b6d1752a1bda77911592252d48e2d2c5421dae5798d5741ef6ec33616
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.13.0 (2021-09-27)
6
+
7
+ - Added `Enumerable#tally` with the resulting hash. ([@skryukov][])
8
+
9
+ - Added `Array#intersect?`. ([@skryukov][])
10
+
5
11
  ## 0.12.0 (2021-01-12)
6
12
 
7
13
  - Added required keyword arguments rewriter. ([@palkan][])
@@ -281,3 +287,4 @@ p a #=> 1
281
287
  [@palkan]: https://github.com/palkan
282
288
  [backports]: https://github.com/marcandre/backports
283
289
  [@sl4vr]: https://github.com/sl4vr
290
+ [@skryukov]: https://github.com/skryukov
data/README.md CHANGED
@@ -21,8 +21,20 @@ That's why Ruby Next implements the `master` features as fast as possible.
21
21
 
22
22
  Read more about the motivation behind the Ruby Next in this post: [Ruby Next: Make all Rubies quack alike](https://evilmartians.com/chronicles/ruby-next-make-all-rubies-quack-alike).
23
23
 
24
- <a href="https://evilmartians.com/?utm_source=ruby-next">
25
- <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
24
+ <table style="border:none;">
25
+ <tr>
26
+ <td>
27
+ <a href="https://evilmartians.com/?utm_source=ruby-next">
28
+ <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54">
29
+ </a>
30
+ </td>
31
+ <td>
32
+ <a href="http://www.digitalfukuoka.jp/topics/169">
33
+ <img src="http://www.digitalfukuoka.jp/javascripts/kcfinder/upload/images/excellence.jpg" width="200">
34
+ </a>
35
+ </td>
36
+ </tr>
37
+ </table>
26
38
 
27
39
  ## Posts
28
40
 
@@ -510,7 +522,7 @@ require "ruby-next/language/runtime"
510
522
 
511
523
  ### Supported edge features
512
524
 
513
- No new features since 3.0 release.
525
+ `Array#intersect?` ([#15198](https://bugs.ruby-lang.org/issues/15198))
514
526
 
515
527
  ### Supported proposed features
516
528
 
@@ -181,6 +181,7 @@ unless defined?(NoMatchingPatternError)
181
181
  end
182
182
 
183
183
  require "ruby-next/core/constants/no_matching_pattern_error"
184
+ require "ruby-next/core/constants/frozen_error"
184
185
  require "ruby-next/core/array/deconstruct"
185
186
  require "ruby-next/core/hash/deconstruct_keys"
186
187
  require "ruby-next/core/struct/deconstruct"
@@ -188,6 +189,8 @@ require "ruby-next/core/struct/deconstruct_keys"
188
189
 
189
190
  require "ruby-next/core/hash/except"
190
191
 
192
+ require "ruby-next/core/array/intersect"
193
+
191
194
  # Generate refinements
192
195
  RubyNext.module_eval do
193
196
  RubyNext::Core.patches.refined.each do |mod, patches|
@@ -0,0 +1,227 @@
1
+ # frozen_string_literal: true
2
+
3
+ gem "ruby-next-parser", ">= 2.8.0.3"
4
+ gem "unparser", ">= 0.4.7"
5
+
6
+ require "set"
7
+
8
+ require "ruby-next"
9
+
10
+ module RubyNext
11
+ # Language module contains tools to transpile newer Ruby syntax
12
+ # into an older one.
13
+ #
14
+ # It works the following way:
15
+ # - Takes a Ruby source code as input
16
+ # - Generates the AST using the edge parser (via the `parser` gem)
17
+ # - Pass this AST through the list of processors (one feature = one processor)
18
+ # - Each processor may modify the AST
19
+ # - Generates a transpiled source code from the transformed AST (via the `unparser` gem)
20
+ module Language
21
+ using RubyNext
22
+
23
+ require "ruby-next/language/parser"
24
+ require "ruby-next/language/unparser"
25
+
26
+ RewriterNotFoundError = Class.new(StandardError)
27
+
28
+ class TransformContext
29
+ attr_reader :versions, :use_ruby_next
30
+
31
+ def initialize
32
+ # Minimum supported RubyNext version
33
+ @min_version = MIN_SUPPORTED_VERSION
34
+ @dirty = false
35
+ @versions = Set.new
36
+ @use_ruby_next = false
37
+ end
38
+
39
+ # Called by rewriter when it performs transfomrations
40
+ def track!(rewriter)
41
+ @dirty = true
42
+ versions << rewriter.class::MIN_SUPPORTED_VERSION
43
+ end
44
+
45
+ def use_ruby_next!
46
+ @use_ruby_next = true
47
+ end
48
+
49
+ alias use_ruby_next? use_ruby_next
50
+
51
+ def dirty?
52
+ @dirty == true
53
+ end
54
+
55
+ def min_version
56
+ versions.min
57
+ end
58
+
59
+ def sorted_versions
60
+ versions.to_a.sort
61
+ end
62
+ end
63
+
64
+ class << self
65
+ attr_accessor :rewriters
66
+ attr_reader :watch_dirs
67
+
68
+ attr_accessor :strategy
69
+
70
+ MODES = %i[rewrite ast].freeze
71
+
72
+ attr_reader :mode
73
+
74
+ def mode=(val)
75
+ raise ArgumentError, "Unknown mode: #{val}. Available: #{MODES.join(",")}" unless MODES.include?(val)
76
+ @mode = val
77
+ end
78
+
79
+ def rewrite?
80
+ mode == :rewrite?
81
+ end
82
+
83
+ def ast?
84
+ mode == :ast
85
+ end
86
+
87
+ def runtime!
88
+ require "ruby-next/language/rewriters/runtime"
89
+
90
+ @runtime = true
91
+ end
92
+
93
+ def runtime?
94
+ @runtime
95
+ end
96
+
97
+ def transform(source, rewriters: self.rewriters, using: RubyNext::Core.refine?, context: TransformContext.new)
98
+ retried = 0
99
+ new_source = nil
100
+ begin
101
+ new_source =
102
+ if mode == :rewrite
103
+ rewrite(source, rewriters: rewriters, using: using, context: context)
104
+ else
105
+ regenerate(source, rewriters: rewriters, using: using, context: context)
106
+ end
107
+ rescue Unparser::UnknownNodeError => err
108
+ RubyNext.warn "Ruby Next fallbacks to \"rewrite\" transpiling mode since the version of Unparser you use doesn't support some syntax yet: #{err.message}.\n" \
109
+ "Try upgrading the Unparser or set transpiling mode to \"rewrite\" in case you use some edge or experimental syntax."
110
+ self.mode = :rewrite
111
+ retried += 1
112
+ retry unless retried > 1
113
+ raise
114
+ end
115
+
116
+ return new_source unless RubyNext::Core.refine?
117
+ return new_source unless using && context.use_ruby_next?
118
+
119
+ Core.inject! new_source.dup
120
+ end
121
+
122
+ def transformable?(path)
123
+ watch_dirs.any? { |dir| path.start_with?(dir) }
124
+ end
125
+
126
+ # Rewriters required for the current version
127
+ def current_rewriters
128
+ @current_rewriters ||= rewriters.select(&:unsupported_syntax?)
129
+ end
130
+
131
+ # This method guarantees that rewriters will be returned in order they defined in Language module
132
+ def select_rewriters(*names)
133
+ rewriters_delta = names - rewriters.map { |rewriter| rewriter::NAME }
134
+ if rewriters_delta.any?
135
+ raise RewriterNotFoundError, "Rewriters not found: #{rewriters_delta.join(",")}"
136
+ end
137
+
138
+ rewriters.select { |rewriter| names.include?(rewriter::NAME) }
139
+ end
140
+
141
+ private
142
+
143
+ def regenerate(source, rewriters: ::Kernel.raise(::ArgumentError, "missing keyword: rewriters"), using: ::Kernel.raise(::ArgumentError, "missing keyword: using"), context: ::Kernel.raise(::ArgumentError, "missing keyword: context"))
144
+ parse_with_comments(source).then do |(ast, comments)|
145
+ rewriters.inject(ast) do |tree, rewriter|
146
+ rewriter.new(context).process(tree)
147
+ end.then do |new_ast|
148
+ next source unless context.dirty?
149
+
150
+ Unparser.unparse(new_ast, comments)
151
+ end
152
+ end
153
+ end
154
+
155
+ def rewrite(source, rewriters: ::Kernel.raise(::ArgumentError, "missing keyword: rewriters"), using: ::Kernel.raise(::ArgumentError, "missing keyword: using"), context: ::Kernel.raise(::ArgumentError, "missing keyword: context"))
156
+ rewriters.inject(source) do |src, rewriter|
157
+ buffer = Parser::Source::Buffer.new("<dynamic>")
158
+ buffer.source = src
159
+
160
+ rewriter.new(context).rewrite(buffer, parse(src))
161
+ end.then do |new_source|
162
+ next source unless context.dirty?
163
+
164
+ new_source
165
+ end
166
+ end
167
+
168
+ attr_writer :watch_dirs
169
+ end
170
+
171
+ self.rewriters = []
172
+ self.watch_dirs = %w[app lib spec test].map { |path| File.join(Dir.pwd, path) }
173
+ self.mode = ENV.fetch("RUBY_NEXT_TRANSPILE_MODE", "rewrite").to_sym
174
+
175
+ require "ruby-next/language/rewriters/base"
176
+
177
+ require "ruby-next/language/rewriters/squiggly_heredoc"
178
+ rewriters << Rewriters::SquigglyHeredoc
179
+
180
+ require "ruby-next/language/rewriters/safe_navigation"
181
+ rewriters << Rewriters::SafeNavigation
182
+
183
+ require "ruby-next/language/rewriters/numeric_literals"
184
+ rewriters << Rewriters::NumericLiterals
185
+
186
+ require "ruby-next/language/rewriters/required_kwargs"
187
+ rewriters << Rewriters::RequiredKwargs
188
+
189
+ require "ruby-next/language/rewriters/args_forward"
190
+ rewriters << Rewriters::ArgsForward
191
+
192
+ # Must be added after general args forward rewriter to become
193
+ # no-op in Ruby <2.7
194
+ require "ruby-next/language/rewriters/args_forward_leading"
195
+ rewriters << Rewriters::ArgsForwardLeading
196
+
197
+ require "ruby-next/language/rewriters/numbered_params"
198
+ rewriters << Rewriters::NumberedParams
199
+
200
+ require "ruby-next/language/rewriters/pattern_matching"
201
+ rewriters << Rewriters::PatternMatching
202
+
203
+ # Must be added after general pattern matching rewriter to become
204
+ # no-op in Ruby <2.7
205
+ require "ruby-next/language/rewriters/find_pattern"
206
+ rewriters << Rewriters::FindPattern
207
+
208
+ require "ruby-next/language/rewriters/in_pattern"
209
+ rewriters << Rewriters::InPattern
210
+
211
+ # Put endless range in the end, 'cause Parser fails to parse it in
212
+ # pattern matching
213
+ require "ruby-next/language/rewriters/endless_range"
214
+ rewriters << Rewriters::EndlessRange
215
+
216
+ require "ruby-next/language/rewriters/endless_method"
217
+ RubyNext::Language.rewriters << RubyNext::Language::Rewriters::EndlessMethod
218
+
219
+ if ENV["RUBY_NEXT_EDGE"] == "1"
220
+ require "ruby-next/language/edge"
221
+ end
222
+
223
+ if ENV["RUBY_NEXT_PROPOSED"] == "1"
224
+ require "ruby-next/language/proposed"
225
+ end
226
+ end
227
+ end
@@ -353,7 +353,7 @@ module RubyNext
353
353
 
354
354
  else_clause = (else_clause || no_matching_pattern).then do |node|
355
355
  next node unless node.type == :empty_else
356
- s(:empty)
356
+ nil
357
357
  end
358
358
 
359
359
  clauses << else_clause
@@ -181,6 +181,7 @@ unless defined?(NoMatchingPatternError)
181
181
  end
182
182
 
183
183
  require "ruby-next/core/constants/no_matching_pattern_error"
184
+ require "ruby-next/core/constants/frozen_error"
184
185
  require "ruby-next/core/array/deconstruct"
185
186
  require "ruby-next/core/hash/deconstruct_keys"
186
187
  require "ruby-next/core/struct/deconstruct"
@@ -188,6 +189,8 @@ require "ruby-next/core/struct/deconstruct_keys"
188
189
 
189
190
  require "ruby-next/core/hash/except"
190
191
 
192
+ require "ruby-next/core/array/intersect"
193
+
191
194
  # Generate refinements
192
195
  RubyNext.module_eval do
193
196
  RubyNext::Core.patches.refined.each do |mod, patches|
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ RubyNext::Core.patch Array, method: :intersect?, version: "3.1" do
4
+ <<-RUBY
5
+ def intersect?(other)
6
+ !(self & other).empty?
7
+ end
8
+ RUBY
9
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ RubyNext::Core.patch Object,
4
+ name: "FrozenError",
5
+ method: nil,
6
+ refineable: [],
7
+ version: "2.5",
8
+ # avoid defining the constant twice, 'causae it's already included in core
9
+ # we only use the contents in `ruby-next core_ext`.
10
+ supported: true,
11
+ location: [__FILE__, __LINE__ + 2] do
12
+ <<-RUBY
13
+ FrozenError ||= RuntimeError
14
+ RUBY
15
+ end
@@ -1,12 +1,51 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Refine Array seprately, 'cause refining modules is vulnerable to prepend:
4
- # - https://bugs.ruby-lang.org/issues/13446
5
- RubyNext::Core.patch Enumerable, method: :tally, version: "2.7", refineable: [Enumerable, Array] do
6
- <<-RUBY
7
- def tally
8
- each_with_object({}) do |v, acc|
9
- acc[v] ||= 0
3
+ # Ruby 3.1 adds an ability to pass a hash as accumulator.
4
+ #
5
+ # NOTE: We have separate patches for MRI 3.0+ and others due to the unsupported refinements vs modules behaviour.
6
+ if Enumerable.method_defined?(:tally) && ([].method(:tally).arity == 0) && !(defined?(JRUBY_VERSION) || defined?(TruffleRuby))
7
+ RubyNext::Core.patch name: "TallyWithHash", supported: false, native: nil, method: :tally, version: "3.1", refineable: [Enumerable] do
8
+ <<-'RUBY'
9
+ def tally(*attrs)
10
+ return super() if attrs.size.zero?
11
+
12
+ raise ArgumentError, "wrong number of arguments (given #{attrs.size}, expected 0..1)" if attrs.size > 1
13
+
14
+ hash = attrs.size.zero? ? {} : attrs[0].to_hash
15
+ raise FrozenError, "can't modify frozen #{hash.class}: #{hash}" if hash.frozen?
16
+
17
+ each_with_object(hash) do |v, acc|
18
+ acc[v] = 0 unless acc.key?(v)
19
+ acc[v] += 1
20
+ end
21
+ end
22
+ RUBY
23
+ end
24
+ else
25
+ RubyNext::Core.patch Enumerable, method: :tally, version: "3.1", refineable: [Enumerable, Array] do
26
+ <<-'RUBY'
27
+ def tally(acc = {})
28
+ hash = acc.to_hash
29
+ raise FrozenError, "can't modify frozen #{hash.class}: #{hash}" if hash.frozen?
30
+
31
+ each_with_object(hash) do |v, acc|
32
+ acc[v] = 0 unless acc.key?(v)
33
+ acc[v] += 1
34
+ end
35
+ end
36
+ RUBY
37
+ end
38
+ end
39
+
40
+ # This patch is intended for core extensions only (since we can not use prepend here)
41
+ RubyNext::Core.patch Enumerable, name: "TallyWithHashCoreExt", version: "3.1", supported: Enumerable.method_defined?(:tally) && ([].method(:tally).arity != 0), method: :tally, refineable: [] do
42
+ <<-'RUBY'
43
+ def tally(acc = {})
44
+ hash = acc.to_hash
45
+ raise FrozenError, "can't modify frozen #{hash.class}: #{hash}" if hash.frozen?
46
+
47
+ each_with_object(hash) do |v, acc|
48
+ acc[v] = 0 unless acc.key?(v)
10
49
  acc[v] += 1
11
50
  end
12
51
  end
@@ -181,6 +181,7 @@ unless defined?(NoMatchingPatternError)
181
181
  end
182
182
 
183
183
  require "ruby-next/core/constants/no_matching_pattern_error"
184
+ require "ruby-next/core/constants/frozen_error"
184
185
  require "ruby-next/core/array/deconstruct"
185
186
  require "ruby-next/core/hash/deconstruct_keys"
186
187
  require "ruby-next/core/struct/deconstruct"
@@ -188,6 +189,8 @@ require "ruby-next/core/struct/deconstruct_keys"
188
189
 
189
190
  require "ruby-next/core/hash/except"
190
191
 
192
+ require "ruby-next/core/array/intersect"
193
+
191
194
  # Generate refinements
192
195
  RubyNext.module_eval do
193
196
  RubyNext::Core.patches.refined.each do |mod, patches|
@@ -11,16 +11,20 @@ module RubyNext
11
11
  REST = :__rest__
12
12
  BLOCK = :__block__
13
13
 
14
- def on_forward_arg(node)
14
+ def on_args(node)
15
+ farg = node.children.find { |child| child.is_a?(::Parser::AST::Node) && child.type == :forward_arg }
16
+ return unless farg
17
+
15
18
  context.track! self
16
19
 
17
20
  node = super(node)
18
21
 
19
- replace(node.loc.expression, "*#{REST}, &#{BLOCK}")
22
+ replace(farg.loc.expression, "*#{REST}, &#{BLOCK}")
20
23
 
21
24
  node.updated(
22
25
  :args,
23
26
  [
27
+ *node.children.slice(0, node.children.index(farg)),
24
28
  s(:restarg, REST),
25
29
  s(:blockarg, BLOCK)
26
30
  ]
@@ -23,7 +23,7 @@ module RubyNext
23
23
  super
24
24
  end
25
25
 
26
- def on_forward_arg(node)
26
+ def on_args(node)
27
27
  return super if leading_farg?
28
28
 
29
29
  node
@@ -353,7 +353,7 @@ module RubyNext
353
353
 
354
354
  else_clause = (else_clause || no_matching_pattern).then do |node|
355
355
  next node unless node.type == :empty_else
356
- s(:empty)
356
+ nil
357
357
  end
358
358
 
359
359
  clauses << else_clause
@@ -50,7 +50,7 @@ module RubyNext
50
50
  GemTranspiler.maybe_transpile(File.dirname(dirname), lib_dir, next_dirname) if transpile
51
51
 
52
52
  current_index = $LOAD_PATH.find_index do |load_path|
53
- Pathname.new(load_path).cleanpath.to_s == dirname
53
+ Pathname.new(load_path).realpath.to_s == dirname
54
54
  end
55
55
 
56
56
  raise "Gem's lib is not in the $LOAD_PATH: #{dirname}" if current_index.nil?
@@ -94,53 +94,29 @@ module RubyNext
94
94
  @runtime
95
95
  end
96
96
 
97
- def transform(*args, **kwargs)
98
- if mode == :rewrite
99
- rewrite(*args, **kwargs)
100
- else
101
- regenerate(*args, **kwargs)
102
- end
103
- rescue Unparser::UnknownNodeError
104
- if Gem::Version.new(::RubyNext.current_ruby_version) >= Gem::Version.new("3.0.0")
105
- RubyNext.warn "Ruby Next fallbacks to \"rewrite\" transpiling mode since Unparser doesn't support 3.0+ AST yet.\n" \
106
- "See https://github.com/mbj/unparser/issues/168"
97
+ def transform(source, rewriters: self.rewriters, using: RubyNext::Core.refine?, context: TransformContext.new)
98
+ retried = 0
99
+ new_source = nil
100
+ begin
101
+ new_source =
102
+ if mode == :rewrite
103
+ rewrite(source, rewriters: rewriters, using: using, context: context)
104
+ else
105
+ regenerate(source, rewriters: rewriters, using: using, context: context)
106
+ end
107
+ rescue Unparser::UnknownNodeError => err
108
+ RubyNext.warn "Ruby Next fallbacks to \"rewrite\" transpiling mode since the version of Unparser you use doesn't support some syntax yet: #{err.message}.\n" \
109
+ "Try upgrading the Unparser or set transpiling mode to \"rewrite\" in case you use some edge or experimental syntax."
107
110
  self.mode = :rewrite
111
+ retried += 1
112
+ retry unless retried > 1
113
+ raise
108
114
  end
109
- rewrite(*args, **kwargs)
110
- end
111
-
112
- def regenerate(source, rewriters: self.rewriters, using: RubyNext::Core.refine?, context: TransformContext.new)
113
- parse_with_comments(source).then do |(ast, comments)|
114
- rewriters.inject(ast) do |tree, rewriter|
115
- rewriter.new(context).process(tree)
116
- end.then do |new_ast|
117
- next source unless context.dirty?
118
115
 
119
- Unparser.unparse(new_ast, comments)
120
- end.then do |source|
121
- next source unless RubyNext::Core.refine?
122
- next source unless using && context.use_ruby_next?
116
+ return new_source unless RubyNext::Core.refine?
117
+ return new_source unless using && context.use_ruby_next?
123
118
 
124
- Core.inject! source.dup
125
- end
126
- end
127
- end
128
-
129
- def rewrite(source, rewriters: self.rewriters, using: RubyNext::Core.refine?, context: TransformContext.new)
130
- rewriters.inject(source) do |src, rewriter|
131
- buffer = Parser::Source::Buffer.new("<dynamic>")
132
- buffer.source = src
133
-
134
- rewriter.new(context).rewrite(buffer, parse(src))
135
- end.then do |new_source|
136
- next source unless context.dirty?
137
- new_source
138
- end.then do |source|
139
- next source unless RubyNext::Core.refine?
140
- next source unless using && context.use_ruby_next?
141
-
142
- Core.inject! source.dup
143
- end
119
+ Core.inject! new_source.dup
144
120
  end
145
121
 
146
122
  def transformable?(path)
@@ -164,6 +140,31 @@ module RubyNext
164
140
 
165
141
  private
166
142
 
143
+ def regenerate(source, rewriters:, using:, context:)
144
+ parse_with_comments(source).then do |(ast, comments)|
145
+ rewriters.inject(ast) do |tree, rewriter|
146
+ rewriter.new(context).process(tree)
147
+ end.then do |new_ast|
148
+ next source unless context.dirty?
149
+
150
+ Unparser.unparse(new_ast, comments)
151
+ end
152
+ end
153
+ end
154
+
155
+ def rewrite(source, rewriters:, using:, context:)
156
+ rewriters.inject(source) do |src, rewriter|
157
+ buffer = Parser::Source::Buffer.new("<dynamic>")
158
+ buffer.source = src
159
+
160
+ rewriter.new(context).rewrite(buffer, parse(src))
161
+ end.then do |new_source|
162
+ next source unless context.dirty?
163
+
164
+ new_source
165
+ end
166
+ end
167
+
167
168
  attr_writer :watch_dirs
168
169
  end
169
170
 
@@ -6,7 +6,9 @@
6
6
  version = RubyNext.next_ruby_version
7
7
  next_dirname = File.join(__dir__, "..", ".rbnext")
8
8
  lib_path = File.realpath(File.join(__dir__, ".."))
9
- current_index = $LOAD_PATH.index(lib_path)
9
+ current_index = $LOAD_PATH.find_index do |load_path|
10
+ File.exist?(load_path) && File.realpath(load_path) == lib_path
11
+ end
10
12
 
11
13
  loop do
12
14
  break unless version
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyNext
4
- VERSION = "0.12.0"
4
+ VERSION = "0.13.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-next-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-12 00:00:00.000000000 Z
11
+ date: 2021-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-next-parser
@@ -28,20 +28,14 @@ dependencies:
28
28
  name: unparser
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 0.5.6
34
- - - "<"
31
+ - - "~>"
35
32
  - !ruby/object:Gem::Version
36
33
  version: 0.6.0
37
34
  type: :development
38
35
  prerelease: false
39
36
  version_requirements: !ruby/object:Gem::Requirement
40
37
  requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- version: 0.5.6
44
- - - "<"
38
+ - - "~>"
45
39
  - !ruby/object:Gem::Version
46
40
  version: 0.6.0
47
41
  description: "\n Ruby Next Core is a zero deps version of Ruby Next meant to be
@@ -63,6 +57,7 @@ files:
63
57
  - bin/ruby-next
64
58
  - bin/transform
65
59
  - lib/.rbnext/2.1/ruby-next/core.rb
60
+ - lib/.rbnext/2.1/ruby-next/language.rb
66
61
  - lib/.rbnext/2.3/ruby-next/commands/core_ext.rb
67
62
  - lib/.rbnext/2.3/ruby-next/commands/nextify.rb
68
63
  - lib/.rbnext/2.3/ruby-next/language/eval.rb
@@ -80,6 +75,8 @@ files:
80
75
  - lib/ruby-next/core.rb
81
76
  - lib/ruby-next/core/array/deconstruct.rb
82
77
  - lib/ruby-next/core/array/difference_union_intersection.rb
78
+ - lib/ruby-next/core/array/intersect.rb
79
+ - lib/ruby-next/core/constants/frozen_error.rb
83
80
  - lib/ruby-next/core/constants/no_matching_pattern_error.rb
84
81
  - lib/ruby-next/core/enumerable/filter.rb
85
82
  - lib/ruby-next/core/enumerable/filter_map.rb
@@ -141,7 +138,7 @@ metadata:
141
138
  documentation_uri: http://github.com/ruby-next/ruby-next/blob/master/README.md
142
139
  homepage_uri: http://github.com/ruby-next/ruby-next
143
140
  source_code_uri: http://github.com/ruby-next/ruby-next
144
- post_install_message:
141
+ post_install_message:
145
142
  rdoc_options: []
146
143
  require_paths:
147
144
  - lib
@@ -156,8 +153,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
156
153
  - !ruby/object:Gem::Version
157
154
  version: '0'
158
155
  requirements: []
159
- rubygems_version: 3.0.6
160
- signing_key:
156
+ rubygems_version: 3.2.15
157
+ signing_key:
161
158
  specification_version: 4
162
159
  summary: Ruby Next core functionality
163
160
  test_files: []