ruby-next-core 0.10.5 → 0.13.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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -0
  3. data/README.md +25 -16
  4. data/lib/.rbnext/2.1/ruby-next/core.rb +206 -0
  5. data/lib/.rbnext/2.1/ruby-next/language.rb +227 -0
  6. data/lib/.rbnext/2.3/ruby-next/commands/nextify.rb +2 -2
  7. data/lib/.rbnext/2.3/ruby-next/language/eval.rb +4 -4
  8. data/lib/.rbnext/2.3/ruby-next/language/rewriters/base.rb +23 -5
  9. data/lib/.rbnext/2.3/ruby-next/language/rewriters/endless_range.rb +1 -1
  10. data/lib/.rbnext/2.3/ruby-next/language/rewriters/pattern_matching.rb +20 -17
  11. data/lib/.rbnext/2.3/ruby-next/utils.rb +1 -1
  12. data/lib/.rbnext/2.7/ruby-next/core.rb +206 -0
  13. data/lib/ruby-next/commands/nextify.rb +1 -1
  14. data/lib/ruby-next/config.rb +50 -0
  15. data/lib/ruby-next/core/array/deconstruct.rb +1 -1
  16. data/lib/ruby-next/core/array/intersect.rb +9 -0
  17. data/lib/ruby-next/core/constants/frozen_error.rb +15 -0
  18. data/lib/ruby-next/core/constants/no_matching_pattern_error.rb +1 -1
  19. data/lib/ruby-next/core/enumerable/tally.rb +46 -7
  20. data/lib/ruby-next/core/hash/deconstruct_keys.rb +1 -1
  21. data/lib/ruby-next/core/struct/deconstruct_keys.rb +3 -3
  22. data/lib/ruby-next/core.rb +8 -4
  23. data/lib/ruby-next/core_ext.rb +3 -1
  24. data/lib/ruby-next/language/bootsnap.rb +1 -1
  25. data/lib/ruby-next/language/edge.rb +0 -6
  26. data/lib/ruby-next/language/eval.rb +3 -3
  27. data/lib/ruby-next/language/parser.rb +16 -0
  28. data/lib/ruby-next/language/rewriters/args_forward.rb +14 -6
  29. data/lib/ruby-next/language/rewriters/args_forward_leading.rb +75 -0
  30. data/lib/ruby-next/language/rewriters/base.rb +19 -1
  31. data/lib/ruby-next/language/rewriters/in_pattern.rb +56 -0
  32. data/lib/ruby-next/language/rewriters/method_reference.rb +1 -1
  33. data/lib/ruby-next/language/rewriters/numeric_literals.rb +41 -0
  34. data/lib/ruby-next/language/rewriters/pattern_matching.rb +18 -15
  35. data/lib/ruby-next/language/rewriters/required_kwargs.rb +39 -0
  36. data/lib/ruby-next/language/rewriters/safe_navigation.rb +42 -29
  37. data/lib/ruby-next/language/rewriters/shorthand_hash.rb +1 -1
  38. data/lib/ruby-next/language/setup.rb +7 -4
  39. data/lib/ruby-next/language/unparser.rb +5 -0
  40. data/lib/ruby-next/language.rb +62 -44
  41. data/lib/ruby-next/rubocop.rb +9 -18
  42. data/lib/ruby-next/setup_self.rb +5 -3
  43. data/lib/ruby-next/version.rb +1 -1
  44. data/lib/ruby-next.rb +5 -38
  45. metadata +20 -18
  46. data/lib/.rbnext/2.3/ruby-next/language/rewriters/right_hand_assignment.rb +0 -117
  47. data/lib/ruby-next/language/rewriters/right_hand_assignment.rb +0 -117
@@ -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(RUBY_VERSION) >= Gem::Version.new("2.7.0")
105
- RubyNext.warn "Ruby Next fallbacks to \"rewrite\" transpiling mode since Unparser doesn't support 2.7+ AST yet.\n" \
106
- "See https://github.com/mbj/unparser/pull/142"
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
-
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?
123
-
124
- Core.inject! source.dup
125
- end
126
- end
127
- end
128
115
 
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
116
+ return new_source unless RubyNext::Core.refine?
117
+ return new_source unless using && context.use_ruby_next?
133
118
 
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,12 +140,37 @@ 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
 
170
171
  self.rewriters = []
171
172
  self.watch_dirs = %w[app lib spec test].map { |path| File.join(Dir.pwd, path) }
