tapioca 0.16.9 → 0.17.7

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 (130) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -0
  3. data/exe/tapioca +6 -1
  4. data/lib/ruby_lsp/tapioca/addon.rb +73 -43
  5. data/lib/ruby_lsp/tapioca/run_gem_rbi_check.rb +43 -43
  6. data/lib/ruby_lsp/tapioca/server_addon.rb +13 -10
  7. data/lib/tapioca/bundler_ext/auto_require_hook.rb +6 -14
  8. data/lib/tapioca/cli.rb +16 -8
  9. data/lib/tapioca/commands/abstract_dsl.rb +39 -66
  10. data/lib/tapioca/commands/abstract_gem.rb +25 -46
  11. data/lib/tapioca/commands/annotations.rb +28 -34
  12. data/lib/tapioca/commands/check_shims.rb +6 -15
  13. data/lib/tapioca/commands/command.rb +12 -26
  14. data/lib/tapioca/commands/command_without_tracker.rb +2 -5
  15. data/lib/tapioca/commands/configure.rb +11 -16
  16. data/lib/tapioca/commands/dsl_compiler_list.rb +2 -1
  17. data/lib/tapioca/commands/dsl_generate.rb +2 -1
  18. data/lib/tapioca/commands/dsl_verify.rb +2 -1
  19. data/lib/tapioca/commands/gem_generate.rb +5 -9
  20. data/lib/tapioca/commands/gem_sync.rb +2 -1
  21. data/lib/tapioca/commands/gem_verify.rb +3 -2
  22. data/lib/tapioca/commands/require.rb +3 -7
  23. data/lib/tapioca/commands/todo.rb +6 -10
  24. data/lib/tapioca/dsl/compiler.rb +36 -63
  25. data/lib/tapioca/dsl/compilers/aasm.rb +33 -44
  26. data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +8 -7
  27. data/lib/tapioca/dsl/compilers/action_mailer.rb +6 -5
  28. data/lib/tapioca/dsl/compilers/action_text.rb +6 -5
  29. data/lib/tapioca/dsl/compilers/active_job.rb +6 -10
  30. data/lib/tapioca/dsl/compilers/active_model_attributes.rb +10 -11
  31. data/lib/tapioca/dsl/compilers/active_model_secure_password.rb +5 -6
  32. data/lib/tapioca/dsl/compilers/active_model_validations_confirmation.rb +5 -12
  33. data/lib/tapioca/dsl/compilers/active_record_associations.rb +17 -44
  34. data/lib/tapioca/dsl/compilers/active_record_columns.rb +20 -26
  35. data/lib/tapioca/dsl/compilers/active_record_delegated_types.rb +9 -8
  36. data/lib/tapioca/dsl/compilers/active_record_enum.rb +7 -6
  37. data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +54 -62
  38. data/lib/tapioca/dsl/compilers/active_record_relations.rb +148 -209
  39. data/lib/tapioca/dsl/compilers/active_record_scope.rb +8 -13
  40. data/lib/tapioca/dsl/compilers/active_record_secure_token.rb +5 -4
  41. data/lib/tapioca/dsl/compilers/active_record_store.rb +5 -4
  42. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +19 -28
  43. data/lib/tapioca/dsl/compilers/active_resource.rb +19 -21
  44. data/lib/tapioca/dsl/compilers/active_storage.rb +6 -14
  45. data/lib/tapioca/dsl/compilers/active_support_concern.rb +9 -8
  46. data/lib/tapioca/dsl/compilers/active_support_current_attributes.rb +8 -7
  47. data/lib/tapioca/dsl/compilers/active_support_time_ext.rb +5 -4
  48. data/lib/tapioca/dsl/compilers/config.rb +5 -4
  49. data/lib/tapioca/dsl/compilers/frozen_record.rb +7 -11
  50. data/lib/tapioca/dsl/compilers/graphql_input_object.rb +9 -10
  51. data/lib/tapioca/dsl/compilers/graphql_mutation.rb +6 -10
  52. data/lib/tapioca/dsl/compilers/identity_cache.rb +11 -39
  53. data/lib/tapioca/dsl/compilers/json_api_client_resource.rb +9 -18
  54. data/lib/tapioca/dsl/compilers/kredis.rb +7 -8
  55. data/lib/tapioca/dsl/compilers/mixed_in_class_attributes.rb +5 -4
  56. data/lib/tapioca/dsl/compilers/protobuf.rb +13 -26
  57. data/lib/tapioca/dsl/compilers/rails_generators.rb +9 -11
  58. data/lib/tapioca/dsl/compilers/sidekiq_worker.rb +23 -13
  59. data/lib/tapioca/dsl/compilers/smart_properties.rb +32 -38
  60. data/lib/tapioca/dsl/compilers/state_machines.rb +15 -26
  61. data/lib/tapioca/dsl/compilers/url_helpers.rb +10 -9
  62. data/lib/tapioca/dsl/compilers.rb +4 -7
  63. data/lib/tapioca/dsl/helpers/active_model_type_helper.rb +13 -16
  64. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +13 -28
  65. data/lib/tapioca/dsl/helpers/active_record_constants_helper.rb +19 -15
  66. data/lib/tapioca/dsl/helpers/graphql_type_helper.rb +5 -24
  67. data/lib/tapioca/dsl/pipeline.rb +30 -58
  68. data/lib/tapioca/executor.rb +6 -12
  69. data/lib/tapioca/gem/events.rb +24 -34
  70. data/lib/tapioca/gem/listeners/base.rb +7 -10
  71. data/lib/tapioca/gem/listeners/dynamic_mixins.rb +4 -2
  72. data/lib/tapioca/gem/listeners/foreign_constants.rb +5 -7
  73. data/lib/tapioca/gem/listeners/methods.rb +36 -47
  74. data/lib/tapioca/gem/listeners/mixins.rb +6 -18
  75. data/lib/tapioca/gem/listeners/remove_empty_payload_scopes.rb +4 -2
  76. data/lib/tapioca/gem/listeners/sorbet_enums.rb +4 -2
  77. data/lib/tapioca/gem/listeners/sorbet_helpers.rb +4 -2
  78. data/lib/tapioca/gem/listeners/sorbet_props.rb +4 -2
  79. data/lib/tapioca/gem/listeners/sorbet_required_ancestors.rb +4 -2
  80. data/lib/tapioca/gem/listeners/sorbet_signatures.rb +7 -5
  81. data/lib/tapioca/gem/listeners/sorbet_type_variables.rb +6 -4
  82. data/lib/tapioca/gem/listeners/source_location.rb +15 -8
  83. data/lib/tapioca/gem/listeners/subconstants.rb +5 -4
  84. data/lib/tapioca/gem/listeners/yard_doc.rb +30 -23
  85. data/lib/tapioca/gem/pipeline.rb +107 -91
  86. data/lib/tapioca/gem_info.rb +1 -1
  87. data/lib/tapioca/gemfile.rb +64 -73
  88. data/lib/tapioca/helpers/cli_helper.rb +4 -7
  89. data/lib/tapioca/helpers/config_helper.rb +17 -29
  90. data/lib/tapioca/helpers/env_helper.rb +2 -5
  91. data/lib/tapioca/helpers/gem_helper.rb +5 -5
  92. data/lib/tapioca/helpers/git_attributes.rb +3 -3
  93. data/lib/tapioca/helpers/rbi_files_helper.rb +76 -73
  94. data/lib/tapioca/helpers/rbi_helper.rb +14 -22
  95. data/lib/tapioca/helpers/sorbet_helper.rb +9 -18
  96. data/lib/tapioca/helpers/source_uri.rb +15 -25
  97. data/lib/tapioca/helpers/test/content.rb +7 -10
  98. data/lib/tapioca/helpers/test/dsl_compiler.rb +20 -33
  99. data/lib/tapioca/helpers/test/isolation.rb +10 -14
  100. data/lib/tapioca/helpers/test/template.rb +6 -11
  101. data/lib/tapioca/internal.rb +18 -8
  102. data/lib/tapioca/loaders/dsl.rb +11 -19
  103. data/lib/tapioca/loaders/gem.rb +6 -21
  104. data/lib/tapioca/loaders/loader.rb +21 -39
  105. data/lib/tapioca/rbi_ext/model.rb +12 -37
  106. data/lib/tapioca/rbi_formatter.rb +10 -19
  107. data/lib/tapioca/rbs/rewriter.rb +55 -0
  108. data/lib/tapioca/repo_index.rb +7 -9
  109. data/lib/tapioca/runtime/attached_class_of_32.rb +1 -1
  110. data/lib/tapioca/runtime/attached_class_of_legacy.rb +2 -5
  111. data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +23 -23
  112. data/lib/tapioca/runtime/generic_type_registry.rb +13 -23
  113. data/lib/tapioca/runtime/reflection.rb +81 -60
  114. data/lib/tapioca/runtime/source_location.rb +44 -0
  115. data/lib/tapioca/runtime/trackers/autoload.rb +7 -9
  116. data/lib/tapioca/runtime/trackers/constant_definition.rb +18 -14
  117. data/lib/tapioca/runtime/trackers/method_definition.rb +65 -0
  118. data/lib/tapioca/runtime/trackers/mixin.rb +8 -11
  119. data/lib/tapioca/runtime/trackers/required_ancestor.rb +3 -3
  120. data/lib/tapioca/runtime/trackers/tracker.rb +3 -6
  121. data/lib/tapioca/runtime/trackers.rb +5 -8
  122. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +9 -15
  123. data/lib/tapioca/sorbet_ext/name_patch.rb +2 -2
  124. data/lib/tapioca/sorbet_ext/proc_bind_patch.rb +1 -1
  125. data/lib/tapioca/static/requires_compiler.rb +6 -6
  126. data/lib/tapioca/static/symbol_loader.rb +14 -16
  127. data/lib/tapioca/static/symbol_table_parser.rb +8 -8
  128. data/lib/tapioca/version.rb +1 -1
  129. data/lib/tapioca.rb +22 -29
  130. metadata +27 -10
