tapioca 0.10.4 → 0.11.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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tapioca/cli.rb +14 -5
  3. data/lib/tapioca/commands/annotations.rb +2 -0
  4. data/lib/tapioca/commands/configure.rb +1 -0
  5. data/lib/tapioca/commands/dsl.rb +17 -3
  6. data/lib/tapioca/commands/gem.rb +4 -2
  7. data/lib/tapioca/dsl/compilers/aasm.rb +78 -17
  8. data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +1 -1
  9. data/lib/tapioca/dsl/compilers/active_record_columns.rb +3 -3
  10. data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +8 -5
  11. data/lib/tapioca/dsl/compilers/active_record_relations.rb +140 -83
  12. data/lib/tapioca/dsl/compilers/active_record_scope.rb +1 -1
  13. data/lib/tapioca/dsl/compilers/active_record_secure_token.rb +74 -0
  14. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +14 -11
  15. data/lib/tapioca/dsl/compilers/active_resource.rb +22 -15
  16. data/lib/tapioca/dsl/compilers/active_storage.rb +4 -2
  17. data/lib/tapioca/dsl/compilers/graphql_input_object.rb +21 -1
  18. data/lib/tapioca/dsl/compilers/kredis.rb +130 -0
  19. data/lib/tapioca/dsl/compilers/smart_properties.rb +7 -4
  20. data/lib/tapioca/dsl/compilers/url_helpers.rb +7 -4
  21. data/lib/tapioca/dsl/extensions/active_record.rb +9 -0
  22. data/lib/tapioca/dsl/extensions/kredis.rb +114 -0
  23. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +37 -27
  24. data/lib/tapioca/dsl/helpers/active_record_constants_helper.rb +1 -0
  25. data/lib/tapioca/dsl/pipeline.rb +12 -5
  26. data/lib/tapioca/gem/listeners/sorbet_enums.rb +1 -1
  27. data/lib/tapioca/gem/listeners/yard_doc.rb +13 -10
  28. data/lib/tapioca/gem/pipeline.rb +14 -0
  29. data/lib/tapioca/gemfile.rb +6 -2
  30. data/lib/tapioca/helpers/rbi_files_helper.rb +12 -6
  31. data/lib/tapioca/helpers/sorbet_helper.rb +7 -4
  32. data/lib/tapioca/helpers/source_uri.rb +10 -7
  33. data/lib/tapioca/loaders/gem.rb +4 -2
  34. data/lib/tapioca/loaders/loader.rb +99 -35
  35. data/lib/tapioca/rbi_ext/model.rb +8 -3
  36. data/lib/tapioca/rbi_formatter.rb +11 -8
  37. data/lib/tapioca/runtime/attached_class_of_32.rb +20 -0
  38. data/lib/tapioca/runtime/attached_class_of_legacy.rb +27 -0
  39. data/lib/tapioca/runtime/reflection.rb +11 -10
  40. data/lib/tapioca/runtime/trackers.rb +17 -0
  41. data/lib/tapioca/static/symbol_loader.rb +14 -14
  42. data/lib/tapioca/version.rb +1 -1
  43. data/lib/tapioca.rb +8 -5
  44. metadata +7 -2
@@ -45,7 +45,11 @@ module Tapioca
45
45
 
46
46
  sig { override.void }
47
47
  def decorate
48
- arguments = constant.all_argument_definitions
48
+ # Skip methods explicitly defined in code
49
+ arguments = constant.all_argument_definitions.select do |argument|
50
+ method_defined_by_graphql?(argument.keyword.to_s)
51
+ end
52
+
49
53
  return if arguments.empty?
50
54
 
51
55
  root.create_path(constant) do |input_object|
@@ -56,6 +60,22 @@ module Tapioca
56
60
  end
57
61
  end
58
62
 
63
+ private
64
+
65
+ sig { returns(T.nilable(String)) }
66
+ def graphql_input_object_argument_source_file
67
+ @graphql_input_object_argument_source_file ||= T.let(
68
+ GraphQL::Schema::InputObject.method(:argument).source_location&.first,
69
+ T.nilable(String),
70
+ )
71
+ end
72
+
73
+ sig { params(method_name: String).returns(T::Boolean) }
74
+ def method_defined_by_graphql?(method_name)
75
+ method_file = constant.instance_method(method_name).source_location&.first
76
+ !!(method_file && graphql_input_object_argument_source_file == method_file)
77
+ end
78
+
59
79
  class << self
