unparser 0.4.4 → 0.4.9

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