@@ -10,12 +10,12 @@ module Tapioca
10
10
 
11
11
  NOOP_METHOD = ->(*_args, **_kwargs, &_block) {}
12
12
 
13
- @constant_names_registered_for_autoload = T.let([], T::Array[String])
13
+ @constant_names_registered_for_autoload = [] #: Array[String]
14
14
 
15
15
  class << self
16
16
  extend T::Sig
17
17
 
18
- sig { void }
18
+ #: -> void
19
19
  def eager_load_all!
20
20
  with_disabled_exits do
21
21
  until @constant_names_registered_for_autoload.empty?
@@ -27,18 +27,14 @@ module Tapioca
27
27
  end
28
28
  end
29
29
 
30
- sig { params(constant_name: String).void }
30
+ #: (String constant_name) -> void
31
31
  def register(constant_name)
32
32
  return unless enabled?
33
33
 
34
34
  @constant_names_registered_for_autoload << constant_name
35
35
  end
36
36
 
37
- sig do
38
- type_parameters(:Result)
39
- .params(block: T.proc.returns(T.type_parameter(:Result)))
40
- .returns(T.type_parameter(:Result))
41
- end
37
+ #: [Result] { -> Result } -> Result
42
38
  def with_disabled_exits(&block)
43
39
  original_abort = Kernel.instance_method(:abort)
