syntax_tree 2.3.1 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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