syntax_tree 3.3.0 → 3.4.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/.rubocop.yml +1 -1
- data/CHANGELOG.md +15 -1
- data/Gemfile.lock +6 -6
- data/README.md +24 -3
- data/lib/syntax_tree/cli.rb +103 -81
- data/lib/syntax_tree/language_server.rb +9 -3
- data/lib/syntax_tree/parser.rb +59 -13
- data/lib/syntax_tree/version.rb +1 -1
- data/lib/syntax_tree.rb +1 -0
- 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: 52707e3169fedfce017259222e4740b2e1032d210dfb628d454134eef578a7b6
|
4
|
+
data.tar.gz: aed3d5b3e6de7ed1e156c5b104007db6a01dab65e0ee80913afa2c1b5c63a5c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b81b4753a5e765712bd31081dedca6e50c67d04a7935a717fc56d278424154e6ed95b648ac1cbdd59b500ee44c2d8d89f57f52e3851f9615e378d8c9c2c6abe1
|
7
|
+
data.tar.gz: 32c95446f19190b8e73d9c3ce83ff4bd5573f5787f844cf695551a2d32c0c159af8c514714c4648a99be4e66189910bde7f01557ea973f6e17aaba66ace7fce2
|
data/.rubocop.yml
CHANGED
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
|
+
## [3.4.0] - 2022-08-19
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- [#127](https://github.com/ruby-syntax-tree/syntax_tree/pull/127) - Allow the language server to handle other file extensions if it is activated for those extensions.
|
14
|
+
- [#133](https://github.com/ruby-syntax-tree/syntax_tree/pull/133) - Add documentation on supporting vim and neovim.
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
|
18
|
+
- [#132](https://github.com/ruby-syntax-tree/syntax_tree/pull/132) - Provide better error messages when end quotes and end keywords are missing from tokens.
|
19
|
+
- [#134](https://github.com/ruby-syntax-tree/syntax_tree/pull/134) - Ensure the correct `end` keyword is getting removed by `begin..rescue` clauses.
|
20
|
+
- [#137](https://github.com/ruby-syntax-tree/syntax_tree/pull/137) - Better support regular expressions with no ending token.
|
21
|
+
|
9
22
|
## [3.3.0] - 2022-08-02
|
10
23
|
|
11
24
|
### Added
|
@@ -319,7 +332,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
|
|
319
332
|
|
320
333
|
- 🎉 Initial release! 🎉
|
321
334
|
|
322
|
-
[unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v3.
|
335
|
+
[unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v3.4.0...HEAD
|
336
|
+
[3.4.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v3.3.0...v3.4.0
|
323
337
|
[3.3.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v3.2.1...v3.3.0
|
324
338
|
[3.2.1]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v3.2.0...v3.2.1
|
325
339
|
[3.2.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v3.1.0...v3.2.0
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
syntax_tree (3.
|
4
|
+
syntax_tree (3.4.0)
|
5
5
|
prettier_print
|
6
6
|
|
7
7
|
GEM
|
@@ -12,24 +12,24 @@ GEM
|
|
12
12
|
json (2.6.2)
|
13
13
|
minitest (5.16.2)
|
14
14
|
parallel (1.22.1)
|
15
|
-
parser (3.1.2.
|
15
|
+
parser (3.1.2.1)
|
16
16
|
ast (~> 2.4.1)
|
17
17
|
prettier_print (0.1.0)
|
18
18
|
rainbow (3.1.1)
|
19
19
|
rake (13.0.6)
|
20
20
|
regexp_parser (2.5.0)
|
21
21
|
rexml (3.2.5)
|
22
|
-
rubocop (1.
|
22
|
+
rubocop (1.35.0)
|
23
23
|
json (~> 2.3)
|
24
24
|
parallel (~> 1.10)
|
25
|
-
parser (>= 3.1.
|
25
|
+
parser (>= 3.1.2.1)
|
26
26
|
rainbow (>= 2.2.2, < 4.0)
|
27
27
|
regexp_parser (>= 1.8, < 3.0)
|
28
28
|
rexml (>= 3.2.5, < 4.0)
|
29
|
-
rubocop-ast (>= 1.
|
29
|
+
rubocop-ast (>= 1.20.1, < 2.0)
|
30
30
|
ruby-progressbar (~> 1.7)
|
31
31
|
unicode-display_width (>= 1.4.0, < 3.0)
|
32
|
-
rubocop-ast (1.
|
32
|
+
rubocop-ast (1.21.0)
|
33
33
|
parser (>= 3.1.1.0)
|
34
34
|
ruby-progressbar (1.11.0)
|
35
35
|
simplecov (0.21.2)
|
data/README.md
CHANGED
@@ -20,6 +20,7 @@ It is built with only standard library dependencies. It additionally ships with
|
|
20
20
|
- [match](#match)
|
21
21
|
- [write](#write)
|
22
22
|
- [Configuration](#configuration)
|
23
|
+
- [Globbing](#globbing)
|
23
24
|
- [Library](#library)
|
24
25
|
- [SyntaxTree.read(filepath)](#syntaxtreereadfilepath)
|
25
26
|
- [SyntaxTree.parse(source)](#syntaxtreeparsesource)
|
@@ -44,7 +45,7 @@ It is built with only standard library dependencies. It additionally ships with
|
|
44
45
|
- [Integration](#integration)
|
45
46
|
- [Rake](#rake)
|
46
47
|
- [RuboCop](#rubocop)
|
47
|
-
- [
|
48
|
+
- [Editors](#editors)
|
48
49
|
- [Contributing](#contributing)
|
49
50
|
- [License](#license)
|
50
51
|
|
@@ -245,6 +246,24 @@ This should be a text file with each argument on a separate line.
|
|
245
246
|
|
246
247
|
If this file is present, it will _always_ be used for CLI commands. You can also pass options from the command line as in the examples above. The options in the `.streerc` file are passed to the CLI first, then the arguments from the command line. In the case of exclusive options (e.g. `--print-width`), this means that the command line options override what's in the config file. In the case of options that can take multiple inputs (e.g. `--plugins`), the effect is additive. That is, the plugins passed from the command line will be loaded _in addition to_ the plugins in the config file.
|
247
248
|
|
249
|
+
### Globbing
|
250
|
+
|
251
|
+
When running commands with `stree`, it's common to pass in lists of files. For example:
|
252
|
+
|
253
|
+
```sh
|
254
|
+
stree write 'lib/*.rb' 'test/*.rb'
|
255
|
+
```
|
256
|
+
|
257
|
+
The commands in the CLI accept any number of arguments. This means you _could_ pass `**/*.rb` (note the lack of quotes). This would make your shell expand out the file paths listed according to its own rules. (For example, [here](https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html) are the rules for GNU bash.)
|
258
|
+
|
259
|
+
However, it's recommended to instead use quotes, which means that Ruby is responsible for performing the file path expansion instead. This ensures a consistent experience across different environments and shells. The globs must follow the Ruby-specific globbing syntax as specified in the documentation for [Dir](https://ruby-doc.org/core-3.1.1/Dir.html#method-c-glob).
|
260
|
+
|
261
|
+
Baked into this syntax is the ability to provide exceptions to file name patterns as well. For example, if you are in a Rails app and want to exclude files named `schema.rb` but write all other Ruby files, you can use the following syntax:
|
262
|
+
|
263
|
+
```shell
|
264
|
+
stree write "**/{[!schema]*,*}.rb"
|
265
|
+
```
|
266
|
+
|
248
267
|
## Library
|
249
268
|
|
250
269
|
Syntax Tree can be used as a library to access the syntax tree underlying Ruby source code.
|
@@ -548,9 +567,11 @@ inherit_gem:
|
|
548
567
|
syntax_tree: config/rubocop.yml
|
549
568
|
```
|
550
569
|
|
551
|
-
###
|
570
|
+
### Editors
|
552
571
|
|
553
|
-
|
572
|
+
* [Neovim](https://neovim.io/) - [neovim/nvim-lspconfig](https://github.com/neovim/nvim-lspconfig).
|
573
|
+
* [Vim](https://www.vim.org/) - [dense-analysis/ale](https://github.com/dense-analysis/ale).
|
574
|
+
* [VSCode](https://code.visualstudio.com/) - [ruby-syntax-tree/vscode-syntax-tree](https://github.com/ruby-syntax-tree/vscode-syntax-tree).
|
554
575
|
|
555
576
|
## Contributing
|
556
577
|
|
data/lib/syntax_tree/cli.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "optparse"
|
4
|
+
|
3
5
|
module SyntaxTree
|
4
6
|
# Syntax Tree ships with the `stree` CLI, which can be used to inspect and
|
5
7
|
# manipulate Ruby code. This module is responsible for powering that CLI.
|
6
8
|
module CLI
|
7
|
-
CONFIG_FILE = ".streerc"
|
8
|
-
|
9
9
|
# A utility wrapper around colored strings in the output.
|
10
10
|
class Color
|
11
11
|
attr_reader :value, :code
|
@@ -70,6 +70,12 @@ module SyntaxTree
|
|
70
70
|
|
71
71
|
# The parent action class for the CLI that implements the basics.
|
72
72
|
class Action
|
73
|
+
attr_reader :options
|
74
|
+
|
75
|
+
def initialize(options)
|
76
|
+
@options = options
|
77
|
+
end
|
78
|
+
|
73
79
|
def run(item)
|
74
80
|
end
|
75
81
|
|
@@ -93,15 +99,9 @@ module SyntaxTree
|
|
93
99
|
class UnformattedError < StandardError
|
94
100
|
end
|
95
101
|
|
96
|
-
attr_reader :print_width
|
97
|
-
|
98
|
-
def initialize(print_width:)
|
99
|
-
@print_width = print_width
|
100
|
-
end
|
101
|
-
|
102
102
|
def run(item)
|
103
103
|
source = item.source
|
104
|
-
if source != item.handler.format(source, print_width)
|
104
|
+
if source != item.handler.format(source, options.print_width)
|
105
105
|
raise UnformattedError
|
106
106
|
end
|
107
107
|
rescue StandardError
|
@@ -124,19 +124,13 @@ module SyntaxTree
|
|
124
124
|
class NonIdempotentFormatError < StandardError
|
125
125
|
end
|
126
126
|
|
127
|
-
attr_reader :print_width
|
128
|
-
|
129
|
-
def initialize(print_width:)
|
130
|
-
@print_width = print_width
|
131
|
-
end
|
132
|
-
|
133
127
|
def run(item)
|
134
128
|
handler = item.handler
|
135
129
|
|
136
130
|
warning = "[#{Color.yellow("warn")}] #{item.filepath}"
|
137
|
-
formatted = handler.format(item.source, print_width)
|
131
|
+
formatted = handler.format(item.source, options.print_width)
|
138
132
|
|
139
|
-
if formatted != handler.format(formatted, print_width)
|
133
|
+
if formatted != handler.format(formatted, options.print_width)
|
140
134
|
raise NonIdempotentFormatError
|
141
135
|
end
|
142
136
|
rescue StandardError
|
@@ -166,14 +160,8 @@ module SyntaxTree
|
|
166
160
|
|
167
161
|
# An action of the CLI that formats the input source and prints it out.
|
168
162
|
class Format < Action
|
169
|
-
attr_reader :print_width
|
170
|
-
|
171
|
-
def initialize(print_width:)
|
172
|
-
@print_width = print_width
|
173
|
-
end
|
174
|
-
|
175
163
|
def run(item)
|
176
|
-
puts item.handler.format(item.source, print_width)
|
164
|
+
puts item.handler.format(item.source, options.print_width)
|
177
165
|
end
|
178
166
|
end
|
179
167
|
|
@@ -197,18 +185,12 @@ module SyntaxTree
|
|
197
185
|
# An action of the CLI that formats the input source and writes the
|
198
186
|
# formatted output back to the file.
|
199
187
|
class Write < Action
|
200
|
-
attr_reader :print_width
|
201
|
-
|
202
|
-
def initialize(print_width:)
|
203
|
-
@print_width = print_width
|
204
|
-
end
|
205
|
-
|
206
188
|
def run(item)
|
207
189
|
filepath = item.filepath
|
208
190
|
start = Time.now
|
209
191
|
|
210
192
|
source = item.source
|
211
|
-
formatted = item.handler.format(source, print_width)
|
193
|
+
formatted = item.handler.format(source, options.print_width)
|
212
194
|
File.write(filepath, formatted) if filepath != :stdin
|
213
195
|
|
214
196
|
color = source == formatted ? Color.gray(filepath) : filepath
|
@@ -264,74 +246,114 @@ module SyntaxTree
|
|
264
246
|
The maximum line width to use when formatting.
|
265
247
|
HELP
|
266
248
|
|
249
|
+
# This represents all of the options that can be passed to the CLI. It is
|
250
|
+
# responsible for parsing the list and then returning the file paths at the
|
251
|
+
# end.
|
252
|
+
class Options
|
253
|
+
attr_reader :print_width
|
254
|
+
|
255
|
+
def initialize(print_width: DEFAULT_PRINT_WIDTH)
|
256
|
+
@print_width = print_width
|
257
|
+
end
|
258
|
+
|
259
|
+
def parse(arguments)
|
260
|
+
parser.parse(arguments)
|
261
|
+
end
|
262
|
+
|
263
|
+
private
|
264
|
+
|
265
|
+
def parser
|
266
|
+
OptionParser.new do |opts|
|
267
|
+
# If there are any plugins specified on the command line, then load
|
268
|
+
# them by requiring them here. We do this by transforming something
|
269
|
+
# like
|
270
|
+
#
|
271
|
+
# stree format --plugins=haml template.haml
|
272
|
+
#
|
273
|
+
# into
|
274
|
+
#
|
275
|
+
# require "syntax_tree/haml"
|
276
|
+
#
|
277
|
+
opts.on("--plugins=PLUGINS") do |plugins|
|
278
|
+
plugins.split(",").each { |plugin| require "syntax_tree/#{plugin}" }
|
279
|
+
end
|
280
|
+
|
281
|
+
# If there is a print width specified on the command line, then
|
282
|
+
# parse that out here and use it when formatting.
|
283
|
+
opts.on("--print-width=NUMBER", Integer) do |print_width|
|
284
|
+
@print_width = print_width
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
# We allow a minimal configuration file to act as additional command line
|
291
|
+
# arguments to the CLI. Each line of the config file should be a new
|
292
|
+
# argument, as in:
|
293
|
+
#
|
294
|
+
# --plugins=plugin/single_quote
|
295
|
+
# --print-width=100
|
296
|
+
#
|
297
|
+
# When invoking the CLI, we will read this config file and then parse it if
|
298
|
+
# it exists in the current working directory.
|
299
|
+
class ConfigFile
|
300
|
+
FILENAME = ".streerc"
|
301
|
+
|
302
|
+
attr_reader :filepath
|
303
|
+
|
304
|
+
def initialize
|
305
|
+
@filepath = File.join(Dir.pwd, FILENAME)
|
306
|
+
end
|
307
|
+
|
308
|
+
def exists?
|
309
|
+
File.readable?(filepath)
|
310
|
+
end
|
311
|
+
|
312
|
+
def arguments
|
313
|
+
exists? ? File.readlines(filepath, chomp: true) : []
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
267
317
|
class << self
|
268
318
|
# Run the CLI over the given array of strings that make up the arguments
|
269
319
|
# passed to the invocation.
|
270
320
|
def run(argv)
|
271
321
|
name, *arguments = argv
|
272
|
-
print_width = DEFAULT_PRINT_WIDTH
|
273
|
-
|
274
|
-
config_file = File.join(Dir.pwd, CONFIG_FILE)
|
275
|
-
if File.readable?(config_file)
|
276
|
-
arguments.unshift(*File.readlines(config_file, chomp: true))
|
277
|
-
end
|
278
322
|
|
279
|
-
|
280
|
-
|
281
|
-
when /^--plugins=(.+)$/
|
282
|
-
# If there are any plugins specified on the command line, then load
|
283
|
-
# them by requiring them here. We do this by transforming something
|
284
|
-
# like
|
285
|
-
#
|
286
|
-
# stree format --plugins=haml template.haml
|
287
|
-
#
|
288
|
-
# into
|
289
|
-
#
|
290
|
-
# require "syntax_tree/haml"
|
291
|
-
#
|
292
|
-
$1.split(",").each { |plugin| require "syntax_tree/#{plugin}" }
|
293
|
-
when /^--print-width=(\d+)$/
|
294
|
-
# If there is a print width specified on the command line, then
|
295
|
-
# parse that out here and use it when formatting.
|
296
|
-
print_width = Integer($1)
|
297
|
-
else
|
298
|
-
warn("Unknown CLI option: #{argument}")
|
299
|
-
warn(HELP)
|
300
|
-
return 1
|
301
|
-
end
|
302
|
-
end
|
323
|
+
config_file = ConfigFile.new
|
324
|
+
arguments.unshift(*config_file.arguments)
|
303
325
|
|
304
|
-
|
305
|
-
|
306
|
-
puts HELP
|
307
|
-
return 0
|
308
|
-
when "lsp"
|
309
|
-
require "syntax_tree/language_server"
|
310
|
-
LanguageServer.new(print_width: print_width).run
|
311
|
-
return 0
|
312
|
-
when "version"
|
313
|
-
puts SyntaxTree::VERSION
|
314
|
-
return 0
|
315
|
-
end
|
326
|
+
options = Options.new
|
327
|
+
options.parse(arguments)
|
316
328
|
|
317
329
|
action =
|
318
330
|
case name
|
319
331
|
when "a", "ast"
|
320
|
-
AST.new
|
332
|
+
AST.new(options)
|
321
333
|
when "c", "check"
|
322
|
-
Check.new(
|
334
|
+
Check.new(options)
|
323
335
|
when "debug"
|
324
|
-
Debug.new(
|
336
|
+
Debug.new(options)
|
325
337
|
when "doc"
|
326
|
-
Doc.new
|
338
|
+
Doc.new(options)
|
339
|
+
when "help"
|
340
|
+
puts HELP
|
341
|
+
return 0
|
327
342
|
when "j", "json"
|
328
|
-
Json.new
|
343
|
+
Json.new(options)
|
344
|
+
when "lsp"
|
345
|
+
require "syntax_tree/language_server"
|
346
|
+
LanguageServer.new(print_width: options.print_width).run
|
347
|
+
return 0
|
329
348
|
when "m", "match"
|
330
|
-
Match.new
|
349
|
+
Match.new(options)
|
331
350
|
when "f", "format"
|
332
|
-
Format.new(
|
351
|
+
Format.new(options)
|
352
|
+
when "version"
|
353
|
+
puts SyntaxTree::VERSION
|
354
|
+
return 0
|
333
355
|
when "w", "write"
|
334
|
-
Write.new(
|
356
|
+
Write.new(options)
|
335
357
|
else
|
336
358
|
warn(HELP)
|
337
359
|
return 1
|
@@ -56,7 +56,7 @@ module SyntaxTree
|
|
56
56
|
store.delete(uri)
|
57
57
|
in { method: "textDocument/formatting", id:, params: { textDocument: { uri: } } }
|
58
58
|
contents = store[uri]
|
59
|
-
write(id: id, result: contents ? [format(store[uri])] : nil)
|
59
|
+
write(id: id, result: contents ? [format(store[uri], uri.split(".").last)] : nil)
|
60
60
|
in { method: "textDocument/inlayHint", id:, params: { textDocument: { uri: } } }
|
61
61
|
contents = store[uri]
|
62
62
|
write(id: id, result: contents ? inlay_hints(store[uri]) : nil)
|
@@ -86,7 +86,9 @@ module SyntaxTree
|
|
86
86
|
}
|
87
87
|
end
|
88
88
|
|
89
|
-
def format(source)
|
89
|
+
def format(source, extension)
|
90
|
+
text = SyntaxTree::HANDLERS[".#{extension}"].format(source, print_width)
|
91
|
+
|
90
92
|
{
|
91
93
|
range: {
|
92
94
|
start: {
|
@@ -98,7 +100,7 @@ module SyntaxTree
|
|
98
100
|
character: 0
|
99
101
|
}
|
100
102
|
},
|
101
|
-
newText:
|
103
|
+
newText: text
|
102
104
|
}
|
103
105
|
end
|
104
106
|
|
@@ -117,5 +119,9 @@ module SyntaxTree
|
|
117
119
|
output.print("Content-Length: #{response.bytesize}\r\n\r\n#{response}")
|
118
120
|
output.flush
|
119
121
|
end
|
122
|
+
|
123
|
+
def log(message)
|
124
|
+
write(method: "window/logMessage", params: { type: 4, message: message })
|
125
|
+
end
|
120
126
|
end
|
121
127
|
end
|
data/lib/syntax_tree/parser.rb
CHANGED
@@ -57,6 +57,26 @@ module SyntaxTree
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
+
# This represents all of the tokens coming back from the lexer. It is
|
61
|
+
# replacing a simple array because it keeps track of the last deleted token
|
62
|
+
# from the list for better error messages.
|
63
|
+
class TokenList < SimpleDelegator
|
64
|
+
attr_reader :last_deleted
|
65
|
+
|
66
|
+
def initialize(object)
|
67
|
+
super
|
68
|
+
@last_deleted = nil
|
69
|
+
end
|
70
|
+
|
71
|
+
def delete(value)
|
72
|
+
@last_deleted = super || @last_deleted
|
73
|
+
end
|
74
|
+
|
75
|
+
def delete_at(index)
|
76
|
+
@last_deleted = super
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
60
80
|
# [String] the source being parsed
|
61
81
|
attr_reader :source
|
62
82
|
|
@@ -124,7 +144,7 @@ module SyntaxTree
|
|
124
144
|
# Most of the time, when a parser event consumes one of these events, it
|
125
145
|
# will be deleted from the list. So ideally, this list stays pretty short
|
126
146
|
# over the course of parsing a source string.
|
127
|
-
@tokens = []
|
147
|
+
@tokens = TokenList.new([])
|
128
148
|
|
129
149
|
# Here we're going to build up a list of SingleByteString or
|
130
150
|
# MultiByteString objects. They're each going to represent a string in the
|
@@ -174,6 +194,33 @@ module SyntaxTree
|
|
174
194
|
line[column].to_i - line.start
|
175
195
|
end
|
176
196
|
|
197
|
+
# Returns the current location that is being looked at for the parser for
|
198
|
+
# the purpose of locating the error.
|
199
|
+
def find_token_error(location)
|
200
|
+
if location
|
201
|
+
# If we explicitly passed a location into this find_token_error method,
|
202
|
+
# that means that's the source of the error, so we'll use that
|
203
|
+
# information for our error object.
|
204
|
+
lineno = location.start_line
|
205
|
+
[lineno, location.start_char - line_counts[lineno - 1].start]
|
206
|
+
elsif lineno && column
|
207
|
+
# If there is a line number associated with the current ripper state,
|
208
|
+
# then we'll use that information to generate the error.
|
209
|
+
[lineno, column]
|
210
|
+
elsif (location = tokens.last_deleted&.location)
|
211
|
+
# If we've already deleted a token from the list of tokens that we are
|
212
|
+
# consuming, then we'll fall back to that token's location.
|
213
|
+
lineno = location.start_line
|
214
|
+
[lineno, location.start_char - line_counts[lineno - 1].start]
|
215
|
+
else
|
216
|
+
# Finally, it's possible that when we hit this error the parsing thread
|
217
|
+
# for ripper has died. In that case, lineno and column both return nil.
|
218
|
+
# So we're just going to set it to line 1, column 0 in the hopes that
|
219
|
+
# that makes any sense.
|
220
|
+
[1, 0]
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
177
224
|
# As we build up a list of tokens, we'll periodically need to go backwards
|
178
225
|
# and find the ones that we've already hit in order to determine the
|
179
226
|
# location information for nodes that use them. For example, if you have a
|
@@ -201,14 +248,7 @@ module SyntaxTree
|
|
201
248
|
unless index
|
202
249
|
token = value == :any ? type.name.split("::", 2).last : value
|
203
250
|
message = "Cannot find expected #{token}"
|
204
|
-
|
205
|
-
if location
|
206
|
-
lineno = location.start_line
|
207
|
-
column = location.start_char - line_counts[lineno - 1].start
|
208
|
-
raise ParseError.new(message, lineno, column)
|
209
|
-
else
|
210
|
-
raise ParseError.new(message, lineno, column)
|
211
|
-
end
|
251
|
+
raise ParseError.new(message, *find_token_error(location))
|
212
252
|
end
|
213
253
|
|
214
254
|
tokens.delete_at(index)
|
@@ -677,8 +717,7 @@ module SyntaxTree
|
|
677
717
|
else
|
678
718
|
keyword = find_token(Kw, "begin")
|
679
719
|
end_location =
|
680
|
-
if bodystmt.
|
681
|
-
bodystmt.else_clause
|
720
|
+
if bodystmt.else_clause
|
682
721
|
bodystmt.location
|
683
722
|
else
|
684
723
|
find_token(Kw, "end").location
|
@@ -2798,14 +2837,21 @@ module SyntaxTree
|
|
2798
2837
|
# :call-seq:
|
2799
2838
|
# on_regexp_literal: (
|
2800
2839
|
# RegexpContent regexp_content,
|
2801
|
-
# RegexpEnd ending
|
2840
|
+
# (nil | RegexpEnd) ending
|
2802
2841
|
# ) -> RegexpLiteral
|
2803
2842
|
def on_regexp_literal(regexp_content, ending)
|
2843
|
+
location = regexp_content.location
|
2844
|
+
|
2845
|
+
if ending.nil?
|
2846
|
+
message = "Cannot find expected regular expression ending"
|
2847
|
+
raise ParseError.new(message, *find_token_error(location))
|
2848
|
+
end
|
2849
|
+
|
2804
2850
|
RegexpLiteral.new(
|
2805
2851
|
beginning: regexp_content.beginning,
|
2806
2852
|
ending: ending.value,
|
2807
2853
|
parts: regexp_content.parts,
|
2808
|
-
location:
|
2854
|
+
location: location.to(ending.location)
|
2809
2855
|
)
|
2810
2856
|
end
|
2811
2857
|
|
data/lib/syntax_tree/version.rb
CHANGED
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: 3.
|
4
|
+
version: 3.4.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-08-
|
11
|
+
date: 2022-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: prettier_print
|