44
40
  original_exit = Kernel.instance_method(:exit)
@@ -47,7 +43,9 @@ module Tapioca
47
43
  Kernel.define_method(:abort, NOOP_METHOD)
48
44
  Kernel.define_method(:exit, NOOP_METHOD)
49
45
 
50
- block.call
46
+ Tapioca.silence_warnings do
47
+ block.call
48
+ end
51
49
  ensure
52
50
  Kernel.define_method(:exit, original_exit)
53
51
  Kernel.define_method(:abort, original_abort)
@@ -13,12 +13,7 @@ module Tapioca
13
13
  extend Reflection
14
14
  extend T::Sig
15
15
 
16
- class ConstantLocation < T::Struct
17
- const :lineno, Integer
18
- const :path, String
19
- end
20
-
21
- @class_files = {}.compare_by_identity
16
+ @class_files = {}.compare_by_identity #: Hash[Module, Set[SourceLocation]]
22
17
 
23
18
  # Immediately activated upon load. Observes class/module definition.
24
19
  @class_tracepoint = TracePoint.trace(:class) do |tp|
@@ -28,14 +23,17 @@ module Tapioca
28
23
 
29
24
  path = tp.path
30
25
  if File.exist?(path)
31
- loc = build_constant_location(tp, caller_locations)
26
+ loc = build_source_location(tp, caller_locations)
32
27
  else
33
28
  caller_location = T.must(caller_locations)
