unparser 0.5.5 → 0.6.1

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -2
  3. data/lib/unparser/abstract_type.rb +121 -0
  4. data/lib/unparser/adamantium/method_builder.rb +111 -0
  5. data/lib/unparser/adamantium.rb +150 -0
  6. data/lib/unparser/anima/attribute.rb +59 -0
  7. data/lib/unparser/anima/error.rb +23 -0
  8. data/lib/unparser/anima.rb +184 -0
  9. data/lib/unparser/ast.rb +1 -2
  10. data/lib/unparser/buffer.rb +2 -2
  11. data/lib/unparser/cli.rb +1 -0
  12. data/lib/unparser/color.rb +1 -1
  13. data/lib/unparser/concord.rb +114 -0
  14. data/lib/unparser/diff.rb +1 -1
  15. data/lib/unparser/either.rb +153 -0
  16. data/lib/unparser/emitter/flow_modifier.rb +6 -0
  17. data/lib/unparser/emitter/hash.rb +1 -31
  18. data/lib/unparser/emitter/hash_pattern.rb +1 -1
  19. data/lib/unparser/emitter/index.rb +1 -1
  20. data/lib/unparser/emitter/kwargs.rb +13 -0
  21. data/lib/unparser/emitter/match_pattern.rb +22 -0
  22. data/lib/unparser/emitter/op_assign.rb +2 -2
  23. data/lib/unparser/emitter/pair.rb +33 -0
  24. data/lib/unparser/emitter/primitive.rb +2 -2
  25. data/lib/unparser/emitter/simple.rb +2 -2
  26. data/lib/unparser/emitter.rb +1 -1
  27. data/lib/unparser/equalizer.rb +98 -0
  28. data/lib/unparser/node_details/send.rb +5 -2
  29. data/lib/unparser/node_details.rb +1 -1
  30. data/lib/unparser/node_helpers.rb +3 -1
  31. data/lib/unparser/validation.rb +3 -3
  32. data/lib/unparser/writer/binary.rb +1 -1
  33. data/lib/unparser/writer/dynamic_string.rb +12 -22
  34. data/lib/unparser/writer/rescue.rb +1 -1
  35. data/lib/unparser/writer/send/unary.rb +1 -1
  36. data/lib/unparser/writer/send.rb +9 -18
  37. data/lib/unparser.rb +34 -24
  38. metadata +30 -113
@@ -3,7 +3,7 @@
3
3
  module Unparser
4
4
  module Writer
5
5
  class Binary
6
- include Writer, Adamantium::Flat
6
+ include Writer, Adamantium
7
7
 
8
8
  children :left, :right
9
9
 
@@ -3,22 +3,20 @@
3
3
  module Unparser
4
4
  module Writer
5
5
  class DynamicString
6
- include Writer, Adamantium::Flat
6
+ include Writer, Adamantium
7
7
 
8
- PATTERNS_2 = IceNine.deep_freeze(
8
+ PATTERNS_2 =
9
9
  [
10
- %i[str_empty begin],
11
- %i[begin str_nl]
12
- ]
13
- )
10
+ %i[str_empty begin].freeze,
11
+ %i[begin str_nl].freeze
12
+ ].freeze
14
13
 
15
- PATTERNS_3 = IceNine.deep_freeze(
14
+ PATTERNS_3 =
16
15
  [
17
- %i[begin str_nl_eol str_nl_eol],
18
- %i[str_nl_eol begin str_nl_eol],
19
- %i[str_ws begin str_nl_eol]
20
- ]
21
- )
16
+ %i[begin str_nl_eol str_nl_eol].freeze,
17
+ %i[str_nl_eol begin str_nl_eol].freeze,
18
+ %i[str_ws begin str_nl_eol].freeze
19
+ ].freeze
22
20
 
23
21
  FLAT_INTERPOLATION = %i[ivar cvar gvar nth_ref].to_set.freeze
24
22
 
@@ -42,7 +40,7 @@ module Unparser
42
40
  private
43
41
 
44
42
  def heredoc_header
45
- need_squiggly? ? '<<~HEREDOC' : '<<-HEREDOC'
43
+ '<<-HEREDOC'
46
44
  end
