unparser 0.4.4 → 0.4.9

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -3
  3. data/lib/unparser.rb +21 -3
  4. data/lib/unparser/ast.rb +1 -1
  5. data/lib/unparser/ast/local_variable_scope.rb +6 -6
  6. data/lib/unparser/cli.rb +65 -45
  7. data/lib/unparser/{cli/color.rb → color.rb} +0 -10
  8. data/lib/unparser/constants.rb +1 -1
  9. data/lib/unparser/diff.rb +115 -0
  10. data/lib/unparser/dsl.rb +1 -1
  11. data/lib/unparser/emitter.rb +4 -5
  12. data/lib/unparser/emitter/argument.rb +9 -13
  13. data/lib/unparser/emitter/literal/primitive.rb +1 -1
  14. data/lib/unparser/emitter/literal/range.rb +1 -1
  15. data/lib/unparser/node_helpers.rb +4 -2
  16. data/lib/unparser/preprocessor.rb +1 -1
  17. data/lib/unparser/validation.rb +149 -0
  18. metadata +97 -78
  19. data/.circleci/config.yml +0 -41
  20. data/.gitignore +0 -37
  21. data/.rspec +0 -4
  22. data/.rubocop.yml +0 -9
  23. data/Changelog.md +0 -142
  24. data/Gemfile +0 -7
  25. data/Gemfile.lock +0 -176
  26. data/LICENSE +0 -20
  27. data/Rakefile +0 -22
  28. data/config/devtools.yml +0 -2
  29. data/config/flay.yml +0 -3
  30. data/config/flog.yml +0 -2
  31. data/config/mutant.yml +0 -6
  32. data/config/reek.yml +0 -98
  33. data/config/rubocop.yml +0 -122
  34. data/config/yardstick.yml +0 -2
  35. data/lib/unparser/cli/differ.rb +0 -152
  36. data/lib/unparser/cli/source.rb +0 -267
  37. data/spec/integration/unparser/corpus_spec.rb +0 -111
  38. data/spec/integrations.yml +0 -87
  39. data/spec/spec_helper.rb +0 -20
  40. data/spec/unit/unparser/buffer/append_spec.rb +0 -24
  41. data/spec/unit/unparser/buffer/append_without_prefix_spec.rb +0 -23
  42. data/spec/unit/unparser/buffer/capture_content_spec.rb +0 -17
  43. data/spec/unit/unparser/buffer/content_spec.rb +0 -38
  44. data/spec/unit/unparser/buffer/fresh_line_spec.rb +0 -20
  45. data/spec/unit/unparser/buffer/indent_spec.rb +0 -20
  46. data/spec/unit/unparser/buffer/nl_spec.rb +0 -16
  47. data/spec/unit/unparser/buffer/unindent_spec.rb +0 -20
  48. data/spec/unit/unparser/comments/consume_spec.rb +0 -22
  49. data/spec/unit/unparser/comments/take_all_spec.rb +0 -19
  50. data/spec/unit/unparser/comments/take_before_spec.rb +0 -46
  51. data/spec/unit/unparser/comments/take_eol_comments_spec.rb +0 -32
  52. data/spec/unit/unparser/emitter/class_methods/handle_spec.rb +0 -17
  53. data/spec/unit/unparser_spec.rb +0 -1841
  54. data/unparser.gemspec +0 -30
@@ -45,7 +45,7 @@ module Unparser
45
45
  #
46
46
  # @return [undefined]
47
47
  #
48
- # @pai private
48
+ # @api private
49
49
  #
50
50
  def define_group(name, range)
51
51
  define_method(name) do
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Unparser
4
+ UnknownNodeError = Class.new(ArgumentError)
4
5
 
5
6
  # Emitter base class
6
7
  #
@@ -79,7 +80,7 @@ module Unparser
79
80
 
80
81
  # Register emitter for type
81
82
  #
82
- # @param [Symbol] type
83
+ # @param [Symbol] types
83
84
  #
84
85
  # @return [undefined]
85
86
  #
@@ -116,7 +117,7 @@ module Unparser
116
117
  def self.emitter(node, parent)