34
29
  .find { |loc| loc.path && File.exist?(loc.path) }
35
30
 
36
31
  next unless caller_location
37
32
 
38
- loc = ConstantLocation.new(path: caller_location.absolute_path || "", lineno: caller_location.lineno)
33
+ loc = SourceLocation.from_loc([
34
+ caller_location.absolute_path || "",
35
+ caller_location.lineno,
36
+ ])
39
37
  end
40
38
 
41
39
  (@class_files[key] ||= Set.new) << loc
@@ -47,31 +45,37 @@ module Tapioca
47
45
  key = tp.return_value
48
46
  next unless Module === key
49
47
 
50
- loc = build_constant_location(tp, caller_locations)
48
+ loc = build_source_location(tp, caller_locations)
51
49
  (@class_files[key] ||= Set.new) << loc
52
50
  end
53
51
 
54
52
  class << self
53
+ extend T::Sig
54
+
55
55
  def disable!
56
56
  @class_tracepoint.disable
57
57
  @creturn_tracepoint.disable
58
58
  super
59
59
  end
60
60
 
61
- def build_constant_location(tp, locations)
62
- file = resolve_loc(locations)
63
- lineno = File.identical?(file, tp.path) ? tp.lineno : 0
61
+ def build_source_location(tp, locations)
62
+ loc = resolve_loc(locations)
63
+ file = loc&.file
64
+ line = loc&.line
65
+ lineno = file && File.identical?(file, tp.path) ? tp.lineno : (line || 0)
64
66
 
65
- ConstantLocation.new(path: file, lineno: lineno)
67
+ SourceLocation.from_loc([file || "", lineno])
66
68
  end
67
69
 
68
70
  # Returns the files in which this class or module was opened. Doesn't know
69
71
  # about situations where the class was opened prior to +require+ing,
70
72
  # or where metaprogramming was used via +eval+, etc.
73
+ #: (Module klass) -> Set[String]
71
74
  def files_for(klass)
72
- locations_for(klass).map(&:path).to_set
75
+ locations_for(klass).map(&:file).to_set
73
76
  end
74
77
 
78
+ #: (Module klass) -> Set[SourceLocation]
75
79
  def locations_for(klass)
76
80
  @class_files.fetch(klass, Set.new)
77
81
  end
@@ -0,0 +1,65 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Tapioca
5
+ module Runtime
6
+ module Trackers
7
+ module MethodDefinition
8
+ extend Tracker
9
+ extend T::Sig
10
+
11
+ @method_definitions = {}.compare_by_identity #: Hash[Module, Hash[Symbol, Array[SourceLocation]]]
12
+
13
+ class << self
14
+ #: (Symbol method_name, Module owner, Array[Thread::Backtrace::Location] locations) -> void
15
+ def register(method_name, owner, locations)
16
+ return unless enabled?
17
+ # If Sorbet runtime is redefining a method, it sets this to true.
18
+ # In those cases, we should skip the registration, as the method's original
19
+ # definition should already be registered.
20
+ return if T::Private::DeclState.current.skip_on_method_added
21
+
22
+ loc = Reflection.resolve_loc(locations)
23
+ return unless loc
24
+
25
+ registrations_for(method_name, owner) << loc
26
+ end
27
+
28
+ #: (Symbol method_name, Module owner) -> Array[SourceLocation]
29
+ def method_definitions_for(method_name, owner)
30
+ definitions = registrations_for(method_name, owner)
31
+
32
+ if definitions.empty?
33
+ source_loc = owner.instance_method(method_name).source_location
34
+ definitions = [SourceLocation.from_loc(source_loc)].compact
35
+ end
36
+
37
+ definitions
38
+ end
39
+
40
+ private
41
+
42
+ #: (Symbol method_name, Module owner) -> Array[SourceLocation]
43
+ def registrations_for(method_name, owner)
44
+ owner_lookup = (@method_definitions[owner] ||= {})
45
+ owner_lookup[method_name] ||= []
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ class Module
54
+ prepend(Module.new do
55
+ def singleton_method_added(method_name)
56
+ Tapioca::Runtime::Trackers::MethodDefinition.register(method_name, singleton_class, Kernel.caller_locations)
57
+ super
58
+ end
59
+
60
+ def method_added(method_name)
61
+ Tapioca::Runtime::Trackers::MethodDefinition.register(method_name, self, Kernel.caller_locations)
62
+ super
63
+ end
64
+ end)
65
+ end
@@ -22,22 +22,19 @@ module Tapioca
22
22
  class << self
