syntax_tree-rbs 0.1.0

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