unparser 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|