tapioca 0.4.21 → 0.4.25

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,410 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Tapioca
5
+ module RBI
6
+ class Printer < Visitor
7
+ extend T::Sig
8
+
9
+ sig { returns(T::Boolean) }
10
+ attr_accessor :in_visibility_group
11
+
12
+ sig { returns(T.nilable(Node)) }
13
+ attr_reader :previous_node
14
+
15
+ sig { params(out: T.any(IO, StringIO), indent: Integer).void }
16
+ def initialize(out: $stdout, indent: 0)
17
+ super()
18
+ @out = out
19
+ @current_indent = indent
20
+ @in_visibility_group = T.let(false, T::Boolean)
21
+ @previous_node = T.let(nil, T.nilable(Node))
22
+ end
23
+
24
+ # Printing
25
+
26
+ sig { void }
27
+ def indent
28
+ @current_indent += 2
29
+ end
30
+
31
+ sig { void }
32
+ def dedent
33
+ @current_indent -= 2
34
+ end
35
+
36
+ # Print a string without indentation nor `\n` at the end.
37
+ sig { params(string: String).void }
38
+ def print(string)
39
+ @out.print(string)
40
+ end
41
+
42
+ # Print a string without indentation but with a `\n` at the end.
43
+ sig { params(string: T.nilable(String)).void }
44
+ def printn(string = nil)
45
+ print(string) if string
46
+ print("\n")
47
+ end
48
+
49
+ # Print a string with indentation but without a `\n` at the end.
50
+ sig { params(string: T.nilable(String)).void }
51
+ def printt(string = nil)
52
+ print(" " * @current_indent)
53
+ print(string) if string
54
+ end
55
+
56
+ # Print a string with indentation and `\n` at the end.
57
+ sig { params(string: String).void }
58
+ def printl(string)
59
+ printt
60
+ printn(string)
61
+ end
62
+
63
+ sig { override.params(node: T.nilable(Node)).void }
64
+ def visit(node)
65
+ return unless node
66
+ node.accept_printer(self)
67
+ end
68
+
69
+ sig { override.params(nodes: T::Array[Node]).void }
70
+ def visit_all(nodes)
71
+ previous_node = @previous_node
72
+ @previous_node = nil
73
+ nodes.each do |node|
74
+ visit(node)
75
+ @previous_node = node
76
+ end
77
+ @previous_node = previous_node
78
+ end
79
+ end
80
+
81
+ class Node
82
+ extend T::Sig
83
+
84
+ sig { abstract.params(v: Printer).void }
85
+ def accept_printer(v); end
86
+
87
+ sig { params(out: T.any(IO, StringIO), indent: Integer).void }
88
+ def print(out: $stdout, indent: 0)
89
+ p = Printer.new(out: out, indent: indent)
90
+ p.visit(self)
91
+ end
92
+
93
+ sig { params(indent: Integer).returns(String) }
94
+ def string(indent: 0)
95
+ out = StringIO.new
96
+ print(out: out, indent: indent)
97
+ out.string
98
+ end
99
+
100
+ sig { returns(T::Boolean) }
101
+ def oneline?
102
+ true
103
+ end
104
+ end
105
+
106
+ class Tree
107
+ extend T::Sig
108
+
109
+ sig { override.params(v: Printer).void }
110
+ def accept_printer(v)
111
+ v.visit_all(nodes)
112
+ end
113
+
114
+ sig { override.returns(T::Boolean) }
115
+ def oneline?
116
+ empty?
117
+ end
118
+ end
119
+
120
+ class Scope
121
+ extend T::Sig
122
+
123
+ sig { override.params(v: Printer).void }
124
+ def accept_printer(v)
125
+ previous_node = v.previous_node
126
+ v.printn if previous_node && (!previous_node.oneline? || !oneline?)
127
+
128
+ case self
129
+ when Module
130
+ v.printt("module #{name}")
131
+ when Class
132
+ v.printt("class #{name}")
133
+ superclass = superclass_name
134
+ v.print(" < #{superclass}") if superclass
135
+ when SingletonClass
136
+ v.printt("class << self")
137
+ end
138
+ if empty?
139
+ v.printn("; end")
140
+ else
141
+ v.printn
142
+ v.indent
143
+ v.visit_all(nodes)
144
+ v.dedent
145
+ v.printl("end")
146
+ end
147
+ end
148
+ end
149
+
150
+ class Const
151
+ extend T::Sig
152
+
153
+ sig { override.params(v: Printer).void }
154
+ def accept_printer(v)
155
+ previous_node = v.previous_node
156
+ v.printn if previous_node && (!previous_node.oneline? || !oneline?)
157
+
158
+ v.printl("#{name} = #{value}")
159
+ end
160
+ end
161
+
162
+ class Method
163
+ extend T::Sig
164
+
165
+ sig { override.params(v: Printer).void }
166
+ def accept_printer(v)
167
+ previous_node = v.previous_node
168
+ v.printn if previous_node && (!previous_node.oneline? || !oneline?)
169
+
170
+ v.visit_all(sigs)
171
+ v.printt
172
+ unless v.in_visibility_group || visibility == Visibility::Public
173
+ v.print(visibility.visibility.to_s)
174
+ v.print(" ")
175
+ end
176
+ v.print("def ")
177
+ v.print("self.") if is_singleton
178
+ v.print(name)
179
+ unless params.empty?
180
+ v.print("(")
181
+ params.each_with_index do |param, index|
182
+ v.print(", ") if index > 0
183
+ v.visit(param)
184
+ end
185
+ v.print(")")
186
+ end
187
+ v.print("; end")
188
+ v.printn
189
+ end
190
+
191
+ sig { override.returns(T::Boolean) }
192
+ def oneline?
193
+ sigs.empty?
194
+ end
195
+ end
196
+
197
+ class Param
198
+ extend T::Sig
199
+
200
+ sig { override.params(v: Printer).void }
201
+ def accept_printer(v)
202
+ v.print(name.to_s)
203
+ end
204
+ end
205
+
206
+ class OptParam
207
+ extend T::Sig
208
+
209
+ sig { override.params(v: Printer).void }
210
+ def accept_printer(v)
211
+ v.print("#{name} = #{value}")
212
+ end
213
+ end
214
+
215
+ class RestParam
216
+ extend T::Sig
217
+
218
+ sig { override.params(v: Printer).void }
219
+ def accept_printer(v)
220
+ v.print("*#{name}")
221
+ end
222
+ end
223
+
224
+ class KwParam
225
+ extend T::Sig
226
+
227
+ sig { override.params(v: Printer).void }
228
+ def accept_printer(v)
229
+ v.print("#{name}:")
230
+ end
231
+ end
232
+
233
+ class KwOptParam
234
+ extend T::Sig
235
+
236
+ sig { override.params(v: Printer).void }
237
+ def accept_printer(v)
238
+ v.print("#{name}: #{value}")
239
+ end
240
+ end
241
+
242
+ class KwRestParam
243
+ extend T::Sig
244
+
245
+ sig { override.params(v: Printer).void }
246
+ def accept_printer(v)
247
+ v.print("**#{name}")
248
+ end
249
+ end
250
+
251
+ class BlockParam
252
+ extend T::Sig
253
+
254
+ sig { override.params(v: Printer).void }
255
+ def accept_printer(v)
256
+ v.print("&#{name}")
257
+ end
258
+ end
259
+
260
+ class Mixin
261
+ extend T::Sig
262
+
263
+ sig { override.params(v: Printer).void }
264
+ def accept_printer(v)
265
+ case self
266
+ when Include
267
+ v.printt("include")
268
+ when Extend
269
+ v.printt("extend")
270
+ when MixesInClassMethods
271
+ v.printt("mixes_in_class_methods")
272
+ end
273
+ v.printn(" #{name}")
274
+ end
275
+ end
276
+
277
+ class Visibility
278
+ extend T::Sig
279
+
280
+ sig { override.params(v: Printer).void }
281
+ def accept_printer(v)
282
+ v.printl(visibility.to_s)
283
+ end
284
+ end
285
+
286
+ class Sig
287
+ extend T::Sig
288
+
289
+ sig { override.params(v: Printer).void }
290
+ def accept_printer(v)
291
+ v.printt("sig { ")
292
+ v.print("abstract.") if is_abstract
293
+ v.print("override.") if is_override
294
+ v.print("overridable.") if is_overridable
295
+ unless type_params.empty?
296
+ v.print("type_parameters(")
297
+ type_params.each_with_index do |param, index|
298
+ v.print(":#{param}")
299
+ v.print(", ") if index < type_params.length - 1
300
+ end
301
+ v.print(").")
302
+ end
303
+ unless params.empty?
304
+ v.print("params(")
305
+ params.each_with_index do |param, index|
306
+ v.visit(param)
307
+ v.print(", ") if index < params.length - 1
308
+ end
309
+ v.print(").")
310
+ end
311
+ if return_type && return_type != "void"
312
+ v.print("returns(#{return_type})")
313
+ else
314
+ v.print("void")
315
+ end
316
+ v.printn(" }")
317
+ end
318
+ end
319
+
320
+ class SigParam
321
+ extend T::Sig
322
+
323
+ sig { override.params(v: Printer).void }
324
+ def accept_printer(v)
325
+ v.print("#{name}: #{type}")
326
+ end
327
+ end
328
+
329
+ class TStructField
330
+ extend T::Sig
331
+
332
+ sig { override.params(v: Printer).void }
333
+ def accept_printer(v)
334
+ case self
335
+ when TStructProp
336
+ v.printt("prop")
337
+ when TStructConst
338
+ v.printt("const")
339
+ end
340
+ v.print(" :#{name}, #{type}")
341
+ default = self.default
342
+ v.print(", default: #{default}") if default
343
+ v.printn
344
+ end
345
+ end
346
+
347
+ class TEnumBlock
348
+ extend T::Sig
349
+
350
+ sig { override.params(v: Printer).void }
351
+ def accept_printer(v)
352
+ v.printl("enums do")
353
+ v.indent
354
+ names.each do |name|
355
+ v.printl("#{name} = new")
356
+ end
357
+ v.dedent
358
+ v.printl("end")
359
+ end
360
+ end
361
+
362
+ class TypeMember
363
+ extend T::Sig
364
+
365
+ sig { override.params(v: Printer).void }
366
+ def accept_printer(v)
367
+ previous_node = v.previous_node
368
+ v.printn if previous_node && (!previous_node.oneline? || !oneline?)
369
+
370
+ v.printl("#{name} = #{value}")
371
+ end
372
+ end
373
+
374
+ class Helper
375
+ extend T::Sig
376
+
377
+ sig { override.params(v: Printer).void }
378
+ def accept_printer(v)
379
+ v.printl("#{name}!")
380
+ end
381
+ end
382
+
383
+ class Group
384
+ extend T::Sig
385
+
386
+ sig { override.params(v: Printer).void }
387
+ def accept_printer(v)
388
+ v.printn unless v.previous_node.nil?
389
+ v.visit_all(nodes)
390
+ end
391
+ end
392
+
393
+ class VisibilityGroup
394
+ extend T::Sig
395
+
396
+ sig { override.params(v: Printer).void }
397
+ def accept_printer(v)
398
+ v.in_visibility_group = true
399
+ v.printn unless v.previous_node.nil?
400
+ case visibility
401
+ when Visibility::Protected, Visibility::Private
402
+ v.visit(visibility)
403
+ v.printn
404
+ end
405
+ v.visit_all(nodes)
406
+ v.in_visibility_group = false
407
+ end
408
+ end
409
+ end
410
+ end
@@ -0,0 +1,106 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Tapioca
5
+ module RBI
6
+ module Rewriters
7
+ class GroupNodes < Visitor
8
+ extend T::Sig
9
+
10
+ sig { override.params(node: T.nilable(Node)).void }
11
+ def visit(node)
12
+ return unless node
13
+
14
+ case node
15
+ when Tree
16
+ kinds = node.nodes.map(&:group_kind)
17
+ kinds.compact!
18
+ kinds.uniq!
19
+
20
+ groups = {}
21
+ kinds.each { |kind| groups[kind] = Group.new(kind) }
22
+
23
+ node.nodes.dup.each do |child|
24
+ visit(child)
25
+ child.detach
26
+ groups[child.group_kind] << child
27
+ end
28
+
29
+ groups.each { |_, group| node << group }
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ class Tree
36
+ extend T::Sig
37
+
38
+ sig { void }
39
+ def group_nodes!
40
+ visitor = Rewriters::GroupNodes.new
41
+ visitor.visit(self)
42
+ end
43
+ end
44
+
45
+ class Node
46
+ extend T::Sig
47
+
48
+ sig { returns(Group::Kind) }
49
+ def group_kind
50
+ case self
51
+ when Include, Extend
52
+ Group::Kind::Mixins
53
+ when Helper
54
+ Group::Kind::Helpers
55
+ when TypeMember
56
+ Group::Kind::TypeMembers
57
+ when MixesInClassMethods
58
+ Group::Kind::MixesInClassMethods
59
+ when TStructField
60
+ Group::Kind::TStructFields
61
+ when TEnumBlock
62
+ Group::Kind::TEnums
63
+ when VisibilityGroup
64
+ Group::Kind::Methods
65
+ when Method
66
+ if name == "initialize"
67
+ Group::Kind::Inits
68
+ else
69
+ Group::Kind::Methods
70
+ end
71
+ when Scope, Const
72
+ Group::Kind::Consts
73
+ else
74
+ raise "Unknown group for #{self}"
75
+ end
76
+ end
77
+ end
78
+
79
+ class Group < Tree
80
+ extend T::Sig
81
+
82
+ sig { returns(Kind) }
83
+ attr_reader :kind
84
+
85
+ sig { params(kind: Kind).void }
86
+ def initialize(kind)
87
+ super()
88
+ @kind = kind
89
+ end
90
+
91
+ class Kind < T::Enum
92
+ enums do
93
+ Mixins = new
94
+ Helpers = new
95
+ TypeMembers = new
96
+ MixesInClassMethods = new
97
+ TStructFields = new
98
+ TEnums = new
99
+ Inits = new
100
+ Methods = new
101
+ Consts = new
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end