tapioca 0.18.0 → 0.19.1

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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/lib/tapioca/cli.rb +1 -1
  4. data/lib/tapioca/commands/abstract_dsl.rb +1 -1
  5. data/lib/tapioca/commands/check_shims.rb +3 -0
  6. data/lib/tapioca/commands/configure.rb +1 -0
  7. data/lib/tapioca/commands/todo.rb +8 -2
  8. data/lib/tapioca/dsl/compiler.rb +18 -13
  9. data/lib/tapioca/dsl/compilers/aasm.rb +5 -2
  10. data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +2 -2
  11. data/lib/tapioca/dsl/compilers/action_mailer.rb +1 -1
  12. data/lib/tapioca/dsl/compilers/action_text.rb +1 -1
  13. data/lib/tapioca/dsl/compilers/active_job.rb +1 -1
  14. data/lib/tapioca/dsl/compilers/active_model_attributes.rb +1 -1
  15. data/lib/tapioca/dsl/compilers/active_model_secure_password.rb +1 -1
  16. data/lib/tapioca/dsl/compilers/active_model_validations_confirmation.rb +1 -1
  17. data/lib/tapioca/dsl/compilers/active_record_associations.rb +1 -1
  18. data/lib/tapioca/dsl/compilers/active_record_columns.rb +1 -1
  19. data/lib/tapioca/dsl/compilers/active_record_delegated_types.rb +1 -1
  20. data/lib/tapioca/dsl/compilers/active_record_enum.rb +1 -1
  21. data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +1 -1
  22. data/lib/tapioca/dsl/compilers/active_record_relations.rb +1 -1
  23. data/lib/tapioca/dsl/compilers/active_record_scope.rb +1 -1
  24. data/lib/tapioca/dsl/compilers/active_record_secure_token.rb +1 -1
  25. data/lib/tapioca/dsl/compilers/active_record_store.rb +1 -1
  26. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +1 -1
  27. data/lib/tapioca/dsl/compilers/active_resource.rb +1 -1
  28. data/lib/tapioca/dsl/compilers/active_storage.rb +2 -2
  29. data/lib/tapioca/dsl/compilers/active_support_concern.rb +6 -6
  30. data/lib/tapioca/dsl/compilers/active_support_current_attributes.rb +1 -1
  31. data/lib/tapioca/dsl/compilers/active_support_environment_inquirer.rb +1 -1
  32. data/lib/tapioca/dsl/compilers/active_support_time_ext.rb +1 -1
  33. data/lib/tapioca/dsl/compilers/config.rb +2 -2
  34. data/lib/tapioca/dsl/compilers/frozen_record.rb +1 -1
  35. data/lib/tapioca/dsl/compilers/graphql_input_object.rb +1 -1
  36. data/lib/tapioca/dsl/compilers/graphql_mutation.rb +1 -1
  37. data/lib/tapioca/dsl/compilers/identity_cache.rb +2 -2
  38. data/lib/tapioca/dsl/compilers/json_api_client_resource.rb +1 -1
  39. data/lib/tapioca/dsl/compilers/kredis.rb +1 -1
  40. data/lib/tapioca/dsl/compilers/mixed_in_class_attributes.rb +2 -2
  41. data/lib/tapioca/dsl/compilers/protobuf.rb +1 -1
  42. data/lib/tapioca/dsl/compilers/rails_generators.rb +1 -1
  43. data/lib/tapioca/dsl/compilers/sidekiq_worker.rb +1 -1
  44. data/lib/tapioca/dsl/compilers/smart_properties.rb +1 -1
  45. data/lib/tapioca/dsl/compilers/state_machines.rb +2 -2
  46. data/lib/tapioca/dsl/compilers/url_helpers.rb +7 -7
  47. data/lib/tapioca/dsl/helpers/graphql_type_helper.rb +1 -1
  48. data/lib/tapioca/dsl/pipeline.rb +10 -10
  49. data/lib/tapioca/gem/events.rb +7 -7
  50. data/lib/tapioca/gem/listeners/documentation.rb +94 -0
  51. data/lib/tapioca/gem/listeners/methods.rb +8 -8
  52. data/lib/tapioca/gem/listeners/mixins.rb +3 -3
  53. data/lib/tapioca/gem/listeners/sorbet_signatures.rb +5 -7
  54. data/lib/tapioca/gem/listeners/sorbet_type_variables.rb +1 -1
  55. data/lib/tapioca/gem/listeners.rb +1 -1
  56. data/lib/tapioca/gem/pipeline.rb +20 -19
  57. data/lib/tapioca/gemfile.rb +0 -16
  58. data/lib/tapioca/helpers/rbi_helper.rb +7 -0
  59. data/lib/tapioca/helpers/sorbet_helper.rb +19 -0
  60. data/lib/tapioca/helpers/test/dsl_compiler.rb +2 -9
  61. data/lib/tapioca/internal.rb +2 -1
  62. data/lib/tapioca/rbi_ext/model.rb +6 -2
  63. data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +6 -6
  64. data/lib/tapioca/runtime/generic_type_registry.rb +8 -8
  65. data/lib/tapioca/runtime/reflection.rb +28 -21
  66. data/lib/tapioca/runtime/trackers/constant_definition.rb +3 -3
  67. data/lib/tapioca/runtime/trackers/method_definition.rb +4 -4
  68. data/lib/tapioca/runtime/trackers/mixin.rb +5 -5
  69. data/lib/tapioca/runtime/trackers/required_ancestor.rb +2 -2
  70. data/lib/tapioca/runtime/trackers/tracker.rb +1 -1
  71. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +1 -1
  72. data/lib/tapioca/sorbet_ext/void_patch.rb +29 -0
  73. data/lib/tapioca/static/symbol_loader.rb +32 -6
  74. data/lib/tapioca/version.rb +1 -1
  75. metadata +13 -12
  76. data/lib/tapioca/gem/listeners/yard_doc.rb +0 -110
