tapioca 0.16.10 → 0.17.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.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ruby_lsp/tapioca/addon.rb +24 -20
  3. data/lib/ruby_lsp/tapioca/run_gem_rbi_check.rb +20 -20
  4. data/lib/tapioca/bundler_ext/auto_require_hook.rb +5 -10
  5. data/lib/tapioca/commands/abstract_dsl.rb +36 -62
  6. data/lib/tapioca/commands/abstract_gem.rb +23 -43
  7. data/lib/tapioca/commands/annotations.rb +27 -33
  8. data/lib/tapioca/commands/check_shims.rb +4 -13
  9. data/lib/tapioca/commands/command.rb +8 -20
  10. data/lib/tapioca/commands/command_without_tracker.rb +1 -1
  11. data/lib/tapioca/commands/configure.rb +11 -16
  12. data/lib/tapioca/commands/dsl_compiler_list.rb +2 -1
  13. data/lib/tapioca/commands/dsl_generate.rb +2 -1
  14. data/lib/tapioca/commands/dsl_verify.rb +2 -1
  15. data/lib/tapioca/commands/gem_generate.rb +4 -8
  16. data/lib/tapioca/commands/gem_sync.rb +2 -1
  17. data/lib/tapioca/commands/gem_verify.rb +3 -2
  18. data/lib/tapioca/commands/require.rb +3 -7
  19. data/lib/tapioca/commands/todo.rb +6 -10
  20. data/lib/tapioca/dsl/compiler.rb +28 -53
  21. data/lib/tapioca/dsl/compilers/aasm.rb +31 -41
  22. data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +7 -5
  23. data/lib/tapioca/dsl/compilers/action_mailer.rb +5 -3
  24. data/lib/tapioca/dsl/compilers/action_text.rb +5 -3
  25. data/lib/tapioca/dsl/compilers/active_job.rb +5 -8
  26. data/lib/tapioca/dsl/compilers/active_model_attributes.rb +9 -7
  27. data/lib/tapioca/dsl/compilers/active_model_secure_password.rb +4 -2
  28. data/lib/tapioca/dsl/compilers/active_model_validations_confirmation.rb +4 -2
  29. data/lib/tapioca/dsl/compilers/active_record_associations.rb +16 -42
  30. data/lib/tapioca/dsl/compilers/active_record_columns.rb +19 -24
  31. data/lib/tapioca/dsl/compilers/active_record_delegated_types.rb +7 -5
  32. data/lib/tapioca/dsl/compilers/active_record_enum.rb +6 -4
  33. data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +53 -61
  34. data/lib/tapioca/dsl/compilers/active_record_relations.rb +86 -119
  35. data/lib/tapioca/dsl/compilers/active_record_scope.rb +7 -11
  36. data/lib/tapioca/dsl/compilers/active_record_secure_token.rb +4 -2
  37. data/lib/tapioca/dsl/compilers/active_record_store.rb +4 -2
  38. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +18 -26
  39. data/lib/tapioca/dsl/compilers/active_resource.rb +18 -19
  40. data/lib/tapioca/dsl/compilers/active_storage.rb +5 -5
  41. data/lib/tapioca/dsl/compilers/active_support_concern.rb +8 -6
  42. data/lib/tapioca/dsl/compilers/active_support_current_attributes.rb +7 -5
  43. data/lib/tapioca/dsl/compilers/active_support_time_ext.rb +4 -2
  44. data/lib/tapioca/dsl/compilers/config.rb +4 -2
  45. data/lib/tapioca/dsl/compilers/frozen_record.rb +6 -9
  46. data/lib/tapioca/dsl/compilers/graphql_input_object.rb +8 -8
  47. data/lib/tapioca/dsl/compilers/graphql_mutation.rb +5 -8
  48. data/lib/tapioca/dsl/compilers/identity_cache.rb +10 -37
  49. data/lib/tapioca/dsl/compilers/json_api_client_resource.rb +8 -16
  50. data/lib/tapioca/dsl/compilers/kredis.rb +6 -4
  51. data/lib/tapioca/dsl/compilers/mixed_in_class_attributes.rb +4 -2
  52. data/lib/tapioca/dsl/compilers/protobuf.rb +12 -24
  53. data/lib/tapioca/dsl/compilers/rails_generators.rb +8 -9
  54. data/lib/tapioca/dsl/compilers/sidekiq_worker.rb +22 -11
  55. data/lib/tapioca/dsl/compilers/smart_properties.rb +11 -20
  56. data/lib/tapioca/dsl/compilers/state_machines.rb +14 -24
  57. data/lib/tapioca/dsl/compilers/url_helpers.rb +9 -7
  58. data/lib/tapioca/dsl/compilers.rb +4 -7
  59. data/lib/tapioca/dsl/helpers/active_model_type_helper.rb +13 -16
  60. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +13 -28
  61. data/lib/tapioca/dsl/helpers/active_record_constants_helper.rb +19 -15
  62. data/lib/tapioca/dsl/helpers/graphql_type_helper.rb +5 -24
  63. data/lib/tapioca/dsl/pipeline.rb +30 -58
  64. data/lib/tapioca/executor.rb +6 -12
  65. data/lib/tapioca/gem/events.rb +22 -28
  66. data/lib/tapioca/gem/listeners/base.rb +6 -6
  67. data/lib/tapioca/gem/listeners/dynamic_mixins.rb +4 -2
  68. data/lib/tapioca/gem/listeners/foreign_constants.rb +5 -7
  69. data/lib/tapioca/gem/listeners/methods.rb +15 -34
  70. data/lib/tapioca/gem/listeners/mixins.rb +6 -18
  71. data/lib/tapioca/gem/listeners/remove_empty_payload_scopes.rb +4 -2
  72. data/lib/tapioca/gem/listeners/sorbet_enums.rb +4 -2
  73. data/lib/tapioca/gem/listeners/sorbet_helpers.rb +4 -2
  74. data/lib/tapioca/gem/listeners/sorbet_props.rb +4 -2
  75. data/lib/tapioca/gem/listeners/sorbet_required_ancestors.rb +4 -2
  76. data/lib/tapioca/gem/listeners/sorbet_signatures.rb +7 -5
  77. data/lib/tapioca/gem/listeners/sorbet_type_variables.rb +6 -4
  78. data/lib/tapioca/gem/listeners/source_location.rb +7 -4
  79. data/lib/tapioca/gem/listeners/subconstants.rb +5 -4
  80. data/lib/tapioca/gem/listeners/yard_doc.rb +23 -22
  81. data/lib/tapioca/gem/pipeline.rb +57 -72
  82. data/lib/tapioca/gem_info.rb +1 -1
  83. data/lib/tapioca/gemfile.rb +64 -73
  84. data/lib/tapioca/helpers/cli_helper.rb +3 -3
  85. data/lib/tapioca/helpers/config_helper.rb +15 -24
  86. data/lib/tapioca/helpers/env_helper.rb +1 -1
  87. data/lib/tapioca/helpers/gem_helper.rb +5 -5
  88. data/lib/tapioca/helpers/git_attributes.rb +3 -3
  89. data/lib/tapioca/helpers/rbi_files_helper.rb +73 -67
  90. data/lib/tapioca/helpers/rbi_helper.rb +14 -22
  91. data/lib/tapioca/helpers/sorbet_helper.rb +9 -18
  92. data/lib/tapioca/helpers/source_uri.rb +15 -25
  93. data/lib/tapioca/helpers/test/content.rb +6 -6
  94. data/lib/tapioca/helpers/test/dsl_compiler.rb +19 -29
  95. data/lib/tapioca/helpers/test/isolation.rb +4 -4
  96. data/lib/tapioca/helpers/test/template.rb +5 -7
  97. data/lib/tapioca/internal.rb +5 -1
  98. data/lib/tapioca/loaders/dsl.rb +11 -19
  99. data/lib/tapioca/loaders/gem.rb +6 -21
  100. data/lib/tapioca/loaders/loader.rb +15 -27
  101. data/lib/tapioca/rbi_ext/model.rb +12 -37
  102. data/lib/tapioca/rbi_formatter.rb +10 -19
  103. data/lib/tapioca/rbs/rewriter.rb +55 -0
  104. data/lib/tapioca/repo_index.rb +7 -7
  105. data/lib/tapioca/runtime/attached_class_of_32.rb +1 -1
  106. data/lib/tapioca/runtime/attached_class_of_legacy.rb +1 -1
  107. data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +23 -23
  108. data/lib/tapioca/runtime/generic_type_registry.rb +13 -23
  109. data/lib/tapioca/runtime/reflection.rb +48 -56
  110. data/lib/tapioca/runtime/trackers/autoload.rb +4 -8
  111. data/lib/tapioca/runtime/trackers/mixin.rb +6 -10
  112. data/lib/tapioca/runtime/trackers/required_ancestor.rb +3 -3
  113. data/lib/tapioca/runtime/trackers/tracker.rb +2 -2
  114. data/lib/tapioca/runtime/trackers.rb +4 -8
  115. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +9 -15
  116. data/lib/tapioca/sorbet_ext/name_patch.rb +1 -1
  117. data/lib/tapioca/sorbet_ext/proc_bind_patch.rb +1 -1
  118. data/lib/tapioca/static/requires_compiler.rb +6 -6
  119. data/lib/tapioca/static/symbol_loader.rb +14 -16
  120. data/lib/tapioca/static/symbol_table_parser.rb +8 -8
  121. data/lib/tapioca/version.rb +1 -1
  122. data/lib/tapioca.rb +22 -29
  123. metadata +25 -10