117
118
  type = node.type
118
119
  klass = REGISTRY.fetch(type) do
119
- raise ArgumentError, "No emitter for node: #{type.inspect}"
120
+ raise UnknownNodeError, "Unknown node type: #{type.inspect}"
120
121
  end
121
122
  klass.new(node, parent)
122
123
  end
@@ -249,7 +250,6 @@ module Unparser
249
250
  # Emit delimited body
250
251
  #
251
252
  # @param [Enumerable<Parser::AST::Node>] nodes
252
- # @param [String] delimiter
253
253
  #
254
254
  # @return [undefined]
255
255
  #
@@ -262,7 +262,6 @@ module Unparser
262
262
  # Emit delimited body
263
263
  #
264
264
  # @param [Enumerable<Parser::AST::Node>] nodes
265
- # @param [String] delimiter
266
265
  #
267
266
  # @return [undefined]
268
267
  #
@@ -432,7 +431,7 @@ module Unparser
432
431
 
433
432
  # Emit non nil body
434
433
  #
435
- # @param [Parser::AST::Node] node
434
+ # @param [Parser::AST::Node] body
436
435
  #
437
436
  # @return [undefined]
438
437
  #
@@ -240,7 +240,7 @@ module Unparser
240
240
 
241
241
  handle :procarg0
242
242
 
243
- children :first_argument
243
+ PARENS = %i[restarg mlhs].freeze
244
244
 
245
245
  private
246
246
 
@@ -251,22 +251,18 @@ module Unparser
251
251
  # @api private
252
252
  #
253
253
  def dispatch
254
- if first_argument.instance_of?(Symbol)
255
- write(first_argument.to_s)
254
+ if needs_parens?
255
+ parentheses do
256
+ delimited(children)
257
+ end
256
258
  else
257
- emit_multiple_children
259
+ delimited(children)
258
260
  end
259
261
  end
260
262
 
261
- # Emit multiple children
262
- #
263
- # @return [undefined]
264
- #
265
- # @api private
266
- #
267
- def emit_multiple_children
268
- parentheses do
269
- delimited(children)
263
+ def needs_parens?
264
+ children.length > 1 || children.any? do |node|
265
+ PARENS.include?(node.type)
270
266
  end
271
267
  end
272
268
  end
@@ -107,7 +107,7 @@ module Unparser
107
107
 
108
108
  # Write rational format
109
109
  #
110
- # @param [#to_s]
110
+ # @param [#to_s] value
111
111
  #
112
112
  # @return [undefined]
113
113
  #
@@ -27,7 +27,7 @@ module Unparser
27
27
  def dispatch
28
28
  visit(begin_node)
29
29
  write(TOKENS.fetch(node.type))
30
- visit(end_node)
30
+ visit(end_node) if end_node
31
31
  end
32
32
 
33
33
  end # Range
@@ -5,7 +5,8 @@ module Unparser
5
5
 
6
6
  # Helper for building nodes
7
7
  #
8
- # @param [Symbol]
8
+ # @param [Symbol] type
9
+ # @param [Parser::AST::Node] children
9
10
  #
10
11
  # @return [Parser::AST::Node]
11
12
  #
@@ -19,9 +20,10 @@ module Unparser
19
20
 
20
21
  # Helper for building nodes
21
22
  #
22
- # @param [Symbol]
23
+ # @param [Symbol] type
23
24
  #
24
25
  # @return [Parser::AST::Node]
26
+ # @param [Array] children
25
27
  #
26
28
  # @api private
27
29
  #
@@ -114,7 +114,7 @@ module Unparser
114
114
 
115
115
  # Return preprocessor result
116
116
  #
117
- # @param [Parser::AST::Node]
117
+ # @return [Parser::AST::Node]
118
118
  #
119
119
  # @api private
