tapioca 0.4.27 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +15 -15
  3. data/README.md +2 -2
  4. data/Rakefile +5 -7
  5. data/exe/tapioca +2 -2
  6. data/lib/tapioca/cli.rb +172 -2
  7. data/lib/tapioca/compilers/dsl/aasm.rb +122 -0
  8. data/lib/tapioca/compilers/dsl/action_controller_helpers.rb +52 -12
  9. data/lib/tapioca/compilers/dsl/action_mailer.rb +6 -9
  10. data/lib/tapioca/compilers/dsl/active_job.rb +8 -12
  11. data/lib/tapioca/compilers/dsl/active_model_attributes.rb +131 -0
  12. data/lib/tapioca/compilers/dsl/active_model_secure_password.rb +101 -0
  13. data/lib/tapioca/compilers/dsl/active_record_associations.rb +33 -54
  14. data/lib/tapioca/compilers/dsl/active_record_columns.rb +10 -105
  15. data/lib/tapioca/compilers/dsl/active_record_enum.rb +8 -10
  16. data/lib/tapioca/compilers/dsl/active_record_fixtures.rb +86 -0
  17. data/lib/tapioca/compilers/dsl/active_record_scope.rb +7 -10
  18. data/lib/tapioca/compilers/dsl/active_record_typed_store.rb +5 -8
  19. data/lib/tapioca/compilers/dsl/active_resource.rb +9 -37
  20. data/lib/tapioca/compilers/dsl/active_storage.rb +98 -0
  21. data/lib/tapioca/compilers/dsl/active_support_concern.rb +106 -0
  22. data/lib/tapioca/compilers/dsl/active_support_current_attributes.rb +13 -8
  23. data/lib/tapioca/compilers/dsl/base.rb +108 -82
  24. data/lib/tapioca/compilers/dsl/config.rb +111 -0
  25. data/lib/tapioca/compilers/dsl/frozen_record.rb +5 -7
  26. data/lib/tapioca/compilers/dsl/identity_cache.rb +66 -29
  27. data/lib/tapioca/compilers/dsl/mixed_in_class_attributes.rb +74 -0
  28. data/lib/tapioca/compilers/dsl/protobuf.rb +19 -69
  29. data/lib/tapioca/compilers/dsl/sidekiq_worker.rb +25 -12
  30. data/lib/tapioca/compilers/dsl/smart_properties.rb +21 -33
  31. data/lib/tapioca/compilers/dsl/state_machines.rb +56 -78
  32. data/lib/tapioca/compilers/dsl/url_helpers.rb +7 -10
  33. data/lib/tapioca/compilers/dsl_compiler.rb +25 -40
  34. data/lib/tapioca/compilers/dynamic_mixin_compiler.rb +198 -0
  35. data/lib/tapioca/compilers/requires_compiler.rb +2 -2
  36. data/lib/tapioca/compilers/sorbet.rb +25 -5
  37. data/lib/tapioca/compilers/symbol_table/symbol_generator.rb +122 -206
  38. data/lib/tapioca/compilers/symbol_table/symbol_loader.rb +4 -4
  39. data/lib/tapioca/compilers/symbol_table_compiler.rb +5 -11
  40. data/lib/tapioca/compilers/todos_compiler.rb +1 -1
  41. data/lib/tapioca/config.rb +3 -0
  42. data/lib/tapioca/config_builder.rb +5 -2
  43. data/lib/tapioca/constant_locator.rb +6 -8
  44. data/lib/tapioca/gemfile.rb +14 -11
  45. data/lib/tapioca/generators/base.rb +61 -0
  46. data/lib/tapioca/generators/dsl.rb +362 -0
  47. data/lib/tapioca/generators/gem.rb +345 -0
  48. data/lib/tapioca/generators/init.rb +79 -0
  49. data/lib/tapioca/generators/require.rb +52 -0
  50. data/lib/tapioca/generators/todo.rb +76 -0
  51. data/lib/tapioca/generators.rb +9 -0
  52. data/lib/tapioca/generic_type_registry.rb +25 -98
  53. data/lib/tapioca/helpers/active_record_column_type_helper.rb +98 -0
  54. data/lib/tapioca/internal.rb +2 -10
  55. data/lib/tapioca/loader.rb +11 -31
  56. data/lib/tapioca/rbi_ext/model.rb +166 -0
  57. data/lib/tapioca/reflection.rb +138 -0
  58. data/lib/tapioca/sorbet_ext/fixed_hash_patch.rb +1 -1
  59. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +72 -4
  60. data/lib/tapioca/sorbet_ext/name_patch.rb +1 -1
  61. data/lib/tapioca/version.rb +1 -1
  62. data/lib/tapioca.rb +3 -0
  63. metadata +45 -23
  64. data/lib/tapioca/cli/main.rb +0 -146
  65. data/lib/tapioca/core_ext/class.rb +0 -28
  66. data/lib/tapioca/core_ext/string.rb +0 -18
  67. data/lib/tapioca/generator.rb +0 -633
  68. data/lib/tapioca/rbi/model.rb +0 -405
  69. data/lib/tapioca/rbi/printer.rb +0 -410
  70. data/lib/tapioca/rbi/rewriters/group_nodes.rb +0 -106
  71. data/lib/tapioca/rbi/rewriters/nest_non_public_methods.rb +0 -65
  72. data/lib/tapioca/rbi/rewriters/nest_singleton_methods.rb +0 -42
  73. data/lib/tapioca/rbi/rewriters/sort_nodes.rb +0 -86
  74. data/lib/tapioca/rbi/visitor.rb +0 -21