@@ -6,37 +6,25 @@ module Tapioca
6
6
  class Pipeline
7
7
  extend T::Sig
8
8
 
9
- sig { returns(T::Enumerable[T.class_of(Compiler)]) }
9
+ #: T::Enumerable[singleton(Compiler)]
10
10
  attr_reader :active_compilers
11
11
 
12
- sig { returns(T::Array[Module]) }
12
+ #: Array[Module]
13
13
  attr_reader :requested_constants
14
14
 
15
- sig { returns(T::Array[Pathname]) }
15
+ #: Array[Pathname]
16
16
  attr_reader :requested_paths
17
17
 
18
- sig { returns(T::Array[Module]) }
18
+ #: Array[Module]
19
19
  attr_reader :skipped_constants
20
20
 
21
- sig { returns(T.proc.params(error: String).void) }
21
+ #: ^(String error) -> void
22
22
  attr_reader :error_handler
23
23
 
24
- sig { returns(T::Array[String]) }
24
+ #: Array[String]
25
25
  attr_reader :errors
26
26
 
27
- sig do
28
- params(
29
- requested_constants: T::Array[Module],
30
- requested_paths: T::Array[Pathname],
31
- requested_compilers: T::Array[T.class_of(Compiler)],
32
- excluded_compilers: T::Array[T.class_of(Compiler)],
33
- error_handler: T.proc.params(error: String).void,
34
- skipped_constants: T::Array[Module],
35
- number_of_workers: T.nilable(Integer),
36
- compiler_options: T::Hash[String, T.untyped],
37
- lsp_addon: T::Boolean,
38
- ).void
39
- end
27
+ #: (requested_constants: Array[Module], ?requested_paths: Array[Pathname], ?requested_compilers: Array[singleton(Compiler)], ?excluded_compilers: Array[singleton(Compiler)], ?error_handler: ^(String error) -> void, ?skipped_constants: Array[Module], ?number_of_workers: Integer?, ?compiler_options: Hash[String, untyped], ?lsp_addon: bool) -> void
40
28
  def initialize(
41
29
  requested_constants:,
42
30
  requested_paths: [],
@@ -48,10 +36,8 @@ module Tapioca
48
36
  compiler_options: {},
49
37
  lsp_addon: false
50
38
  )