60
80
  extend T::Sig
61
81
 
@@ -0,0 +1,130 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ begin
5
+ require "kredis"
6
+ rescue LoadError
7
+ return
8
+ end
9
+
10
+ module Tapioca
11
+ module Dsl
12
+ module Compilers
13
+ # `Tapioca::Dsl::Compilers::Kredis` decorates RBI files for all
14
+ # classes that include [`Kredis::Attributes`](https://github.com/rails/kredis/blob/main/lib/kredis/attributes.rb).
15
+ #
16
+ # For example, with the following class:
17
+ #
18
+ # ~~~rb
19
+ # class Person < ApplicationRecord
20
+ # kredis_list :names
21
+ # kredis_flag :awesome
22
+ # kredis_counter :steps, expires_in: 1.hour
23
+ # kredis_enum :morning, values: %w[ bright blue black ], default: "bright"
24
+ # end
25
+ # ~~~
26
+ #
27
+ # this compiler will produce an RBI file with the following content:
28
+ # ~~~rbi
29
+ # # typed: true
30
+ #
31
+ # class Person
32
+ # module GeneratedKredisAttributeMethods
33
+ # sig { returns(Kredis::Types::Flag) }
34
+ # def awesome; end
35
+ #
36
+ # sig { returns(T::Boolean) }
37
+ # def awesome?; end
38
+ #
39
+ # sig { returns(PrivateEnumMorning) }
40
+ # def morning; end
41
+ #
42
+ # sig { returns(Kredis::Types::List) }
43
+ # def names; end
44
+ #
45
+ # sig { returns(Kredis::Types::Counter) }
46
+ # def steps; end
47
+ #
48
+ # class PrivateEnumMorning < Kredis::Types::Enum
49
+ # sig { void }
50
+ # def black!; end
51
+ #
52
+ # sig { returns(T::Boolean) }
53
+ # def black?; end
54
+ #
55
+ # sig { void }
56
+ # def blue!; end
57
+ #
58
+ # sig { returns(T::Boolean) }
59
+ # def blue?; end
60
+ #
61
+ # sig { void }
62
+ # def bright!; end
63
+ #
64
+ # sig { returns(T::Boolean) }
65
+ # def bright?; end
66
+ # end
67
+ # end
68
+ # end
69
+ # ~~~
70
+ class Kredis < Compiler
71
+ extend T::Sig
72
+
73
+ ConstantType = type_member { { fixed: T.all(Class, ::Kredis::Attributes::ClassMethods, Extensions::Kredis) } }
74
+
75
+ sig { override.void }
76
+ def decorate
77
+ return if constant.__tapioca_kredis_types.nil?
78
+
79
+ module_name = "GeneratedKredisAttributeMethods"
80
+
81
+ root.create_path(constant) do |model|
82
+ model.create_module(module_name) do |mod|
83
+ constant.__tapioca_kredis_types.each do |method, data|
84
+ generate_methods(mod, method, data)
85
+ end
86
+ end
87
+ model.create_include(module_name)
88
+ end
89
+ end
90
+
91
+ class << self
92
+ extend T::Sig
93
+
94
+ sig { override.returns(T::Enumerable[Module]) }
95
+ def gather_constants
96
+ all_classes
97
+ .grep(::Kredis::Attributes::ClassMethods)
98
+ .reject { |klass| klass.to_s == "ActiveRecord::Base" || klass.try(:abstract_class?) }
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ sig { params(mod: RBI::Scope, method: String, data: T::Hash[Symbol, T.untyped]).void }
105
+ def generate_methods(mod, method, data)
106
+ return_type = data.fetch(:type)
107
+ case return_type
108
+ when "Kredis::Types::Enum"
109
+ klass_name = "PrivateEnum#{method.split("_").map(&:capitalize).join}"
110
+ create_enum_class(mod, klass_name, data.fetch(:values))
111
+ return_type = klass_name
112
+ when "Kredis::Types::Flag"
113
+ mod.create_method("#{method}?", return_type: "T::Boolean")
114
+ end
115
+
116
+ mod.create_method(method, return_type: return_type)
117
+ end
118
+
119
+ sig { params(mod: RBI::Scope, klass_name: String, values: T::Array[T.untyped]).void }
120
+ def create_enum_class(mod, klass_name, values)
121
+ klass = mod.create_class(klass_name, superclass_name: "Kredis::Types::Enum")
122
+ values.each do |value|
123
+ klass.create_method("#{value}!", return_type: "void")
124
+ klass.create_method("#{value}?", return_type: "T::Boolean")
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -119,10 +119,13 @@ module Tapioca
119
119
  mod.create_method(property.reader.to_s, return_type: type)