47
45
 
48
46
  def heredoc?
@@ -55,11 +53,7 @@ module Unparser
55
53
 
56
54
  def emit_heredoc_body
57
55
  nl
58
- if need_squiggly?
59
- emit_squiggly_heredoc_body
60
- else
61
- emit_normal_heredoc_body
62
- end
56
+ emit_normal_heredoc_body
63
57
  end
64
58
 
65
59
  def emit_heredoc_footer
@@ -119,10 +113,6 @@ module Unparser
119
113
  n_str?(last) && last.children.first[-1].eql?("\n")
120
114
  end
121
115
 
122
- def need_squiggly?
123
- children.any?(s(:str, ''))
124
- end
125
-
126
116
  def emit_squiggly_heredoc_body
127
117
  buffer.indent
128
118
  children.each do |child|
@@ -3,7 +3,7 @@
3
3
  module Unparser
4
4
  module Writer
5
5
  class Rescue
6
- include Writer, Adamantium::Flat
6
+ include Writer, Adamantium
7
7
 
8
8
  children :body, :rescue_body
9
9
 
@@ -17,7 +17,7 @@ module Unparser
17
17
 
18
18
  write(MAP.fetch(name, name).to_s)
19
19
 
20
- if n_int?(receiver) && selector.equal?(:'+@')
20
+ if n_int?(receiver) && selector.equal?(:+@)
21
21
  write('+')
22
22
  end
23
23
 
@@ -4,10 +4,10 @@ module Unparser
4
4
  module Writer
5
5
  # Writer for send
6
6
  class Send
7
- include Writer, Adamantium::Flat, Constants, Generation
7
+ include Writer, Adamantium, Constants, Generation
8
8
 
9
- INDEX_ASSIGN = :'[]='
10
- INDEX_REFERENCE = :'[]'
9
+ INDEX_ASSIGN = :[]=
10
+ INDEX_REFERENCE = :[]
11
11
 