@@ -1,410 +0,0 @@
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
@@ -1,106 +0,0 @@
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
@@ -1,65 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module Tapioca
5
- module RBI
6
- module Rewriters
7
- class NestNonPublicMethods < 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
- public_group = VisibilityGroup.new(Visibility::Public)
17
- protected_group = VisibilityGroup.new(Visibility::Protected)
18
- private_group = VisibilityGroup.new(Visibility::Private)
19
-
20
- node.nodes.dup.each do |child|
21
- visit(child)
22
- next unless child.is_a?(Method)
23
- child.detach
24
- case child.visibility
25
- when Visibility::Protected
26
- protected_group << child
27
- when Visibility::Private
28
- private_group << child
29
- else
30
- public_group << child
31
- end
32
- end
33
-
34
- node << public_group unless public_group.empty?
35
- node << protected_group unless protected_group.empty?
36
- node << private_group unless private_group.empty?
37
- end
38
- end
39
- end
40
- end
41
-
42
- class Tree
43
- extend T::Sig
44
-
45
- sig { void }
46
- def nest_non_public_methods!
47
- visitor = Rewriters::NestNonPublicMethods.new
48
- visitor.visit(self)
49
- end
50
- end
51
-
52
- class VisibilityGroup < Tree
53
- extend T::Sig
54
-
55
- sig { returns(Visibility) }
56
- attr_reader :visibility
57
-
58
- sig { params(visibility: Visibility).void }
59
- def initialize(visibility)
60
- super()
61
- @visibility = visibility
62
- end
63
- end
64
- end
65
- end
@@ -1,42 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module Tapioca
5
- module RBI
6
- module Rewriters
7
- class NestSingletonMethods < 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
- singleton_class = SingletonClass.new
17
-
18
- node.nodes.dup.each do |child|
19
- visit(child)
20
- next unless child.is_a?(Method) && child.is_singleton
21
- child.detach
22
- child.is_singleton = false
23
- singleton_class << child
24
- end
25
-
26
- node << singleton_class unless singleton_class.empty?
27
- end
28
- end
29
- end
30
- end
31
-
32
- class Tree
33
- extend T::Sig
34
-
35
- sig { void }
36
- def nest_singleton_methods!
37
- visitor = Rewriters::NestSingletonMethods.new
38
- visitor.visit(self)
39
- end
40
- end
41
- end
42
- end
@@ -1,86 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module Tapioca
5
- module RBI
6
- module Rewriters
7
- class SortNodes < Visitor
8
- extend T::Sig
9
-
10
- sig { override.params(node: T.nilable(Node)).void }
11
- def visit(node)
12
- return unless node.is_a?(Tree)
13
- visit_all(node.nodes)
14
- original_order = node.nodes.map.with_index.to_h
15
- node.nodes.sort! do |a, b|
16
- res = node_rank(a) <=> node_rank(b)
17
- res = node_name(a) <=> node_name(b) if res == 0
18
- res = (original_order[a] || 0) <=> (original_order[b] || 0) if res == 0
19
- res || 0
20
- end
21
- end
22
-
23
- private
24
-
25
- sig { params(node: Node).returns(Integer) }
26
- def node_rank(node)
27
- case node
28
- when Group then group_rank(node.kind)
29
- when Include, Extend then 10
30
- when Helper then 20
31
- when TypeMember then 30
32
- when MixesInClassMethods then 40
33
- when TStructField then 50
34
- when TEnumBlock then 60
35
- when Method
36
- if node.name == "initialize"
37
- 71
38
- elsif !node.is_singleton
39
- 72
40
- else
41
- 73
42
- end
43
- when Scope, Const then 80
44
- else
45
- 100
46
- end
47
- end
48
-
49
- sig { params(kind: Group::Kind).returns(Integer) }
50
- def group_rank(kind)
51
- case kind
52
- when Group::Kind::Mixins then 0
53
- when Group::Kind::Helpers then 1
54
- when Group::Kind::TypeMembers then 2
55
- when Group::Kind::MixesInClassMethods then 3
56
- when Group::Kind::TStructFields then 4
57
- when Group::Kind::TEnums then 5
58
- when Group::Kind::Inits then 6
59
- when Group::Kind::Methods then 7
60
- when Group::Kind::Consts then 8
61
- else
62
- T.absurd(kind)
63
- end
64
- end
65
-
66
- sig { params(node: Node).returns(T.nilable(String)) }
67
- def node_name(node)
68
- case node
69
- when Module, Class, Const, Method, Helper, TStructField
70
- node.name
71
- end
72
- end
73
- end
74
- end
75
-
76
- class Tree
77
- extend T::Sig
78
-
79
- sig { void }
80
- def sort_nodes!
81
- visitor = Rewriters::SortNodes.new
82
- visitor.visit(self)
83
- end
84
- end
85
- end
86
- end