172
- self.mode = ENV.fetch("RUBY_NEXT_TRANSPILE_MODE", "ast").to_sym
173
+ self.mode = ENV.fetch("RUBY_NEXT_TRANSPILE_MODE", "rewrite").to_sym
173
174
 
174
175
  require "ruby-next/language/rewriters/base"
175
176
 
@@ -179,9 +180,20 @@ module RubyNext
179
180
  require "ruby-next/language/rewriters/safe_navigation"
180
181
  rewriters << Rewriters::SafeNavigation
181
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
+
182
189
  require "ruby-next/language/rewriters/args_forward"
183
190
  rewriters << Rewriters::ArgsForward
184
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
+
185
197
  require "ruby-next/language/rewriters/numbered_params"
186
198
  rewriters << Rewriters::NumberedParams
187
199
 
@@ -193,11 +205,17 @@ module RubyNext
193
205
  require "ruby-next/language/rewriters/find_pattern"
194
206
  rewriters << Rewriters::FindPattern
195
207
 
208
+ require "ruby-next/language/rewriters/in_pattern"
209
+ rewriters << Rewriters::InPattern
210
+
196
211
  # Put endless range in the end, 'cause Parser fails to parse it in
197
212
  # pattern matching
198
213
  require "ruby-next/language/rewriters/endless_range"
199
214
  rewriters << Rewriters::EndlessRange
200
215
 
216
+ require "ruby-next/language/rewriters/endless_method"
217
+ RubyNext::Language.rewriters << RubyNext::Language::Rewriters::EndlessMethod
218
+
201
219
  if ENV["RUBY_NEXT_EDGE"] == "1"
202
220
  require "ruby-next/language/edge"
203
221
  end
@@ -4,6 +4,7 @@
4
4
  # edge features and fix some bugs with 2.7+ syntax
5
5
 
6
6
  require "parser/ruby-next/version"
7
+ require "ruby-next/language/parser"
7
8
 
8
9
  module RuboCop
9
10
  # Transform Ruby Next parser version to a float, e.g.: "2.8.0.1" => 2.801
@@ -37,7 +38,6 @@ module RuboCop
37
38
  def parser_class(version)
38
39
  return super unless version == RUBY_NEXT_VERSION
39
40
 
40
- require "parser/rubynext"
41
41
  Parser::RubyNext
42
42
  end
43
43
  end
@@ -52,7 +52,7 @@ module RuboCop
52
52
  module AST
53
53
  module Traversal
54
54
  # Fixed in https://github.com/rubocop-hq/rubocop/pull/7786
55
- %i[case_match in_pattern find_pattern].each do |type|
55
+ %i[case_match in_pattern find_pattern match_pattern match_pattern_p].each do |type|
56
56
  next if method_defined?(:"on_#{type}")
57
57
  module_eval(<<-RUBY, __FILE__, __LINE__ + 1)
58
58
  def on_#{type}(node)
@@ -62,6 +62,10 @@ end
62
62
  RUBY
63
63
  end
64
64
  end
65
+
66
+ unless Builder.method_defined?(:match_pattern_p)
67
+ Builder.include RubyNext::Language::BuilderExt
68
+ end
65
69
  end
66
70
  end
67
71
  # rubocop:enable Layout/HeredocIndentation
@@ -102,27 +106,14 @@ module RuboCop
102
106
  send(:"on_#{body_node.type}", body_node)
103
107
  end
104
108
  end
105
-
106
- unless method_defined?(:on_rasgn)
107
- def on_rasgn(node)
108
- val_node, asgn_node = *node
109
- send(:"on_#{asgn_node.type}", asgn_node)
110
- send(:"on_#{val_node.type}", val_node)
111
- end
112
-
113
- def on_mrasgn(node)
114
- lhs, rhs = *node
115
- send(:"on_#{lhs.type}", lhs)
116
- send(:"on_#{rhs.type}", rhs)
117
- end
118
- end
119
109
  end
120
110
 
121
111
  module Layout
122
112
  require "rubocop/cop/layout/assignment_indentation"
