syntax_tree-rbs 0.1.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.
@@ -0,0 +1,400 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SyntaxTree
4
+ module RBS
5
+ # Prints out an attr_* meta method, which looks like:
6
+ # attr_accessor foo: Foo
7
+ # attr_reader foo: Foo
8
+ # attr_writer foo: Foo
9
+ class Attribute
10
+ attr_reader :type, :node
11
+
12
+ def initialize(type, node)
13
+ @type = type
14
+ @node = node
15
+ end
16
+
17
+ def format(q)
18
+ q.group do
19
+ q.text("attr_#{type} ")
20
+ q.text("self.") if node.kind == :singleton
21
+ q.text(node.name)
22
+
23
+ if node.ivar_name == false
24
+ q.text("()")
25
+ elsif node.ivar_name
26
+ q.text("(")
27
+ q.text(node.ivar_name)
28
+ q.text(")")
29
+ end
30
+
31
+ q.text(": ")
32
+ node.type.format(q)
33
+ end
34
+ end
35
+
36
+ def pretty_print(q)
37
+ if node.kind == :singleton
38
+ q.breakable
39
+ q.text("singleton")
40
+ end
41
+
42
+ q.breakable
43
+ q.text("name=")
44
+ q.pp(node.name)
45
+
46
+ unless node.ivar_name.nil?
47
+ q.breakable
48
+ q.text("ivar_name=")
49
+ q.pp(node.ivar_name)
50
+ end
51
+
52
+ q.breakable
53
+ q.text("type=")
54
+ q.pp(node.type)
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ module RBS
61
+ module AST
62
+ module Members
63
+ class Alias
64
+ # Prints out an alias within a declaration, which looks like:
65
+ # alias foo bar
66
+ # alias self.foo self.bar
67
+ def format(q)
68
+ SyntaxTree::RBS::Comment.maybe_format(q, comment)
69
+ SyntaxTree::RBS::Annotations.maybe_format(q, annotations)
70
+
71
+ if kind == :singleton
72
+ q.text("alias self.")
73
+ q.text(new_name)
74
+ q.text(" self.")
75
+ q.text(old_name)
76
+ else
77
+ q.text("alias ")
78
+ q.text(new_name)
79
+ q.text(" ")
80
+ q.text(old_name)
81
+ end
82
+ end
83
+
84
+ def pretty_print(q)
85
+ q.group(2, "(alias", ")") do
86
+ SyntaxTree::RBS::Comment.maybe_pretty_print(q, comment)
87
+ SyntaxTree::RBS::Annotations.maybe_pretty_print(q, annotations)
88
+
89
+ if kind == :singleton
90
+ q.breakable
91
+ q.text("singleton")
92
+ end
93
+
94
+ q.breakable
95
+ q.text("new_name=")
96
+ q.pp(new_name)
97
+
98
+ q.breakable
99
+ q.text("old_name=")
100
+ q.pp(old_name)
101
+ end
102
+ end
103
+ end
104
+
105
+ class AttrAccessor
106
+ # Prints out an attr_accessor meta method, which looks like:
107
+ # attr_accessor foo: Foo
108
+ def format(q)
109
+ SyntaxTree::RBS::Comment.maybe_format(q, comment)
110
+ SyntaxTree::RBS::Annotations.maybe_format(q, annotations)
111
+ SyntaxTree::RBS::Attribute.new(:accessor, self).format(q)
112
+ end
113
+
114
+ def pretty_print(q)
115
+ q.group(2, "(attr-accessor", ")") do
116
+ SyntaxTree::RBS::Comment.maybe_pretty_print(q, comment)
117
+ SyntaxTree::RBS::Annotations.maybe_pretty_print(q, annotations)
118
+ q.pp(SyntaxTree::RBS::Attribute.new(:accessor, self))
119
+ end
120
+ end
121
+ end
122
+
123
+ class AttrReader
124
+ # Prints out an attr_reader meta method, which looks like:
125
+ # attr_reader foo: Foo
126
+ def format(q)
127
+ SyntaxTree::RBS::Comment.maybe_format(q, comment)
128
+ SyntaxTree::RBS::Annotations.maybe_format(q, annotations)
129
+ SyntaxTree::RBS::Attribute.new(:reader, self).format(q)
130
+ end
131
+
132
+ def pretty_print(q)
133
+ q.group(2, "(attr-reader", ")") do
134
+ SyntaxTree::RBS::Comment.maybe_pretty_print(q, comment)
135
+ SyntaxTree::RBS::Annotations.maybe_pretty_print(q, annotations)
136
+ q.pp(SyntaxTree::RBS::Attribute.new(:reader, self))
137
+ end
138
+ end
139
+ end
140
+
141
+ class AttrWriter
142
+ # Prints out an attr_writer meta method, which looks like:
143
+ # attr_writer foo: Foo
144
+ def format(q)
145
+ SyntaxTree::RBS::Comment.maybe_format(q, comment)
146
+ SyntaxTree::RBS::Annotations.maybe_format(q, annotations)
147
+ SyntaxTree::RBS::Attribute.new(:writer, self).format(q)
148
+ end
149
+
150
+ def pretty_print(q)
151
+ q.group(2, "(attr-writer", ")") do
152
+ SyntaxTree::RBS::Comment.maybe_pretty_print(q, comment)
153
+ SyntaxTree::RBS::Annotations.maybe_pretty_print(q, annotations)
154
+ q.pp(SyntaxTree::RBS::Attribute.new(:writer, self))
155
+ end
156
+ end
157
+ end
158
+
159
+ class ClassInstanceVariable
160
+ # Prints out a class instance variable member, which looks like:
161
+ # self.@foo: String
162
+ def format(q)
163
+ SyntaxTree::RBS::Comment.maybe_format(q, comment)
164
+
165
+ q.group do
166
+ q.text("self.")
167
+ q.text(name)
168
+ q.text(": ")
169
+ type.format(q)
170
+ end
171
+ end
172
+
173
+ def pretty_print(q)
174
+ q.group(2, "(class-instance-variable", ")") do
175
+ SyntaxTree::RBS::Comment.maybe_pretty_print(q, comment)
176
+
177
+ q.breakable
178
+ q.text("name=")
179
+ q.pp(name)
180
+ end
181
+ end
182
+ end
183
+
184
+ class ClassVariable
185
+ # Prints out a class variable member, which looks like:
186
+ # @@foo: String
187
+ def format(q)
188
+ SyntaxTree::RBS::Comment.maybe_format(q, comment)
189
+
190
+ q.group do
191
+ q.text(name)
192
+ q.text(": ")
193
+ type.format(q)
194
+ end
195
+ end
196
+
197
+ def pretty_print(q)
198
+ q.group(2, "(class-variable", ")") do
199
+ SyntaxTree::RBS::Comment.maybe_pretty_print(q, comment)
200
+
201
+ q.breakable
202
+ q.text("name=")
203
+ q.pp(name)
204
+ end
205
+ end
206
+ end
207
+
208
+ class Extend
209
+ # Prints out an extend, which looks like:
210
+ # extend Foo
211
+ def format(q)
212
+ SyntaxTree::RBS::Comment.maybe_format(q, comment)
213
+ SyntaxTree::RBS::Annotations.maybe_format(q, annotations)
214
+
215
+ q.group do
216
+ q.text("extend ")
217
+ SyntaxTree::RBS::NameAndArgs.new(self).format(q)
218
+ end
219
+ end
220
+
221
+ def pretty_print(q)
222
+ q.group(2, "(extend", ")") do
223
+ SyntaxTree::RBS::Comment.maybe_pretty_print(q, comment)
224
+ SyntaxTree::RBS::Annotations.maybe_pretty_print(q, annotations)
225
+ q.pp(SyntaxTree::RBS::NameAndArgs.new(self))
226
+ end
227
+ end
228
+ end
229
+
230
+ class Include
231
+ # Prints out an include, which looks like:
232
+ # include Foo
233
+ def format(q)
234
+ SyntaxTree::RBS::Comment.maybe_format(q, comment)
235
+ SyntaxTree::RBS::Annotations.maybe_format(q, annotations)
236
+
237
+ q.group do
238
+ q.text("include ")
239
+ SyntaxTree::RBS::NameAndArgs.new(self).format(q)
240
+ end
241
+ end
242
+
243
+ def pretty_print(q)
244
+ q.group(2, "(include", ")") do
245
+ SyntaxTree::RBS::Comment.maybe_pretty_print(q, comment)
246
+ SyntaxTree::RBS::Annotations.maybe_pretty_print(q, annotations)
247
+ q.pp(SyntaxTree::RBS::NameAndArgs.new(self))
248
+ end
249
+ end
250
+ end
251
+
252
+ class InstanceVariable
253
+ # Prints out an instance variable member, which looks like:
254
+ # @foo: String
255
+ def format(q)
256
+ SyntaxTree::RBS::Comment.maybe_format(q, comment)
257
+
258
+ q.group do
259
+ q.text(name)
260
+ q.text(": ")
261
+ type.format(q)
262
+ end
263
+ end
264
+
265
+ def pretty_print(q)
266
+ q.group(2, "(instance-variable", ")") do
267
+ SyntaxTree::RBS::Comment.maybe_pretty_print(q, comment)
268
+
269
+ q.breakable
270
+ q.text("name=")
271
+ q.pp(name)
272
+ end
273
+ end
274
+ end
275
+
276
+ class MethodDefinition
277
+ # Prints out a method definition, which looks like:
278
+ # def t: (T t) -> void
279
+ def format(q)
280
+ SyntaxTree::RBS::Comment.maybe_format(q, comment)
281
+ SyntaxTree::RBS::Annotations.maybe_format(q, annotations)
282
+
283
+ q.group do
284
+ q.text("def ")
285
+
286
+ if kind == :singleton
287
+ q.text("self.")
288
+ elsif kind == :singleton_instance
289
+ q.text("self?.")
290
+ end
291
+
292
+ q.text(Parser::KEYWORDS.include?(name.to_s) ? "`#{name}`" : name)
293
+ q.text(":")
294
+
295
+ if types.length == 1 && !overload?
296
+ q.text(" ")
297
+ SyntaxTree::RBS::MethodSignature.new(types.first).format(q)
298
+ else
299
+ separator =
300
+ lambda do
301
+ q.breakable
302
+ q.text("| ")
303
+ end
304
+
305
+ q.group do
306
+ q.indent do
307
+ q.breakable
308
+ q.seplist(types, separator) do |type|
309
+ SyntaxTree::RBS::MethodSignature.new(type).format(q)
310
+ end
311
+
312
+ if overload?
313
+ separator.call
314
+ q.text("...")
315
+ end
316
+ end
317
+ end
318
+ end
319
+ end
320
+ end
321
+
322
+ def pretty_print(q)
323
+ q.group(2, "(method-definition", ")") do
324
+ SyntaxTree::RBS::Comment.maybe_pretty_print(q, comment)
325
+ SyntaxTree::RBS::Annotations.maybe_pretty_print(q, annotations)
326
+
327
+ q.breakable
328
+ q.text("kind=")
329
+ q.pp(kind)
330
+
331
+ q.breakable
332
+ q.text("name=")
333
+ q.pp(name)
334
+
335
+ if overload?
336
+ q.breakable
337
+ q.text("overload")
338
+ end
339
+
340
+ q.breakable
341
+ q.text("types=")
342
+ q.group(2, "[", "]") do
343
+ q.breakable("")
344
+ q.seplist(types) do |type|
345
+ q.pp(SyntaxTree::RBS::MethodSignature.new(type))
346
+ end
347
+ q.breakable("")
348
+ end
349
+ end
350
+ end
351
+ end
352
+
353
+ class Prepend
354
+ # Prints out a prepend, which looks like:
355
+ # prepend Foo
356
+ def format(q)
357
+ SyntaxTree::RBS::Comment.maybe_format(q, comment)
358
+ SyntaxTree::RBS::Annotations.maybe_format(q, annotations)
359
+
360
+ q.group do
361
+ q.text("prepend ")
362
+ SyntaxTree::RBS::NameAndArgs.new(self).format(q)
363
+ end
364
+ end
365
+
366
+ def pretty_print(q)
367
+ q.group(2, "(prepend", ")") do
368
+ SyntaxTree::RBS::Comment.maybe_pretty_print(q, comment)
369
+ SyntaxTree::RBS::Annotations.maybe_pretty_print(q, annotations)
370
+ q.pp(SyntaxTree::RBS::NameAndArgs.new(self))
371
+ end
372
+ end
373
+ end
374
+
375
+ class Private
376
+ # Prints out a private declaration, which looks like:
377
+ # private
378
+ def format(q)
379
+ q.text("private")
380
+ end
381
+
382
+ def pretty_print(q)
383
+ q.text("(private)")
384
+ end
385
+ end
386
+
387
+ class Public
388
+ # Prints out a public declaration, which looks like:
389
+ # public
390
+ def format(q)
391
+ q.text("public")
392
+ end
393
+
394
+ def pretty_print(q)
395
+ q.text("(public)")
396
+ end
397
+ end
398
+ end
399
+ end
400
+ end
@@ -0,0 +1,293 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ class TypeName
5
+ def format(q)
6
+ q.text(to_s)
7
+ end
8
+
9
+ def pretty_print(q)
10
+ q.group(2, "(type-name", ")") do
11
+ q.breakable
12
+ q.pp(to_s)
13
+ end
14
+ end
15
+ end
16
+
17
+ module Types
18
+ class Alias
19
+ def format(q)
20
+ name.format(q)
21
+ end
22
+
23
+ def pretty_print(q)
24
+ q.group(2, "(alias", ")") do
25
+ q.breakable
26
+ q.text("name=")
27
+ q.pp(name)
28
+ end
29
+ end
30
+ end
31
+
32
+ module Bases
33
+ class Base
34
+ def format(q)
35
+ q.text(to_s)
36
+ end
37
+
38
+ def pretty_print(q)
39
+ q.text("(#{self.class.name.downcase})")
40
+ end
41
+ end
42
+ end
43
+
44
+ class ClassInstance
45
+ def format(q)
46
+ SyntaxTree::RBS::NameAndArgs.new(self).format(q)
47
+ end
48
+
49
+ def pretty_print(q)
50
+ q.group(2, "(class-instance", ")") do
51
+ q.pp(SyntaxTree::RBS::NameAndArgs.new(self))
52
+ end
53
+ end
54
+ end
55
+
56
+ class ClassSingleton
57
+ def format(q)
58
+ q.text("singleton(")
59
+ name.format(q)
60
+ q.text(")")
61
+ end
62
+
63
+ def pretty_print(q)
64
+ q.group(2, "(class-singleton", ")") do
65
+ q.breakable
66
+ q.text("name=")
67
+ q.pp(name)
68
+ end
69
+ end
70
+ end
71
+
72
+ class Function
73
+ class Param
74
+ def format(q)
75
+ type.format(q)
76
+
77
+ if name
78
+ q.text(" ")
79
+
80
+ if Parser::KEYWORDS.include?(name.to_s)
81
+ q.text("`#{name}`")
82
+ else
83
+ q.text(name)
84
+ end
85
+ end
86
+ end
87
+
88
+ def pretty_print(q)
89
+ q.group(2, "(param", ")") do
90
+ q.breakable
91
+ q.text("type=")
92
+ q.pp(type)
93
+
94
+ if name
95
+ q.breakable
96
+ q.text("name=")
97
+ q.pp(name)
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ class Interface
105
+ def format(q)
106
+ SyntaxTree::RBS::NameAndArgs.new(self).format(q)
107
+ end
108
+
109
+ def pretty_print(q)
110
+ q.group(2, "(interface", ")") do
111
+ q.pp(SyntaxTree::RBS::NameAndArgs.new(self))
112
+ end
113
+ end
114
+ end
115
+
116
+ class Intersection
117
+ def format(q)
118
+ separator =
119
+ lambda do
120
+ q.breakable
121
+ q.text("& ")
122
+ end
123
+
124
+ q.text("(") if q.force_parens?
125
+ q.group do
126
+ q.force_parens { q.seplist(types, separator) { |type| type.format(q) } }
127
+ end
128
+ q.text(")") if q.force_parens?
129
+ end
130
+
131
+ def pretty_print(q)
132
+ q.group(2, "(intersection", ")") do
133
+ q.breakable
134
+ q.text("types=")
135
+ q.pp(types)
136
+ end
137
+ end
138
+ end
139
+
140
+ class Literal
141
+ def format(q)
142
+ unless literal in String
143
+ q.text(literal.inspect)
144
+ return
145
+ end
146
+
147
+ # We're going to go straight to the source here, as if we don't then
148
+ # we're going to end up with the result of String#inspect, which does
149
+ # weird things to escape sequences.
150
+ source = q.source[location.range]
151
+ quote = source.include?("\\") ? source[0] : "\""
152
+ source = SyntaxTree::Quotes.normalize(source[1..-2], quote)
153
+
154
+ q.text(quote)
155
+ q.seplist(source.split(/\r?\n/), -> { q.breakable(force: true) }) do |line|
156
+ q.text(line)
157
+ end
158
+ q.text(quote)
159
+ end
160
+
161
+ def pretty_print(q)
162
+ q.group(2, "(literal", ")") do
163
+ q.breakable
164
+ q.pp(literal)
165
+ end
166
+ end
167
+ end
168
+
169
+ class Optional
170
+ def format(q)
171
+ q.force_parens { type.format(q) }
172
+ q.text("?")
173
+ end
174
+
175
+ def pretty_print(q)
176
+ q.group(2, "(optional", ")") do
177
+ q.breakable
178
+ q.pp(type)
179
+ end
180
+ end
181
+ end
182
+
183
+ class Proc
184
+ def format(q)
185
+ q.text("^")
186
+ SyntaxTree::RBS::MethodSignature.new(self).format(q)
187
+ end
188
+
189
+ def pretty_print(q)
190
+ q.group(2, "(proc", ")") do
191
+ q.pp(SyntaxTree::RBS::MethodSignature.new(self))
192
+ end
193
+ end
194
+ end
195
+
196
+ class Record
197
+ def format(q)
198
+ separator =
199
+ lambda do
200
+ q.text(",")
201
+ q.breakable
202
+ end
203
+
204
+ q.group do
205
+ q.text("{")
206
+ q.indent do
207
+ q.breakable
208
+ q.seplist(fields, separator, :each_pair) do |key, type|
209
+ if key.is_a?(Symbol) && key.match?(/\A[A-Za-z_][A-Za-z_]*\z/)
210
+ q.text("#{key}: ")
211
+ else
212
+ q.text("#{key.inspect} => ")
213
+ end
214
+
215
+ type.format(q)
216
+ end
217
+ end
218
+ q.breakable
219
+ q.text("}")
220
+ end
221
+ end
222
+
223
+ def pretty_print(q)
224
+ q.group(2, "(record", ")") do
225
+ q.breakable
226
+ q.text("fields=")
227
+ q.pp(fields)
228
+ end
229
+ end
230
+ end
231
+
232
+ class Tuple
233
+ def format(q)
234
+ # If we don't have any sub types, we explicitly need the space in
235
+ # between the brackets to not confuse the parser.
236
+ if types.empty?
237
+ q.text("[ ]")
238
+ return
239
+ end
240
+
241
+ q.group do
242
+ q.text("[")
243
+ q.seplist(types, -> { q.text(", ") }) { |type| type.format(q) }
244
+ q.text("]")
245
+ end
246
+ end
247
+
248
+ def pretty_print(q)
249
+ q.group(2, "(tuple", ")") do
250
+ q.breakable
251
+ q.text("types=")
252
+ q.pp(types)
253
+ end
254
+ end
255
+ end
256
+
257
+ class Union
258
+ def format(q)
259
+ separator =
260
+ lambda do
261
+ q.breakable
262
+ q.text("| ")
263
+ end
264
+
265
+ q.text("(") if q.force_parens?
266
+ q.group { q.seplist(types, separator) { |type| type.format(q) } }
267
+ q.text(")") if q.force_parens?
268
+ end
269
+
270
+ def pretty_print(q)
271
+ q.group(2, "(union", ")") do
272
+ q.breakable
273
+ q.text("types=")
274
+ q.pp(types)
275
+ end
276
+ end
277
+ end
278
+
279
+ class Variable
280
+ def format(q)
281
+ q.text(name)
282
+ end
283
+
284
+ def pretty_print(q)
285
+ q.group(2, "(variable", ")") do
286
+ q.breakable
287
+ q.text("name=")
288
+ q.pp(name)
289
+ end
290
+ end
291
+ end
292
+ end
293
+ end