23
23
  extend T::Sig
24
24
 
25
- sig do
26
- type_parameters(:Result)
27
- .params(block: T.proc.returns(T.type_parameter(:Result)))
28
- .returns(T.type_parameter(:Result))
29
- end
25
+ #: [Result] { -> Result } -> Result
30
26
  def with_disabled_registration(&block)
31
27
  with_disabled_tracker(&block)
32
28
  end
33
29
 
34
- sig { params(constant: Module, mixin: Module, mixin_type: Type).void }
30
+ #: (Module constant, Module mixin, Type mixin_type) -> void
35
31
  def register(constant, mixin, mixin_type)
36
32
  return unless enabled?
37
33
 
38
34
  location = Reflection.resolve_loc(caller_locations)
35
+ return unless location
39
36
 
40
- register_with_location(constant, mixin, mixin_type, location)
37
+ register_with_location(constant, mixin, mixin_type, location.file)
41
38
  end
42
39
 
43
40
  def resolve_to_attached_class(constant, mixin, mixin_type)
@@ -52,19 +49,19 @@ module Tapioca
52
49
  attached_class
53
50
  end
54
51
 
55
- sig { params(mixin: Module).returns(T::Hash[Type, T::Hash[Module, String]]) }
52
+ #: (Module mixin) -> Hash[Type, Hash[Module, String]]
56
53
  def constants_with_mixin(mixin)
57
54
  find_or_initialize_mixin_lookup(mixin)
58
55
  end
59
56
 
60
- sig { params(mixin: Module, mixin_type: Type, constant: Module).returns(T.nilable(String)) }
57
+ #: (Module mixin, Type mixin_type, Module constant) -> String?
61
58
  def mixin_location(mixin, mixin_type, constant)
62
59
  find_or_initialize_mixin_lookup(mixin).dig(mixin_type, constant)
63
60
  end
64
61
 
65
62
  private
66
63
 
67
- sig { params(constant: Module, mixin: Module, mixin_type: Type, location: String).void }
64
+ #: (Module constant, Module mixin, Type mixin_type, String location) -> void
68
65
  def register_with_location(constant, mixin, mixin_type, location)
69
66
  return unless @enabled
70
67
 
@@ -72,7 +69,7 @@ module Tapioca
72
69
  constants.fetch(mixin_type).store(constant, location)
73
70
  end
74
71
 
75
- sig { params(mixin: Module).returns(T::Hash[Type, T::Hash[Module, String]]) }
72
+ #: (Module mixin) -> Hash[Type, Hash[Module, String]]
76
73
  def find_or_initialize_mixin_lookup(mixin)