120
120
  #
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ # Validation of unparser results
5
+ #
6
+ # ignore :reek:TooManyMethods
7
+ class Validation
8
+ include Adamantium::Flat, Anima.new(
9
+ :generated_node,
10
+ :generated_source,
11
+ :identification,
12
+ :original_node,
13
+ :original_source
14
+ )
15
+
16
+ # Test if source could be unparsed successfully
17
+ #
18
+ # @return [Boolean]
19
+ #
20
+ # @api private
21
+ #
22
+ def success?
23
+ [
24
+ original_source,
25
+ original_node,
26
+ generated_source,
27
+ generated_node
28
+ ].all?(&:right?) && generated_node.from_right.eql?(original_node.from_right)
29
+ end
30
+
31
+ # Return error report
32
+ #
33
+ # @return [String]
34
+ #
35
+ # @api private
36
+ #
37
+ def report
38
+ message = [identification]
39
+
40
+ message.concat(make_report('Original-Source', :original_source))
41
+ message.concat(make_report('Generated-Source', :generated_source))
42
+ message.concat(make_report('Original-Node', :original_node))
43
+ message.concat(make_report('Generated-Node', :generated_node))
44
+ message.concat(node_diff_report)
45
+
46
+ message.join("\n")
47
+ end
48
+ memoize :report
49
+
50
+ # Create validator from string
51
+ #
52
+ # @param [String] original_source
53
+ #
54
+ # @return [Validator]
55
+ def self.from_string(original_source)
56
+ original_node = Unparser
57
+ .parse_either(original_source)
58
+ .fmap(&Preprocessor.method(:run))
59
+
60
+ generated_source = original_node
61
+ .lmap(&method(:const_unit))
62
+ .bind(&method(:unparse_either))
63
+
64
+ generated_node = generated_source
65
+ .lmap(&method(:const_unit))
66
+ .bind(&Unparser.method(:parse_either))
67
+ .fmap(&Preprocessor.method(:run))
68
+
69
+ new(
70
+ identification: '(string)',
71
+ original_source: MPrelude::Either::Right.new(original_source),
72
+ original_node: original_node,
73
+ generated_source: generated_source,
74
+ generated_node: generated_node
75
+ )
76
+ end
77
+
78
+ # Create validator from file
79
+ #
80
+ # @param [Pathname] path
81
+ #
82
+ # @return [Validator]
83
+ def self.from_path(path)
84
+ from_string(path.read).with(identification: path.to_s)
85
+ end
86
+
87
+ private
88
+
89
+ # Create a labeled report from
90
+ #
91
+ # @param [String] label
92
+ # @param [Symbol] attribute_name
93
+ #
94
+ # @return [Array<String>]
95
+ def make_report(label, attribute_name)
96
+ ["#{label}:"].concat(public_send(attribute_name).either(method(:report_exception), ->(value) { [value] }))
97
+ end
98
+
99
+ # Report optional exception
100
+ #
101
+ # @param [Exception, nil] exception
102
+ #
103
+ # @return [Array<String>]
104
+ def report_exception(exception)
105
+ if exception
106
+ [exception.inspect].concat(exception.backtrace.take(20))
107
+ else
108
+ ['undefined']
109
+ end
110
+ end
111
+
112
+ # Report the node diff
113
+ #
114
+ # @return [Array<String>]
115
+ def node_diff_report
116
+ diff = nil
117
+
118
+ original_node.fmap do |original|
119
+ generated_node.fmap do |generated|
120
+ diff = Diff.new(
121
+ original.to_s.lines.map(&:chomp),
122
+ generated.to_s.lines.map(&:chomp)
123
+ ).colorized_diff
124
+ end
125
+ end
126
+
127
+ diff ? ['Node-Diff:', diff] : []
128
+ end
129
+
130
+ # Create unit represented as nil
131
+ #
132
+ # @param [Object] _value
133
+ #
134
+ # @return [nil]
135
+ def self.const_unit(_value); end
136
+ private_class_method :const_unit
137
+
138
+ # Unparse capturing errors
139
+ #
140
+ # @param [Parser::AST::Node] node
141
+ #
142
+ # @return [Either<RuntimeError, String>]
143
+ def self.unparse_either(node)
144
+ MPrelude::Either
145
+ .wrap_error(RuntimeError) { Unparser.unparse(node) }
146
+ end
147
+ private_class_method :unparse_either
148
+ end # Validation
149
+ end # Unparser
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unparser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-27 00:00:00.000000000 Z
11
+ date: 2020-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: abstract_type
@@ -39,19 +39,33 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.2.0
41
41
  - !ruby/object:Gem::Dependency