12
12
  OPERATORS = {
13
13
  csend: '&.',
@@ -75,20 +75,7 @@ module Unparser
75
75
  end
76
76
 
77
77
  def emit_normal_arguments
78
- parentheses do
79
- arguments.each_with_index do |node, index|
80
- write(', ') unless index.zero?
81
- emit_argument(node, index.succ.equal?(arguments.length))
82
- end
83
- end
84
- end
85
-
86
- def emit_argument(argument, last)
87
- if n_hash?(argument) && last
88
- writer_with(Emitter::Hash, argument).emit_last_argument_hash
89
- else
90
- visit(argument)
91
- end
78
+ parentheses { delimited(arguments) }
92
79
  end
93
80
 
94
81
  def emit_heredoc_reminder(argument)
@@ -104,7 +91,11 @@ module Unparser
104
91
  end
105
92
 
106
93
  def parses_as_constant?
107
- n_const?(Unparser.parse(selector.to_s))
94
+ test = Unparser.parse_either(selector.to_s).from_right do
95
+ fail InvalidNodeError.new("Invalid selector for send node: #{selector.inspect}", node)
96
+ end
97
+
98
+ n_const?(test)
108
99
  end
109
100
 
110
101
  def details
data/lib/unparser.rb CHANGED
@@ -1,16 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'abstract_type'
4
- require 'anima'
5
- require 'concord'
6
3
  require 'diff/lcs'
7
4
  require 'diff/lcs/hunk'
8
- require 'mprelude'
9
5
  require 'optparse'
10
6
  require 'parser/current'
11
- require 'procto'
12
7
  require 'set'
13
8
 
9
+ require 'unparser/equalizer'
10
+ require 'unparser/adamantium'
11
+ require 'unparser/adamantium/method_builder'
12
+ require 'unparser/abstract_type'
13
+
14
+ require 'unparser/concord'
15
+ require 'unparser/either'
16
+ require 'unparser/anima'
17
+ require 'unparser/anima/attribute'
18
+ require 'unparser/anima/error'
19
+
14
20
  # Library namespace
15
21
  module Unparser
16
22
  # Unparser specific AST builder defaulting to modern AST format
@@ -27,7 +33,18 @@ module Unparser
27
33
  EMPTY_STRING = ''.freeze
28
34
  EMPTY_ARRAY = [].freeze
29
35
 
30
- private_constant(*constants(false))
36
+ private_constant(*constants(false) - %i[Adamantium AbstractType Anima Concord Either Equalizer Memoizable])
37
+
38
+ # Error raised when unparser encounters an invalid AST
39
+ class InvalidNodeError < RuntimeError
40
+ attr_reader :node
41
+
42
+ def initialize(message, node)
43
+ super(message)
44
+ @node = node
45
+ freeze
46
+ end
47
+ end
31
48
 
32
49
  # Unparse an AST (and, optionally, comments) into a string
33
50
  #
@@ -36,8 +53,10 @@ module Unparser
36
53
  #
37
54
  # @return [String]
38
55
  #
39
- # @api private
56
+ # @raise InvalidNodeError
57
+ # if the node passed is invalid
40
58
  #
59
+ # @api public
41
60
  def self.unparse(node, comment_array = [])
42
61
  return '' if node.nil?
43
62
 
@@ -61,9 +80,9 @@ module Unparser
61
80
  validation = Validation.from_string(generated)
62
81
 
63
82
  if validation.success?
64
- MPrelude::Either::Right.new(generated)
83
+ Either::Right.new(generated)
65
84
  else
66
- MPrelude::Either::Left.new(validation)
85
+ Either::Left.new(validation)
67
86
  end
68
87
  end
69
88
 
@@ -75,8 +94,7 @@ module Unparser
75
94
  #
76
95
  # @return [Either<Exception, String>]
77
96
  def self.unparse_either(node)
78
- MPrelude::Either
79
- .wrap_error(Exception) { unparse(node) }
97
+ Either.wrap_error(Exception) { unparse(node) }
80
98
  end
81
99
 
82
100
  # Parse string into AST
@@ -92,9 +110,9 @@ module Unparser
92
110
  #
93
111
  # @param [String] source
94
112
  #
95
- # @return [MPrelude::Either<Parser::SyntaxError, (Parser::ASTNode, nil)>]
113
+ # @return [Either<Parser::SyntaxError, (Parser::ASTNode, nil)>]
96
114
  def self.parse_either(source)
97
- MPrelude::Either.wrap_error(Parser::SyntaxError) do
115
+ Either.wrap_error(Parser::SyntaxError) do
98
116
  parser.parse(buffer(source))
99
117
  end
100
118
  end
@@ -117,21 +135,10 @@ module Unparser
117
135
  Parser::CurrentRuby.new(Builder.new).tap do |parser|
118
136
  parser.diagnostics.tap do |diagnostics|
119
137
  diagnostics.all_errors_are_fatal = true
120
- diagnostics.consumer = method(:consume_diagnostic)
121
138
  end
122
139
  end
123
140
  end
124
141
 
125
- # Consume diagnostic
126
- #
127
- # @param [Parser::Diagnostic] diagnostic
128
- #
129
- # @return [undefined]
130
- def self.consume_diagnostic(diagnostic)
131
- Kernel.warn(diagnostic.render)
132
- end
133
- private_class_method :consume_diagnostic
134
-
135
142
  # Construct a parser buffer from string
136
143
  #
137
144
  # @param [String] source
@@ -209,6 +216,9 @@ require 'unparser/emitter/undef'
209
216
  require 'unparser/emitter/variable'
210
217
  require 'unparser/emitter/xstr'
211
218
  require 'unparser/emitter/yield'
219
+ require 'unparser/emitter/kwargs'
220
+ require 'unparser/emitter/pair'
221
+ require 'unparser/emitter/match_pattern'
212
222
  require 'unparser/writer'
213
223
  require 'unparser/writer/binary'
214
224
  require 'unparser/writer/dynamic_string'
metadata CHANGED
@@ -1,71 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unparser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-24 00:00:00.000000000 Z
11
+ date: 2021-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: abstract_type
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: 0.0.7
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: 0.0.7
27
- - !ruby/object:Gem::Dependency
28
- name: adamantium
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: 0.2.0
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: 0.2.0
41
- - !ruby/object:Gem::Dependency
42
- name: anima
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: 0.3.1
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: 0.3.1
55
- - !ruby/object:Gem::Dependency
56
- name: concord
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 0.1.5
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 0.1.5
69
13
  - !ruby/object:Gem::Dependency
70
14
  name: diff-lcs
71
15
  requirement: !ruby/object:Gem::Requirement
@@ -80,90 +24,48 @@ dependencies:
80
24
  - - "~>"
81
25
  - !ruby/object:Gem::Version
82
26
  version: '1.3'
83
- - !ruby/object:Gem::Dependency
84
- name: equalizer
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: 0.0.9
90
- type: :runtime
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: 0.0.9
97
- - !ruby/object:Gem::Dependency
98
- name: mprelude
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: 0.1.0
104
- type: :runtime
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: 0.1.0
111
27
  - !ruby/object:Gem::Dependency
112
28
  name: parser
113
29
  requirement: !ruby/object:Gem::Requirement
114
30
  requirements:
115
31
  - - ">="
116
32
  - !ruby/object:Gem::Version
117
- version: 2.6.5
33
+ version: 3.0.0
118
34
  type: :runtime
119
35
  prerelease: false
120
36
  version_requirements: !ruby/object:Gem::Requirement
121
37
  requirements:
122
38
  - - ">="
123
39
  - !ruby/object:Gem::Version
124
- version: 2.6.5
125
- - !ruby/object:Gem::Dependency
126
- name: procto
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: 0.0.2
132
- type: :runtime
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: 0.0.2
40
+ version: 3.0.0
139
41
  - !ruby/object:Gem::Dependency
140
42
  name: mutant
141
43
  requirement: !ruby/object:Gem::Requirement
142
44
  requirements:
143
45
  - - "~>"
144
46
  - !ruby/object:Gem::Version
145
- version: 0.10.19
47
+ version: 0.11.1
146
48
  type: :development
147
49
  prerelease: false
148
50
  version_requirements: !ruby/object:Gem::Requirement
149
51
  requirements:
150
52
  - - "~>"
151
53
  - !ruby/object:Gem::Version
152
- version: 0.10.19
54
+ version: 0.11.1
153
55
  - !ruby/object:Gem::Dependency
154
56
  name: mutant-rspec
155
57
  requirement: !ruby/object:Gem::Requirement
156
58
  requirements:
157
59
  - - "~>"
158
60
  - !ruby/object:Gem::Version
159
- version: 0.10.19
61
+ version: 0.11.1
160
62
  type: :development
161
63
  prerelease: false
162
64
  version_requirements: !ruby/object:Gem::Requirement
163
65
  requirements:
164
66
  - - "~>"
165
67
  - !ruby/object:Gem::Version
166
- version: 0.10.19
68
+ version: 0.11.1
167
69
  - !ruby/object:Gem::Dependency
168
70
  name: rspec
169
71
  requirement: !ruby/object:Gem::Requirement
@@ -212,28 +114,28 @@ dependencies:
212
114
  requirements:
213
115
  - - "~>"
214
116
  - !ruby/object:Gem::Version
215
- version: 1.6.1
117
+ version: '1.7'
216
118
  type: :development
217
119
  prerelease: false
218
120
  version_requirements: !ruby/object:Gem::Requirement
219
121
  requirements:
220
122
  - - "~>"
221
123
  - !ruby/object:Gem::Version
222
- version: 1.6.1
124
+ version: '1.7'
223
125
  - !ruby/object:Gem::Dependency
224
126
  name: rubocop-packaging
225
127
  requirement: !ruby/object:Gem::Requirement
226
128
  requirements:
227
129
  - - "~>"
228
130
  - !ruby/object:Gem::Version
229
- version: 0.5.0
131
+ version: '0.5'
230
132
  type: :development
231
133
  prerelease: false
232
134
  version_requirements: !ruby/object:Gem::Requirement
233
135
  requirements:
234
136
  - - "~>"
235
137
  - !ruby/object:Gem::Version
236
- version: 0.5.0
138
+ version: '0.5'
237
139
  description: Generate equivalent source for parser gem AST nodes
238
140
  email: mbj@schirp-dso.com
239
141
  executables:
@@ -245,15 +147,23 @@ files:
245
147
  - README.md
246
148
  - bin/unparser
247
149
  - lib/unparser.rb
150
+ - lib/unparser/abstract_type.rb
151
+ - lib/unparser/adamantium.rb
152
+ - lib/unparser/adamantium/method_builder.rb
153
+ - lib/unparser/anima.rb
154
+ - lib/unparser/anima/attribute.rb
155
+ - lib/unparser/anima/error.rb
248
156
  - lib/unparser/ast.rb
249
157
  - lib/unparser/ast/local_variable_scope.rb
250
158
  - lib/unparser/buffer.rb
251
159
  - lib/unparser/cli.rb
252
160
  - lib/unparser/color.rb
253
161
  - lib/unparser/comments.rb
162
+ - lib/unparser/concord.rb
254
163
  - lib/unparser/constants.rb
255
164
  - lib/unparser/diff.rb
256
165
  - lib/unparser/dsl.rb
166
+ - lib/unparser/either.rb
257
167
  - lib/unparser/emitter.rb
258
168
  - lib/unparser/emitter/alias.rb
259
169
  - lib/unparser/emitter/args.rb
@@ -285,17 +195,20 @@ files:
285
195
  - lib/unparser/emitter/in_match.rb
286
196
  - lib/unparser/emitter/in_pattern.rb
287
197
  - lib/unparser/emitter/index.rb
198
+ - lib/unparser/emitter/kwargs.rb
288
199
  - lib/unparser/emitter/kwbegin.rb
289
200
  - lib/unparser/emitter/lambda.rb
290
201
  - lib/unparser/emitter/masgn.rb
291
202
  - lib/unparser/emitter/match.rb
292
203
  - lib/unparser/emitter/match_alt.rb
293
204
  - lib/unparser/emitter/match_as.rb
205
+ - lib/unparser/emitter/match_pattern.rb
294
206
  - lib/unparser/emitter/match_rest.rb
295
207
  - lib/unparser/emitter/match_var.rb
296
208
  - lib/unparser/emitter/mlhs.rb
297
209
  - lib/unparser/emitter/module.rb
298
210
  - lib/unparser/emitter/op_assign.rb
211
+ - lib/unparser/emitter/pair.rb
299
212
  - lib/unparser/emitter/pin.rb
300
213
  - lib/unparser/emitter/primitive.rb
301
214
  - lib/unparser/emitter/range.rb
@@ -311,6 +224,7 @@ files:
311
224
  - lib/unparser/emitter/variable.rb
312
225
  - lib/unparser/emitter/xstr.rb
313
226
  - lib/unparser/emitter/yield.rb
227
+ - lib/unparser/equalizer.rb
314
228
  - lib/unparser/finalize.rb
315
229
  - lib/unparser/generation.rb
316
230
  - lib/unparser/node_details.rb
@@ -331,7 +245,10 @@ files:
331
245
  homepage: http://github.com/mbj/unparser
332
246
  licenses:
333
247
  - MIT
334
- metadata: {}
248
+ metadata:
249
+ bug_tracker_uri: https://github.com/mbj/unparser/issues
250
+ changelog_uri: https://github.com/mbj/unparser/blob/master/Changelog.md
251
+ funding_uri: https://github.com/sponsors/mbj
335
252
  post_install_message:
336
253
  rdoc_options: []
337
254
  require_paths:
@@ -340,14 +257,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
340
257
  requirements:
341
258
  - - ">="
342
259
  - !ruby/object:Gem::Version
343
- version: '2.5'
260
+ version: '2.6'
344
261
  required_rubygems_version: !ruby/object:Gem::Requirement
345
262
  requirements:
346
263
  - - ">="
347
264
  - !ruby/object:Gem::Version
348
265
  version: '0'
349
266
  requirements: []
350
- rubygems_version: 3.1.4
267
+ rubygems_version: 3.1.6
351
268
  signing_key:
352
269
  specification_version: 4
353
270
  summary: Generate equivalent source for parser gem AST nodes