syntax_tree-rbs 0.2.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,293 +0,0 @@
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.is_a?(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
@@ -1,432 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SyntaxTree
4
- module RBS
5
- # An annotation can be attached to many kinds of nodes, and should be
6
- # printed using %a{}. This class wraps a set of annotations and provides the
7
- # ability to print them if they are found.
8
- class Annotations
9
- attr_reader :annotations
10
-
11
- def initialize(annotations)
12
- @annotations = annotations
13
- end
14
-
15
- def format(q)
16
- q.seplist(annotations, -> { q.breakable(force: true) }) do |annotation|
17
- if annotation.string.match?(/[{}]/)
18
- # Bail out and just print the source string if there are any braces
19
- # because we don't want to mess with escaping them.
20
- q.text(q.source[annotation.location.range])
21
- else
22
- q.text("%a{")
23
- q.text(annotation.string)
24
- q.text("}")
25
- end
26
- end
27
- q.breakable(force: true)
28
- end
29
-
30
- def pretty_print(q)
31
- q.seplist(annotations) do |annotation|
32
- q.group(2, "(annotation", ")") do
33
- q.breakable
34
- q.pp(annotation.string)
35
- end
36
- end
37
- end
38
-
39
- def self.maybe_format(q, annotations)
40
- new(annotations).format(q) if annotations.any?
41
- end
42
-
43
- def self.maybe_pretty_print(q, annotations)
44
- if annotations.any?
45
- q.breakable
46
- q.text("annotations=")
47
- q.pp(new(annotations))
48
- end
49
- end
50
- end
51
-
52
- # A comment can be attached to many kinds of nodes, and should be printed
53
- # before them. This class wraps a comment and provides the ability to print
54
- # it if it is found.
55
- class Comment
56
- attr_reader :comment
57
-
58
- def initialize(comment)
59
- @comment = comment
60
- end
61
-
62
- # Comments come in as one whole string, so here we split it up into
63
- # multiple lines and then prefix it with the pound sign.
64
- def format(q)
65
- q.seplist(comment.string.split(/\r?\n/), -> { q.breakable(force: true) }) do |line|
66
- q.text("# #{line}")
67
- end
68
- q.breakable(force: true)
69
- end
70
-
71
- def pretty_print(q)
72
- q.group(2, "(comment", ")") do
73
- q.breakable
74
- q.pp(comment.string)
75
- end
76
- end
77
-
78
- def self.maybe_format(q, comment)
79
- new(comment).format(q) if comment
80
- end
81
-
82
- def self.maybe_pretty_print(q, comment)
83
- if comment
84
- q.breakable
85
- q.text("comment=")
86
- q.pp(new(comment))
87
- end
88
- end
89
- end
90
-
91
- # Certain nodes are names with optional arguments attached, as in Array[A].
92
- # We handle all of that printing centralized here.
93
- class NameAndArgs
94
- attr_reader :node
95
-
96
- def initialize(node)
97
- @node = node
98
- end
99
-
100
- def format(q)
101
- q.group do
102
- node.name.format(q)
103
-
104
- if node.args.any?
105
- q.text("[")
106
- q.seplist(node.args, -> { q.text(", ") }) { |arg| arg.format(q) }
107
- q.text("]")
108
- end
109
- end
110
- end
111
-
112
- def pretty_print(q)
113
- q.breakable
114
- q.pp(node.name)
115
-
116
- if node.args.any?
117
- q.breakable
118
- q.pp(node.args)
119
- end
120
- end
121
- end
122
-
123
- # Prints out the name of a class, interface, or module declaration.
124
- # Additionally loops through each type parameter if there are any and print
125
- # them out joined by commas. Checks for validation and variance.
126
- class NameAndTypeParams
127
- attr_reader :node
128
-
129
- def initialize(node)
130
- @node = node
131
- end
132
-
133
- def format(q)
134
- node.name.format(q)
135
- return if node.type_params.empty?
136
-
137
- q.text("[")
138
- q.seplist(node.type_params, -> { q.text(", ") }) do |param|
139
- parts = []
140
-
141
- if param.unchecked?
142
- parts << "unchecked"
143
- end
144
-
145
- if param.variance == :covariant
146
- parts << "out"
147
- elsif param.variance == :contravariant
148
- parts << "in"
149
- end
150
-
151
- parts << param.name
152
- q.text(parts.join(" "))
153
-
154
- if param.upper_bound
155
- q.text(" < ")
156
- param.upper_bound.format(q)
157
- end
158
- end
159
-
160
- q.text("]")
161
- end
162
-
163
- def pretty_print(q)
164
- q.breakable
165
- q.pp(node.name)
166
-
167
- if node.type_params.any?
168
- q.breakable
169
- q.group(2, "type_params=[", "]") do
170
- q.seplist(node.type_params) do |param|
171
- q.group(2, "(type-param", ")") do
172
- if param.unchecked?
173
- q.breakable
174
- q.text("unchecked")
175
- end
176
-
177
- if param.variance == :covariant
178
- q.breakable
179
- q.text("covariant")
180
- elsif param.variance == :contravariant
181
- q.breakable
182
- q.text("contravariant")
183
- end
184
-
185
- q.breakable
186
- q.text("name=")
187
- q.pp(param.name)
188
-
189
- if param.upper_bound
190
- q.breakable
191
- q.text("upper_bound=")
192
- q.pp(param.upper_bound)
193
- end
194
- end
195
- end
196
- end
197
- end
198
- end
199
- end
200
-
201
- # Nodes which have members will all flow their printing through this class,
202
- # which keeps track of
203
- class Members
204
- attr_reader :node
205
-
206
- def initialize(node)
207
- @node = node
208
- end
209
-
210
- def format(q)
211
- last_line = nil
212
-
213
- node.members.each do |member|
214
- q.breakable(force: true)
215
-
216
- if last_line && (member.location.start_line - last_line >= 2)
217
- q.breakable(force: true)
218
- end
219
-
220
- member.format(q)
221
- last_line = member.location.end_line
222
- end
223
- end
224
- end
225
-
226
- # Prints out a specific method signature, which looks like:
227
- # (T t) -> void
228
- class MethodSignature
229
- class OptionalPositional
230
- attr_reader :param
231
-
232
- def initialize(param)
233
- @param = param
234
- end
235
-
236
- def format(q)
237
- q.text("?")
238
- param.format(q)
239
- end
240
- end
241
-
242
- class RestPositional
243
- attr_reader :param
244
-
245
- def initialize(param)
246
- @param = param
247
- end
248
-
249
- def format(q)
250
- q.text("*")
251
- param.format(q)
252
- end
253
- end
254
-
255
- class RequiredKeyword
256
- attr_reader :name, :param
257
-
258
- def initialize(name, param)
259
- @name = name
260
- @param = param
261
- end
262
-
263
- def format(q)
264
- q.text(name)
265
- q.text(": ")
266
- param.format(q)
267
- end
268
- end
269
-
270
- class OptionalKeyword
271
- attr_reader :name, :param
272
-
273
- def initialize(name, param)
274
- @name = name
275
- @param = param
276
- end
277
-
278
- def format(q)
279
- q.text("?")
280
- q.text(name)
281
- q.text(": ")
282
- param.format(q)
283
- end
284
- end
285
-
286
- class RestKeyword
287
- attr_reader :param
288
-
289
- def initialize(param)
290
- @param = param
291
- end
292
-
293
- def format(q)
294
- q.text("**")
295
- param.format(q)
296
- end
297
- end
298
-
299
- attr_reader :node
300
-
301
- def initialize(node)
302
- @node = node
303
- end
304
-
305
- def format(q)
306
- q.group do
307
- # We won't have a type_params key if we're printing a block
308
- if node.respond_to?(:type_params) && node.type_params.any?
309
- q.text("[")
310
- q.seplist(node.type_params, -> { q.text(", ") }) do |param|
311
- # We need to do a type check here to support RBS 1.0
312
- q.text(param.is_a?(Symbol) ? param.to_s : param.name)
313
- end
314
- q.text("] ")
315
- end
316
-
317
- params = [
318
- *node.type.required_positionals,
319
- *node.type.optional_positionals.map { |param| OptionalPositional.new(param) },
320
- *(RestPositional.new(node.type.rest_positionals) if node.type.rest_positionals),
321
- *node.type.trailing_positionals,
322
- *node.type.required_keywords.map { |name, param| RequiredKeyword.new(name, param) },
323
- *node.type.optional_keywords.map { |name, param| OptionalKeyword.new(name, param) },
324
- *(RestKeyword.new(node.type.rest_keywords) if node.type.rest_keywords)
325
- ]
326
-
327
- if params.any?
328
- q.text("(")
329
- q.indent do
330
- q.breakable("")
331
- q.seplist(params) { |param| param.format(q) }
332
- end
333
- q.breakable("")
334
- q.text(") ")
335
- end
336
-
337
- if node.respond_to?(:block) && node.block
338
- q.text("?") unless node.block.required
339
- q.text("{")
340
- q.indent do
341
- q.breakable
342
- MethodSignature.new(node.block).format(q)
343
- end
344
- q.breakable
345
- q.text("} ")
346
- end
347
-
348
- q.text("-> ")
349
- q.force_parens { node.type.return_type.format(q) }
350
- end
351
- end
352
-
353
- def pretty_print(q)
354
- if node.respond_to?(:type_params) && node.type_params.any?
355
- q.breakable
356
- q.text("type_params=")
357
- q.group(2, "[", "]") do
358
- q.breakable("")
359
- q.seplist(node.type_params) do |param|
360
- q.group(2, "(type-param", ")") do
361
- q.breakable
362
- q.text("name=")
363
- q.pp(param.name)
364
- end
365
- end
366
- q.breakable("")
367
- end
368
- end
369
-
370
- if node.type.required_positionals.any?
371
- q.breakable
372
- q.text("required_positionals=")
373
- q.pp(node.type.required_positionals)
374
- end
375
-
376
- if node.type.optional_positionals.any?
377
- q.breakable
378
- q.text("optional_positionals=")
379
- q.pp(node.type.optional_positionals)
380
- end
381
-
382
- if node.type.rest_positionals
383
- q.breakable
384
- q.text("rest_positionals=")
385
- q.pp(node.type.rest_positionals)
386
- end
387
-
388
- if node.type.trailing_positionals.any?
389
- q.breakable
390
- q.text("trailing_positionals=")
391
- q.pp(node.type.trailing_positionals)
392
- end
393
-
394
- if node.type.required_keywords.any?
395
- q.breakable
396
- q.text("required_keywords=")
397
- q.pp(node.type.required_keywords)
398
- end
399
-
400
- if node.type.optional_keywords.any?
401
- q.breakable
402
- q.text("optional_keywords=")
403
- q.pp(node.type.optional_keywords)
404
- end
405
-
406
- if node.type.rest_keywords
407
- q.breakable
408
- q.text("rest_keywords=")
409
- q.pp(node.type.rest_keywords)
410
- end
411
-
412
- if node.respond_to?(:block) && node.block
413
- q.breakable
414
- q.text("block=")
415
- q.group(2, "(block", ")") do
416
- if node.block.required
417
- q.breakable
418
- q.text("required")
419
- end
420
-
421
- q.breakable
422
- q.pp(MethodSignature.new(node.block))
423
- end
424
- end
425
-
426
- q.breakable
427
- q.text("return_type=")
428
- q.pp(node.type.return_type)
429
- end
430
- end
431
- end
432
- end