42
- name: equalizer
42
+ name: anima
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.0.9
47
+ version: 0.3.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.0.9
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
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: diff-lcs
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -67,33 +81,47 @@ dependencies:
67
81
  - !ruby/object:Gem::Version
68
82
  version: '1.3'
69
83
  - !ruby/object:Gem::Dependency
70
- name: concord
84
+ name: equalizer
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: 0.1.5
89
+ version: 0.0.9
76
90
  type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: 0.1.5
96
+ version: 0.0.9
83
97
  - !ruby/object:Gem::Dependency
84
- name: parser
98
+ name: mprelude
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: 2.6.2
103
+ version: 0.1.0
90
104
  type: :runtime
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: 2.6.2
110
+ version: 0.1.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: parser
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: 2.6.5
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: 2.6.5
97
125
  - !ruby/object:Gem::Dependency
98
126
  name: procto
99
127
  requirement: !ruby/object:Gem::Requirement
@@ -109,47 +137,89 @@ dependencies:
109
137
  - !ruby/object:Gem::Version
110
138
  version: 0.0.2
111
139
  - !ruby/object:Gem::Dependency
112
- name: anima
140
+ name: mutant
113
141
  requirement: !ruby/object:Gem::Requirement
114
142
  requirements:
115
143
  - - "~>"
116
144
  - !ruby/object:Gem::Version
117
- version: 0.3.1
145
+ version: 0.9.9
118
146
  type: :development
119
147
  prerelease: false
120
148
  version_requirements: !ruby/object:Gem::Requirement
121
149
  requirements:
122
150
  - - "~>"
123
151
  - !ruby/object:Gem::Version
124
- version: 0.3.1
152
+ version: 0.9.9
153
+ - !ruby/object:Gem::Dependency
154
+ name: mutant-rspec
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 0.9.9
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 0.9.9
167
+ - !ruby/object:Gem::Dependency
168
+ name: rspec
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '3.9'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '3.9'
181
+ - !ruby/object:Gem::Dependency
182
+ name: rspec-core
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '3.9'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '3.9'
125
195
  - !ruby/object:Gem::Dependency
126
- name: devtools
196
+ name: rspec-its
127
197
  requirement: !ruby/object:Gem::Requirement
128
198
  requirements:
129
199
  - - "~>"
130
200
  - !ruby/object:Gem::Version
131
- version: 0.1.23
201
+ version: 1.2.0
132
202
  type: :development
133
203
  prerelease: false
134
204
  version_requirements: !ruby/object:Gem::Requirement
135
205
  requirements:
136
206
  - - "~>"
137
207
  - !ruby/object:Gem::Version
138
- version: 0.1.23
208
+ version: 1.2.0
139
209
  - !ruby/object:Gem::Dependency
140
- name: morpher
210
+ name: rubocop
141
211
  requirement: !ruby/object:Gem::Requirement
142
212
  requirements:
143
213
  - - "~>"
144
214
  - !ruby/object:Gem::Version
145
- version: 0.2.6
215
+ version: 0.79.0
146
216
  type: :development
147
217
  prerelease: false
148
218
  version_requirements: !ruby/object:Gem::Requirement
149
219
  requirements:
150
220
  - - "~>"
151
221
  - !ruby/object:Gem::Version
152
- version: 0.2.6
222
+ version: 0.79.0
153
223
  description: Generate equivalent source for parser gem AST nodes
154
224
  email: mbj@schirp-dso.com
155
225
  executables:
@@ -158,34 +228,17 @@ extensions: []
158
228
  extra_rdoc_files:
159
229
  - README.md
160
230
  files:
161
- - ".circleci/config.yml"
162
- - ".gitignore"
163
- - ".rspec"
164
- - ".rubocop.yml"
165
- - Changelog.md
166
- - Gemfile
167
- - Gemfile.lock
168
- - LICENSE
169
231
  - README.md
170
- - Rakefile
171
232
  - bin/unparser