51
- @active_compilers = T.let(
52
- gather_active_compilers(requested_compilers, excluded_compilers),
53
- T::Enumerable[T.class_of(Compiler)],
54
- )
39
+ @active_compilers =
40
+ gather_active_compilers(requested_compilers, excluded_compilers) #: Enumerable[singleton(Compiler)]
55
41
  @requested_constants = requested_constants
56
42
  @requested_paths = requested_paths
57
43
  @error_handler = error_handler
@@ -59,14 +45,10 @@ module Tapioca
59
45
  @number_of_workers = number_of_workers
60
46
  @compiler_options = compiler_options
61
47
  @lsp_addon = lsp_addon
62
- @errors = T.let([], T::Array[String])
48
+ @errors = [] #: Array[String]
63
49
  end
64
50
 
65
- sig do
66
- type_parameters(:T).params(
67
- blk: T.proc.params(constant: Module, rbi: RBI::File).returns(T.type_parameter(:T)),
68
- ).returns(T::Array[T.type_parameter(:T)])
69
- end
51
+ #: [T] { (Module constant, RBI::File rbi) -> T } -> Array[T]
70
52
  def run(&blk)
71
53
  constants_to_process = gather_constants(requested_constants, requested_paths, skipped_constants)
72
54
  .select { |c| Module === c } # Filter value constants out
@@ -78,6 +60,7 @@ module Tapioca
78
60
  No classes/modules can be matched for RBI generation.
79
61
  Please check that the requested classes/modules include processable DSL methods.
80
62
  ERROR
63
+ raise Thor::Error, ""
81
64
  end
82
65
 
83
66
  if defined?(::ActiveRecord::Base) && constants_to_process.any? { |c| ::ActiveRecord::Base > c }
@@ -94,19 +77,23 @@ module Tapioca
94
77
  blk.call(constant, rbi)
95
78
  end
96
79
 
97
- errors.each do |msg|
98
- report_error(msg)
80
+ if errors.any?
81
+ errors.each do |msg|
82
+ report_error(msg)
83
+ end
84
+
85
+ raise Thor::Error, ""
99
86
  end
100
87
 
101
88
  result.compact
102
89
  end
103
90
 
104
- sig { params(error: String).void }
91
+ #: (String error) -> void
105
92
  def add_error(error)
