tapioca 0.9.4 → 0.10.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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +21 -0
  3. data/README.md +48 -22
  4. data/lib/tapioca/cli.rb +17 -23
  5. data/lib/tapioca/commands/annotations.rb +2 -2
  6. data/lib/tapioca/commands/dsl.rb +43 -65
  7. data/lib/tapioca/commands/gem.rb +18 -50
  8. data/lib/tapioca/commands/todo.rb +1 -2
  9. data/lib/tapioca/dsl/compiler.rb +34 -37
  10. data/lib/tapioca/dsl/compilers/aasm.rb +7 -3
  11. data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +7 -3
  12. data/lib/tapioca/dsl/compilers/action_mailer.rb +7 -3
  13. data/lib/tapioca/dsl/compilers/active_job.rb +7 -3
  14. data/lib/tapioca/dsl/compilers/active_model_attributes.rb +9 -5
  15. data/lib/tapioca/dsl/compilers/active_model_secure_password.rb +11 -7
  16. data/lib/tapioca/dsl/compilers/active_record_associations.rb +7 -3
  17. data/lib/tapioca/dsl/compilers/active_record_columns.rb +7 -3
  18. data/lib/tapioca/dsl/compilers/active_record_enum.rb +7 -3
  19. data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +8 -4
  20. data/lib/tapioca/dsl/compilers/active_record_relations.rb +7 -3
  21. data/lib/tapioca/dsl/compilers/active_record_scope.rb +5 -3
  22. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +8 -4
  23. data/lib/tapioca/dsl/compilers/active_resource.rb +7 -3
  24. data/lib/tapioca/dsl/compilers/active_storage.rb +9 -5
  25. data/lib/tapioca/dsl/compilers/active_support_concern.rb +21 -18
  26. data/lib/tapioca/dsl/compilers/active_support_current_attributes.rb +7 -3
  27. data/lib/tapioca/dsl/compilers/config.rb +12 -8
  28. data/lib/tapioca/dsl/compilers/frozen_record.rb +7 -3
  29. data/lib/tapioca/dsl/compilers/graphql_input_object.rb +71 -0
  30. data/lib/tapioca/dsl/compilers/graphql_mutation.rb +81 -0
  31. data/lib/tapioca/dsl/compilers/identity_cache.rb +8 -4
  32. data/lib/tapioca/dsl/compilers/mixed_in_class_attributes.rb +9 -5
  33. data/lib/tapioca/dsl/compilers/protobuf.rb +69 -25
  34. data/lib/tapioca/dsl/compilers/rails_generators.rb +12 -8
  35. data/lib/tapioca/dsl/compilers/sidekiq_worker.rb +7 -3
  36. data/lib/tapioca/dsl/compilers/smart_properties.rb +10 -6
  37. data/lib/tapioca/dsl/compilers/state_machines.rb +7 -3
  38. data/lib/tapioca/dsl/compilers/url_helpers.rb +29 -26
  39. data/lib/tapioca/dsl/compilers.rb +0 -5
  40. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +1 -9
  41. data/lib/tapioca/dsl/helpers/graphql_type_helper.rb +62 -0
  42. data/lib/tapioca/dsl/pipeline.rb +19 -11
  43. data/lib/tapioca/gem/listeners/source_location.rb +16 -9
  44. data/lib/tapioca/gemfile.rb +30 -0
  45. data/lib/tapioca/helpers/config_helper.rb +2 -2
  46. data/lib/tapioca/helpers/rbi_helper.rb +43 -30
  47. data/lib/tapioca/helpers/source_uri.rb +77 -0
  48. data/lib/tapioca/helpers/test/dsl_compiler.rb +1 -1
  49. data/lib/tapioca/helpers/test/isolation.rb +7 -3
  50. data/lib/tapioca/internal.rb +5 -1
  51. data/lib/tapioca/loaders/dsl.rb +84 -0
  52. data/lib/tapioca/loaders/gem.rb +85 -0
  53. data/lib/tapioca/{runtime → loaders}/loader.rb +39 -31
  54. data/lib/tapioca/repo_index.rb +12 -8
  55. data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +2 -2
  56. data/lib/tapioca/runtime/trackers/constant_definition.rb +15 -13
  57. data/lib/tapioca/runtime/trackers/mixin.rb +35 -31
  58. data/lib/tapioca/runtime/trackers/required_ancestor.rb +21 -19
  59. data/lib/tapioca/static/requires_compiler.rb +2 -3
  60. data/lib/tapioca/static/symbol_table_parser.rb +19 -17
  61. data/lib/tapioca/version.rb +1 -1
  62. data/lib/tapioca.rb +24 -20
  63. metadata +10 -5
  64. data/Gemfile +0 -53
  65. data/Rakefile +0 -18