@@ -94,21 +94,14 @@ module Tapioca
94
94
  compiler.decorate
95
95
 
96
96
  rbi = Tapioca::DEFAULT_RBI_FORMATTER.print_file(file)
97
- result = sorbet(
98
- "--no-config",
99
- "--stop-after",
100
- "parser",
101
- "-e",
102
- "\"#{rbi}\"",
103
- )
104
97
 
105
- unless result.status
98
+ sorbet_syntax_check!(rbi, rbi_mode: true) do |stderr|
106
99
  raise(SyntaxError, <<~MSG)
107
100
  Expected generated RBI file for `#{constant_name}` to not have any parsing errors.
108
101
 
109
102
  Got these parsing errors:
110
103
 
111
- #{result.err}
104
+ #{stderr}
112
105
  MSG
113
106
  end
114
107
 
@@ -13,6 +13,7 @@ require "tapioca/sorbet_ext/backcompat_patches"
13
13
  require "tapioca/sorbet_ext/name_patch"
14
14
  require "tapioca/sorbet_ext/generic_name_patch"
15
15
  require "tapioca/sorbet_ext/proc_bind_patch"
16
+ require "tapioca/sorbet_ext/void_patch"
16
17
  require "tapioca/runtime/generic_type_registry"
17
18
 
18
19
  # The rewriter needs to be loaded very early so RBS comments within Tapioca itself are rewritten
@@ -41,7 +42,7 @@ require "shellwords"
41
42
  require "tempfile"
42
43
  require "thor"
43
44
  require "yaml"
44
- require "yard-sorbet"
45
+ require "rubydex"
45
46
  require "prism"
46
47
 
47
48
  require "tapioca/helpers/gem_helper"
@@ -3,7 +3,7 @@
3
3
 
4
4
  module RBI
5
5
  class Tree
6
- #: (T::Module[top] constant) ?{ (Scope scope) -> void } -> Scope
6
+ #: (Module[top] constant) ?{ (Scope scope) -> void } -> Scope
7
7
  def create_path(constant, &block)
8
8
  constant_name = Tapioca::Runtime::Reflection.name_of(constant)
9
9
  raise "given constant does not have a name" unless constant_name
@@ -77,7 +77,11 @@ module RBI
77
77
  # If there is no block, and the params and return type have not been supplied, then
78
78
  # we create a single signature with the given parameters and return type
79
79
  params = parameters.map { |param| RBI::SigParam.new(param.param.name.to_s, param.type) }
80
- sigs << RBI::Sig.new(params: params, return_type: return_type || "T.untyped")
80
+ return_type ||= "T.untyped"
81
+ type_params = Tapioca::RBIHelper.extract_type_parameters(parameters.map(&:type).append(return_type))
82
+
83
+ sig = RBI::Sig.new(params: params, return_type: return_type, type_params: type_params)
84
+ sigs << sig
81
85
  end
82
86
 