77
74
  @mixins_to_constants[mixin] ||= {
78
75
  Type::Prepend => {}.compare_by_identity,
@@ -11,7 +11,7 @@ module Tapioca
11
11
  class << self
12
12
  extend T::Sig
13
13
 
14
- sig { params(requiring: T::Helpers, block: T.proc.void).void }
14
+ #: (T::Helpers requiring, ^-> void block) -> void
15
15
  def register(requiring, block)
16
16
  return unless enabled?
17
17
 
@@ -19,12 +19,12 @@ module Tapioca
19
19
  ancestors << block
20
20
  end
21
21
 
22
- sig { params(mod: Module).returns(T::Array[T.proc.void]) }
22
+ #: (Module mod) -> Array[^-> void]
23
23
  def required_ancestors_blocks_by(mod)
24
24
  @required_ancestors_map[mod] || []
25
25
  end
26
26
 
27
- sig { params(mod: Module).returns(T::Array[T.untyped]) }
27
+ #: (Module mod) -> Array[untyped]
28
28
  def required_ancestors_by(mod)
29
29
  blocks = required_ancestors_blocks_by(mod)
30
30
  blocks.map do |block|
@@ -4,16 +4,13 @@
4
4
  module Tapioca
5
5
  module Runtime
6
6
  module Trackers
7
+ # @abstract
7
8
  module Tracker
8
9
  extend T::Sig
9
- extend T::Helpers
10
-
11
- abstract!
12
-
13
10
  class << self
14
11
  extend T::Sig
15
12
 
16
- sig { params(base: T.all(Tracker, Module)).void }
13
+ #: ((Tracker & Module) base) -> void
17
14
  def extended(base)
18
15
  Trackers.register_tracker(base)
19
16
  base.instance_exec do
@@ -22,7 +19,7 @@ module Tapioca
22
19
  end
23
20
  end
24
21
 
25
- sig { void }
22
+ #: -> void
26
23
  def disable!
27
24
  @enabled = false
28
25
  end
@@ -8,16 +8,12 @@ module Tapioca
8
8
  module Trackers
9
9
  extend T::Sig
10
10
 
11
- @trackers = T.let([], T::Array[Tracker])
11
+ @trackers = [] #: Array[Tracker]
12
12
 
13
13
  class << self
14
14
  extend T::Sig
15
15
 
16
- sig do
17
- type_parameters(:Return)
18
- .params(blk: T.proc.returns(T.type_parameter(:Return)))
19
- .returns(T.type_parameter(:Return))
20
- end
16
+ #: [Return] { -> Return } -> Return
21
17
  def with_trackers_enabled(&blk)
22
18
  # Currently this is a dirty hack to ensure disabling trackers
23
19
  # doesn't work while in the block passed to this method.
@@ -30,12 +26,12 @@ module Tapioca
30
26
  end
31
27
  end
32
28
 
33
- sig { void }
29
+ #: -> void
34
30
  def disable_all!
35
31
  @trackers.each(&:disable!)
36
32
  end
37
33
 
38
- sig { params(tracker: Tracker).void }
34
+ #: (Tracker tracker) -> void
39
35
  def register_tracker(tracker)
40
36
  @trackers << tracker
41
37
  end
@@ -56,3 +52,4 @@ require "tapioca/runtime/trackers/mixin"
56
52
  require "tapioca/runtime/trackers/constant_definition"
57
53
  require "tapioca/runtime/trackers/autoload"
58
54
  require "tapioca/runtime/trackers/required_ancestor"
55
+ require "tapioca/runtime/trackers/method_definition"
@@ -130,19 +130,12 @@ module Tapioca
130
130
  end
131
131
  end
132
132
 
133
- DEFAULT_BOUNDS_PROC = T.let(-> { {} }, T.proc.returns(T::Hash[Symbol, T.untyped]))
133
+ DEFAULT_BOUNDS_PROC = -> { {} } #: ^-> Hash[Symbol, untyped]
134
134
 
135
- sig { returns(Type) }
135
+ #: Type
136
136
  attr_reader :type
137
137
 
138
- sig do
139
- params(
140
- context: Module,
141
- type: Type,
142
- variance: Symbol,
143
- bounds_proc: T.nilable(T.proc.returns(T::Hash[Symbol, T.untyped])),
144
- ).void
145
- end
138
+ #: (Module context, Type type, Symbol variance, (^-> Hash[Symbol, untyped])? bounds_proc) -> void
146
139
  def initialize(context, type, variance, bounds_proc)
147
140
  @context = context
148
141
  @type = type
@@ -151,18 +144,19 @@ module Tapioca
151
144
 
152
145
  super()
153
146
  end
154
- sig { returns(T.nilable(String)) }
147
+
148
+ #: -> String?
155
149
  def name
156
150
  constant_name = super
157
151
  constant_name&.split("::")&.last
158
152
  end
159
153
 
160
- sig { returns(T::Boolean) }
154
+ #: -> bool
161
155
  def fixed?
162
156
  bounds.key?(:fixed)
163
157
  end
164
158
 
165
- sig { returns(String) }
159
+ #: -> String
166
160
  def serialize
167
161
  fixed = bounds[:fixed].to_s if fixed?
168
162
  lower = bounds[:lower].to_s if bounds.key?(:lower)
@@ -177,14 +171,14 @@ module Tapioca
177
171
  )
178
172
  end
179
173
 
180
- sig { returns(Tapioca::TypeVariable) }
174
+ #: -> Tapioca::TypeVariable
181
175
  def coerce_to_type_variable
182
176
  TypeVariable.new(name, @variance)
183
177
  end
184
178
 
185
179
  private
186
180
 
187
- sig { returns(T::Hash[Symbol, T.untyped]) }
181
+ #: -> Hash[Symbol, untyped]
188
182
  def bounds
