syntax_tree 2.3.0 → 2.4.1

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.
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SyntaxTree
4
+ class Visitor
5
+ # This visitor transforms the AST into a Ruby pattern matching expression
6
+ # that would match correctly against the AST.
7
+ class MatchVisitor < FieldVisitor
8
+ attr_reader :q
9
+
10
+ def initialize(q)
11
+ @q = q
12
+ end
13
+
14
+ def visit(node)
15
+ case node
16
+ when Node
17
+ super
18
+ when String
19
+ # pp will split up a string on newlines and concat them together using
20
+ # a "+" operator. This breaks the pattern matching expression. So
21
+ # instead we're going to check here for strings and manually put the
22
+ # entire value into the output buffer.
23
+ q.text(node.inspect)
24
+ else
25
+ q.pp(node)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def comments(node)
32
+ return if node.comments.empty?
33
+
34
+ q.nest(0) do
35
+ q.text("comments: [")
36
+ q.indent do
37
+ q.breakable("")
38
+ q.seplist(node.comments) { |comment| visit(comment) }
39
+ end
40
+ q.breakable("")
41
+ q.text("]")
42
+ end
43
+ end
44
+
45
+ def field(name, value)
46
+ q.nest(0) do
47
+ q.text(name)
48
+ q.text(": ")
49
+ visit(value)
50
+ end
51
+ end
52
+
53
+ def list(name, values)
54
+ q.group do
55
+ q.text(name)
56
+ q.text(": [")
57
+ q.indent do
58
+ q.breakable("")
59
+ q.seplist(values) { |value| visit(value) }
60
+ end
61
+ q.breakable("")
62
+ q.text("]")
63
+ end
64
+ end
65
+
66
+ def node(node, _type)
67
+ items = []
68
+ q.with_target(items) { yield }
69
+
70
+ if items.empty?
71
+ q.text(node.class.name)
72
+ return
73
+ end
74
+
75
+ q.group do
76
+ q.text(node.class.name)
77
+ q.text("[")
78
+ q.indent do
79
+ q.breakable("")
80
+ q.seplist(items) { |item| q.target << item }
81
+ end
82
+ q.breakable("")
83
+ q.text("]")
84
+ end
85
+ end
86
+
87
+ def pairs(name, values)
88
+ q.group do
89
+ q.text(name)
90
+ q.text(": [")
91
+ q.indent do
92
+ q.breakable("")
93
+ q.seplist(values) do |(key, value)|
94
+ q.group do
95
+ q.text("[")
96
+ q.indent do
97
+ q.breakable("")
98
+ visit(key)
99
+ q.text(",")
100
+ q.breakable
101
+ visit(value || nil)
102
+ end
103
+ q.breakable("")
104
+ q.text("]")
105
+ end
106
+ end
107
+ end
108
+ q.breakable("")
109
+ q.text("]")
110
+ end
111
+ end
112
+
113
+ def text(name, value)
114
+ q.nest(0) do
115
+ q.text(name)
116
+ q.text(": ")
117
+ q.pp(value)
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end