@@ -136,6 +136,22 @@ module Tapioca
136
136
  extend(T::Sig)
137
137
  include GemHelper
138
138
 
139
+ class << self
140
+ extend T::Sig
141
+
142
+ sig { returns(T::Hash[String, Gemfile::GemSpec]) }
143
+ def spec_lookup_by_file_path
144
+ @lookup ||= T.let(
145
+ [*::Gem::Specification.default_stubs, *::Gem::Specification.stubs]
146
+ .map! { |spec| new(spec.to_spec) }
147
+ .flat_map do |spec|
148
+ spec.files.filter_map { |file| [file.realpath.to_s, spec] if file.exist? }
149
+ end.to_h,
150
+ T.nilable(T::Hash[String, Gemfile::GemSpec])
151
+ )
152
+ end
153
+ end
154
+
139
155
  IGNORED_GEMS = T.let(
140
156
  [
141
157
  "sorbet", "sorbet-static", "sorbet-runtime", "sorbet-static-and-runtime",
@@ -160,6 +176,11 @@ module Tapioca
160
176
  @files = T.let(collect_files, T::Array[Pathname])
161
177
  end
162
178
 
179
+ sig { params(other: BasicObject).returns(T::Boolean) }
180
+ def ==(other)
181
+ GemSpec === other && other.name == name && other.version == version
182
+ end
183
+
163
184
  sig { params(gemfile_dir: String).returns(T::Boolean) }
164
185
  def ignore?(gemfile_dir)
165
186
  gem_ignored? || gem_in_app_dir?(gemfile_dir, full_gem_path)
@@ -211,6 +232,15 @@ module Tapioca
211
232
  rewriter.tree
212
233
  end
213
234
 
235
+ sig { params(file: Pathname).returns(Pathname) }
236
+ def relative_path_for(file)
237
+ if default_gem?
238
+ file.realpath.relative_path_from(RbConfig::CONFIG["rubylibdir"])
239
+ else
240
+ file.realpath.relative_path_from(full_gem_path)
241
+ end
242
+ end
243
+
214
244
  private
215
245
 
216
246
  sig { returns(T::Array[Pathname]) }
@@ -100,7 +100,7 @@ module Tapioca
100
100
  ).returns(T::Array[ConfigError])
101
101
  end
102
102
  def validate_config_options(command_options, config_key, config_options)
103
- config_options.map do |config_option_key, config_option_value|
103
+ config_options.filter_map do |config_option_key, config_option_value|
104
104
  command_option = command_options[config_option_key.to_sym]
105
105
  error_msg = "unknown option `#{config_option_key}` for key `#{config_key}`"
106
106
  next build_error(error_msg) unless command_option
@@ -135,7 +135,7 @@ module Tapioca
135
135
  all_strings = (config_option_value.keys + config_option_value.values).all? { |v| v.is_a?(String) }
136
136
  next build_error(error_msg) unless all_strings
137
137
  end
138
- end.compact
138
+ end
139
139
  end
140
140
 
141
141
  class ConfigErrorMessagePart < T::Struct
@@ -8,6 +8,44 @@ module Tapioca
8
8
  extend SorbetHelper
9
9
  extend self
10
10
 
11
+ class << self
12
+ extend T::Sig
13
+
14
+ sig do
15
+ params(
16
+ type: String,
17
+ variance: Symbol,
18
+ fixed: T.nilable(String),
19
+ upper: T.nilable(String),
20
+ lower: T.nilable(String)
21
+ ).returns(String)
22
+ end
23
+ def serialize_type_variable(type, variance, fixed, upper, lower)
24
+ variance = nil if variance == :invariant
25
+
26
+ bounds = []
27
+ bounds << "fixed: #{fixed}" if fixed
28
+ bounds << "lower: #{lower}" if lower
29
+ bounds << "upper: #{upper}" if upper
30
+
31
+ parameters = []
32
+ block = []
33
+
34
+ parameters << ":#{variance}" if variance
35
+
36
+ if sorbet_supports?(:type_variable_block_syntax)
37
+ block = bounds
38
+ else
39
+ parameters.concat(bounds)
40
+ end
41
+
42
+ serialized = type.dup
43
+ serialized << "(#{parameters.join(", ")})" unless parameters.empty?
44
+ serialized << " { { #{block.join(", ")} } }" unless block.empty?
45
+ serialized
46
+ end
47
+ end
48
+
11
49
  sig { params(name: String, type: String).returns(RBI::TypedParam) }
12
50
  def create_param(name, type:)
13
51
  create_typed_param(RBI::Param.new(name), type)
@@ -57,38 +95,13 @@ module Tapioca
57
95
  .gsub(".params()", "")
58
96
  end
59
97
 
60
- sig do
61
- params(
62
- type: String,
63
- variance: Symbol,
64
- fixed: T.nilable(String),
65
- upper: T.nilable(String),
66
- lower: T.nilable(String)
67
- ).returns(String)
68
- end
69
- def self.serialize_type_variable(type, variance, fixed, upper, lower)
70
- variance = nil if variance == :invariant
71
-
72
- bounds = []
73
- bounds << "fixed: #{fixed}" if fixed
74
- bounds << "lower: #{lower}" if lower
75
- bounds << "upper: #{upper}" if upper
76
-
77
- parameters = []
78
- block = []
79
-
80
- parameters << ":#{variance}" if variance
81
-
82
- if sorbet_supports?(:type_variable_block_syntax)
83
- block = bounds
98
+ sig { params(type: String).returns(String) }
99
+ def as_nilable_type(type)
100
+ if type.start_with?("T.nilable(", "::T.nilable(") || type == "T.untyped" || type == "::T.untyped"
101
+ type
84
102
  else
85
- parameters.concat(bounds)
103
+ "T.nilable(#{type})"
86
104
  end
87
-
88
- serialized = type.dup
89
- serialized << "(#{parameters.join(", ")})" unless parameters.empty?
90
- serialized << " { { #{block.join(", ")} } }" unless block.empty?
91
- serialized
92
105
  end
93
106
 
94
107
  sig { params(name: String).returns(T::Boolean) }
@@ -0,0 +1,77 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require "uri/file"
5
+
6
+ module URI
7
+ class Source < URI::File
8
+ extend T::Sig
9
+
10
+ COMPONENT = T.let([
11
+ :scheme,
12
+ :gem_name,
13
+ :gem_version,
14
+ :path,
15
+ :line_number,
16
+ ].freeze, T::Array[Symbol])
17
+
18
+ alias_method(:gem_name, :host)
19
+ alias_method(:line_number, :fragment)
20
+
21
+ sig { returns(T.nilable(String)) }
22
+ attr_reader :gem_version
23
+
24
+ class << self
25
+ extend T::Sig
26
+
27
+ sig do
28
+ params(
29
+ gem_name: String,
30
+ gem_version: T.nilable(String),
31
+ path: String,
32
+ line_number: T.nilable(String)
33
+ ).returns(URI::Source)
34
+ end
35
+ def build(gem_name:, gem_version:, path:, line_number:)
36
+ super(
37
+ {
38
+ scheme: "source",
39
+ host: gem_name,
40
+ path: DEFAULT_PARSER.escape("/#{gem_version}/#{path}"),
41
+ fragment: line_number,
42
+ }
43
+ )
44
+ end
45
+ end
46
+
47
+ sig { params(v: T.nilable(String)).void }
48
+ def set_path(v) # rubocop:disable Naming/AccessorMethodName
49
+ return if v.nil?
50
+
51
+ @gem_version, @path = v.split("/", 2)
52
+ end
53
+
54
+ sig { params(v: T.nilable(String)).returns(T::Boolean) }
55
+ def check_host(v)
56
+ return true unless v
57
+
58
+ if /[A-Za-z][A-Za-z0-9\-_]*/ !~ v
59
+ raise InvalidComponentError,
60
+ "bad component(expected gem name): #{v}"
61
+ end
62
+
63
+ true
64
+ end
65
+
66
+ sig { returns(String) }
67
+ def to_s
68
+ "source://#{gem_name}/#{gem_version}#{path}##{line_number}"
69
+ end
70
+
71
+ if URI.respond_to?(:register_scheme)
72
+ URI.register_scheme("SOURCE", self)
73
+ else
74
+ @@schemes["SOURCE"] = self
75
+ end
76
+ end
77
+ end
@@ -79,7 +79,7 @@ module Tapioca
79
79
 
80
80
  sig { returns(T::Array[String]) }
81
81
  def gathered_constants
82
- compiler_class.processable_constants.map(&:name).compact.sort
82
+ compiler_class.processable_constants.filter_map(&:name).sort
83
83
  end
84
84
 
85
85
  sig { params(constant_name: T.any(Symbol, String)).returns(String) }
@@ -10,9 +10,13 @@ module Tapioca
10
10
  extend T::Sig
11
11
  require "thread"
12
12
 
13
- sig { returns(T::Boolean) }
14
- def self.forking_env?
15
- !ENV["NO_FORK"] && Process.respond_to?(:fork)
13
+ class << self
14
+ extend T::Sig
15
+
16
+ sig { returns(T::Boolean) }
17
+ def forking_env?
18
+ !ENV["NO_FORK"] && Process.respond_to?(:fork)
19
+ end
16
20
  end
17
21
 
18
22
  def run
@@ -27,7 +27,6 @@ require "yard-sorbet"
27
27
 
28
28
  require "tapioca/runtime/dynamic_mixin_compiler"
29
29
  require "tapioca/helpers/gem_helper"
30
- require "tapioca/runtime/loader"
31
30
 
32
31
  require "tapioca/helpers/sorbet_helper"
33
32
  require "tapioca/helpers/rbi_helper"
@@ -37,6 +36,7 @@ require "tapioca/sorbet_ext/generic_name_patch"
37
36
  require "tapioca/sorbet_ext/proc_bind_patch"
38
37
  require "tapioca/runtime/generic_type_registry"
39
38
 
39
+ require "tapioca/helpers/source_uri"
40
40
  require "tapioca/helpers/cli_helper"
41
41
  require "tapioca/helpers/config_helper"
42
42
  require "tapioca/helpers/rbi_files_helper"
@@ -50,6 +50,10 @@ require "tapioca/static/symbol_table_parser"
50
50
  require "tapioca/static/symbol_loader"
51
51
  require "tapioca/static/requires_compiler"
52
52
 
53
+ require "tapioca/loaders/loader"
54
+ require "tapioca/loaders/gem"
55
+ require "tapioca/loaders/dsl"
56
+
53
57
  require "tapioca/gem"
54
58
  require "tapioca/dsl"
55
59
  require "tapioca/commands"
@@ -0,0 +1,84 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Tapioca
5
+ module Loaders
6
+ class Dsl < Loader
7
+ extend T::Sig
8
+
9
+ class << self
10
+ extend T::Sig
11
+
12
+ sig { params(tapioca_path: String, eager_load: T::Boolean).void }
13
+ def load_application(tapioca_path:, eager_load: true)
14
+ loader = new(tapioca_path: tapioca_path)
15
+ loader.load
16
+ end
17
+ end
18
+
19
+ sig { override.void }
20
+ def load
21
+ load_dsl_extensions
22
+ load_application
23
+ abort_if_pending_migrations!
24
+ load_dsl_compilers
25
+ end
26
+
27
+ protected
28
+
29
+ sig { params(tapioca_path: String, eager_load: T::Boolean).void }
30
+ def initialize(tapioca_path:, eager_load: true)
31
+ super()
32
+
33
+ @tapioca_path = tapioca_path
34
+ @eager_load = eager_load
35
+ end
36
+
37
+ sig { void }
38
+ def load_dsl_extensions
39
+ Dir["#{__dir__}/../dsl/extensions/*.rb"].sort.each { |f| require(f) }
40
+ end
41
+
42
+ sig { void }
43
+ def load_dsl_compilers
44
+ say("Loading DSL compiler classes... ")
45
+
46
+ Dir.glob([
47
+ "#{@tapioca_path}/generators/**/*.rb", # TODO: Here for backcompat, remove later
48
+ "#{@tapioca_path}/compilers/**/*.rb",
49
+ ]).each do |compiler|
50
+ require File.expand_path(compiler)
51
+ end
52
+
53
+ ::Gem.find_files("tapioca/dsl/compilers/*.rb").each do |compiler|
54
+ require File.expand_path(compiler)
55
+ end
56
+
57
+ say("Done", :green)
58
+ end
59
+
60
+ sig { void }
61
+ def load_application
62
+ say("Loading Rails application... ")
63
+
64
+ load_rails_application(
65
+ environment_load: true,
66
+ eager_load: @eager_load
67
+ )
68
+
69
+ say("Done", :green)
70
+ end
71
+
72
+ sig { void }
73
+ def abort_if_pending_migrations!
74
+ return unless File.exist?("config/application.rb")
75
+ return unless defined?(::Rake)
76
+
77
+ Rails.application.load_tasks
78
+ if Rake::Task.task_defined?("db:abort_if_pending_migrations")
79
+ Rake::Task["db:abort_if_pending_migrations"].invoke
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,85 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Tapioca
5
+ module Loaders
6
+ class Gem < Loader
7
+ extend T::Sig
8
+
9
+ class << self
10
+ extend T::Sig
11
+
12
+ sig do
13
+ params(
14
+ bundle: Gemfile,
15
+ prerequire: T.nilable(String),
16
+ postrequire: String,
17
+ default_command: String
18
+ ).void
19
+ end
20
+ def load_application(bundle:, prerequire:, postrequire:, default_command:)
21
+ loader = new(bundle: bundle,
22
+ prerequire: prerequire,
23
+ postrequire: postrequire,
24
+ default_command: default_command)
25
+ loader.load
26
+ end
27
+ end
28
+
29
+ sig { override.void }
30
+ def load
31
+ require_gem_file
32
+ end
33
+
34
+ protected
35
+
36
+ sig do
37
+ params(
38
+ bundle: Gemfile,
39
+ prerequire: T.nilable(String),
40
+ postrequire: String,
41
+ default_command: String
42
+ ).void
43
+ end
44
+ def initialize(bundle:, prerequire:, postrequire:, default_command:)
45
+ super()
46
+
47
+ @bundle = bundle
48
+ @prerequire = prerequire
49
+ @postrequire = postrequire
50
+ @default_command = default_command
51
+ end
52
+
53
+ sig { void }
54
+ def require_gem_file
55
+ say("Requiring all gems to prepare for compiling... ")
56
+ begin
57
+ load_bundle(@bundle, @prerequire, @postrequire)
58
+ rescue LoadError => e
59
+ explain_failed_require(@postrequire, e)
60
+ exit(1)
61
+ end
62
+
63
+ Runtime::Trackers::Autoload.eager_load_all!
64
+
65
+ say(" Done", :green)
66
+ unless @bundle.missing_specs.empty?
67
+ say(" completed with missing specs: ")
68
+ say(@bundle.missing_specs.join(", "), :yellow)
69
+ end
70
+ puts
71
+ end
72
+
73
+ sig { params(file: String, error: LoadError).void }
74
+ def explain_failed_require(file, error)
75
+ say_error("\n\nLoadError: #{error}", :bold, :red)
76
+ say_error("\nTapioca could not load all the gems required by your application.", :yellow)
77
+ say_error("If you populated ", :yellow)
78
+ say_error("#{file} ", :bold, :blue)
79
+ say_error("with ", :yellow)
80
+ say_error("`#{@default_command}`", :bold, :blue)
81
+ say_error("you should probably review it and remove the faulty line.", :yellow)
82
+ end
83
+ end
84
+ end
85
+ end
@@ -1,12 +1,22 @@
1
- # typed: strict
1
+ # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Tapioca
5
- module Runtime
5
+ module Loaders
6
6
  class Loader
7
- extend(T::Sig)
8
- include Tapioca::GemHelper
7
+ extend T::Sig
8
+ extend T::Helpers
9
+
9
10
  include Thor::Base
11
+ include CliHelper
12
+ include Tapioca::GemHelper
13
+
14
+ abstract!
15
+
16
+ sig { abstract.void }
17
+ def load; end
18
+
19
+ private
10
20
 
11
21
  sig do
12
22
  params(gemfile: Tapioca::Gemfile, initialize_file: T.nilable(String), require_file: T.nilable(String)).void
@@ -43,16 +53,27 @@ module Tapioca
43
53
  say("Continuing RBI generation without loading the Rails application.")
44
54
  end
45
55
 
46
- private
47
-
48
- sig { params(file: T.nilable(String)).void }
49
- def require_helper(file)
50
- return unless file
56
+ sig { void }
57
+ def load_rails_engines
58
+ rails_engines.each do |engine|
59
+ errored_files = []
51
60
 
52
- file = File.absolute_path(file)
53
- return unless File.exist?(file)
61
+ engine.config.eager_load_paths.each do |load_path|
62
+ Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
63
+ require(file)
64
+ rescue LoadError, StandardError
65
+ errored_files << file
66
+ end
67
+ end
54
68
 
55
- require(file)
69
+ # Try files that have errored one more time
70
+ # It might have been a load order problem
71
+ errored_files.each do |file|
72
+ require(file)
73
+ rescue LoadError, StandardError
74
+ nil
75
+ end
76
+ end
56
77
  end
57
78
 
58
79
  sig { returns(T::Array[T.untyped]) }
@@ -110,27 +131,14 @@ module Tapioca
110
131
  end
111
132
  end
112
133
 
113
- sig { void }
114
- def load_rails_engines
115
- rails_engines.each do |engine|
116
- errored_files = []
134
+ sig { params(file: T.nilable(String)).void }
135
+ def require_helper(file)
136
+ return unless file
117
137
 
118
- engine.config.eager_load_paths.each do |load_path|
119
- Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
120
- require(file)
121
- rescue LoadError, StandardError
122
- errored_files << file
123
- end
124
- end
138
+ file = File.absolute_path(file)
139
+ return unless File.exist?(file)
125
140
 
126
- # Try files that have errored one more time
127
- # It might have been a load order problem
128
- errored_files.each do |file|
129
- require(file)
130
- rescue LoadError, StandardError
131
- nil
132
- end
133
- end
141
+ require(file)
134
142
  end
135
143
  end
136
144
  end
@@ -6,15 +6,19 @@ module Tapioca
6
6
  extend T::Sig
7
7
  extend T::Generic
8
8
 
9
- sig { params(json: String).returns(RepoIndex) }
10
- def self.from_json(json)
11
- RepoIndex.from_hash(JSON.parse(json))
12
- end
9
+ class << self
10
+ extend T::Sig
11
+
12
+ sig { params(json: String).returns(RepoIndex) }
13
+ def from_json(json)
14
+ RepoIndex.from_hash(JSON.parse(json))
15
+ end
13
16
 
14
- sig { params(hash: T::Hash[String, T::Hash[T.untyped, T.untyped]]).returns(RepoIndex) }
15
- def self.from_hash(hash)
16
- hash.each_with_object(RepoIndex.new) do |(name, _), index|
17
- index << name
17
+ sig { params(hash: T::Hash[String, T::Hash[T.untyped, T.untyped]]).returns(RepoIndex) }
18
+ def from_hash(hash)
19
+ hash.each_with_object(RepoIndex.new) do |(name, _), index|
20
+ index << name
21
+ end
18
22
  end
19
23
  end
20
24
 
@@ -178,7 +178,7 @@ module Tapioca
178
178
 
179
179
  sig { params(tree: RBI::Tree).returns([T::Array[Module], T::Array[Module]]) }
180
180
  def compile_mixes_in_class_methods(tree)
181
- includes = dynamic_includes.map do |mod|
181
+ includes = dynamic_includes.filter_map do |mod|
182
182
  qname = qualified_name_of(mod)
183
183
 
184
184
  next if qname.nil? || qname.empty?
@@ -187,7 +187,7 @@ module Tapioca
187
187
  tree << RBI::Include.new(qname)
188
188
 
189
189
  mod
190
- end.compact
190
+ end
191
191
 
192
192
  # If we can generate multiple mixes_in_class_methods, then we want to use all dynamic extends that are not the
193
193
  # constant itself
@@ -49,22 +49,24 @@ module Tapioca
49
49
  (@class_files[key] ||= Set.new) << loc
50
50
  end
51
51
 
52
- def self.build_constant_location(tp, locations)
53
- file = resolve_loc(caller_locations)
54
- lineno = file == File.realpath(tp.path) ? tp.lineno : 0
52
+ class << self
53
+ def build_constant_location(tp, locations)
54
+ file = resolve_loc(caller_locations)
55
+ lineno = file == File.realpath(tp.path) ? tp.lineno : 0
55
56
 
56
- ConstantLocation.new(path: file, lineno: lineno)
57
- end
57
+ ConstantLocation.new(path: file, lineno: lineno)
58
+ end
58
59
 
59
- # Returns the files in which this class or module was opened. Doesn't know
60
- # about situations where the class was opened prior to +require+ing,
61
- # or where metaprogramming was used via +eval+, etc.
62
- def self.files_for(klass)
63
- locations_for(klass).map(&:path).to_set
64
- end
60
+ # Returns the files in which this class or module was opened. Doesn't know
61
+ # about situations where the class was opened prior to +require+ing,
62
+ # or where metaprogramming was used via +eval+, etc.
63
+ def files_for(klass)
64
+ locations_for(klass).map(&:path).to_set
65
+ end
65
66
 
66
- def self.locations_for(klass)
67
- @class_files.fetch(klass, Set.new)
67
+ def locations_for(klass)
68
+ @class_files.fetch(klass, Set.new)
69
+ end
68
70
  end
69
71
  end
70
72
  end