189
183
  @bounds ||= @bounds_proc.call
190
184
  end
@@ -5,7 +5,7 @@ module T
5
5
  module Types
6
6
  class Simple
7
7
  module NamePatch
8
- NAME_METHOD = T.let(Module.instance_method(:name), UnboundMethod)
8
+ NAME_METHOD = Module.instance_method(:name) #: UnboundMethod
9
9
 
10
10
  def name
11
11
  # Sorbet memoizes this method into the `@name` instance variable but
@@ -16,7 +16,7 @@ module T
16
16
  def qualified_name_of(constant)
17
17
  name = NAME_METHOD.bind_call(constant)
18
18
  name = nil if name&.start_with?("#<")
19
- return if name.nil?
19
+ return "::T.untyped" if name.nil?
20
20
 
21
21
  if name.start_with?("::")
22
22
  name
@@ -8,7 +8,7 @@ module T
8
8
  super(arg_types, returns)
9
9
 
10
10
  unless bind == T::Private::Methods::ARG_NOT_PROVIDED
11
- @bind = T.let(T::Utils.coerce(bind), T::Types::Base)
11
+ @bind = T::Utils.coerce(bind) #: T::Types::Base
12
12
  end
13
13
  end
14
14
 
@@ -6,12 +6,12 @@ module Tapioca
6
6
  class RequiresCompiler
7
7
  extend T::Sig
8
8
 
9
- sig { params(sorbet_path: String).void }
9
+ #: (String sorbet_path) -> void
10
10
  def initialize(sorbet_path)
11
11
  @sorbet_path = sorbet_path
12
12
  end
13
13
 
14
- sig { returns(String) }
14
+ #: -> String
15
15
  def compile
16
16
  config = Spoom::Sorbet::Config.parse_file(@sorbet_path)
17
17
  files = collect_files(config)
@@ -25,7 +25,7 @@ module Tapioca
25
25
 
26
26
  private
27
27
 
28
- sig { params(config: Spoom::Sorbet::Config).returns(T::Array[String]) }
28
+ #: (Spoom::Sorbet::Config config) -> Array[String]
29
29
  def collect_files(config)
30
30
  config.paths.flat_map do |path|
31
31
  path = (Pathname.new(@sorbet_path) / "../.." / path).cleanpath
@@ -40,14 +40,14 @@ module Tapioca
40
40
  end.sort.uniq
41
41
  end
42
42
 
43
- sig { params(file_path: String).returns(T::Enumerable[String]) }
43
+ #: (String file_path) -> T::Enumerable[String]
44
44
  def collect_requires(file_path)
45
45
  File.binread(file_path).lines.filter_map do |line|
46
46
  /^\s*require\s*(\(\s*)?['"](?<name>[^'"]+)['"](\s*\))?/.match(line) { |m| m["name"] }
47
47
  end.reject { |require| require.include?('#{') } # ignore interpolation
48
48
  end
49
49
 
50
- sig { params(config: Spoom::Sorbet::Config, file_path: Pathname).returns(T::Boolean) }
50
+ #: (Spoom::Sorbet::Config config, Pathname file_path) -> bool
51
51
  def file_ignored_by_sorbet?(config, file_path)
52
52
  file_path_parts = path_parts(file_path)
53
53
 
@@ -76,7 +76,7 @@ module Tapioca
76
76
  end
77
77
  end
78
78
 
79
- sig { params(path: Pathname).returns(T::Array[String]) }
79
+ #: (Pathname path) -> Array[String]
80
80
  def path_parts(path)
81
81
  T.unsafe(path).descend.map { |part| part.basename.to_s }
82
82
  end
@@ -9,17 +9,17 @@ module Tapioca
9
9
  include SorbetHelper
10
10
  include Runtime::Reflection
11
11
 
12
- sig { returns(T::Set[String]) }
12
+ #: -> Set[String]
13
13
  def payload_symbols
14
14
  unless @payload_symbols
15
15
  output = symbol_table_json_from("-e ''", table_type: "symbol-table-full-json")
16
- @payload_symbols = T.let(SymbolTableParser.parse_json(output), T.nilable(T::Set[String]))
16
+ @payload_symbols = SymbolTableParser.parse_json(output) #: Set[String]?
17
17
  end
18
18
 