123
- AssignmentIndentation.prepend(Module.new do
124
- POTENTIAL_RIGHT_TYPES = %i[ivasgn lvasgn cvasgn gvasgn casgn masgn].freeze
125
113
 
114
+ POTENTIAL_RIGHT_TYPES = %i[ivasgn lvasgn cvasgn gvasgn casgn masgn].freeze
115
+
116
+ AssignmentIndentation.prepend(Module.new do
126
117
  def check_assignment(node, *)
127
118
  return if rightward?(node)
128
119
  super
@@ -3,10 +3,12 @@
3
3
  # This file setup LOAD_PATH to load Ruby Next own transpiled paths
4
4
  # (we cannot use language/setup here, 'cause it requires Core to be loaded)
5
5
 
6
- version = RubyNext.next_version
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
@@ -18,5 +20,5 @@ loop do
18
20
  current_index += 1
19
21
  end
20
22
 
21
- version = RubyNext.next_version(version)
23
+ version = RubyNext.next_ruby_version(version)
22
24
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyNext
4
- VERSION = "0.10.5"
4
+ VERSION = "0.13.0"
5
5
  end
data/lib/ruby-next.rb CHANGED
@@ -1,41 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "ruby-next/version"
4
-
5
- module RubyNext
6
- # Mininum Ruby version supported by RubyNext
7
- MIN_SUPPORTED_VERSION = Gem::Version.new("2.2.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 => 8, # 2.8 is required for backward compatibility: some gems already uses it
15
- 3 => 0
16
- }.freeze
17
-
18
- LATEST_VERSION = [3, 0].freeze
19
-
20
- class << self
21
- def next_version(version = RUBY_VERSION)
22
- major, minor = Gem::Version.new(version).segments.map(&:to_i)
23
-
24
- return if major >= LATEST_VERSION.first && minor >= LATEST_VERSION.last
25
-
26
- nxt =
27
- if LAST_MINOR_VERSIONS[major] == minor
28
- "#{major + 1}.0.0"
29
- else
30
- "#{major}.#{minor + 1}.0"
31
- end
32
-
33
- Gem::Version.new(nxt)
34
- end
35
- end
36
-
37
- require "ruby-next/setup_self"
38
- require "ruby-next/core"
39
- require "ruby-next/core_ext" if RubyNext::Core.core_ext?
40
- require "ruby-next/logging"
41
- end
4
+ require "ruby-next/config"
5
+ require "ruby-next/setup_self"
6
+ require "ruby-next/core"
7
+ require "ruby-next/core_ext" if RubyNext::Core.core_ext?
8
+ require "ruby-next/logging"
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.10.5
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: 2020-10-13 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
@@ -16,32 +16,26 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 3.0.0.1
19
+ version: 3.0.0.3
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 3.0.0.1
26
+ version: 3.0.0.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: unparser
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 0.4.8
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.4.8
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
@@ -62,22 +56,27 @@ files:
62
56
  - bin/reparse
63
57
  - bin/ruby-next
64
58
  - bin/transform
59
+ - lib/.rbnext/2.1/ruby-next/core.rb
60
+ - lib/.rbnext/2.1/ruby-next/language.rb
65
61
  - lib/.rbnext/2.3/ruby-next/commands/core_ext.rb
66
62
  - lib/.rbnext/2.3/ruby-next/commands/nextify.rb
67
63
  - lib/.rbnext/2.3/ruby-next/language/eval.rb
68
64
  - lib/.rbnext/2.3/ruby-next/language/rewriters/base.rb
69
65
  - lib/.rbnext/2.3/ruby-next/language/rewriters/endless_range.rb
70
66
  - lib/.rbnext/2.3/ruby-next/language/rewriters/pattern_matching.rb
71
- - lib/.rbnext/2.3/ruby-next/language/rewriters/right_hand_assignment.rb
72
67
  - lib/.rbnext/2.3/ruby-next/utils.rb
68
+ - lib/.rbnext/2.7/ruby-next/core.rb
73
69
  - lib/ruby-next.rb
74
70
  - lib/ruby-next/cli.rb
75
71
  - lib/ruby-next/commands/base.rb
76
72
  - lib/ruby-next/commands/core_ext.rb
77
73
  - lib/ruby-next/commands/nextify.rb
74
+ - lib/ruby-next/config.rb
78
75
  - lib/ruby-next/core.rb
79
76
  - lib/ruby-next/core/array/deconstruct.rb
80
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
81
80
  - lib/ruby-next/core/constants/no_matching_pattern_error.rb
82
81
  - lib/ruby-next/core/enumerable/filter.rb
83
82
  - lib/ruby-next/core/enumerable/filter_map.rb
@@ -105,14 +104,17 @@ files:
105
104
  - lib/ruby-next/language/parser.rb
106
105
  - lib/ruby-next/language/proposed.rb
107
106
  - lib/ruby-next/language/rewriters/args_forward.rb
107
+ - lib/ruby-next/language/rewriters/args_forward_leading.rb
108
108
  - lib/ruby-next/language/rewriters/base.rb
109
109
  - lib/ruby-next/language/rewriters/endless_method.rb
110
110
  - lib/ruby-next/language/rewriters/endless_range.rb
111
111
  - lib/ruby-next/language/rewriters/find_pattern.rb
112
+ - lib/ruby-next/language/rewriters/in_pattern.rb
112
113
  - lib/ruby-next/language/rewriters/method_reference.rb
113
114
  - lib/ruby-next/language/rewriters/numbered_params.rb
115
+ - lib/ruby-next/language/rewriters/numeric_literals.rb
114
116
  - lib/ruby-next/language/rewriters/pattern_matching.rb
115
- - lib/ruby-next/language/rewriters/right_hand_assignment.rb
117
+ - lib/ruby-next/language/rewriters/required_kwargs.rb
116
118
  - lib/ruby-next/language/rewriters/runtime.rb
117
119
  - lib/ruby-next/language/rewriters/runtime/dir.rb
118
120
  - lib/ruby-next/language/rewriters/safe_navigation.rb
@@ -136,7 +138,7 @@ metadata:
136
138
  documentation_uri: http://github.com/ruby-next/ruby-next/blob/master/README.md
137
139
  homepage_uri: http://github.com/ruby-next/ruby-next
138
140
  source_code_uri: http://github.com/ruby-next/ruby-next
139
- post_install_message:
141
+ post_install_message:
140
142
  rdoc_options: []
141
143
  require_paths:
142
144
  - lib
@@ -151,8 +153,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
151
153
  - !ruby/object:Gem::Version
152
154
  version: '0'
153
155
  requirements: []
154
- rubygems_version: 3.0.6
155
- signing_key:
156
+ rubygems_version: 3.2.15
157
+ signing_key:
156
158
  specification_version: 4
157
159
  summary: Ruby Next core functionality
158
160
  test_files: []
@@ -1,117 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RubyNext
4
- module Language
5
- module Rewriters
6
- class RightHandAssignment < Base
7
- NAME = "right-hand-assignment"
8
- SYNTAX_PROBE = "1 + 2 => a"
9
- MIN_SUPPORTED_VERSION = Gem::Version.new("3.0.0")
10
-
11
- def on_rasgn(node)
12
- context.track! self
13
-
14
- node = super(node)
15
-
16
- val_node, asgn_node = *node
17
-
18
- remove(val_node.loc.expression.end.join(asgn_node.loc.expression))
19
- insert_before(val_node.loc.expression, "#{asgn_node.loc.expression.source} = ")
20
-
21
- asgn_node.updated(
22
- nil,
23
- asgn_node.children + [val_node]
24
- )
25
- end
26
-
27
- def on_vasgn(node)
28
- return super(node) unless rightward?(node)
29
-
30
- context.track! self
31
-
32
- name, val_node = *node
33
-
34
- remove(val_node.loc.expression.end.join(node.loc.name))
35
- insert_before(val_node.loc.expression, "#{name} = ")
36
-
37
- super(node)
38
- end
39
-
40
- def on_casgn(node)
41
- return super(node) unless rightward?(node)
42
-
43
- context.track! self
44
-
45
- scope_node, name, val_node = *node
46
-
47
- if scope_node
48
- scope = scope_node.type == :cbase ? scope_node.loc.expression.source : "#{scope_node.loc.expression.source}::"
49
- name = "#{scope}#{name}"
50
- end
51
-
52
- remove(val_node.loc.expression.end.join(node.loc.name))
53
- insert_before(val_node.loc.expression, "#{name} = ")
54
-
55
- super(node)
56
- end
57
-
58
- def on_mrasgn(node)
59
- context.track! self
60
-
61
- node = super(node)
62
-
63
- lhs, rhs = *node
64
-
65
- replace(lhs.loc.expression.end.join(rhs.loc.expression), ")")
66
- insert_before(lhs.loc.expression, "#{rhs.loc.expression.source} = (")
67
-
68
- node.updated(
69
- :masgn,
70
- [rhs, lhs]
71
- )
72
- end
73
-
74
- def on_masgn(node)
75
- return super(node) unless rightward?(node)
76
-
77
- context.track! self
78
-
79
- rhs, lhs = *node
80
-
81
- replace(lhs.loc.expression.end.join(rhs.loc.expression), ")")
82
- insert_before(lhs.loc.expression, "#{rhs.loc.expression.source} = (")
83
-
84
- node = super(node)
85
-
86
- lhs, rhs = *node
87
-
88
- node.updated(
89
- nil,
90
- [
91
- lhs,
92
- s(:begin, rhs)
93
- ]
94
- )
95
- end
96
-
97
- private
98
-
99
- def rightward?(node)
100
- # Location could be empty for node built by rewriters
101
- return false unless ((!node.loc.nil? || nil) && node.loc.operator)
102
-
103
- assignee_loc =
104
- if node.type == :masgn
105
- node.children[0].loc.expression
106
- else
107
- node.loc.name
108
- end
109
-
110
- return false unless assignee_loc
111
-
112
- assignee_loc.begin_pos > node.loc.operator.end_pos
113
- end
114
- end
115
- end
116
- end
117
- end
@@ -1,117 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RubyNext
4
- module Language
5
- module Rewriters
6
- class RightHandAssignment < Base
7
- NAME = "right-hand-assignment"
8
- SYNTAX_PROBE = "1 + 2 => a"
9
- MIN_SUPPORTED_VERSION = Gem::Version.new("3.0.0")
10
-
11
- def on_rasgn(node)
12
- context.track! self
13
-
14
- node = super(node)
15
-
16
- val_node, asgn_node = *node
17
-
18
- remove(val_node.loc.expression.end.join(asgn_node.loc.expression))
19
- insert_before(val_node.loc.expression, "#{asgn_node.loc.expression.source} = ")
20
-
21
- asgn_node.updated(
22
- nil,
23
- asgn_node.children + [val_node]
24
- )
25
- end
26
-
27
- def on_vasgn(node)
28
- return super(node) unless rightward?(node)
29
-
30
- context.track! self
31
-
32
- name, val_node = *node
33
-
34
- remove(val_node.loc.expression.end.join(node.loc.name))
35
- insert_before(val_node.loc.expression, "#{name} = ")
36
-
37
- super(node)
38
- end
39
-
40
- def on_casgn(node)
41
- return super(node) unless rightward?(node)
42
-
43
- context.track! self
44
-
45
- scope_node, name, val_node = *node
46
-
47
- if scope_node
48
- scope = scope_node.type == :cbase ? scope_node.loc.expression.source : "#{scope_node.loc.expression.source}::"
49
- name = "#{scope}#{name}"
50
- end
51
-
52
- remove(val_node.loc.expression.end.join(node.loc.name))
53
- insert_before(val_node.loc.expression, "#{name} = ")
54
-
55
- super(node)
56
- end
57
-
58
- def on_mrasgn(node)
59
- context.track! self
60
-
61
- node = super(node)
62
-
63
- lhs, rhs = *node
64
-
65
- replace(lhs.loc.expression.end.join(rhs.loc.expression), ")")
66
- insert_before(lhs.loc.expression, "#{rhs.loc.expression.source} = (")
67
-
68
- node.updated(
69
- :masgn,
70
- [rhs, lhs]
71
- )
72
- end
73
-
74
- def on_masgn(node)
75
- return super(node) unless rightward?(node)
76
-
77
- context.track! self
78
-
79
- rhs, lhs = *node
80
-
81
- replace(lhs.loc.expression.end.join(rhs.loc.expression), ")")
82
- insert_before(lhs.loc.expression, "#{rhs.loc.expression.source} = (")
83
-
84
- node = super(node)
85
-
86
- lhs, rhs = *node
87
-
88
- node.updated(
89
- nil,
90
- [
91
- lhs,
92
- s(:begin, rhs)
93
- ]
94
- )
95
- end
96
-
97
- private
98
-
99
- def rightward?(node)
100
- # Location could be empty for node built by rewriters
101
- return false unless node.loc&.operator
102
-
103
- assignee_loc =
104
- if node.type == :masgn
105
- node.children[0].loc.expression
106
- else
107
- node.loc.name
108
- end
109
-
110
- return false unless assignee_loc
111
-
112
- assignee_loc.begin_pos > node.loc.operator.end_pos
113
- end
114
- end
115
- end
116
- end
117
- end