tapioca 0.10.4 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
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