120
120
  end
121
121
 
122
- BOOLEANS = T.let([
123
- [true, false],
124
- [false, true],
125
- ].freeze, T::Array[[T::Boolean, T::Boolean]])
122
+ BOOLEANS = T.let(
123
+ [
124
+ [true, false],
125
+ [false, true],
126
+ ].freeze,
127
+ T::Array[[T::Boolean, T::Boolean]],
128
+ )
126
129
 
127
130
  sig { params(property: ::SmartProperties::Property).returns(String) }
128
131
  def type_for(property)
@@ -102,10 +102,13 @@ module Tapioca
102
102
  end
103
103
  end
104
104
 
105
- NON_DISCOVERABLE_INCLUDERS = T.let([
106
- ActionDispatch::IntegrationTest,
107
- ActionView::Helpers,
108
- ], T::Array[Module])
105
+ NON_DISCOVERABLE_INCLUDERS = T.let(
106
+ [
107
+ ActionDispatch::IntegrationTest,
108
+ ActionView::Helpers,
109
+ ],
110
+ T::Array[Module],
111
+ )
109
112
 
110
113
  class << self
111
114
  extend T::Sig
@@ -21,6 +21,15 @@ module Tapioca
21
21
  super
22
22
  end
23
23
 
24
+ attr_reader :__tapioca_secure_tokens
25
+
26
+ def has_secure_token(attribute = :token, length: ::ActiveRecord::SecureToken::MINIMUM_TOKEN_LENGTH)
27
+ @__tapioca_secure_tokens ||= []
28
+ @__tapioca_secure_tokens << attribute
29
+
30
+ super
31
+ end
32
+
24
33
  ::ActiveRecord::Base.singleton_class.prepend(self)
25
34
  end
26
35
  end