83
87
  method = RBI::Method.new(
@@ -6,7 +6,7 @@ module Tapioca
6
6
  class DynamicMixinCompiler
7
7
  include Runtime::Reflection
8
8
 
9
- #: Array[T::Module[top]]
9
+ #: Array[Module[top]]
10
10
  attr_reader :dynamic_extends, :dynamic_includes
11
11
 
12
12
  #: Array[Symbol]
@@ -15,7 +15,7 @@ module Tapioca
15
15
  #: Array[Symbol]
16
16
  attr_reader :instance_attribute_readers, :instance_attribute_writers, :instance_attribute_predicates
17
17
 
18
- #: (T::Module[top] constant) -> void
18
+ #: (Module[top] constant) -> void
19
19
  def initialize(constant)
20
20
  @constant = constant
21
21
  mixins_from_modules = {}.compare_by_identity
@@ -109,12 +109,12 @@ module Tapioca
109
109
  # is the list of all dynamically extended modules because of that
110
110
  # constant. We grab that value by deleting the key for the original
111
111
  # constant.
112
- @dynamic_extends = mixins_from_modules.delete(constant) || [] #: Array[T::Module[top]]
112
+ @dynamic_extends = mixins_from_modules.delete(constant) || [] #: Array[Module[top]]
113
113
 
114
114
  # Since we deleted the original constant from the list of keys, all
115
115
  # the keys that remain are the ones that are dynamically included modules
116
116
  # during the include of the original constant.
117
- @dynamic_includes = mixins_from_modules.keys #: Array[T::Module[top]]
117
+ @dynamic_includes = mixins_from_modules.keys #: Array[Module[top]]
118
118
 
119
119
  @class_attribute_readers = class_attribute_readers #: Array[Symbol]
120
120
  @class_attribute_writers = class_attribute_writers #: Array[Symbol]
@@ -173,7 +173,7 @@ module Tapioca
173
173
  tree << RBI::Include.new("GeneratedInstanceMethods")
174
174
  end
175
175
 
176
- #: (RBI::Tree tree) -> [Array[T::Module[top]], Array[T::Module[top]]]
176
+ #: (RBI::Tree tree) -> [Array[Module[top]], Array[Module[top]]]
177
177
  def compile_mixes_in_class_methods(tree)
178
178
  includes = dynamic_includes.filter_map do |mod|
179
179
  qname = qualified_name_of(mod)
@@ -208,7 +208,7 @@ module Tapioca
208
208
  [[], []] # silence errors
209
209
  end
210
210
 
211
- #: (T::Module[top] mod, Array[T::Module[top]] dynamic_extends) -> bool
211
+ #: (Module[top] mod, Array[Module[top]] dynamic_extends) -> bool
212
212
  def module_included_by_another_dynamic_extend?(mod, dynamic_extends)
213
213
  dynamic_extends.any? do |dynamic_extend|
214
214
  mod != dynamic_extend && ancestors_of(dynamic_extend).include?(mod)
@@ -21,16 +21,16 @@ module Tapioca
21
21
  # variable to type variable serializers. This allows us to associate type variables
22
22
  # to the constant names that represent them, easily.
23
23
  module GenericTypeRegistry
24
- @generic_instances = {} #: Hash[String, T::Module[top]]
24
+ @generic_instances = {} #: Hash[String, Module[top]]
25
25
 
26
- @type_variables = {}.compare_by_identity #: Hash[T::Module[top], Array[TypeVariableModule]]
26
+ @type_variables = {}.compare_by_identity #: Hash[Module[top], Array[TypeVariableModule]]
27
27
 
28
28
  class GenericType < T::Types::Simple
29
- #: (T::Module[top] raw_type, T::Module[top] underlying_type) -> void
29
+ #: (Module[top] raw_type, Module[top] underlying_type) -> void
30
30
  def initialize(raw_type, underlying_type)
31
31
  super(raw_type)
32
32
 
33
- @underlying_type = underlying_type #: T::Module[top]
33
+ @underlying_type = underlying_type #: Module[top]
34
34
  end
35
35
 
36
36
  # @override
@@ -52,7 +52,7 @@ module Tapioca
52
52
  # 2 hash lookups (for the other two `Foo[Integer]`s).
53
53
  #
54
54
  # This method returns the created or cached clone of the constant.
55
- #: (untyped constant, untyped types) -> T::Module[top]
55
+ #: (untyped constant, untyped types) -> Module[top]
56
56
  def register_type(constant, types)
57
57
  # Build the name of the instantiated generic type,
58
58
  # something like `"Foo[X, Y, Z]"`
@@ -72,7 +72,7 @@ module Tapioca
72
72
  @generic_instances.values.any? { |generic_type| generic_type === instance }
73
73
  end
74
74
 
75
- #: (T::Module[top] constant) -> Array[TypeVariableModule]?
75
+ #: (Module[top] constant) -> Array[TypeVariableModule]?
76
76
  def lookup_type_variables(constant)
77
77
  @type_variables[constant]
78
78
  end
@@ -95,7 +95,7 @@ module Tapioca
95
95
 
96
96
  private
97
97
 
98
- #: (T::Module[top] constant, String name) -> T::Module[top]
98
+ #: (Module[top] constant, String name) -> Module[top]
99
99
  def create_generic_type(constant, name)
100
100
  generic_type = case constant
101
101
  when Class
@@ -164,7 +164,7 @@ module Tapioca
164
164
  end
165
165
  end
166
166
 
167
- #: (T::Module[top] constant) -> Array[TypeVariableModule]
167
+ #: (Module[top] constant) -> Array[TypeVariableModule]
168
168
  def lookup_or_initialize_type_variables(constant)
169
169
  @type_variables[constant] ||= []
170
170
  end
@@ -20,7 +20,7 @@ module Tapioca
20
20
  PROTECTED_INSTANCE_METHODS_METHOD = Module.instance_method(:protected_instance_methods) #: UnboundMethod
21
21
  PRIVATE_INSTANCE_METHODS_METHOD = Module.instance_method(:private_instance_methods) #: UnboundMethod
22
22
  METHOD_METHOD = Kernel.instance_method(:method) #: UnboundMethod
23
- UNDEFINED_CONSTANT = Module.new.freeze #: T::Module[top]
23
+ UNDEFINED_CONSTANT = Module.new.freeze #: Module[top]
24
24
 
25
25
  REQUIRED_FROM_LABELS = ["<top (required)>", "<main>", "<compiled>"].freeze #: Array[String]
26
26
 
@@ -31,7 +31,7 @@ module Tapioca
31
31
  end
32
32
 
33
33
  # @without_runtime
34
- #: (String symbol, ?inherit: bool, ?namespace: T::Module[top]) -> BasicObject
34
+ #: (String symbol, ?inherit: bool, ?namespace: Module[top]) -> BasicObject
35
35
  def constantize(symbol, inherit: false, namespace: Object)
36
36
  namespace.const_get(symbol, inherit)
37
37
  rescue NameError, LoadError, RuntimeError, ArgumentError, TypeError
@@ -43,23 +43,23 @@ module Tapioca
43
43
  CLASS_METHOD.bind_call(object)
44
44
  end
45
45
 
46
- #: (T::Module[top] constant) -> Array[Symbol]
46
+ #: (Module[top] constant) -> Array[Symbol]
47
47
  def constants_of(constant)
48
48
  CONSTANTS_METHOD.bind_call(constant, false)
49
49
  end
50
50
 
51
- #: (T::Module[top] constant) -> String?
51
+ #: (Module[top] constant) -> String?
52
52
  def name_of(constant)
53
53
  name = NAME_METHOD.bind_call(constant)
54
54
  name&.start_with?("#<") ? nil : name
55
55
  end
56
56
 
57
- #: (T::Module[top] constant) -> Class[top]
57
+ #: (Module[top] constant) -> Class[top]
58
58
  def singleton_class_of(constant)
59
59
  SINGLETON_CLASS_METHOD.bind_call(constant)
60
60
  end
61
61
 
62
- #: (T::Module[top] constant) -> Array[T::Module[top]]
62
+ #: (Module[top] constant) -> Array[Module[top]]
63
63
  def ancestors_of(constant)
64
64
  ANCESTORS_METHOD.bind_call(constant)
65
65
  end
@@ -69,7 +69,7 @@ module Tapioca
69
69
  SUPERCLASS_METHOD.bind_call(constant)
70
70
  end
71
71
 
72
- #: (Class[top] singleton_class) -> T::Module[top]?
72
+ #: (Class[top] singleton_class) -> Module[top]?
73
73
  def attached_class_of(singleton_class)
74
74
  result = singleton_class.attached_object
75
75
  Module === result ? result : nil
@@ -85,22 +85,22 @@ module Tapioca
85
85
  EQUAL_METHOD.bind_call(object, other)
86
86
  end
87
87
 
88
- #: (T::Module[top] constant) -> Array[Symbol]
88
+ #: (Module[top] constant) -> Array[Symbol]
89
89
  def public_instance_methods_of(constant)
90
90
  PUBLIC_INSTANCE_METHODS_METHOD.bind_call(constant)
91
91
  end
92
92
 
93
- #: (T::Module[top] constant) -> Array[Symbol]
93
+ #: (Module[top] constant) -> Array[Symbol]
94
94
  def protected_instance_methods_of(constant)
95
95
  PROTECTED_INSTANCE_METHODS_METHOD.bind_call(constant)
96
96
  end
97
97
 
98
- #: (T::Module[top] constant) -> Array[Symbol]
98
+ #: (Module[top] constant) -> Array[Symbol]
99
99
  def private_instance_methods_of(constant)
100
100
  PRIVATE_INSTANCE_METHODS_METHOD.bind_call(constant)
101
101
  end
102
102
 
103
- #: (T::Module[top] constant) -> Array[T::Module[top]]
103
+ #: (Module[top] constant) -> Array[Module[top]]
104
104
  def inherited_ancestors_of(constant)
105
105
  if Class === constant
106
106
  ancestors_of(superclass_of(constant) || Object)
@@ -109,7 +109,7 @@ module Tapioca
109
109
  end
110
110
  end
111
111
 
112
- #: (T::Module[top] constant) -> String?
112
+ #: (Module[top] constant) -> String?
113
113
  def qualified_name_of(constant)
114
114
  name = name_of(constant)
115
115
  return if name.nil?
@@ -142,7 +142,7 @@ module Tapioca
142
142
  type.to_s
143
143
  end
144
144
 
145
- #: (T::Module[top] constant, Symbol method) -> Method
145
+ #: (Module[top] constant, Symbol method) -> Method
146
146
  def method_of(constant, method)
147
147
  METHOD_METHOD.bind_call(constant, method)
148
148
  end
@@ -211,32 +211,39 @@ module Tapioca
211
211
  SourceLocation.from_loc([file, resolved_loc.lineno])
212
212
  end
213
213
 
214
- #: (T::Module[top] constant) -> Set[String]
214
+ #: (Module[top] constant) -> Set[String]
215
215
  def file_candidates_for(constant)
216
- relevant_methods_for(constant).filter_map do |method|
216
+ # Grab all source files for (relevant) methods defined on the constant
217
+ candidates = relevant_methods_for(constant).filter_map do |method|
217
218
  method.source_location&.first
218
219
  end.to_set
220
+
221
+ # Add the source file for the constant definition itself, if available.
222
+ source_location_candidate = const_source_location(name_of(constant).to_s)&.file
223
+ candidates.add(source_location_candidate) if source_location_candidate
224
+
225
+ candidates
219
226
  end
220
227
 
221
- #: (T::Module[top] constant) -> untyped
228
+ #: (Module[top] constant) -> untyped
222
229
  def abstract_type_of(constant)
223
230
  T::Private::Abstract::Data.get(constant, :abstract_type) ||
224
231
  T::Private::Abstract::Data.get(singleton_class_of(constant), :abstract_type)
225
232
  end
226
233
 
227
- #: (T::Module[top] constant) -> bool
234
+ #: (Module[top] constant) -> bool
228
235
  def final_module?(constant)
229
236
  T::Private::Final.final_module?(constant)
230
237
  end
231
238
 
232
- #: (T::Module[top] constant) -> bool
239
+ #: (Module[top] constant) -> bool
233
240
  def sealed_module?(constant)
234
241
  T::Private::Sealed.sealed_module?(constant)
235
242
  end
236
243
 
237
244
  private
238
245
 
239
- #: (T::Module[top] constant) -> Array[UnboundMethod]
246
+ #: (Module[top] constant) -> Array[UnboundMethod]
240
247
  def relevant_methods_for(constant)
241
248
  methods = methods_for(constant).select(&:source_location)
242
249
  .reject { |x| method_defined_by_forwardable_module?(x) }
@@ -252,7 +259,7 @@ module Tapioca
252
259
  end
253
260
  end
254
261
 
255
- #: (T::Module[top] constant) -> Array[UnboundMethod]
262
+ #: (Module[top] constant) -> Array[UnboundMethod]
256
263
  def methods_for(constant)
257
264
  modules = [constant, singleton_class_of(constant)]
258
265
  method_list_methods = [
@@ -266,7 +273,7 @@ module Tapioca
266
273
  end
267
274
  end
268
275
 
269
- #: (T::Module[top] parent, String name) -> T::Module[top]?
276
+ #: (Module[top] parent, String name) -> Module[top]?
270
277
  def child_module_for_parent_with_name(parent, name)
271
278
  return if parent.autoload?(name)
272
279
 
@@ -12,7 +12,7 @@ module Tapioca
12
12
  extend Tracker
13
13
  extend Reflection
14
14
 
15
- @class_files = {}.compare_by_identity #: Hash[T::Module[top], Set[SourceLocation]]
15
+ @class_files = {}.compare_by_identity #: Hash[Module[top], Set[SourceLocation]]
16
16
 
17
17
  # Immediately activated upon load. Observes class/module definition.
18
18
  @class_tracepoint = TracePoint.trace(:class) do |tp|
@@ -83,12 +83,12 @@ module Tapioca
83
83
  # Returns the files in which this class or module was opened. Doesn't know
84
84
  # about situations where the class was opened prior to +require+ing,
85
85
  # or where metaprogramming was used via +eval+, etc.
86
- #: (T::Module[top] klass) -> Set[String]
86
+ #: (Module[top] klass) -> Set[String]
87
87
  def files_for(klass)
88
88
  locations_for(klass).map(&:file).to_set
89
89
  end
90
90
 
91
- #: (T::Module[top] klass) -> Set[SourceLocation]
91
+ #: (Module[top] klass) -> Set[SourceLocation]
92
92
  def locations_for(klass)
93
93
  @class_files.fetch(klass, Set.new)
94
94
  end
@@ -7,10 +7,10 @@ module Tapioca
7
7
  module MethodDefinition
8
8
  extend Tracker
9
9
 
10
- @method_definitions = {}.compare_by_identity #: Hash[T::Module[top], Hash[Symbol, Array[SourceLocation]]]
10
+ @method_definitions = {}.compare_by_identity #: Hash[Module[top], Hash[Symbol, Array[SourceLocation]]]
11
11
 
12
12
  class << self
13
- #: (Symbol method_name, T::Module[top] owner, Array[Thread::Backtrace::Location] locations) -> void
13
+ #: (Symbol method_name, Module[top] owner, Array[Thread::Backtrace::Location] locations) -> void
14
14
  def register(method_name, owner, locations)
15
15
  return unless enabled?
16
16
  # If Sorbet runtime is redefining a method, it sets this to true.
@@ -24,7 +24,7 @@ module Tapioca
24
24
  registrations_for(method_name, owner) << loc
25
25
  end
26
26
 
27
- #: (Symbol method_name, T::Module[top] owner) -> Array[SourceLocation]
27
+ #: (Symbol method_name, Module[top] owner) -> Array[SourceLocation]
28
28
  def method_definitions_for(method_name, owner)
29
29
  definitions = registrations_for(method_name, owner)
30
30
 
@@ -38,7 +38,7 @@ module Tapioca
38
38
 
39
39
  private
40
40
 
41
- #: (Symbol method_name, T::Module[top] owner) -> Array[SourceLocation]
41
+ #: (Symbol method_name, Module[top] owner) -> Array[SourceLocation]
42
42
  def registrations_for(method_name, owner)
43
43
  owner_lookup = (@method_definitions[owner] ||= {})
44
44
  owner_lookup[method_name] ||= []
@@ -24,7 +24,7 @@ module Tapioca
24
24
  with_disabled_tracker(&block)
25
25
  end
26
26
 
27
- #: (T::Module[top] constant, T::Module[top] mixin, Type mixin_type) -> void
27
+ #: (Module[top] constant, Module[top] mixin, Type mixin_type) -> void
28
28
  def register(constant, mixin, mixin_type)
29
29
  return unless enabled?
30
30
 
@@ -46,19 +46,19 @@ module Tapioca
46
46
  attached_class
47
47
  end
48
48
 
49
- #: (T::Module[top] mixin) -> Hash[Type, Hash[T::Module[top], String]]
49
+ #: (Module[top] mixin) -> Hash[Type, Hash[Module[top], String]]
50
50
  def constants_with_mixin(mixin)
51
51
  find_or_initialize_mixin_lookup(mixin)
52
52
  end
53
53
 
54
- #: (T::Module[top] mixin, Type mixin_type, T::Module[top] constant) -> String?
54
+ #: (Module[top] mixin, Type mixin_type, Module[top] constant) -> String?
55
55
  def mixin_location(mixin, mixin_type, constant)
56
56
  find_or_initialize_mixin_lookup(mixin).dig(mixin_type, constant)
57
57
  end
58
58
 
59
59
  private
60
60
 
61
- #: (T::Module[top] constant, T::Module[top] mixin, Type mixin_type, String location) -> void
61
+ #: (Module[top] constant, Module[top] mixin, Type mixin_type, String location) -> void
62
62
  def register_with_location(constant, mixin, mixin_type, location)
63
63
  return unless @enabled
64
64
 
@@ -66,7 +66,7 @@ module Tapioca
66
66
  constants.fetch(mixin_type).store(constant, location)
67
67
  end
68
68
 
69
- #: (T::Module[top] mixin) -> Hash[Type, Hash[T::Module[top], String]]
69
+ #: (Module[top] mixin) -> Hash[Type, Hash[Module[top], String]]
70
70
  def find_or_initialize_mixin_lookup(mixin)
71
71
  @mixins_to_constants[mixin] ||= {
72
72
  Type::Prepend => {}.compare_by_identity,
@@ -17,12 +17,12 @@ module Tapioca
17
17
  ancestors << block
18
18
  end
19
19
 
20
- #: (T::Module[top] mod) -> Array[^-> void]
20
+ #: (Module[top] mod) -> Array[^-> void]
21
21
  def required_ancestors_blocks_by(mod)
22
22
  @required_ancestors_map[mod] || []
23
23
  end
24
24
 
25
- #: (T::Module[top] mod) -> Array[untyped]
25
+ #: (Module[top] mod) -> Array[untyped]
26
26
  def required_ancestors_by(mod)
27
27
  blocks = required_ancestors_blocks_by(mod)
28
28
  blocks.map do |block|
@@ -7,7 +7,7 @@ module Tapioca
7
7
  # @abstract
8
8
  module Tracker
9
9
  class << self
10
- #: ((Tracker & T::Module[top]) base) -> void
10
+ #: ((Tracker & Module[top]) base) -> void
11
11
  def extended(base)
12
12
  Trackers.register_tracker(base)
13
13
  base.instance_exec do
@@ -133,7 +133,7 @@ module Tapioca
133
133
  #: Type
134
134
  attr_reader :type
135
135
 
136
- #: (T::Module[top] context, Type type, Symbol variance, (^-> Hash[Symbol, untyped])? bounds_proc) -> void
136
+ #: (Module[top] context, Type type, Symbol variance, (^-> Hash[Symbol, untyped])? bounds_proc) -> void
137
137
  def initialize(context, type, variance, bounds_proc)
138
138
  @context = context
139
139
  @type = type
@@ -0,0 +1,29 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ # If Signature has `effective_return_type`, then `return_type` always returns the correct type.
5
+ # Ref: https://github.com/sorbet/sorbet/pull/10121
6
+ return if T::Private::Methods::Signature.method_defined?(:effective_return_type)
7
+
8
+ module T
9
+ module Private
10
+ module Methods
11
+ module DeclBuilderPatch
12
+ def void
13
+ super.tap do
14
+ @_real_returns_is_void = true
15
+ end
16
+ end
17
+
18
+ def finalize!
19
+ super.tap do
20
+ #: self as untyped
21
+ decl.returns = T::Private::Types::Void::Private::INSTANCE if @_real_returns_is_void
22
+ end
23
+ end
24
+ end
25
+
26
+ DeclBuilder.prepend(DeclBuilderPatch)
27
+ end
28
+ end
29
+ end
@@ -18,6 +18,19 @@ module Tapioca
18
18
  T.must(@payload_symbols)
19
19
  end
20
20
 
21
+ #: (Array[Pathname] paths) -> Rubydex::Graph
22
+ def graph_from_paths(paths)
23
+ graph = Rubydex::Graph.new
24
+ graph.index_all(paths.map(&:to_s))
25
+ graph.resolve
26
+ graph
27
+ end
28
+
29
+ #: (Gemfile::GemSpec gem) -> Set[String]
30
+ def gem_symbols(gem)
31
+ symbols_from_paths(gem.files)
32
+ end
33
+
21
34
  #: (Gemfile::GemSpec gem) -> Set[String]
22
35
  def engine_symbols(gem)
23
36
  gem_engine = engines.find do |engine|
@@ -43,11 +56,6 @@ module Tapioca
43
56
  Set.new
44
57
  end
45
58
 
46
- #: (Gemfile::GemSpec gem) -> Set[String]
47
- def gem_symbols(gem)
48
- symbols_from_paths(gem.files)
49
- end
50
-
51
59
  #: (Array[Pathname] paths) -> Set[String]
52
60
  def symbols_from_paths(paths)
53
61
  return Set.new if paths.empty?
@@ -79,7 +87,25 @@ module Tapioca
79
87
 
80
88
  #: (String input, ?table_type: String) -> String
81
89
  def symbol_table_json_from(input, table_type: "symbol-table-json")
82
- sorbet("--no-config", "--quiet", "--print=#{table_type}", input).out
90
+ supported_values = ["symbol-table-json", "symbol-table-full-json"]
91
+ unless supported_values.include?(table_type)
92
+ raise NotImplementedError, <<~MSG
93
+ Got an unsupported value for `table_type` (#{table_type.inspect}).
94
+ The only supported values are:
95
+ #{supported_values.map { |v| "- #{v}" }.join("\n")}
96
+
97
+ This is because we use `--stop-after=namer` as a performance optimization. Other print formats
98
+ may require running later stages of Sorbet's pipeline. Please adjust the `stop-after` accordingly.
99
+ MSG
100
+ end
101
+
102
+ sorbet(
103
+ "--no-config",
104
+ "--quiet",
105
+ "--print=#{table_type}",
106
+ "--stop-after=namer",
107
+ input,
108
+ ).out
83
109
  end
84
110
  end
85
111
  end
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Tapioca
5
- VERSION = "0.18.0"
5
+ VERSION = "0.19.1"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tapioca
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0
4
+ version: 0.19.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ufuk Kayserilioglu
@@ -83,47 +83,47 @@ dependencies:
83
83
  - !ruby/object:Gem::Version
84
84
  version: 0.2.2
85
85
  - !ruby/object:Gem::Dependency
86
- name: sorbet-static-and-runtime
86
+ name: rubydex
87
87
  requirement: !ruby/object:Gem::Requirement
88
88
  requirements:
89
89
  - - ">="
90
90
  - !ruby/object:Gem::Version
91
- version: 0.5.11087
91
+ version: 0.1.0.beta10
92
92
  type: :runtime
93
93
  prerelease: false
94
94
  version_requirements: !ruby/object:Gem::Requirement
95
95
  requirements:
96
96
  - - ">="
97
97
  - !ruby/object:Gem::Version
98
- version: 0.5.11087
98
+ version: 0.1.0.beta10
99
99
  - !ruby/object:Gem::Dependency
100
- name: thor
100
+ name: sorbet-static-and-runtime
101
101
  requirement: !ruby/object:Gem::Requirement
102
102
  requirements:
103
103
  - - ">="
104
104
  - !ruby/object:Gem::Version
105
- version: 1.2.0
105
+ version: 0.6.12698
106
106
  type: :runtime
107
107
  prerelease: false
108
108
  version_requirements: !ruby/object:Gem::Requirement
109
109
  requirements:
110
110
  - - ">="
111
111
  - !ruby/object:Gem::Version
112
- version: 1.2.0
112
+ version: 0.6.12698
113
113
  - !ruby/object:Gem::Dependency
114
- name: yard-sorbet
114
+ name: thor
115
115
  requirement: !ruby/object:Gem::Requirement
116
116
  requirements:
117
117
  - - ">="
118
118
  - !ruby/object:Gem::Version
119
- version: '0'
119
+ version: 1.2.0
120
120
  type: :runtime
121
121
  prerelease: false
122
122
  version_requirements: !ruby/object:Gem::Requirement
123
123
  requirements:
124
124
  - - ">="
125
125
  - !ruby/object:Gem::Version
126
- version: '0'
126
+ version: 1.2.0
127
127
  - !ruby/object:Gem::Dependency
128
128
  name: rbi
129
129
  requirement: !ruby/object:Gem::Requirement
@@ -253,6 +253,7 @@ files:
253
253
  - lib/tapioca/gem/events.rb
254
254
  - lib/tapioca/gem/listeners.rb
255
255
  - lib/tapioca/gem/listeners/base.rb
256
+ - lib/tapioca/gem/listeners/documentation.rb
256
257
  - lib/tapioca/gem/listeners/dynamic_mixins.rb
257
258
  - lib/tapioca/gem/listeners/foreign_constants.rb
258
259
  - lib/tapioca/gem/listeners/methods.rb
@@ -266,7 +267,6 @@ files:
266
267
  - lib/tapioca/gem/listeners/sorbet_type_variables.rb
267
268
  - lib/tapioca/gem/listeners/source_location.rb
268
269
  - lib/tapioca/gem/listeners/subconstants.rb
269
- - lib/tapioca/gem/listeners/yard_doc.rb
270
270
  - lib/tapioca/gem/pipeline.rb
271
271
  - lib/tapioca/gem_info.rb
272
272
  - lib/tapioca/gemfile.rb
@@ -307,6 +307,7 @@ files:
307
307
  - lib/tapioca/sorbet_ext/generic_name_patch.rb
308
308
  - lib/tapioca/sorbet_ext/name_patch.rb
309
309
  - lib/tapioca/sorbet_ext/proc_bind_patch.rb
310
+ - lib/tapioca/sorbet_ext/void_patch.rb
310
311
  - lib/tapioca/static/requires_compiler.rb
311
312
  - lib/tapioca/static/symbol_loader.rb
312
313
  - lib/tapioca/static/symbol_table_parser.rb
@@ -330,7 +331,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
330
331
  - !ruby/object:Gem::Version
331
332
  version: '0'
332
333
  requirements: []
333
- rubygems_version: 4.0.3
334
+ rubygems_version: 4.0.6
334
335
  specification_version: 4
335
336
  summary: A Ruby Interface file generator for gems, core types and the Ruby standard
336
337
  library