unparser 0.2.7 → 0.2.8
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.
- checksums.yaml +4 -4
- data/Changelog.md +5 -0
- data/lib/unparser.rb +1 -0
- data/lib/unparser/emitter/meta.rb +14 -0
- data/spec/support/parser_class_generator.rb +21 -0
- data/spec/unit/unparser_spec.rb +84 -22
- data/unparser.gemspec +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89eae693b0b2b09ebd3fcb9ade1e24b126c68afaa05ac5d2fa635c33c8b25229
|
4
|
+
data.tar.gz: 1c04a551559a58cebb43475e3a43cb8100ae68d5f6ff0a8fea78e7a7e92d55e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6236052606af0a610cd6819ad2b19bf47877428057dc53d7c16cc1c7bef91cbb9d169ad62f402c2113bb211275588041443242c179c9fa5233b1938fce4ffd84
|
7
|
+
data.tar.gz: e7b4b900464471d40e2f0f385d992c20cf3fec04b6ba7f560b3c784c6d677d652ac9364c62fca6a70990f0e88c113f107bac05adec02c073f480cc371b3fff1b
|
data/Changelog.md
CHANGED
data/lib/unparser.rb
CHANGED
@@ -50,6 +50,7 @@ require 'unparser/emitter/literal/hash'
|
|
50
50
|
require 'unparser/emitter/literal/range'
|
51
51
|
require 'unparser/emitter/literal/dynamic_body'
|
52
52
|
require 'unparser/emitter/literal/execute_string'
|
53
|
+
require 'unparser/emitter/meta'
|
53
54
|
require 'unparser/emitter/send'
|
54
55
|
require 'unparser/emitter/send/unary'
|
55
56
|
require 'unparser/emitter/send/binary'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Unparser
|
2
|
+
class Emitter
|
3
|
+
# Namespace class for meta emitters
|
4
|
+
class Meta < self
|
5
|
+
include Terminated
|
6
|
+
|
7
|
+
handle(:__FILE__, :__LINE__)
|
8
|
+
|
9
|
+
def dispatch
|
10
|
+
write(node.type.to_s) # (e.g. literally write '__FILE__' or '__LINE__')
|
11
|
+
end
|
12
|
+
end # Meta
|
13
|
+
end # Emitter
|
14
|
+
end # Unparser
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ParserClassGenerator
|
2
|
+
def self.generate_with_options(base_parser_class, builder_options)
|
3
|
+
# This builds a dynamic subclass of the base_parser_class (e.g. Parser::Ruby23)
|
4
|
+
# and overrides the default_parser method to return a parser whose builder
|
5
|
+
# has various options set.
|
6
|
+
#
|
7
|
+
# Currently the only builder option is :emit_file_line_as_literals
|
8
|
+
|
9
|
+
Class.new(base_parser_class) do
|
10
|
+
define_singleton_method(:default_parser) do |*args|
|
11
|
+
super(*args).tap do |parser|
|
12
|
+
parser.builder.emit_file_line_as_literals = builder_options[:emit_file_line_as_literals]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
define_singleton_method(:inspect) do
|
17
|
+
"#{base_parser_class.inspect} with builder options: #{builder_options.inspect}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/spec/unit/unparser_spec.rb
CHANGED
@@ -1,26 +1,76 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'parser/all'
|
3
|
+
require 'support/parser_class_generator'
|
3
4
|
|
4
5
|
describe Unparser, mutant_expression: 'Unparser::Emitter*' do
|
5
6
|
describe '.unparse' do
|
6
7
|
|
7
|
-
|
8
|
+
RUBY_VERSION_PARSERS = IceNine.deep_freeze(
|
8
9
|
'2.1' => Parser::Ruby21,
|
9
10
|
'2.2' => Parser::Ruby22,
|
10
11
|
'2.3' => Parser::Ruby23
|
11
12
|
)
|
12
13
|
|
13
|
-
|
14
|
+
RUBY_VERSIONS = RUBY_VERSION_PARSERS.keys.freeze
|
14
15
|
|
15
|
-
def self.
|
16
|
-
|
17
|
-
|
16
|
+
def self.builder_options
|
17
|
+
@builder_options ||= {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.builder_options=(options)
|
21
|
+
@builder_options = options
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.ruby_versions
|
25
|
+
@ruby_versions ||= RUBY_VERSIONS
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.ruby_versions=(versions)
|
29
|
+
@ruby_versions = versions
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.with_ruby_versions(beginning_at: nil, ending_at: nil, only: nil)
|
33
|
+
original_ruby_versions = ruby_versions
|
34
|
+
if only
|
35
|
+
self.ruby_versions = only & ruby_versions # intersection
|
36
|
+
else
|
37
|
+
if ending_at
|
38
|
+
idx = ruby_versions.index(ending_at) || fail('Invalid Ruby specified')
|
39
|
+
self.ruby_versions = ruby_versions[0..idx]
|
40
|
+
end
|
41
|
+
if beginning_at
|
42
|
+
idx = ruby_versions.index(beginning_at) || fail('Invalid Ruby specified')
|
43
|
+
self.ruby_versions = ruby_versions[idx..-1]
|
44
|
+
end
|
18
45
|
end
|
46
|
+
|
47
|
+
yield
|
48
|
+
|
49
|
+
self.ruby_versions = original_ruby_versions
|
19
50
|
end
|
20
51
|
|
21
|
-
def self.
|
22
|
-
|
23
|
-
|
52
|
+
def self.current_parsers
|
53
|
+
ruby_versions.map do |ruby_version|
|
54
|
+
if builder_options != {}
|
55
|
+
ParserClassGenerator.generate_with_options(parser_for_ruby_version(ruby_version), builder_options)
|
56
|
+
else
|
57
|
+
parser_for_ruby_version(ruby_version)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.with_builder_options(options)
|
63
|
+
original_options = builder_options
|
64
|
+
self.builder_options = builder_options.merge(options)
|
65
|
+
|
66
|
+
yield
|
67
|
+
|
68
|
+
self.builder_options = original_options
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.parser_for_ruby_version(version)
|
72
|
+
RUBY_VERSION_PARSERS.fetch(version) do
|
73
|
+
raise "Unrecognized Ruby version #{version}"
|
24
74
|
end
|
25
75
|
end
|
26
76
|
|
@@ -50,14 +100,14 @@ describe Unparser, mutant_expression: 'Unparser::Emitter*' do
|
|
50
100
|
assert_source("(#{expression}).foo")
|
51
101
|
end
|
52
102
|
|
53
|
-
def self.assert_terminated(expression
|
54
|
-
assert_source(expression
|
55
|
-
assert_source("foo(#{expression})"
|
56
|
-
assert_source("#{expression}.foo"
|
103
|
+
def self.assert_terminated(expression)
|
104
|
+
assert_source(expression)
|
105
|
+
assert_source("foo(#{expression})")
|
106
|
+
assert_source("#{expression}.foo")
|
57
107
|
end
|
58
108
|
|
59
|
-
def self.assert_generates(ast_or_string, expected
|
60
|
-
|
109
|
+
def self.assert_generates(ast_or_string, expected)
|
110
|
+
current_parsers.each do |parser|
|
61
111
|
it "should generate #{ast_or_string} as #{expected} under #{parser.inspect}" do
|
62
112
|
if ast_or_string.is_a?(String)
|
63
113
|
expected = strip(expected)
|
@@ -69,16 +119,16 @@ describe Unparser, mutant_expression: 'Unparser::Emitter*' do
|
|
69
119
|
end
|
70
120
|
end
|
71
121
|
|
72
|
-
def self.assert_round_trip(input
|
73
|
-
|
122
|
+
def self.assert_round_trip(input)
|
123
|
+
current_parsers.each do |parser|
|
74
124
|
it "should round trip #{input} under #{parser.inspect}" do
|
75
125
|
assert_round_trip(input, parser)
|
76
126
|
end
|
77
127
|
end
|
78
128
|
end
|
79
129
|
|
80
|
-
def self.assert_source(input
|
81
|
-
assert_round_trip(strip(input)
|
130
|
+
def self.assert_source(input)
|
131
|
+
assert_round_trip(strip(input))
|
82
132
|
end
|
83
133
|
|
84
134
|
context 'kwargs' do
|
@@ -273,8 +323,18 @@ describe Unparser, mutant_expression: 'Unparser::Emitter*' do
|
|
273
323
|
|
274
324
|
context 'magic keywords' do
|
275
325
|
assert_generates '__ENCODING__', 'Encoding::UTF_8'
|
276
|
-
|
277
|
-
|
326
|
+
|
327
|
+
# These two assertions don't actually need to be wrapped in this block since `true` is the default,
|
328
|
+
# but it is helpful to contrast with the assertions farther down.
|
329
|
+
with_builder_options(emit_file_line_as_literals: true) do
|
330
|
+
assert_generates '__FILE__', '"(string)"'
|
331
|
+
assert_generates '__LINE__', '1'
|
332
|
+
end
|
333
|
+
|
334
|
+
with_builder_options(emit_file_line_as_literals: false) do
|
335
|
+
assert_source '__FILE__'
|
336
|
+
assert_source '__LINE__'
|
337
|
+
end
|
278
338
|
end
|
279
339
|
|
280
340
|
context 'assignment' do
|
@@ -408,8 +468,10 @@ describe Unparser, mutant_expression: 'Unparser::Emitter*' do
|
|
408
468
|
end
|
409
469
|
|
410
470
|
context 'conditional send (csend)' do
|
411
|
-
|
412
|
-
|
471
|
+
with_ruby_versions(beginning_at: '2.3') do
|
472
|
+
assert_terminated 'a&.b'
|
473
|
+
assert_terminated 'a&.b(c)'
|
474
|
+
end
|
413
475
|
end
|
414
476
|
|
415
477
|
context 'send' do
|
data/unparser.gemspec
CHANGED
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.2.
|
4
|
+
version: 0.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Markus Schirp
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: abstract_type
|
@@ -223,6 +223,7 @@ files:
|
|
223
223
|
- lib/unparser/emitter/literal/regexp.rb
|
224
224
|
- lib/unparser/emitter/literal/singleton.rb
|
225
225
|
- lib/unparser/emitter/match.rb
|
226
|
+
- lib/unparser/emitter/meta.rb
|
226
227
|
- lib/unparser/emitter/module.rb
|
227
228
|
- lib/unparser/emitter/op_assign.rb
|
228
229
|
- lib/unparser/emitter/redo.rb
|
@@ -250,6 +251,7 @@ files:
|
|
250
251
|
- spec/integration/unparser/corpus_spec.rb
|
251
252
|
- spec/integrations.yml
|
252
253
|
- spec/spec_helper.rb
|
254
|
+
- spec/support/parser_class_generator.rb
|
253
255
|
- spec/unit/unparser/buffer/append_spec.rb
|
254
256
|
- spec/unit/unparser/buffer/append_without_prefix_spec.rb
|
255
257
|
- spec/unit/unparser/buffer/capture_content_spec.rb
|
@@ -285,7 +287,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
285
287
|
version: '0'
|
286
288
|
requirements: []
|
287
289
|
rubyforge_project:
|
288
|
-
rubygems_version: 2.7.
|
290
|
+
rubygems_version: 2.7.7
|
289
291
|
signing_key:
|
290
292
|
specification_version: 4
|
291
293
|
summary: Generate equivalent source for parser gem AST nodes
|
@@ -293,6 +295,7 @@ test_files:
|
|
293
295
|
- spec/integration/unparser/corpus_spec.rb
|
294
296
|
- spec/integrations.yml
|
295
297
|
- spec/spec_helper.rb
|
298
|
+
- spec/support/parser_class_generator.rb
|
296
299
|
- spec/unit/unparser/buffer/append_spec.rb
|
297
300
|
- spec/unit/unparser/buffer/append_without_prefix_spec.rb
|
298
301
|
- spec/unit/unparser/buffer/capture_content_spec.rb
|