synvert-core 0.15.2 → 0.16.0
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 +4 -2
- data/Gemfile +2 -0
- data/Guardfile +2 -0
- data/Rakefile +2 -0
- data/lib/synvert/core.rb +2 -0
- data/lib/synvert/core/configuration.rb +2 -1
- data/lib/synvert/core/engine.rb +1 -1
- data/lib/synvert/core/engine/erb.rb +2 -1
- data/lib/synvert/core/exceptions.rb +2 -0
- data/lib/synvert/core/node_ext.rb +7 -2
- data/lib/synvert/core/rewriter.rb +1 -1
- data/lib/synvert/core/rewriter/action.rb +1 -1
- data/lib/synvert/core/rewriter/action/append_action.rb +2 -2
- data/lib/synvert/core/rewriter/action/insert_action.rb +2 -2
- data/lib/synvert/core/rewriter/action/insert_after_action.rb +1 -1
- data/lib/synvert/core/rewriter/action/remove_action.rb +1 -1
- data/lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb +1 -1
- data/lib/synvert/core/rewriter/action/replace_with_action.rb +1 -1
- data/lib/synvert/core/rewriter/condition.rb +1 -1
- data/lib/synvert/core/rewriter/condition/if_exist_condition.rb +1 -1
- data/lib/synvert/core/rewriter/condition/if_only_exist_condition.rb +1 -1
- data/lib/synvert/core/rewriter/condition/unless_exist_condition.rb +1 -1
- data/lib/synvert/core/rewriter/gem_spec.rb +1 -1
- data/lib/synvert/core/rewriter/helper.rb +1 -1
- data/lib/synvert/core/rewriter/instance.rb +17 -6
- data/lib/synvert/core/rewriter/ruby_version.rb +1 -1
- data/lib/synvert/core/rewriter/scope.rb +1 -1
- data/lib/synvert/core/rewriter/scope/goto_scope.rb +2 -1
- data/lib/synvert/core/rewriter/scope/within_scope.rb +13 -4
- data/lib/synvert/core/rewriter/warning.rb +1 -1
- data/lib/synvert/core/version.rb +2 -2
- data/spec/spec_helper.rb +2 -0
- data/spec/support/parser_helper.rb +2 -0
- data/spec/synvert/core/configuration_spec.rb +3 -1
- data/spec/synvert/core/engine/erb_spec.rb +2 -0
- data/spec/synvert/core/node_ext_spec.rb +4 -2
- data/spec/synvert/core/rewriter/action/append_action_spec.rb +2 -0
- data/spec/synvert/core/rewriter/action/insert_action_spec.rb +2 -0
- data/spec/synvert/core/rewriter/action/insert_after_action_spec.rb +2 -0
- data/spec/synvert/core/rewriter/action/remove_action_spec.rb +2 -0
- data/spec/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action_spec.rb +2 -0
- data/spec/synvert/core/rewriter/action/replace_with_action_spec.rb +2 -0
- data/spec/synvert/core/rewriter/action_spec.rb +2 -0
- data/spec/synvert/core/rewriter/condition/if_exist_condition_spec.rb +2 -0
- data/spec/synvert/core/rewriter/condition/if_only_exist_condition_spec.rb +2 -0
- data/spec/synvert/core/rewriter/condition/unless_exist_condition_spec.rb +2 -0
- data/spec/synvert/core/rewriter/condition_spec.rb +2 -0
- data/spec/synvert/core/rewriter/gem_spec_spec.rb +2 -0
- data/spec/synvert/core/rewriter/helper_spec.rb +2 -0
- data/spec/synvert/core/rewriter/instance_spec.rb +22 -4
- data/spec/synvert/core/rewriter/scope/goto_scope_spec.rb +2 -0
- data/spec/synvert/core/rewriter/scope/within_scope.rb +2 -0
- data/spec/synvert/core/rewriter/scope_spec.rb +2 -0
- data/spec/synvert/core/rewriter/warning_spec.rb +2 -0
- data/spec/synvert/core/rewriter_spec.rb +7 -5
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c2c7961db23fe0b1984a90265b8a35d1927d7cfc7dfaa5d66cc7d71d80f3315a
|
|
4
|
+
data.tar.gz: 66826322dc49882fd9b718e895af0ff954e3c2137014661f97832a94d3de5104
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c396d7f949f0300cbac84fd1324728d3466c514cedcc463ab955f3c7cae3f83bd4e080c92d3ca88f32798ce8b0b6c882113cac4b4ea41a98540b8cc4977ebdb0
|
|
7
|
+
data.tar.gz: 804ebc08dd0fe453f932e767c960923bbe7270a3cef0fd95cb61d5b85488a137d0b2da8558823c4cf8cba22b150ca742fb1818d22a1bacccfc1a92da55daf1cc
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/Guardfile
CHANGED
data/Rakefile
CHANGED
data/lib/synvert/core.rb
CHANGED
data/lib/synvert/core/engine.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Parser::AST
|
|
2
4
|
# ArgumentsNode allows to handle all args as one node or handle all args as an array.
|
|
3
5
|
class ArgumentsNode
|
|
@@ -133,9 +135,11 @@ module Parser::AST
|
|
|
133
135
|
self.children
|
|
134
136
|
when :def, :block
|
|
135
137
|
return [] if self.children[2].nil?
|
|
138
|
+
|
|
136
139
|
:begin == self.children[2].type ? self.children[2].body : self.children[2..-1]
|
|
137
140
|
when :defs
|
|
138
141
|
return [] if self.children[3].nil?
|
|
142
|
+
|
|
139
143
|
:begin == self.children[3].type ? self.children[3].body : self.children[3..-1]
|
|
140
144
|
else
|
|
141
145
|
raise Synvert::Core::MethodNotSupported.new "body is not handled for #{self.debug_info}"
|
|
@@ -234,7 +238,7 @@ module Parser::AST
|
|
|
234
238
|
# @return [Parser::AST::Node] variable nodes.
|
|
235
239
|
# @raise [Synvert::Core::MethodNotSupported] if calls on other node.
|
|
236
240
|
def left_value
|
|
237
|
-
if [
|
|
241
|
+
if %i[masgn lvasgn ivasgn].include? self.type
|
|
238
242
|
self.children[0]
|
|
239
243
|
else
|
|
240
244
|
raise Synvert::Core::MethodNotSupported.new "left_value is not handled for #{self.debug_info}"
|
|
@@ -246,7 +250,7 @@ module Parser::AST
|
|
|
246
250
|
# @return [Array<Parser::AST::Node>] variable nodes.
|
|
247
251
|
# @raise [Synvert::Core::MethodNotSupported] if calls on other node.
|
|
248
252
|
def right_value
|
|
249
|
-
if [
|
|
253
|
+
if %i[masgn lvasgn ivasgn].include? self.type
|
|
250
254
|
self.children[1]
|
|
251
255
|
else
|
|
252
256
|
raise Synvert::Core::MethodNotSupported.new "right_value is not handled for #{self.debug_info}"
|
|
@@ -425,6 +429,7 @@ module Parser::AST
|
|
|
425
429
|
end
|
|
426
430
|
when Array
|
|
427
431
|
return false unless expected.length == actual.length
|
|
432
|
+
|
|
428
433
|
actual.zip(expected).all? { |a, e| match_value?(a, e) }
|
|
429
434
|
when NilClass
|
|
430
435
|
actual.nil?
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Synvert::Core
|
|
4
4
|
# AppendAction to append code to the bottom of node body.
|
|
@@ -30,7 +30,7 @@ module Synvert::Core
|
|
|
30
30
|
# @param node [Parser::AST::Node]
|
|
31
31
|
# @return [String] n times whitesphace
|
|
32
32
|
def indent(node)
|
|
33
|
-
if [
|
|
33
|
+
if %i[block class].include? node.type
|
|
34
34
|
' ' * (node.indent + DEFAULT_INDENT)
|
|
35
35
|
else
|
|
36
36
|
' ' * node.indent
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Synvert::Core
|
|
4
4
|
# InsertAction to insert code to the top of node body.
|
|
@@ -33,7 +33,7 @@ module Synvert::Core
|
|
|
33
33
|
# @param node [Parser::AST::Node]
|
|
34
34
|
# @return [String] n times whitesphace
|
|
35
35
|
def indent(node)
|
|
36
|
-
if [
|
|
36
|
+
if %i[block class].include? node.type
|
|
37
37
|
' ' * (node.indent + DEFAULT_INDENT)
|
|
38
38
|
else
|
|
39
39
|
' ' * node.indent
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Synvert::Core
|
|
4
4
|
# Instance is an execution unit, it finds specified ast nodes,
|
|
@@ -91,7 +91,7 @@ module Synvert::Core
|
|
|
91
91
|
unless Configuration.instance.get(:skip_files).include? file_path
|
|
92
92
|
begin
|
|
93
93
|
conflict_actions = []
|
|
94
|
-
source = self.class.file_source(file_path)
|
|
94
|
+
source = +self.class.file_source(file_path)
|
|
95
95
|
ast = self.class.file_ast(file_path)
|
|
96
96
|
|
|
97
97
|
@current_file = file_path
|
|
@@ -156,15 +156,28 @@ module Synvert::Core
|
|
|
156
156
|
# DSL #
|
|
157
157
|
#######
|
|
158
158
|
|
|
159
|
-
# Parse within_node dsl, it creates a [Synvert::Core::Rewriter::WithinScope] to find matching ast nodes,
|
|
159
|
+
# Parse within_node dsl, it creates a [Synvert::Core::Rewriter::WithinScope] to find recursive matching ast nodes,
|
|
160
160
|
# then continue operating on each matching ast node.
|
|
161
161
|
#
|
|
162
162
|
# @param rules [Hash] rules to find mathing ast nodes.
|
|
163
163
|
# @param block [Block] block code to continue operating on the matching nodes.
|
|
164
164
|
def within_node(rules, &block)
|
|
165
|
-
Rewriter::WithinScope.new(self, rules, &block).process
|
|
165
|
+
Rewriter::WithinScope.new(self, rules, { recursive: true }, &block).process
|
|
166
166
|
end
|
|
167
167
|
|
|
168
|
+
alias_method :with_node, :within_node
|
|
169
|
+
|
|
170
|
+
# Parse within_direct_node dsl, it creates a [Synvert::Core::Rewriter::WithinScope] to find direct matching ast nodes,
|
|
171
|
+
# then continue operating on each matching ast node.
|
|
172
|
+
#
|
|
173
|
+
# @param rules [Hash] rules to find mathing ast nodes.
|
|
174
|
+
# @param block [Block] block code to continue operating on the matching nodes.
|
|
175
|
+
def within_direct_node(rules, &block)
|
|
176
|
+
Rewriter::WithinScope.new(self, rules, { recursive: false }, &block).process
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
alias_method :with_direct_node, :within_direct_node
|
|
180
|
+
|
|
168
181
|
# Parse goto_node dsl, it creates a [Synvert::Core::Rewriter::GotoScope] to go to a child node,
|
|
169
182
|
# then continue operating on the child node.
|
|
170
183
|
#
|
|
@@ -174,8 +187,6 @@ module Synvert::Core
|
|
|
174
187
|
Rewriter::GotoScope.new(self, child_node_name, &block).process
|
|
175
188
|
end
|
|
176
189
|
|
|
177
|
-
alias_method :with_node, :within_node
|
|
178
|
-
|
|
179
190
|
# Parse if_exist_node dsl, it creates a [Synvert::Core::Rewriter::IfExistCondition] to check
|
|
180
191
|
# if matching nodes exist in the child nodes, if so, then continue operating on each matching ast node.
|
|
181
192
|
#
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Synvert::Core
|
|
4
4
|
# Go to and change its scope to a child node.
|
|
@@ -18,6 +18,7 @@ module Synvert::Core
|
|
|
18
18
|
def process
|
|
19
19
|
current_node = @instance.current_node
|
|
20
20
|
return unless current_node
|
|
21
|
+
|
|
21
22
|
child_node = current_node.send @child_node_name
|
|
22
23
|
@instance.process_with_other_node child_node do
|
|
23
24
|
@instance.instance_eval &@block
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Synvert::Core
|
|
4
4
|
# WithinScope finds out nodes which match rules, then change its scope to matching node.
|
|
@@ -7,10 +7,12 @@ module Synvert::Core
|
|
|
7
7
|
#
|
|
8
8
|
# @param instance [Synvert::Core::Rewriter::Instance]
|
|
9
9
|
# @param rules [Hash]
|
|
10
|
+
# @param options [Hash]
|
|
10
11
|
# @param block [Block]
|
|
11
|
-
def initialize(instance, rules, &block)
|
|
12
|
+
def initialize(instance, rules, options = { recursive: true }, &block)
|
|
12
13
|
@instance = instance
|
|
13
14
|
@rules = rules
|
|
15
|
+
@options = options
|
|
14
16
|
@block = block
|
|
15
17
|
end
|
|
16
18
|
|
|
@@ -19,11 +21,18 @@ module Synvert::Core
|
|
|
19
21
|
def process
|
|
20
22
|
current_node = @instance.current_node
|
|
21
23
|
return unless current_node
|
|
24
|
+
|
|
22
25
|
@instance.process_with_node current_node do
|
|
23
26
|
matching_nodes = []
|
|
24
27
|
matching_nodes << current_node if current_node.match? @rules
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
if @options[:recursive]
|
|
29
|
+
current_node.recursive_children do |child_node|
|
|
30
|
+
matching_nodes << child_node if child_node.match? @rules
|
|
31
|
+
end
|
|
32
|
+
else
|
|
33
|
+
current_node.children do |child_node|
|
|
34
|
+
matching_nodes << child_node if child_node.match? @rules
|
|
35
|
+
end
|
|
27
36
|
end
|
|
28
37
|
matching_nodes.each do |matching_node|
|
|
29
38
|
@instance.process_with_node matching_node do
|
data/lib/synvert/core/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
|
|
3
5
|
module Synvert::Core
|
|
4
6
|
describe Configuration do
|
|
5
7
|
it 'sets / gets' do
|
|
6
8
|
Configuration.instance.set :key, 'value'
|
|
7
|
-
expect(Configuration.instance.get
|
|
9
|
+
expect(Configuration.instance.get(:key)).to eq 'value'
|
|
8
10
|
end
|
|
9
11
|
end
|
|
10
12
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
|
|
3
5
|
describe Parser::AST::Node do
|
|
@@ -102,12 +104,12 @@ describe Parser::AST::Node do
|
|
|
102
104
|
describe '#arguments' do
|
|
103
105
|
it 'gets for def node' do
|
|
104
106
|
node = parse("def test(foo, bar); foo + bar; end")
|
|
105
|
-
expect(node.arguments.map { |argument| argument.to_source }).to eq [
|
|
107
|
+
expect(node.arguments.map { |argument| argument.to_source }).to eq %w[foo bar]
|
|
106
108
|
end
|
|
107
109
|
|
|
108
110
|
it 'gets for defs node' do
|
|
109
111
|
node = parse("def self.test(foo, bar); foo + bar; end")
|
|
110
|
-
expect(node.arguments.map { |argument| argument.to_source }).to eq [
|
|
112
|
+
expect(node.arguments.map { |argument| argument.to_source }).to eq %w[foo bar]
|
|
111
113
|
end
|
|
112
114
|
|
|
113
115
|
it 'gets for block node' do
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
|
|
3
5
|
module Synvert::Core
|
|
@@ -12,7 +14,7 @@ module Synvert::Core
|
|
|
12
14
|
it 'parses within_node' do
|
|
13
15
|
scope = double()
|
|
14
16
|
block = Proc.new {}
|
|
15
|
-
expect(Rewriter::WithinScope).to receive(:new).with(instance, type: 'send', message: 'create', &block).and_return(scope)
|
|
17
|
+
expect(Rewriter::WithinScope).to receive(:new).with(instance, { type: 'send', message: 'create' }, { recursive: true }, &block).and_return(scope)
|
|
16
18
|
expect(scope).to receive(:process)
|
|
17
19
|
instance.within_node(type: 'send', message: 'create', &block)
|
|
18
20
|
end
|
|
@@ -20,11 +22,27 @@ module Synvert::Core
|
|
|
20
22
|
it 'parses with_node' do
|
|
21
23
|
scope = double()
|
|
22
24
|
block = Proc.new {}
|
|
23
|
-
expect(Rewriter::WithinScope).to receive(:new).with(instance, type: 'send', message: 'create', &block).and_return(scope)
|
|
25
|
+
expect(Rewriter::WithinScope).to receive(:new).with(instance, { type: 'send', message: 'create' }, { recursive: true }, &block).and_return(scope)
|
|
24
26
|
expect(scope).to receive(:process)
|
|
25
27
|
instance.with_node(type: 'send', message: 'create', &block)
|
|
26
28
|
end
|
|
27
29
|
|
|
30
|
+
it 'parses within_direct_node' do
|
|
31
|
+
scope = double()
|
|
32
|
+
block = Proc.new {}
|
|
33
|
+
expect(Rewriter::WithinScope).to receive(:new).with(instance, { type: 'send', message: 'create' }, { recursive: false }, &block).and_return(scope)
|
|
34
|
+
expect(scope).to receive(:process)
|
|
35
|
+
instance.within_direct_node(type: 'send', message: 'create', &block)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'parses with_direct_node' do
|
|
39
|
+
scope = double()
|
|
40
|
+
block = Proc.new {}
|
|
41
|
+
expect(Rewriter::WithinScope).to receive(:new).with(instance, { type: 'send', message: 'create' }, { recursive: false }, &block).and_return(scope)
|
|
42
|
+
expect(scope).to receive(:process)
|
|
43
|
+
instance.with_direct_node(type: 'send', message: 'create', &block)
|
|
44
|
+
end
|
|
45
|
+
|
|
28
46
|
it 'parses goto_node' do
|
|
29
47
|
scope = double()
|
|
30
48
|
block = Proc.new {}
|
|
@@ -205,7 +223,7 @@ end
|
|
|
205
223
|
instance.instance_variable_set :@actions, [action1, action2, action3]
|
|
206
224
|
conflict_actions = instance.send(:get_conflict_actions)
|
|
207
225
|
expect(conflict_actions).to eq []
|
|
208
|
-
expect(instance.instance_variable_get
|
|
226
|
+
expect(instance.instance_variable_get(:@actions)).to eq [action1, action2, action3]
|
|
209
227
|
end
|
|
210
228
|
|
|
211
229
|
it "has no conflict" do
|
|
@@ -216,7 +234,7 @@ end
|
|
|
216
234
|
instance.instance_variable_set :@actions, [action1, action2, action3]
|
|
217
235
|
conflict_actions = instance.send(:get_conflict_actions)
|
|
218
236
|
expect(conflict_actions).to eq [action2, action1]
|
|
219
|
-
expect(instance.instance_variable_get
|
|
237
|
+
expect(instance.instance_variable_get(:@actions)).to eq [action3]
|
|
220
238
|
end
|
|
221
239
|
end
|
|
222
240
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
|
|
3
5
|
module Synvert::Core
|
|
@@ -92,7 +94,7 @@ module Synvert::Core
|
|
|
92
94
|
add_file 'foo.bar', 'FooBar'
|
|
93
95
|
end
|
|
94
96
|
rewriter.process
|
|
95
|
-
expect(File.read
|
|
97
|
+
expect(File.read('./foo.bar')).to eq 'FooBar'
|
|
96
98
|
FileUtils.rm './foo.bar'
|
|
97
99
|
end
|
|
98
100
|
|
|
@@ -112,7 +114,7 @@ module Synvert::Core
|
|
|
112
114
|
remove_file 'foo.bar'
|
|
113
115
|
end
|
|
114
116
|
rewriter.process
|
|
115
|
-
expect(File.exist?
|
|
117
|
+
expect(File.exist?('./foo.bar')).to be_falsey
|
|
116
118
|
end
|
|
117
119
|
|
|
118
120
|
it 'does nothing if file not exist' do
|
|
@@ -120,7 +122,7 @@ module Synvert::Core
|
|
|
120
122
|
remove_file 'foo.bar'
|
|
121
123
|
end
|
|
122
124
|
rewriter.process
|
|
123
|
-
expect(File.exist?
|
|
125
|
+
expect(File.exist?('./foo.bar')).to be_falsey
|
|
124
126
|
end
|
|
125
127
|
|
|
126
128
|
it 'does nothing in sandbox mode' do
|
|
@@ -204,11 +206,11 @@ module Synvert::Core
|
|
|
204
206
|
context "exist?" do
|
|
205
207
|
it 'returns true if rewriter exists' do
|
|
206
208
|
Rewriter.new 'group', 'rewriter'
|
|
207
|
-
expect(Rewriter.exist?
|
|
209
|
+
expect(Rewriter.exist?('group', 'rewriter')).to be_truthy
|
|
208
210
|
end
|
|
209
211
|
|
|
210
212
|
it 'returns false if rewriter does not exist' do
|
|
211
|
-
expect(Rewriter.exist?
|
|
213
|
+
expect(Rewriter.exist?('group', 'rewriter')).to be_falsey
|
|
212
214
|
end
|
|
213
215
|
end
|
|
214
216
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: synvert-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.16.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Richard Huang
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-01-
|
|
11
|
+
date: 2021-01-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: parser
|