@@ -0,0 +1,114 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ begin
5
+ require "kredis"
6
+ rescue LoadError
7
+ return
8
+ end
9
+
10
+ module Tapioca
11
+ module Dsl
12
+ module Compilers
13
+ module Extensions
14
+ module Kredis
15
+ attr_reader :__tapioca_kredis_types
16
+
17
+ def kredis_proxy(name, key: nil, config: :shared, after_change: nil)
18
+ collect_kredis_type(name, "Kredis::Types::Proxy")
19
+ super
20
+ end
21
+
22
+ def kredis_string(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
23
+ collect_kredis_type(name, "Kredis::Types::Scalar")
24
+ super
25
+ end
26
+
27
+ def kredis_integer(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
28
+ collect_kredis_type(name, "Kredis::Types::Scalar")
29
+ super
30
+ end
31
+
32
+ def kredis_decimal(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
33
+ collect_kredis_type(name, "Kredis::Types::Scalar")
34
+ super
35
+ end
36
+
37
+ def kredis_datetime(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
38
+ collect_kredis_type(name, "Kredis::Types::Scalar")
39
+ super
40
+ end
41
+
42
+ def kredis_flag(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
43
+ collect_kredis_type(name, "Kredis::Types::Flag")
44
+ super
45
+ end
46
+
47
+ def kredis_float(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
48
+ collect_kredis_type(name, "Kredis::Types::Scalar")
49
+ super
50
+ end
51
+
52
+ def kredis_enum(name, key: nil, values:, default:, config: :shared, after_change: nil)
53
+ collect_kredis_type(name, "Kredis::Types::Enum", values: values)
54
+ super
55
+ end
56
+
57
+ def kredis_json(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
58
+ collect_kredis_type(name, "Kredis::Types::Scalar")
59
+ super
60
+ end
61
+
62
+ def kredis_list(name, key: nil, typed: :string, config: :shared, after_change: nil)
63
+ collect_kredis_type(name, "Kredis::Types::List")
64
+ super
65
+ end
66
+
67
+ def kredis_unique_list(name, limit: nil, key: nil, typed: :string, config: :shared, after_change: nil)
68
+ collect_kredis_type(name, "Kredis::Types::UniqueList")
69
+ super
70
+ end
71
+
72
+ def kredis_set(name, key: nil, typed: :string, config: :shared, after_change: nil)
73
+ collect_kredis_type(name, "Kredis::Types::Set")
74
+ super
75
+ end
76
+
77
+ def kredis_slot(name, key: nil, config: :shared, after_change: nil)
78
+ collect_kredis_type(name, "Kredis::Types::Slots")
79
+ super
80
+ end
81
+
82
+ def kredis_slots(name, available:, key: nil, config: :shared, after_change: nil)
83
+ collect_kredis_type(name, "Kredis::Types::Slots")
84
+ super
85
+ end
86
+
87
+ def kredis_counter(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
88
+ collect_kredis_type(name, "Kredis::Types::Counter")
89
+ super
90
+ end
91
+
92
+ def kredis_hash(name, key: nil, typed: :string, config: :shared, after_change: nil)
93
+ collect_kredis_type(name, "Kredis::Types::Hash")
94
+ super
95
+ end
96
+
97
+ def kredis_boolean(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
98
+ collect_kredis_type(name, "Kredis::Types::Scalar")
99
+ super
100
+ end
101
+
102
+ private
103
+
104
+ def collect_kredis_type(method, type, values: nil)
105
+ @__tapioca_kredis_types ||= {}
106
+ @__tapioca_kredis_types[method.to_s] = { type: type, values: values }
107
+ end
108
+
109
+ ::Kredis::Attributes::ClassMethods.prepend(self)
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -19,33 +19,7 @@ module Tapioca
19
19
 
20
20
  column_type = @constant.attribute_types[column_name]
21
21
 
22
- getter_type =
23
- case column_type
24
- when defined?(MoneyColumn) && MoneyColumn::ActiveRecordType
25
- "::Money"
26
- when ActiveRecord::Type::Integer
27
- "::Integer"
28
- when ActiveRecord::Type::String
29
- "::String"
30
- when ActiveRecord::Type::Date
31
- "::Date"
32
- when ActiveRecord::Type::Decimal
33
- "::BigDecimal"
34
- when ActiveRecord::Type::Float
35
- "::Float"
36
- when ActiveRecord::Type::Boolean
37
- "T::Boolean"
38
- when ActiveRecord::Type::DateTime, ActiveRecord::Type::Time
39
- "::Time"
40
- when ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter
41
- "::ActiveSupport::TimeWithZone"
42
- when ActiveRecord::Enum::EnumType
43
- "::String"
44
- when ActiveRecord::Type::Serialized
45
- serialized_column_type(column_type)
46
- else
47
- handle_unknown_type(column_type)
48
- end
22
+ getter_type = type_for_activerecord_value(column_type)
49
23
 
50
24
  column = @constant.columns_hash[column_name]
51
25
  setter_type =
@@ -71,6 +45,42 @@ module Tapioca
71
45
 
72
46
  private
73
47
 
48
+ sig { params(column_type: T.untyped).returns(String) }
49
+ def type_for_activerecord_value(column_type)
50
+ case column_type
51
+ when defined?(MoneyColumn) && MoneyColumn::ActiveRecordType
52
+ "::Money"
53
+ when ActiveRecord::Type::Integer
54
+ "::Integer"
55
+ when ActiveRecord::Type::String
56
+ "::String"
57
+ when ActiveRecord::Type::Date
58
+ "::Date"
59
+ when ActiveRecord::Type::Decimal
60
+ "::BigDecimal"
61
+ when ActiveRecord::Type::Float
62
+ "::Float"
63
+ when ActiveRecord::Type::Boolean
64
+ "T::Boolean"
65
+ when ActiveRecord::Type::DateTime, ActiveRecord::Type::Time
66
+ "::Time"
67
+ when ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter
68
+ "::ActiveSupport::TimeWithZone"
69
+ when ActiveRecord::Enum::EnumType
70
+ "::String"
71
+ when ActiveRecord::Type::Serialized
72
+ serialized_column_type(column_type)
73
+ when defined?(ActiveRecord::ConnectionAdapters::PostgreSQL) &&
74
+ ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Hstore
75
+ "T::Hash[::String, ::String]"
76
+ when defined?(ActiveRecord::ConnectionAdapters::PostgreSQL) &&
77
+ ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array
78
+ "T::Array[#{type_for_activerecord_value(column_type.subtype)}]"
79
+ else
80
+ handle_unknown_type(column_type)
81
+ end
82
+ end
83
+
74
84
  sig { params(constant: Module).returns(T::Boolean) }
75
85
  def do_not_generate_strong_types?(constant)
76
86
  Object.const_defined?(:StrongTypeGeneration) &&
@@ -14,6 +14,7 @@ module Tapioca
14
14
  AttributeMethodsModuleName = T.let("GeneratedAttributeMethods", String)
15
15
  AssociationMethodsModuleName = T.let("GeneratedAssociationMethods", String)
16
16
  DelegatedTypesModuleName = T.let("GeneratedDelegatedTypeMethods", String)
17
+ SecureTokensModuleName = T.let("GeneratedSecureTokenMethods", String)
17
18
 
18
19
  RelationMethodsModuleName = T.let("GeneratedRelationMethods", String)
19
20
  AssociationRelationMethodsModuleName = T.let("GeneratedAssociationRelationMethods", String)
@@ -12,6 +12,9 @@ module Tapioca
12
12
  sig { returns(T::Array[Module]) }
13
13
  attr_reader :requested_constants
14
14
 
15
+ sig { returns(T::Array[Pathname]) }
16
+ attr_reader :requested_paths
17
+
15
18
  sig { returns(T.proc.params(error: String).void) }
16
19
  attr_reader :error_handler
17
20
 
@@ -21,6 +24,7 @@ module Tapioca
21
24
  sig do
22
25
  params(
23
26
  requested_constants: T::Array[Module],
27
+ requested_paths: T::Array[Pathname],
24
28
  requested_compilers: T::Array[T.class_of(Compiler)],
25
29
  excluded_compilers: T::Array[T.class_of(Compiler)],
26
30
  error_handler: T.proc.params(error: String).void,
@@ -29,6 +33,7 @@ module Tapioca
29
33
  end
30
34
  def initialize(
31
35
  requested_constants:,
36
+ requested_paths: [],
32
37
  requested_compilers: [],
33
38
  excluded_compilers: [],
34
39
  error_handler: $stderr.method(:puts).to_proc,
@@ -39,6 +44,7 @@ module Tapioca
39
44
  T::Enumerable[T.class_of(Compiler)],
40
45
  )
41
46
  @requested_constants = requested_constants
47
+ @requested_paths = requested_paths
42
48
  @error_handler = error_handler
43
49
  @number_of_workers = number_of_workers
44
50
  @errors = T.let([], T::Array[String])
@@ -50,11 +56,12 @@ module Tapioca
50
56
  ).returns(T::Array[T.type_parameter(:T)])
51
57
  end
52
58
  def run(&blk)
53
- constants_to_process = gather_constants(requested_constants)
59
+ constants_to_process = gather_constants(requested_constants, requested_paths)
54
60
  .select { |c| Module === c } # Filter value constants out
55
61
  .sort_by! { |c| T.must(Runtime::Reflection.name_of(c)) }
56
62
 
57
- if constants_to_process.empty?
63
+ # It's OK if there are no constants to process if we received a valid file/path.
64
+ if constants_to_process.empty? && requested_paths.select { |p| File.exist?(p) }.empty?
58
65
  report_error(<<~ERROR)
59
66
  No classes/modules can be matched for RBI generation.
60
67
  Please check that the requested classes/modules include processable DSL methods.
@@ -115,12 +122,12 @@ module Tapioca
115
122
  active_compilers
116
123
  end
117
124
 
118
- sig { params(requested_constants: T::Array[Module]).returns(T::Set[Module]) }
119
- def gather_constants(requested_constants)
125
+ sig { params(requested_constants: T::Array[Module], requested_paths: T::Array[Pathname]).returns(T::Set[Module]) }
126
+ def gather_constants(requested_constants, requested_paths)
120
127
  constants = active_compilers.map(&:processable_constants).reduce(Set.new, :union)
121
128
  constants = filter_anonymous_and_reloaded_constants(constants)
122
129
 
123
- constants &= requested_constants unless requested_constants.empty?
130
+ constants &= requested_constants unless requested_constants.empty? && requested_paths.empty?
124
131
  constants
125
132
  end
126
133
 
@@ -12,7 +12,7 @@ module Tapioca
12
12
  sig { override.params(event: ScopeNodeAdded).void }
13
13
  def on_scope(event)
14
14
  constant = event.constant
15
- return unless T::Enum > event.constant
15
+ return unless T::Enum > event.constant # rubocop:disable Style/InvertibleUnlessCondition
16
16
 
17
17
  enums = T.unsafe(constant).values.map do |enum_type|
18
18
  enum_type.instance_variable_get(:@const_name).to_s
@@ -7,16 +7,19 @@ module Tapioca
7
7
  class YardDoc < Base
8
8
  extend T::Sig
9
9
 
10
- IGNORED_COMMENTS = T.let([
11
- ":doc:",
12
- ":nodoc:",
13
- "typed:",
14
- "frozen_string_literal:",
15
- "encoding:",
16
- "warn_indent:",
17
- "shareable_constant_value:",
18
- "rubocop:",
19
- ], T::Array[String])
10
+ IGNORED_COMMENTS = T.let(
11
+ [
12
+ ":doc:",
13
+ ":nodoc:",
14
+ "typed:",
15
+ "frozen_string_literal:",
16
+ "encoding:",
17
+ "warn_indent:",
18
+ "shareable_constant_value:",
19
+ "rubocop:",
20
+ ],
21
+ T::Array[String],
22
+ )
20
23
 
21
24
  IGNORED_SIG_TAGS = T.let(["param", "return"], T::Array[String])
22
25
 
@@ -106,6 +106,18 @@ module Tapioca
106
106
  @payload_symbols.include?(symbol_name)
107
107
  end
108
108
 
109
+ sig { params(name: T.any(String, Symbol)).returns(T::Boolean) }
110
+ def constant_in_gem?(name)
111
+ return true unless Object.respond_to?(:const_source_location)
112
+
113
+ source_location, _ = Object.const_source_location(name)
114
+ return true unless source_location
115
+ # If the source location of the constant is "(eval)", all bets are off.
116
+ return true if source_location == "(eval)"
117
+
118
+ gem.contains_path?(source_location)
119
+ end
120
+
109
121
  sig { params(method: UnboundMethod).returns(T::Boolean) }
110
122
  def method_in_gem?(method)
111
123
  source_location = method.source_location&.first
@@ -216,6 +228,7 @@ module Tapioca
216
228
  mark_seen(name)
217
229
 
218
230
  return if symbol_in_payload?(name)
231
+ return unless constant_in_gem?(name)
219
232
 
220
233
  target = name_of(constant)
221
234
  # If target has no name, let's make it an anonymous class or module with `Class.new` or `Module.new`
@@ -237,6 +250,7 @@ module Tapioca
237
250
  mark_seen(name)
238
251
 
239
252
  return if symbol_in_payload?(name)
253
+ return unless constant_in_gem?(name)
240
254
 
241
255
  klass = class_of(value)
242
256
 
@@ -154,8 +154,12 @@ module Tapioca
154
154
 
155
155
  IGNORED_GEMS = T.let(
156
156
  [
157
- "sorbet", "sorbet-static", "sorbet-runtime", "sorbet-static-and-runtime",
158
- "debug", "fakefs",
157
+ "sorbet",
158
+ "sorbet-static",
159
+ "sorbet-runtime",
160
+ "sorbet-static-and-runtime",
161
+ "debug",
162
+ "fakefs",
159
163
  ].freeze,
160
164
  T::Array[String],
161
165
  )
@@ -212,16 +212,22 @@ module Tapioca
212
212
 
213
213
  sig { params(nodes: T::Array[RBI::Node]).returns(T::Array[T.any(RBI::Method, RBI::Attr)]) }
214
214
  def extract_methods_and_attrs(nodes)
215
- T.cast(nodes.select do |node|
216
- node.is_a?(RBI::Method) || node.is_a?(RBI::Attr)
217
- end, T::Array[T.any(RBI::Method, RBI::Attr)])
215
+ T.cast(
216
+ nodes.select do |node|
217
+ node.is_a?(RBI::Method) || node.is_a?(RBI::Attr)
218
+ end,
219
+ T::Array[T.any(RBI::Method, RBI::Attr)],
220
+ )
218
221
  end
219
222
 
220
223
  sig { params(nodes: T::Array[RBI::Node]).returns(T::Array[T.any(RBI::Mixin, RBI::RequiresAncestor)]) }
221
224
  def extract_mixins(nodes)
222
- T.cast(nodes.select do |node|
223
- node.is_a?(RBI::Mixin) || node.is_a?(RBI::RequiresAncestor)
224
- end, T::Array[T.all(RBI::Mixin, RBI::RequiresAncestor)])
225
+ T.cast(
226
+ nodes.select do |node|
227
+ node.is_a?(RBI::Mixin) || node.is_a?(RBI::RequiresAncestor)
228
+ end,
229
+ T::Array[T.all(RBI::Mixin, RBI::RequiresAncestor)],
230
+ )
225
231
  end
226
232
 
227
233
  sig { params(nodes: T::Array[T.any(RBI::Method, RBI::Attr)]).returns(T::Array[T.any(RBI::Method, RBI::Attr)]) }
@@ -19,10 +19,13 @@ module Tapioca
19
19
 
20
20
  SORBET_PAYLOAD_URL = "https://github.com/sorbet/sorbet/tree/master/rbi"
21
21
 
22
- FEATURE_REQUIREMENTS = T.let({
23
- # feature_name: ::Gem::Requirement.new(">= ___"), # https://github.com/sorbet/sorbet/pull/___
24
- non_generic_weak_map: ::Gem::Requirement.new(">= 0.5.10587"), # https://github.com/sorbet/sorbet/pull/6610
25
- }.freeze, T::Hash[Symbol, ::Gem::Requirement])
22
+ FEATURE_REQUIREMENTS = T.let(
23
+ {
24
+ # feature_name: ::Gem::Requirement.new(">= ___"), # https://github.com/sorbet/sorbet/pull/___
25
+ non_generic_weak_map: ::Gem::Requirement.new(">= 0.5.10587"), # https://github.com/sorbet/sorbet/pull/6610
26
+ }.freeze,
27
+ T::Hash[Symbol, ::Gem::Requirement],
28
+ )
26
29
 
27
30
  sig { params(sorbet_args: String).returns(Spoom::ExecResult) }
28
31
  def sorbet(*sorbet_args)
@@ -7,13 +7,16 @@ module URI
7
7
  class Source < URI::File
8
8
  extend T::Sig
9
9
 
10
- COMPONENT = T.let([
11
- :scheme,
12
- :gem_name,
13
- :gem_version,
14
- :path,
15
- :line_number,
16
- ].freeze, T::Array[Symbol])
10
+ COMPONENT = T.let(
11
+ [
12
+ :scheme,
13
+ :gem_name,
14
+ :gem_version,
15
+ :path,
16
+ :line_number,
17
+ ].freeze,
18
+ T::Array[Symbol],
19
+ )
17
20
 
18
21
  alias_method(:gem_name, :host)
19
22
  alias_method(:line_number, :fragment)
@@ -18,10 +18,12 @@ module Tapioca
18
18
  ).void
19
19
  end
20
20
  def load_application(bundle:, prerequire:, postrequire:, default_command:)
21
- loader = new(bundle: bundle,
21
+ loader = new(
22
+ bundle: bundle,
22
23
  prerequire: prerequire,
23
24
  postrequire: postrequire,
24
- default_command: default_command)
25
+ default_command: default_command,
26
+ )
25
27
  loader.load
26
28
  end
27
29
  end