19
19
  T.must(@payload_symbols)
20
20
  end
21
21
 
22
- sig { params(gem: Gemfile::GemSpec).returns(T::Set[String]) }
22
+ #: (Gemfile::GemSpec gem) -> Set[String]
23
23
  def engine_symbols(gem)
24
24
  gem_engine = engines.find do |engine|
25
25
  gem.full_gem_path == engine.config.root.to_s
@@ -44,12 +44,12 @@ module Tapioca
44
44
  Set.new
45
45
  end
46
46
 
47
- sig { params(gem: Gemfile::GemSpec).returns(T::Set[String]) }
47
+ #: (Gemfile::GemSpec gem) -> Set[String]
48
48
  def gem_symbols(gem)
49
49
  symbols_from_paths(gem.files)
50
50
  end
51
51
 
52
- sig { params(paths: T::Array[Pathname]).returns(T::Set[String]) }
52
+ #: (Array[Pathname] paths) -> Set[String]
53
53
  def symbols_from_paths(paths)
54
54
  return Set.new if paths.empty?
55
55
 
@@ -67,20 +67,18 @@ module Tapioca
67
67
 
68
68
  private
69
69
 
70
- T::Sig::WithoutRuntime.sig { returns(T::Array[T.class_of(Rails::Engine)]) }
70
+ # @without_runtime
71
+ #: -> Array[singleton(Rails::Engine)]
71
72
  def engines
72
- @engines ||= T.let(
73
- if Object.const_defined?("Rails::Engine")
74
- descendants_of(Object.const_get("Rails::Engine"))
75
- .reject(&:abstract_railtie?)
76
- else
77
- []
78
- end,
79
- T.nilable(T::Array[T.class_of(Rails::Engine)]),
80
- )
73
+ @engines ||= if Object.const_defined?("Rails::Engine")
74
+ descendants_of(Object.const_get("Rails::Engine"))
75
+ .reject(&:abstract_railtie?)
76
+ else
77
+ []
78
+ end #: Array[singleton(Rails::Engine)]?
81
79
  end
82
80
 
83
- sig { params(input: String, table_type: String).returns(String) }
81
+ #: (String input, ?table_type: String) -> String
84
82
  def symbol_table_json_from(input, table_type: "symbol-table-json")
85
83
  sorbet("--no-config", "--quiet", "--print=#{table_type}", input).out
86
84
  end
@@ -6,12 +6,12 @@ module Tapioca
6
6
  class SymbolTableParser
7
7
  extend T::Sig
8
8
 
9
- SKIP_PARSE_KINDS = T.let(["CLASS_OR_MODULE", "STATIC_FIELD"].freeze, T::Array[String])
9
+ SKIP_PARSE_KINDS = ["CLASS_OR_MODULE", "STATIC_FIELD"].freeze #: Array[String]
10
10
 
11
11
  class << self
12
12
  extend T::Sig
13
13
 
14
- sig { params(json_string: String).returns(T::Set[String]) }
14
+ #: (String json_string) -> Set[String]
15
15
  def parse_json(json_string)
16
16
  obj = JSON.parse(json_string)
17
17
 
@@ -23,16 +23,16 @@ module Tapioca
23
23
  end
24
24
  end
25
25
 
26
- sig { returns(T::Set[String]) }
26
+ #: Set[String]
27
27
  attr_reader :symbols
28
28
 
29
- sig { void }
29
+ #: -> void
30
30
  def initialize
31
- @symbols = T.let(Set.new, T::Set[String])
32
- @parents = T.let([], T::Array[String])
31
+ @symbols = Set.new #: Set[String]
32
+ @parents = [] #: Array[String]
33
33
  end
34
34
 
35
- sig { params(object: T::Hash[String, T.untyped]).void }
35
+ #: (Hash[String, untyped] object) -> void
36
36
  def parse_object(object)
37
37
  children = object.fetch("children", [])
38
38
 
@@ -61,7 +61,7 @@ module Tapioca
61
61
  end
62
62
  end
63
63
 
64
- sig { params(name: String).returns(String) }
64
+ #: (String name) -> String
65
65
  def fully_qualified_name(name)
66
66
  [*@parents, name].join("::")
67
67
  end
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Tapioca
5
- VERSION = "0.16.9"
5
+ VERSION = "0.17.7"
6
6
  end