106
93
  @errors << error
107
94
  end
108
95
 
109
- sig { params(compiler_name: String).returns(T::Boolean) }
96
+ #: (String compiler_name) -> bool
110
97
  def compiler_enabled?(compiler_name)
111
98
  potential_names = Compilers::NAMESPACES.map { |namespace| namespace + compiler_name }
112
99
 
@@ -115,24 +102,16 @@ module Tapioca
115
102
  end
116
103
  end
117
104
 
118
- sig { returns(T::Array[T.class_of(Compiler)]) }
105
+ #: -> Array[singleton(Compiler)]
119
106
  def compilers
120
- @compilers ||= T.let(
121
- Runtime::Reflection.descendants_of(Compiler).sort_by do |compiler|
122
- T.must(compiler.name)
123
- end,
124
- T.nilable(T::Array[T.class_of(Compiler)]),
125
- )
107
+ @compilers ||= Runtime::Reflection.descendants_of(Compiler).sort_by do |compiler|
108
+ T.must(compiler.name)
109
+ end #: Array[singleton(Compiler)]?
126
110
  end
127
111
 
128
112
  private
129
113
 
130
- sig do
131
- params(
132
- requested_compilers: T::Array[T.class_of(Compiler)],
133
- excluded_compilers: T::Array[T.class_of(Compiler)],
134
- ).returns(T::Enumerable[T.class_of(Compiler)])
135
- end
114
+ #: (Array[singleton(Compiler)] requested_compilers, Array[singleton(Compiler)] excluded_compilers) -> T::Enumerable[singleton(Compiler)]
136
115
  def gather_active_compilers(requested_compilers, excluded_compilers)
137
116
  active_compilers = compilers
138
117
  active_compilers -= excluded_compilers
@@ -140,13 +119,7 @@ module Tapioca
140
119
  active_compilers
141
120
  end
142
121
 
143
- sig do
144
- params(
145
- requested_constants: T::Array[Module],
146
- requested_paths: T::Array[Pathname],
147
- skipped_constants: T::Array[Module],
148
- ).returns(T::Set[Module])
149
- end
122
+ #: (Array[Module] requested_constants, Array[Pathname] requested_paths, Array[Module] skipped_constants) -> Set[Module]
150
123
  def gather_constants(requested_constants, requested_paths, skipped_constants)
151
124
  Compiler.requested_constants = requested_constants
152
125
  constants = Set.new.compare_by_identity
@@ -168,7 +141,7 @@ module Tapioca
168
141
  constants
169
142
  end
170
143
 
171
- sig { params(constants: T::Set[Module]).returns(T::Set[Module]) }
144
+ #: (Set[Module] constants) -> Set[Module]
172
145
  def filter_anonymous_and_reloaded_constants(constants)
173
146
  # Group constants by their names
174
147
  constants_by_name = constants
@@ -197,7 +170,7 @@ module Tapioca
197
170
  Set.new.compare_by_identity.merge(filtered_constants)
198
171
  end
199
172
 
200
- sig { params(constant: Module).returns(T.nilable(RBI::File)) }
173
+ #: (Module constant) -> RBI::File?
201
174
  def rbi_for_constant(constant)
202
175
  file = RBI::File.new(strictness: "true")
203
176
 
@@ -216,14 +189,13 @@ module Tapioca
216
189
  file
217
190
  end
218
191
 
219
- sig { params(error: String).returns(T.noreturn) }
192
+ #: (String error) -> void
220
193
  def report_error(error)
221
194
  handler = error_handler
222
195
  handler.call(error)
223
- exit(1)
224
196
  end
225
197
 
226
- sig { void }
198
+ #: -> void
227
199
  def abort_if_pending_migrations!
228
200
  # When running within the add-on, we cannot invoke the abort if pending migrations task because that will exit
229
201
  # the process and crash the Rails runtime server. Instead, the Rails add-on checks for pending migrations and
@@ -5,26 +5,20 @@ module Tapioca
5
5
  class Executor
6
6
  extend T::Sig
7
7
 
8
- MINIMUM_ITEMS_PER_WORKER = T.let(2, Integer)
8
+ MINIMUM_ITEMS_PER_WORKER = 2 #: Integer
9
9
 
10
- sig { params(queue: T::Array[T.untyped], number_of_workers: T.nilable(Integer)).void }
10
+ #: (Array[untyped] queue, ?number_of_workers: Integer?) -> void
11
11
  def initialize(queue, number_of_workers: nil)
12
12
  @queue = queue
13
13
 
14
14
  # Forking workers is expensive and not worth it for a low number of gems. Here we assign the number of workers to
15
15
  # be the minimum between the number of available processors (max) or the number of workers to make sure that each
