syntax_tree 2.7.1 → 2.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -1
- data/Gemfile.lock +6 -6
- data/lib/syntax_tree/basic_visitor.rb +5 -1
- data/lib/syntax_tree/cli.rb +133 -67
- data/lib/syntax_tree/language_server.rb +2 -1
- data/lib/syntax_tree/node.rb +42 -3
- data/lib/syntax_tree/parser.rb +11 -1
- data/lib/syntax_tree/version.rb +1 -1
- data/lib/syntax_tree/visitor/field_visitor.rb +4 -0
- data/lib/syntax_tree/visitor.rb +3 -0
- data/lib/syntax_tree.rb +1 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad3c35843b6e3148499ac001d05a9c5d613d69debff5fdc411dff89a9adc5ca4
|
4
|
+
data.tar.gz: 570ae99edf8b17b5d205142872621b0551632d29ac4671ee14fed8415cf9cfe4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ec0e9d8f5f4f828ba0d451d49bd7fa9f5576570f7427c91973503e795fe068e21a61dac4f1880be12dbd551855eb0b8d27f359a9a682b964f3183aaf687e1da
|
7
|
+
data.tar.gz: b8ae5c0132ebc445d060b1d5cef477253c724ea2c7a22a536d4ea78b3fb2d905c560e1f044f8843b92f79e0dbc1a434cda2a38e76b2732b426719150785a59af
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [2.8.0] - 2022-06-21
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- [#95](https://github.com/ruby-syntax-tree/syntax_tree/pull/95) - The `HeredocEnd` node has been added which effectively results in the ability to determine the location of the ending of a heredoc from source.
|
14
|
+
- [#99](https://github.com/ruby-syntax-tree/syntax_tree/pull/99) - The LSP now allows you to pass the same configuration options as the other CLI commands which allows formatting to be modified in the VSCode extension.
|
15
|
+
- [#100](https://github.com/ruby-syntax-tree/syntax_tree/pull/100) - The LSP now explicitly responds to the shutdown request so that VSCode never deadlocks.
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
|
19
|
+
- [#96](https://github.com/ruby-syntax-tree/syntax_tree/pull/96) - The CLI now runs in parallel by default. There is a worker created for each processor on the running machine (as determined by `Etc.nprocessors`).
|
20
|
+
- [#97](https://github.com/ruby-syntax-tree/syntax_tree/pull/97) - Syntax Tree now handles the case where `DidYouMean` is not available for whatever reason, as well as handles the newer `detailed_message` API for errors.
|
21
|
+
|
9
22
|
## [2.7.1] - 2022-05-25
|
10
23
|
|
11
24
|
### Added
|
@@ -259,7 +272,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
|
|
259
272
|
|
260
273
|
- 🎉 Initial release! 🎉
|
261
274
|
|
262
|
-
[unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.
|
275
|
+
[unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.8.0...HEAD
|
276
|
+
[2.8.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.7.1...v2.8.0
|
263
277
|
[2.7.1]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.7.0...v2.7.1
|
264
278
|
[2.7.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.6.0...v2.7.0
|
265
279
|
[2.6.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.5.0...v2.6.0
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
syntax_tree (2.
|
4
|
+
syntax_tree (2.8.0)
|
5
5
|
prettier_print
|
6
6
|
|
7
7
|
GEM
|
@@ -9,25 +9,25 @@ GEM
|
|
9
9
|
specs:
|
10
10
|
ast (2.4.2)
|
11
11
|
docile (1.4.0)
|
12
|
-
minitest (5.
|
12
|
+
minitest (5.16.0)
|
13
13
|
parallel (1.22.1)
|
14
14
|
parser (3.1.2.0)
|
15
15
|
ast (~> 2.4.1)
|
16
16
|
prettier_print (0.1.0)
|
17
17
|
rainbow (3.1.1)
|
18
18
|
rake (13.0.6)
|
19
|
-
regexp_parser (2.
|
19
|
+
regexp_parser (2.5.0)
|
20
20
|
rexml (3.2.5)
|
21
|
-
rubocop (1.
|
21
|
+
rubocop (1.30.1)
|
22
22
|
parallel (~> 1.10)
|
23
23
|
parser (>= 3.1.0.0)
|
24
24
|
rainbow (>= 2.2.2, < 4.0)
|
25
25
|
regexp_parser (>= 1.8, < 3.0)
|
26
26
|
rexml (>= 3.2.5, < 4.0)
|
27
|
-
rubocop-ast (>= 1.
|
27
|
+
rubocop-ast (>= 1.18.0, < 2.0)
|
28
28
|
ruby-progressbar (~> 1.7)
|
29
29
|
unicode-display_width (>= 1.4.0, < 3.0)
|
30
|
-
rubocop-ast (1.
|
30
|
+
rubocop-ast (1.18.0)
|
31
31
|
parser (>= 3.1.1.0)
|
32
32
|
ruby-progressbar (1.11.0)
|
33
33
|
simplecov (0.21.2)
|
@@ -33,7 +33,11 @@ module SyntaxTree
|
|
33
33
|
).correct(visit_method)
|
34
34
|
end
|
35
35
|
|
36
|
-
DidYouMean
|
36
|
+
# In some setups with Ruby you can turn off DidYouMean, so we're going to
|
37
|
+
# respect that setting here.
|
38
|
+
if defined?(DidYouMean) && DidYouMean.method_defined?(:correct_error)
|
39
|
+
DidYouMean.correct_error(VisitMethodError, self)
|
40
|
+
end
|
37
41
|
end
|
38
42
|
|
39
43
|
class << self
|
data/lib/syntax_tree/cli.rb
CHANGED
@@ -34,9 +34,41 @@ module SyntaxTree
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
# An item of work that corresponds to a file to be processed.
|
38
|
+
class FileItem
|
39
|
+
attr_reader :filepath
|
40
|
+
|
41
|
+
def initialize(filepath)
|
42
|
+
@filepath = filepath
|
43
|
+
end
|
44
|
+
|
45
|
+
def handler
|
46
|
+
HANDLERS[File.extname(filepath)]
|
47
|
+
end
|
48
|
+
|
49
|
+
def source
|
50
|
+
handler.read(filepath)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# An item of work that corresponds to the stdin content.
|
55
|
+
class STDINItem
|
56
|
+
def handler
|
57
|
+
HANDLERS[".rb"]
|
58
|
+
end
|
59
|
+
|
60
|
+
def filepath
|
61
|
+
:stdin
|
62
|
+
end
|
63
|
+
|
64
|
+
def source
|
65
|
+
$stdin.read
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
37
69
|
# The parent action class for the CLI that implements the basics.
|
38
70
|
class Action
|
39
|
-
def run(
|
71
|
+
def run(item)
|
40
72
|
end
|
41
73
|
|
42
74
|
def success
|
@@ -48,8 +80,8 @@ module SyntaxTree
|
|
48
80
|
|
49
81
|
# An action of the CLI that prints out the AST for the given source.
|
50
82
|
class AST < Action
|
51
|
-
def run(
|
52
|
-
pp handler.parse(source)
|
83
|
+
def run(item)
|
84
|
+
pp item.handler.parse(item.source)
|
53
85
|
end
|
54
86
|
end
|
55
87
|
|
@@ -59,10 +91,11 @@ module SyntaxTree
|
|
59
91
|
class UnformattedError < StandardError
|
60
92
|
end
|
61
93
|
|
62
|
-
def run(
|
63
|
-
|
94
|
+
def run(item)
|
95
|
+
source = item.source
|
96
|
+
raise UnformattedError if source != item.handler.format(source)
|
64
97
|
rescue StandardError
|
65
|
-
warn("[#{Color.yellow("warn")}] #{filepath}")
|
98
|
+
warn("[#{Color.yellow("warn")}] #{item.filepath}")
|
66
99
|
raise
|
67
100
|
end
|
68
101
|
|
@@ -81,9 +114,11 @@ module SyntaxTree
|
|
81
114
|
class NonIdempotentFormatError < StandardError
|
82
115
|
end
|
83
116
|
|
84
|
-
def run(
|
85
|
-
|
86
|
-
|
117
|
+
def run(item)
|
118
|
+
handler = item.handler
|
119
|
+
|
120
|
+
warning = "[#{Color.yellow("warn")}] #{item.filepath}"
|
121
|
+
formatted = handler.format(item.source)
|
87
122
|
|
88
123
|
raise NonIdempotentFormatError if formatted != handler.format(formatted)
|
89
124
|
rescue StandardError
|
@@ -102,25 +137,27 @@ module SyntaxTree
|
|
102
137
|
|
103
138
|
# An action of the CLI that prints out the doc tree IR for the given source.
|
104
139
|
class Doc < Action
|
105
|
-
def run(
|
140
|
+
def run(item)
|
141
|
+
source = item.source
|
142
|
+
|
106
143
|
formatter = Formatter.new(source, [])
|
107
|
-
handler.parse(source).format(formatter)
|
144
|
+
item.handler.parse(source).format(formatter)
|
108
145
|
pp formatter.groups.first
|
109
146
|
end
|
110
147
|
end
|
111
148
|
|
112
149
|
# An action of the CLI that formats the input source and prints it out.
|
113
150
|
class Format < Action
|
114
|
-
def run(
|
115
|
-
puts handler.format(source)
|
151
|
+
def run(item)
|
152
|
+
puts item.handler.format(item.source)
|
116
153
|
end
|
117
154
|
end
|
118
155
|
|
119
156
|
# An action of the CLI that converts the source into its equivalent JSON
|
120
157
|
# representation.
|
121
158
|
class Json < Action
|
122
|
-
def run(
|
123
|
-
object = Visitor::JSONVisitor.new.visit(handler.parse(source))
|
159
|
+
def run(item)
|
160
|
+
object = Visitor::JSONVisitor.new.visit(item.handler.parse(item.source))
|
124
161
|
puts JSON.pretty_generate(object)
|
125
162
|
end
|
126
163
|
end
|
@@ -128,27 +165,28 @@ module SyntaxTree
|
|
128
165
|
# An action of the CLI that outputs a pattern-matching Ruby expression that
|
129
166
|
# would match the input given.
|
130
167
|
class Match < Action
|
131
|
-
def run(
|
132
|
-
puts handler.parse(source).construct_keys
|
168
|
+
def run(item)
|
169
|
+
puts item.handler.parse(item.source).construct_keys
|
133
170
|
end
|
134
171
|
end
|
135
172
|
|
136
173
|
# An action of the CLI that formats the input source and writes the
|
137
174
|
# formatted output back to the file.
|
138
175
|
class Write < Action
|
139
|
-
def run(
|
140
|
-
|
176
|
+
def run(item)
|
177
|
+
filepath = item.filepath
|
141
178
|
start = Time.now
|
142
179
|
|
143
|
-
|
180
|
+
source = item.source
|
181
|
+
formatted = item.handler.format(source)
|
144
182
|
File.write(filepath, formatted) if filepath != :stdin
|
145
183
|
|
146
184
|
color = source == formatted ? Color.gray(filepath) : filepath
|
147
185
|
delta = ((Time.now - start) * 1000).round
|
148
186
|
|
149
|
-
puts "
|
187
|
+
puts "#{color} #{delta}ms"
|
150
188
|
rescue StandardError
|
151
|
-
puts
|
189
|
+
puts filepath
|
152
190
|
raise
|
153
191
|
end
|
154
192
|
end
|
@@ -180,7 +218,7 @@ module SyntaxTree
|
|
180
218
|
#{Color.bold("stree help")}
|
181
219
|
Display this help message
|
182
220
|
|
183
|
-
#{Color.bold("stree lsp")}
|
221
|
+
#{Color.bold("stree lsp [OPTIONS]")}
|
184
222
|
Run syntax tree in language server mode
|
185
223
|
|
186
224
|
#{Color.bold("stree version")}
|
@@ -201,6 +239,20 @@ module SyntaxTree
|
|
201
239
|
def run(argv)
|
202
240
|
name, *arguments = argv
|
203
241
|
|
242
|
+
# If there are any plugins specified on the command line, then load them
|
243
|
+
# by requiring them here. We do this by transforming something like
|
244
|
+
#
|
245
|
+
# stree format --plugins=haml template.haml
|
246
|
+
#
|
247
|
+
# into
|
248
|
+
#
|
249
|
+
# require "syntax_tree/haml"
|
250
|
+
#
|
251
|
+
if arguments.first&.start_with?("--plugins=")
|
252
|
+
plugins = arguments.shift[/^--plugins=(.*)$/, 1]
|
253
|
+
plugins.split(",").each { |plugin| require "syntax_tree/#{plugin}" }
|
254
|
+
end
|
255
|
+
|
204
256
|
case name
|
205
257
|
when "help"
|
206
258
|
puts HELP
|
@@ -244,38 +296,41 @@ module SyntaxTree
|
|
244
296
|
return 1
|
245
297
|
end
|
246
298
|
|
247
|
-
#
|
248
|
-
|
249
|
-
#
|
250
|
-
# stree format --plugins=haml template.haml
|
251
|
-
#
|
252
|
-
# into
|
253
|
-
#
|
254
|
-
# require "syntax_tree/haml"
|
255
|
-
#
|
256
|
-
if arguments.first&.start_with?("--plugins=")
|
257
|
-
plugins = arguments.shift[/^--plugins=(.*)$/, 1]
|
258
|
-
plugins.split(",").each { |plugin| require "syntax_tree/#{plugin}" }
|
259
|
-
end
|
299
|
+
# We're going to build up a queue of items to process.
|
300
|
+
queue = Queue.new
|
260
301
|
|
261
|
-
#
|
262
|
-
#
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
rescue StandardError => error
|
274
|
-
warn(error.message)
|
275
|
-
warn(error.backtrace)
|
276
|
-
errored = true
|
302
|
+
# If we're reading from stdin, then we'll just add the stdin object to
|
303
|
+
# the queue. Otherwise, we'll add each of the filepaths to the queue.
|
304
|
+
if $stdin.tty? || arguments.any?
|
305
|
+
arguments.each do |pattern|
|
306
|
+
Dir
|
307
|
+
.glob(pattern)
|
308
|
+
.each do |filepath|
|
309
|
+
queue << FileItem.new(filepath) if File.file?(filepath)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
else
|
313
|
+
queue << STDINItem.new
|
277
314
|
end
|
278
315
|
|
316
|
+
# At the end, we're going to return whether or not this worker ever
|
317
|
+
# encountered an error.
|
318
|
+
errored =
|
319
|
+
with_workers(queue) do |item|
|
320
|
+
action.run(item)
|
321
|
+
false
|
322
|
+
rescue Parser::ParseError => error
|
323
|
+
warn("Error: #{error.message}")
|
324
|
+
highlight_error(error, item.source)
|
325
|
+
true
|
326
|
+
rescue Check::UnformattedError, Debug::NonIdempotentFormatError
|
327
|
+
true
|
328
|
+
rescue StandardError => error
|
329
|
+
warn(error.message)
|
330
|
+
warn(error.backtrace)
|
331
|
+
true
|
332
|
+
end
|
333
|
+
|
279
334
|
if errored
|
280
335
|
action.failure
|
281
336
|
1
|
@@ -287,22 +342,33 @@ module SyntaxTree
|
|
287
342
|
|
288
343
|
private
|
289
344
|
|
290
|
-
def
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
345
|
+
def with_workers(queue)
|
346
|
+
# If the queue is just 1 item, then we're not going to bother going
|
347
|
+
# through the whole ceremony of parallelizing the work.
|
348
|
+
return yield queue.shift if queue.size == 1
|
349
|
+
|
350
|
+
workers =
|
351
|
+
Etc.nprocessors.times.map do
|
352
|
+
Thread.new do
|
353
|
+
# Propagate errors in the worker threads up to the parent thread.
|
354
|
+
Thread.current.abort_on_exception = true
|
355
|
+
|
356
|
+
# Track whether or not there are any errors from any of the files
|
357
|
+
# that we take action on so that we can properly clean up and
|
358
|
+
# exit.
|
359
|
+
errored = false
|
360
|
+
|
361
|
+
# While there is still work left to do, shift off the queue and
|
362
|
+
# process the item.
|
363
|
+
(errored ||= yield queue.shift) until queue.empty?
|
364
|
+
|
365
|
+
# At the end, we're going to return whether or not this worker
|
366
|
+
# ever encountered an error.
|
367
|
+
errored
|
368
|
+
end
|
302
369
|
end
|
303
|
-
|
304
|
-
|
305
|
-
end
|
370
|
+
|
371
|
+
workers.inject(false) { |accum, thread| accum || thread.value }
|
306
372
|
end
|
307
373
|
|
308
374
|
# Highlights a snippet from a source and parse error.
|
@@ -36,8 +36,9 @@ module SyntaxTree
|
|
36
36
|
write(id: id, result: { capabilities: capabilities })
|
37
37
|
in method: "initialized"
|
38
38
|
# ignored
|
39
|
-
in method: "shutdown"
|
39
|
+
in method: "shutdown" # tolerate missing ID to be a good citizen
|
40
40
|
store.clear
|
41
|
+
write(id: request[:id], result: {})
|
41
42
|
return
|
42
43
|
in {
|
43
44
|
method: "textDocument/didChange",
|
data/lib/syntax_tree/node.rb
CHANGED
@@ -4813,7 +4813,7 @@ module SyntaxTree
|
|
4813
4813
|
# [HeredocBeg] the opening of the heredoc
|
4814
4814
|
attr_reader :beginning
|
4815
4815
|
|
4816
|
-
# [
|
4816
|
+
# [HeredocEnd] the ending of the heredoc
|
4817
4817
|
attr_reader :ending
|
4818
4818
|
|
4819
4819
|
# [Integer] how far to dedent the heredoc
|
@@ -4847,7 +4847,7 @@ module SyntaxTree
|
|
4847
4847
|
end
|
4848
4848
|
|
4849
4849
|
def child_nodes
|
4850
|
-
[beginning, *parts]
|
4850
|
+
[beginning, *parts, ending]
|
4851
4851
|
end
|
4852
4852
|
|
4853
4853
|
alias deconstruct child_nodes
|
@@ -4883,7 +4883,7 @@ module SyntaxTree
|
|
4883
4883
|
end
|
4884
4884
|
end
|
4885
4885
|
|
4886
|
-
q.
|
4886
|
+
q.format(ending)
|
4887
4887
|
end
|
4888
4888
|
end
|
4889
4889
|
end
|
@@ -4929,6 +4929,45 @@ module SyntaxTree
|
|
4929
4929
|
end
|
4930
4930
|
end
|
4931
4931
|
|
4932
|
+
# HeredocEnd represents the closing declaration of a heredoc.
|
4933
|
+
#
|
4934
|
+
# <<~DOC
|
4935
|
+
# contents
|
4936
|
+
# DOC
|
4937
|
+
#
|
4938
|
+
# In the example above the HeredocEnd node represents the closing DOC.
|
4939
|
+
class HeredocEnd < Node
|
4940
|
+
# [String] the closing declaration of the heredoc
|
4941
|
+
attr_reader :value
|
4942
|
+
|
4943
|
+
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
4944
|
+
attr_reader :comments
|
4945
|
+
|
4946
|
+
def initialize(value:, location:, comments: [])
|
4947
|
+
@value = value
|
4948
|
+
@location = location
|
4949
|
+
@comments = comments
|
4950
|
+
end
|
4951
|
+
|
4952
|
+
def accept(visitor)
|
4953
|
+
visitor.visit_heredoc_end(self)
|
4954
|
+
end
|
4955
|
+
|
4956
|
+
def child_nodes
|
4957
|
+
[]
|
4958
|
+
end
|
4959
|
+
|
4960
|
+
alias deconstruct child_nodes
|
4961
|
+
|
4962
|
+
def deconstruct_keys(_keys)
|
4963
|
+
{ value: value, location: location, comments: comments }
|
4964
|
+
end
|
4965
|
+
|
4966
|
+
def format(q)
|
4967
|
+
q.text(value)
|
4968
|
+
end
|
4969
|
+
end
|
4970
|
+
|
4932
4971
|
# HshPtn represents matching against a hash pattern using the Ruby 2.7+
|
4933
4972
|
# pattern matching syntax.
|
4934
4973
|
#
|
data/lib/syntax_tree/parser.rb
CHANGED
@@ -1640,9 +1640,19 @@ module SyntaxTree
|
|
1640
1640
|
def on_heredoc_end(value)
|
1641
1641
|
heredoc = @heredocs[-1]
|
1642
1642
|
|
1643
|
+
location =
|
1644
|
+
Location.token(
|
1645
|
+
line: lineno,
|
1646
|
+
char: char_pos,
|
1647
|
+
column: current_column,
|
1648
|
+
size: value.size + 1
|
1649
|
+
)
|
1650
|
+
|
1651
|
+
heredoc_end = HeredocEnd.new(value: value.chomp, location: location)
|
1652
|
+
|
1643
1653
|
@heredocs[-1] = Heredoc.new(
|
1644
1654
|
beginning: heredoc.beginning,
|
1645
|
-
ending:
|
1655
|
+
ending: heredoc_end,
|
1646
1656
|
dedent: heredoc.dedent,
|
1647
1657
|
parts: heredoc.parts,
|
1648
1658
|
location:
|
data/lib/syntax_tree/version.rb
CHANGED
@@ -497,6 +497,10 @@ module SyntaxTree
|
|
497
497
|
visit_token(node, "heredoc_beg")
|
498
498
|
end
|
499
499
|
|
500
|
+
def visit_heredoc_end(node)
|
501
|
+
visit_token(node, "heredoc_end")
|
502
|
+
end
|
503
|
+
|
500
504
|
def visit_hshptn(node)
|
501
505
|
node(node, "hshptn") do
|
502
506
|
field("constant", node.constant) if node.constant
|
data/lib/syntax_tree/visitor.rb
CHANGED
@@ -194,6 +194,9 @@ module SyntaxTree
|
|
194
194
|
# Visit a HeredocBeg node.
|
195
195
|
alias visit_heredoc_beg visit_child_nodes
|
196
196
|
|
197
|
+
# Visit a HeredocEnd node.
|
198
|
+
alias visit_heredoc_end visit_child_nodes
|
199
|
+
|
197
200
|
# Visit a HshPtn node.
|
198
201
|
alias visit_hshptn visit_child_nodes
|
199
202
|
|
data/lib/syntax_tree.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: syntax_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Newton
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: prettier_print
|
@@ -160,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
160
|
- !ruby/object:Gem::Version
|
161
161
|
version: '0'
|
162
162
|
requirements: []
|
163
|
-
rubygems_version: 3.
|
163
|
+
rubygems_version: 3.3.3
|
164
164
|
signing_key:
|
165
165
|
specification_version: 4
|
166
166
|
summary: A parser based on ripper
|