syntax_tree 2.6.0 → 2.7.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 +12 -1
- data/Gemfile.lock +1 -1
- data/README.md +15 -0
- data/lib/syntax_tree/basic_visitor.rb +74 -0
- data/lib/syntax_tree/node.rb +39 -14
- data/lib/syntax_tree/version.rb +1 -1
- data/lib/syntax_tree/visitor/field_visitor.rb +1 -3
- data/lib/syntax_tree/visitor.rb +1 -66
- data/lib/syntax_tree.rb +2 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 126d8e2e86fc77aeab82d0130da3ed5d20b85ecbfb6cfd84ea4056f48c9c5cb9
|
4
|
+
data.tar.gz: c7abdbc2427c75561ae5e08b55345ecce65c4ff4cf6c5b6c02151734f9e54f5c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b06e13f4f4ff47b250a5423e3e47de324c77ca4cd965539a040edc0b02b4aa9e78367cd5a8a5fad504f80dea82029798e8001d82eddf042e745b6080041a389
|
7
|
+
data.tar.gz: '0910deb51a5d6a458530923f5014b02030092b957f056e6339ef252ab6cb951014f738e2443d44d28e836dbb399567f934ac21b1b26e8ea75ddb8782475f4647'
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,16 @@ 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.7.0] - 2022-05-19
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- [#88](https://github.com/ruby-syntax-tree/syntax_tree/pull/88) - Provide a `SyntaxTree::BasicVisitor` that has no visit methods implemented.
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
|
17
|
+
- [#90](https://github.com/ruby-syntax-tree/syntax_tree/pull/90) - Provide better formatting for `SyntaxTree::AryPtn` when its nested inside a `SyntaxTree::RAssign`.
|
18
|
+
|
9
19
|
## [2.6.0] - 2022-05-16
|
10
20
|
|
11
21
|
### Added
|
@@ -236,7 +246,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
|
|
236
246
|
|
237
247
|
- 🎉 Initial release! 🎉
|
238
248
|
|
239
|
-
[unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.
|
249
|
+
[unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.7.0...HEAD
|
250
|
+
[2.7.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.6.0...v2.7.0
|
240
251
|
[2.6.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.5.0...v2.6.0
|
241
252
|
[2.5.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.4.1...v2.5.0
|
242
253
|
[2.4.1]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.4.0...v2.4.1
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -32,6 +32,7 @@ It is built with only standard library dependencies. It additionally ships with
|
|
32
32
|
- [construct_keys](#construct_keys)
|
33
33
|
- [Visitor](#visitor)
|
34
34
|
- [visit_method](#visit_method)
|
35
|
+
- [BasicVisitor](#basicvisitor)
|
35
36
|
- [Language server](#language-server)
|
36
37
|
- [textDocument/formatting](#textdocumentformatting)
|
37
38
|
- [textDocument/inlayHints](#textdocumentinlayhints)
|
@@ -373,6 +374,20 @@ Did you mean? visit_binary
|
|
373
374
|
from bin/console:8:in `<main>'
|
374
375
|
```
|
375
376
|
|
377
|
+
### BasicVisitor
|
378
|
+
|
379
|
+
When you're defining your own visitor, by default it will walk down the tree even if you don't define `visit_*` methods. This is to ensure you can define a subset of the necessary methods in order to only interact with the nodes you're interested in. If you'd like to change this default to instead raise an error if you visit a node you haven't explicitly handled, you can instead inherit from `BasicVisitor`.
|
380
|
+
|
381
|
+
```ruby
|
382
|
+
class MyVisitor < SyntaxTree::BasicVisitor
|
383
|
+
def visit_int(node)
|
384
|
+
# ...
|
385
|
+
end
|
386
|
+
end
|
387
|
+
```
|
388
|
+
|
389
|
+
The visitor defined above will error out unless it's only visiting a `SyntaxTree::Int` node. This is useful in a couple of ways, e.g., if you're trying to define a visitor to handle the whole tree but it's currently a work-in-progress.
|
390
|
+
|
376
391
|
## Language server
|
377
392
|
|
378
393
|
Syntax Tree additionally ships with a language server conforming to the [language server protocol](https://microsoft.github.io/language-server-protocol/). It can be invoked through the CLI by running:
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SyntaxTree
|
4
|
+
# BasicVisitor is the parent class of the Visitor class that provides the
|
5
|
+
# ability to walk down the tree. It does not define any handlers, so you
|
6
|
+
# should extend this class if you want your visitor to raise an error if you
|
7
|
+
# attempt to visit a node that you don't handle.
|
8
|
+
class BasicVisitor
|
9
|
+
# This is raised when you use the Visitor.visit_method method and it fails.
|
10
|
+
# It is correctable to through DidYouMean.
|
11
|
+
class VisitMethodError < StandardError
|
12
|
+
attr_reader :visit_method
|
13
|
+
|
14
|
+
def initialize(visit_method)
|
15
|
+
@visit_method = visit_method
|
16
|
+
super("Invalid visit method: #{visit_method}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# This class is used by DidYouMean to offer corrections to invalid visit
|
21
|
+
# method names.
|
22
|
+
class VisitMethodChecker
|
23
|
+
attr_reader :visit_method
|
24
|
+
|
25
|
+
def initialize(error)
|
26
|
+
@visit_method = error.visit_method
|
27
|
+
end
|
28
|
+
|
29
|
+
def corrections
|
30
|
+
@corrections ||=
|
31
|
+
DidYouMean::SpellChecker.new(
|
32
|
+
dictionary: Visitor.visit_methods
|
33
|
+
).correct(visit_method)
|
34
|
+
end
|
35
|
+
|
36
|
+
DidYouMean.correct_error(VisitMethodError, self)
|
37
|
+
end
|
38
|
+
|
39
|
+
class << self
|
40
|
+
# This method is here to help folks write visitors.
|
41
|
+
#
|
42
|
+
# It's not always easy to ensure you're writing the correct method name in
|
43
|
+
# the visitor since it's perfectly valid to define methods that don't
|
44
|
+
# override these parent methods.
|
45
|
+
#
|
46
|
+
# If you use this method, you can ensure you're writing the correct method
|
47
|
+
# name. It will raise an error if the visit method you're defining isn't
|
48
|
+
# actually a method on the parent visitor.
|
49
|
+
def visit_method(method_name)
|
50
|
+
return if visit_methods.include?(method_name)
|
51
|
+
|
52
|
+
raise VisitMethodError, method_name
|
53
|
+
end
|
54
|
+
|
55
|
+
# This is the list of all of the valid visit methods.
|
56
|
+
def visit_methods
|
57
|
+
@visit_methods ||=
|
58
|
+
Visitor.instance_methods.grep(/^visit_(?!child_nodes)/)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def visit(node)
|
63
|
+
node&.accept(self)
|
64
|
+
end
|
65
|
+
|
66
|
+
def visit_all(nodes)
|
67
|
+
nodes.map { |node| visit(node) }
|
68
|
+
end
|
69
|
+
|
70
|
+
def visit_child_nodes(node)
|
71
|
+
visit_all(node.child_nodes)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/syntax_tree/node.rb
CHANGED
@@ -1131,7 +1131,11 @@ module SyntaxTree
|
|
1131
1131
|
q.group do
|
1132
1132
|
q.format(constant)
|
1133
1133
|
q.text("[")
|
1134
|
-
q.
|
1134
|
+
q.indent do
|
1135
|
+
q.breakable("")
|
1136
|
+
q.seplist(parts) { |part| q.format(part) }
|
1137
|
+
end
|
1138
|
+
q.breakable("")
|
1135
1139
|
q.text("]")
|
1136
1140
|
end
|
1137
1141
|
|
@@ -1141,7 +1145,11 @@ module SyntaxTree
|
|
1141
1145
|
parent = q.parent
|
1142
1146
|
if parts.length == 1 || PATTERNS.include?(parent.class)
|
1143
1147
|
q.text("[")
|
1144
|
-
q.
|
1148
|
+
q.indent do
|
1149
|
+
q.breakable("")
|
1150
|
+
q.seplist(parts) { |part| q.format(part) }
|
1151
|
+
end
|
1152
|
+
q.breakable("")
|
1145
1153
|
q.text("]")
|
1146
1154
|
elsif parts.empty?
|
1147
1155
|
q.text("[]")
|
@@ -2777,10 +2785,17 @@ module SyntaxTree
|
|
2777
2785
|
q.format(value)
|
2778
2786
|
q.text(" ")
|
2779
2787
|
q.format(operator)
|
2780
|
-
|
2781
|
-
|
2782
|
-
|
2783
|
-
|
2788
|
+
|
2789
|
+
case pattern
|
2790
|
+
in AryPtn | FndPtn | HshPtn
|
2791
|
+
q.text(" ")
|
2792
|
+
q.format(pattern)
|
2793
|
+
else
|
2794
|
+
q.group do
|
2795
|
+
q.indent do
|
2796
|
+
q.breakable
|
2797
|
+
q.format(pattern)
|
2798
|
+
end
|
2784
2799
|
end
|
2785
2800
|
end
|
2786
2801
|
end
|
@@ -4573,16 +4588,26 @@ module SyntaxTree
|
|
4573
4588
|
|
4574
4589
|
def format(q)
|
4575
4590
|
q.format(constant) if constant
|
4576
|
-
q.group(0, "[", "]") do
|
4577
|
-
q.text("*")
|
4578
|
-
q.format(left)
|
4579
|
-
q.comma_breakable
|
4580
4591
|
|
4581
|
-
|
4582
|
-
q.
|
4592
|
+
q.group do
|
4593
|
+
q.text("[")
|
4583
4594
|
|
4584
|
-
q.
|
4585
|
-
|
4595
|
+
q.indent do
|
4596
|
+
q.breakable("")
|
4597
|
+
|
4598
|
+
q.text("*")
|
4599
|
+
q.format(left)
|
4600
|
+
q.comma_breakable
|
4601
|
+
|
4602
|
+
q.seplist(values) { |value| q.format(value) }
|
4603
|
+
q.comma_breakable
|
4604
|
+
|
4605
|
+
q.text("*")
|
4606
|
+
q.format(right)
|
4607
|
+
end
|
4608
|
+
|
4609
|
+
q.breakable("")
|
4610
|
+
q.text("]")
|
4586
4611
|
end
|
4587
4612
|
end
|
4588
4613
|
end
|
data/lib/syntax_tree/version.rb
CHANGED
@@ -49,9 +49,7 @@ module SyntaxTree
|
|
49
49
|
# of circumstances, like when visiting the list of optional parameters
|
50
50
|
# defined on a method.
|
51
51
|
#
|
52
|
-
class FieldVisitor <
|
53
|
-
attr_reader :q
|
54
|
-
|
52
|
+
class FieldVisitor < BasicVisitor
|
55
53
|
def visit_aref(node)
|
56
54
|
node(node, "aref") do
|
57
55
|
field("collection", node.collection)
|
data/lib/syntax_tree/visitor.rb
CHANGED
@@ -4,72 +4,7 @@ module SyntaxTree
|
|
4
4
|
# Visitor is a parent class that provides the ability to walk down the tree
|
5
5
|
# and handle a subset of nodes. By defining your own subclass, you can
|
6
6
|
# explicitly handle a node type by defining a visit_* method.
|
7
|
-
class Visitor
|
8
|
-
# This is raised when you use the Visitor.visit_method method and it fails.
|
9
|
-
# It is correctable to through DidYouMean.
|
10
|
-
class VisitMethodError < StandardError
|
11
|
-
attr_reader :visit_method
|
12
|
-
|
13
|
-
def initialize(visit_method)
|
14
|
-
@visit_method = visit_method
|
15
|
-
super("Invalid visit method: #{visit_method}")
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# This class is used by DidYouMean to offer corrections to invalid visit
|
20
|
-
# method names.
|
21
|
-
class VisitMethodChecker
|
22
|
-
attr_reader :visit_method
|
23
|
-
|
24
|
-
def initialize(error)
|
25
|
-
@visit_method = error.visit_method
|
26
|
-
end
|
27
|
-
|
28
|
-
def corrections
|
29
|
-
@corrections ||=
|
30
|
-
DidYouMean::SpellChecker.new(
|
31
|
-
dictionary: Visitor.visit_methods
|
32
|
-
).correct(visit_method)
|
33
|
-
end
|
34
|
-
|
35
|
-
DidYouMean.correct_error(VisitMethodError, self)
|
36
|
-
end
|
37
|
-
|
38
|
-
class << self
|
39
|
-
# This method is here to help folks write visitors.
|
40
|
-
#
|
41
|
-
# It's not always easy to ensure you're writing the correct method name in
|
42
|
-
# the visitor since it's perfectly valid to define methods that don't
|
43
|
-
# override these parent methods.
|
44
|
-
#
|
45
|
-
# If you use this method, you can ensure you're writing the correct method
|
46
|
-
# name. It will raise an error if the visit method you're defining isn't
|
47
|
-
# actually a method on the parent visitor.
|
48
|
-
def visit_method(method_name)
|
49
|
-
return if visit_methods.include?(method_name)
|
50
|
-
|
51
|
-
raise VisitMethodError, method_name
|
52
|
-
end
|
53
|
-
|
54
|
-
# This is the list of all of the valid visit methods.
|
55
|
-
def visit_methods
|
56
|
-
@visit_methods ||=
|
57
|
-
Visitor.instance_methods.grep(/^visit_(?!child_nodes)/)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def visit(node)
|
62
|
-
node&.accept(self)
|
63
|
-
end
|
64
|
-
|
65
|
-
def visit_all(nodes)
|
66
|
-
nodes.map { |node| visit(node) }
|
67
|
-
end
|
68
|
-
|
69
|
-
def visit_child_nodes(node)
|
70
|
-
visit_all(node.child_nodes)
|
71
|
-
end
|
72
|
-
|
7
|
+
class Visitor < BasicVisitor
|
73
8
|
# Visit an ARef node.
|
74
9
|
alias visit_aref visit_child_nodes
|
75
10
|
|
data/lib/syntax_tree.rb
CHANGED
@@ -10,6 +10,8 @@ require_relative "syntax_tree/formatter"
|
|
10
10
|
require_relative "syntax_tree/node"
|
11
11
|
require_relative "syntax_tree/parser"
|
12
12
|
require_relative "syntax_tree/version"
|
13
|
+
|
14
|
+
require_relative "syntax_tree/basic_visitor"
|
13
15
|
require_relative "syntax_tree/visitor"
|
14
16
|
require_relative "syntax_tree/visitor/field_visitor"
|
15
17
|
require_relative "syntax_tree/visitor/json_visitor"
|
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.7.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-05-
|
11
|
+
date: 2022-05-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: prettier_print
|
@@ -121,6 +121,7 @@ files:
|
|
121
121
|
- doc/logo.svg
|
122
122
|
- exe/stree
|
123
123
|
- lib/syntax_tree.rb
|
124
|
+
- lib/syntax_tree/basic_visitor.rb
|
124
125
|
- lib/syntax_tree/cli.rb
|
125
126
|
- lib/syntax_tree/formatter.rb
|
126
127
|
- lib/syntax_tree/formatter/single_quotes.rb
|