16
16
  # one has at least 4 items to process
17
- @number_of_workers = T.let(
18
- number_of_workers || [max_processors, (queue.length.to_f / MINIMUM_ITEMS_PER_WORKER).ceil].min,
19
- Integer,
20
- )
17
+ @number_of_workers = number_of_workers ||
18
+ [max_processors, (queue.length.to_f / MINIMUM_ITEMS_PER_WORKER).ceil].min #: Integer
21
19
  end
22
20
 
23
- sig do
24
- type_parameters(:T).params(
25
- block: T.proc.params(item: T.untyped).returns(T.type_parameter(:T)),
26
- ).returns(T::Array[T.type_parameter(:T)])
27
- end
21
+ #: [T] { (untyped item) -> T } -> Array[T]
28
22
  def run_in_parallel(&block)
29
23
  # To have the parallel gem run jobs in the parent process, you must pass 0 as the number of processes
30
24
  number_of_processes = @number_of_workers == 1 ? 0 : @number_of_workers
@@ -33,7 +27,7 @@ module Tapioca
33
27
 
34
28
  private
35
29
 
36
- sig { returns(Integer) }
30
+ #: -> Integer
37
31
  def max_processors
38
32
  env_max_processors = ENV["PARALLEL_PROCESSOR_COUNT"].to_i
39
33
  env_max_processors.positive? ? env_max_processors : Etc.nprocessors
@@ -13,10 +13,10 @@ module Tapioca
13
13
  class SymbolFound < Event
14
14
  extend T::Sig
15
15
 
16
- sig { returns(String) }
16
+ #: String
17
17
  attr_reader :symbol
18
18
 
19
- sig { params(symbol: String).void }
19
+ #: (String symbol) -> void
20
20
  def initialize(symbol)
21
21
  super()
22
22
  @symbol = symbol
@@ -26,13 +26,15 @@ module Tapioca
26
26
  class ConstantFound < Event
27
27
  extend T::Sig
28
28
 
29
- sig { returns(String) }
29
+ #: String
30
30
  attr_reader :symbol
31
31
 
32
- sig { returns(BasicObject).checked(:never) }
32
+ # @without_runtime
33
+ #: BasicObject
33
34
  attr_reader :constant
34
35
 
35
- sig { params(symbol: String, constant: BasicObject).void.checked(:never) }
36
+ # @without_runtime
37
+ #: (String symbol, BasicObject constant) -> void
36
38
  def initialize(symbol, constant)
37
39
  super()
38
40
  @symbol = symbol
@@ -43,12 +45,13 @@ module Tapioca
43
45
  class ForeignConstantFound < ConstantFound
44
46
  extend T::Sig
45
47
 
46
- sig { override.returns(Module) }
48
+ # @override
49
+ #: -> Module
47
50
  def constant
48
51
  T.cast(@constant, Module)
49
52
  end
50
53
 
51
- sig { params(symbol: String, constant: Module).void }
54
+ #: (String symbol, Module constant) -> void
52
55
  def initialize(symbol, constant)
53
56
  super
54
57
  end
@@ -60,13 +63,13 @@ module Tapioca
60
63
 
61
64
  abstract!
62
65
 
63
- sig { returns(String) }
66
+ #: String
64
67
  attr_reader :symbol
65
68
 
66
- sig { returns(Module).checked(:never) }
69
+ #: Module
67
70
  attr_reader :constant
68
71
 
69
- sig { params(symbol: String, constant: Module).void.checked(:never) }
72
+ #: (String symbol, Module constant) -> void
70
73
  def initialize(symbol, constant)
71
74
  super()
72
75
  @symbol = symbol
@@ -77,10 +80,10 @@ module Tapioca
77
80
  class ConstNodeAdded < NodeAdded
78
81
  extend T::Sig
79
82
 
80
- sig { returns(RBI::Const) }
83
+ #: RBI::Const
81
84
  attr_reader :node
82
85
 
83
- sig { params(symbol: String, constant: Module, node: RBI::Const).void.checked(:never) }
86
+ #: (String symbol, Module constant, RBI::Const node) -> void
84
87
  def initialize(symbol, constant, node)
85
88
  super(symbol, constant)
86
89
  @node = node
@@ -90,10 +93,10 @@ module Tapioca
90
93
  class ScopeNodeAdded < NodeAdded
91
94
  extend T::Sig
92
95
 
93
- sig { returns(RBI::Scope) }
96
+ #: RBI::Scope
94
97
  attr_reader :node
95
98
 
96
- sig { params(symbol: String, constant: Module, node: RBI::Scope).void.checked(:never) }
99
+ #: (String symbol, Module constant, RBI::Scope node) -> void
97
100
  def initialize(symbol, constant, node)
98
101
  super(symbol, constant)