172
- - config/devtools.yml
173
- - config/flay.yml
174
- - config/flog.yml
175
- - config/mutant.yml
176
- - config/reek.yml
177
- - config/rubocop.yml
178
- - config/yardstick.yml
179
233
  - lib/unparser.rb
180
234
  - lib/unparser/ast.rb
181
235
  - lib/unparser/ast/local_variable_scope.rb
182
236
  - lib/unparser/buffer.rb
183
237
  - lib/unparser/cli.rb
184
- - lib/unparser/cli/color.rb
185
- - lib/unparser/cli/differ.rb
186
- - lib/unparser/cli/source.rb
238
+ - lib/unparser/color.rb
187
239
  - lib/unparser/comments.rb
188
240
  - lib/unparser/constants.rb
241
+ - lib/unparser/diff.rb
189
242
  - lib/unparser/dsl.rb
190
243
  - lib/unparser/emitter.rb
191
244
  - lib/unparser/emitter/alias.rb
@@ -242,29 +295,12 @@ files:
242
295
  - lib/unparser/finalize.rb
243
296
  - lib/unparser/node_helpers.rb
244
297
  - lib/unparser/preprocessor.rb
245
- - spec/integration/unparser/corpus_spec.rb
246
- - spec/integrations.yml
247
- - spec/spec_helper.rb
248
- - spec/unit/unparser/buffer/append_spec.rb
249
- - spec/unit/unparser/buffer/append_without_prefix_spec.rb
250
- - spec/unit/unparser/buffer/capture_content_spec.rb
251
- - spec/unit/unparser/buffer/content_spec.rb
252
- - spec/unit/unparser/buffer/fresh_line_spec.rb
253
- - spec/unit/unparser/buffer/indent_spec.rb
254
- - spec/unit/unparser/buffer/nl_spec.rb
255
- - spec/unit/unparser/buffer/unindent_spec.rb
256
- - spec/unit/unparser/comments/consume_spec.rb
257
- - spec/unit/unparser/comments/take_all_spec.rb
258
- - spec/unit/unparser/comments/take_before_spec.rb
259
- - spec/unit/unparser/comments/take_eol_comments_spec.rb
260
- - spec/unit/unparser/emitter/class_methods/handle_spec.rb
261
- - spec/unit/unparser_spec.rb
262
- - unparser.gemspec
298
+ - lib/unparser/validation.rb
263
299
  homepage: http://github.com/mbj/unparser
264
300
  licenses:
265
301
  - MIT
266
302
  metadata: {}
267
- post_install_message:
303
+ post_install_message:
268
304
  rdoc_options: []
269
305
  require_paths:
270
306
  - lib
@@ -280,24 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
280
316
  version: '0'
281
317
  requirements: []
282
318
  rubygems_version: 3.0.3
283
- signing_key:
319
+ signing_key:
284
320
  specification_version: 4
285
321
  summary: Generate equivalent source for parser gem AST nodes
286
- test_files:
287
- - spec/integration/unparser/corpus_spec.rb
288
- - spec/integrations.yml
289
- - spec/spec_helper.rb
290
- - spec/unit/unparser/buffer/append_spec.rb
291
- - spec/unit/unparser/buffer/append_without_prefix_spec.rb
292
- - spec/unit/unparser/buffer/capture_content_spec.rb
293
- - spec/unit/unparser/buffer/content_spec.rb
294
- - spec/unit/unparser/buffer/fresh_line_spec.rb
295
- - spec/unit/unparser/buffer/indent_spec.rb
296
- - spec/unit/unparser/buffer/nl_spec.rb
297
- - spec/unit/unparser/buffer/unindent_spec.rb
298
- - spec/unit/unparser/comments/consume_spec.rb
299
- - spec/unit/unparser/comments/take_all_spec.rb
300
- - spec/unit/unparser/comments/take_before_spec.rb
301
- - spec/unit/unparser/comments/take_eol_comments_spec.rb
302
- - spec/unit/unparser/emitter/class_methods/handle_spec.rb
303
- - spec/unit/unparser_spec.rb
322
+ test_files: []