99
102
  @node = node
@@ -105,28 +108,19 @@ module Tapioca
105
108
  class MethodNodeAdded < NodeAdded
106
109
  extend T::Sig
107
110
 
108
- sig { returns(UnboundMethod) }
111
+ #: UnboundMethod
109
112
  attr_reader :method
110
113
 
111
- sig { returns(RBI::Method) }
114
+ #: RBI::Method
112
115
  attr_reader :node
113
116
 
114
- sig { returns(T.untyped) }
117
+ #: untyped
115
118
  attr_reader :signature
116
119
 
117
- sig { returns(T::Array[[Symbol, String]]) }
120
+ #: Array[[Symbol, String]]
118
121
  attr_reader :parameters
119
122
 
120
- sig do
121
- params(
122
- symbol: String,
123
- constant: Module,
124
- method: UnboundMethod,
125
- node: RBI::Method,
126
- signature: T.untyped,
127
- parameters: T::Array[[Symbol, String]],
128
- ).void.checked(:never)
129
- end
123
+ #: (String symbol, Module constant, UnboundMethod method, RBI::Method node, untyped signature, Array[[Symbol, String]] parameters) -> void
130
124
  def initialize(symbol, constant, method, node, signature, parameters) # rubocop:disable Metrics/ParameterLists
131
125
  super(symbol, constant)
132
126
  @node = node
@@ -10,12 +10,12 @@ module Tapioca
10
10
 
11
11
  abstract!
12
12
 
13
- sig { params(pipeline: Pipeline).void }
13
+ #: (Pipeline pipeline) -> void
14
14
  def initialize(pipeline)
15
15
  @pipeline = pipeline
16
16
  end
17
17
 
18
- sig { params(event: NodeAdded).void }
18
+ #: (NodeAdded event) -> void
19
19
  def dispatch(event)
20
20
  return if ignore?(event)
21
21
 
@@ -33,19 +33,19 @@ module Tapioca
33
33
 
34
34
  private
35
35
 
36
- sig { params(event: ConstNodeAdded).void }
36
+ #: (ConstNodeAdded event) -> void
37
37
  def on_const(event)
38
38
  end
39
39
 
40
- sig { params(event: ScopeNodeAdded).void }
40
+ #: (ScopeNodeAdded event) -> void
41
41
  def on_scope(event)
42
42
  end
43
43
 
44
- sig { params(event: MethodNodeAdded).void }
44
+ #: (MethodNodeAdded event) -> void
45
45
  def on_method(event)
46
46
  end
47
47
 
48
- sig { params(event: NodeAdded).returns(T::Boolean) }
48
+ #: (NodeAdded event) -> bool
49
49
  def ignore?(event)
50
50
  # Some listeners do not have to take any action on certain events. For example,
51
51
  # almost every listener should skip ForeignScopeNodeAdded events in order not to generate
@@ -11,7 +11,8 @@ module Tapioca
11
11
 
12
12
  private
13
13
 
14
- sig { override.params(event: ScopeNodeAdded).void }
14
+ # @override
15
+ #: (ScopeNodeAdded event) -> void
15
16
  def on_scope(event)
16
17
  constant = event.constant
17
18
  return if constant.is_a?(Class)
@@ -27,7 +28,8 @@ module Tapioca
27
28
  end
28
29
  end
29
30
 
30
- sig { override.params(event: NodeAdded).returns(T::Boolean) }
31
+ # @override
32
+ #: (NodeAdded event) -> bool
31
33
  def ignore?(event)
32
34
  event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
33
35
  end
@@ -11,7 +11,8 @@ module Tapioca
11
11
 
12
12
  private
13
13
 
14
- sig { override.params(event: ScopeNodeAdded).void }
14
+ # @override
15
+ #: (ScopeNodeAdded event) -> void
15
16
  def on_scope(event)
16
17
  mixin = event.constant
17
18
  return if Class === mixin # Classes can't be mixed into other constants
@@ -47,16 +48,13 @@ module Tapioca
47
48
  end
48
49
  end
49
50
 
50
- sig do
51
- params(
52
- location: String,
53
- ).returns(T::Boolean)
54
- end
51
+ #: (String location) -> bool
55
52
  def mixed_in_by_gem?(location)
56
53
  @pipeline.gem.contains_path?(location)
57
54
  end
58
55
 
59
- sig { override.params(event: NodeAdded).returns(T::Boolean) }
56
+ # @override
57
+ #: (NodeAdded event) -> bool
60
58
  def ignore?(event)
61
59
  event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
62
60
  end
@@ -12,7 +12,8 @@ module Tapioca
12
12
 
13
13
  private
14
14
 
15
- sig { override.params(event: ScopeNodeAdded).void }
15
+ # @override
16
+ #: (ScopeNodeAdded event) -> void
16
17
  def on_scope(event)
17
18
  symbol = event.symbol
18
19
  constant = event.constant
@@ -23,15 +24,7 @@ module Tapioca
23
24
  compile_directly_owned_methods(node, symbol, singleton_class_of(constant), attached_class: constant)
24
25
  end
25
26
 
26
- sig do
27
- params(
28
- tree: RBI::Tree,
29
- module_name: String,
30
- mod: Module,
31
- for_visibility: T::Array[Symbol],
32
- attached_class: T.nilable(Module),
33
- ).void
34
- end
27
+ #: (RBI::Tree tree, String module_name, Module mod, ?Array[Symbol] for_visibility, ?attached_class: Module?) -> void
35
28
  def compile_directly_owned_methods(
36
29
  tree,
37
30
  module_name,
@@ -59,29 +52,21 @@ module Tapioca
59
52
  end
60
53
  end
61
54
 
62
- sig do
63
- params(
64
- tree: RBI::Tree,
65
- symbol_name: String,
66
- constant: Module,
67
- method: T.nilable(UnboundMethod),
68
- visibility: RBI::Visibility,
69
- ).void
70
- end
55
+ #: (RBI::Tree tree, String symbol_name, Module constant, UnboundMethod? method, ?RBI::Visibility visibility) -> void
71
56
  def compile_method(tree, symbol_name, constant, method, visibility = RBI::Public.new)
72
57
  return unless method
73
58
  return unless method_owned_by_constant?(method, constant)
74
59
  return if @pipeline.symbol_in_payload?(symbol_name) && !@pipeline.method_in_gem?(method)
75
60
 
76
61
  signature = lookup_signature_of(method)
77
- method = T.let(signature.method, UnboundMethod) if signature
62
+ method = signature.method if signature #: UnboundMethod
78
63
 
79
64
  method_name = method.name.to_s
80
65
  return unless valid_method_name?(method_name)
81
66
  return if struct_method?(constant, method_name)
82
67
  return if method_name.start_with?("__t_props_generated_")
83
68
 
84
- parameters = T.let(method.parameters, T::Array[[Symbol, T.nilable(Symbol)]])
69
+ parameters = method.parameters #: Array[[Symbol, Symbol?]]
85
70
 
86
71
  sanitized_parameters = parameters.each_with_index.map do |(type, name), index|
87
72
  fallback_arg_name = "_arg#{index}"
@@ -154,10 +139,10 @@ module Tapioca
154
139
  # This method implements a better way of checking whether a constant defines a method.
155
140
  # It walks up the ancestor tree via the `super_method` method; if any of the super
156
141
  # methods are owned by the constant, it means that the constant declares the method.
157
- sig { params(method: UnboundMethod, constant: Module).returns(T::Boolean) }
142
+ #: (UnboundMethod method, Module constant) -> bool
158
143
  def method_owned_by_constant?(method, constant)
159
144
  # Widen the type of `method` to be nilable
160
- method = T.let(method, T.nilable(UnboundMethod))
145
+ method = method #: UnboundMethod?
161
146
 
162
147
  while method
163
148
  return true if method.owner == constant
@@ -168,7 +153,7 @@ module Tapioca
168
153
  false
169
154
  end
170
155
 
171
- sig { params(mod: Module).returns(T::Hash[Symbol, T::Array[Symbol]]) }
156
+ #: (Module mod) -> Hash[Symbol, Array[Symbol]]
172
157
  def method_names_by_visibility(mod)
173
158
  {
174
159
  public: public_instance_methods_of(mod),
@@ -177,7 +162,7 @@ module Tapioca
177
162
  }
178
163
  end
179
164
 
180
- sig { params(constant: Module, method_name: String).returns(T::Boolean) }
165
+ #: (Module constant, String method_name) -> bool
181
166
  def struct_method?(constant, method_name)
182
167
  return false unless T::Props::ClassMethods === constant
183
168
 
@@ -187,12 +172,7 @@ module Tapioca
187
172
  .include?(method_name.gsub(/=$/, "").to_sym)
188
173
  end
189
174
 
190
- sig do
191
- params(
192
- attached_class: T.nilable(Module),
193
- method_name: Symbol,
194
- ).returns(T.nilable(T::Boolean))
195
- end
175
+ #: (Module? attached_class, Symbol method_name) -> bool?
196
176
  def method_new_in_abstract_class?(attached_class, method_name)
197
177
  attached_class &&
198
178
  method_name == :new &&
@@ -200,19 +180,20 @@ module Tapioca
200
180
  Class === attached_class.singleton_class
201
181
  end
202
182
 
203
- sig { params(constant: Module).returns(T.nilable(UnboundMethod)) }
183
+ #: (Module constant) -> UnboundMethod?
204
184
  def initialize_method_for(constant)
205
185
  constant.instance_method(:initialize)
206
186
  rescue
207
187
  nil
208
188
  end
209
189
 
210
- sig { override.params(event: NodeAdded).returns(T::Boolean) }
190
+ # @override
191
+ #: (NodeAdded event) -> bool
211
192
  def ignore?(event)
212
193
  event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
213
194
  end
214
195
 
215
- sig { params(method: UnboundMethod).returns(T.untyped) }
196
+ #: (UnboundMethod method) -> untyped
216
197
  def lookup_signature_of(method)
217
198
  signature_of!(method)
218
199
  rescue LoadError, StandardError => error
@@ -11,7 +11,8 @@ module Tapioca
11
11
 
12
12
  private
13
13
 
14
- sig { override.params(event: ScopeNodeAdded).void }
14
+ # @override
15
+ #: (ScopeNodeAdded event) -> void
15
16
  def on_scope(event)
16
17
  constant = event.constant
17
18
  singleton_class = singleton_class_of(constant)
@@ -31,14 +32,7 @@ module Tapioca
31
32
  add_mixins(node, constant, extends.reverse, Runtime::Trackers::Mixin::Type::Extend)
32
33
  end
33
34
 
34
- sig do
35
- params(
36
- tree: RBI::Tree,
37
- constant: Module,
38
- mods: T::Array[Module],
39
- mixin_type: Runtime::Trackers::Mixin::Type,
40
- ).void
41
- end
35
+ #: (RBI::Tree tree, Module constant, Array[Module] mods, Runtime::Trackers::Mixin::Type mixin_type) -> void
42
36
  def add_mixins(tree, constant, mods, mixin_type)
43
37
  mods
44
38
  .select do |mod|
@@ -65,13 +59,7 @@ module Tapioca
65
59
  end
66
60
  end
67
61
 
68
- sig do
69
- params(
70
- constant: Module,
71
- mixin: Module,
72
- mixin_type: Runtime::Trackers::Mixin::Type,
73
- ).returns(T::Boolean)
74
- end
62
+ #: (Module constant, Module mixin, Runtime::Trackers::Mixin::Type mixin_type) -> bool
75
63
  def mixed_in_by_gem?(constant, mixin, mixin_type)
76
64
  mixin_location = Runtime::Trackers::Mixin.mixin_location(mixin, mixin_type, constant)
77
65
 
@@ -80,14 +68,14 @@ module Tapioca
80
68
  @pipeline.gem.contains_path?(mixin_location)
81
69
  end
82
70
 
83
- sig { params(mixin_name: String).returns(T::Boolean) }
71
+ #: (String mixin_name) -> bool
84
72
  def filtered_mixin?(mixin_name)
85
73
  # filter T:: namespace mixins that aren't T::Props
86
74
  # T::Props and subconstants have semantic value
87
75
  mixin_name.start_with?("T::") && !mixin_name.start_with?("T::Props")
88
76
  end
89
77
 
90
- sig { params(constant: Module).returns(T::Array[Module]) }
78
+ #: (Module constant) -> Array[Module]
91
79
  def interesting_ancestors_of(constant)
92
80
  inherited_ancestors = Set.new.compare_by_identity.merge(inherited_ancestors_of(constant))
93
81
 
@@ -11,12 +11,14 @@ module Tapioca
11
11
 
12
12
  private
13
13
 
14
- sig { override.params(event: ScopeNodeAdded).void }
14
+ # @override
15
+ #: (ScopeNodeAdded event) -> void
15
16
  def on_scope(event)
16
17
  event.node.detach if @pipeline.symbol_in_payload?(event.symbol) && event.node.empty?
17
18
  end
18
19
 
19
- sig { override.params(event: NodeAdded).returns(T::Boolean) }
20
+ # @override
21
+ #: (NodeAdded event) -> bool
20
22
  def ignore?(event)
21
23
  event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
22
24
  end
@@ -9,7 +9,8 @@ module Tapioca
9
9
 
10
10
  private
11
11
 
12
- sig { override.params(event: ScopeNodeAdded).void }
12
+ # @override
13
+ #: (ScopeNodeAdded event) -> void
13
14
  def on_scope(event)
14
15
  constant = event.constant
15
16
  return unless T::Enum > event.constant # rubocop:disable Style/InvertibleUnlessCondition
@@ -24,7 +25,8 @@ module Tapioca
24
25
  event.node << enum_block
25
26
  end
26
27
 
27
- sig { override.params(event: NodeAdded).returns(T::Boolean) }
28
+ # @override
29
+ #: (NodeAdded event) -> bool
28
30
  def ignore?(event)
29
31
  event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
30
32
  end