tapioca 0.8.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -2
  3. data/README.md +182 -36
  4. data/lib/tapioca/cli.rb +122 -65
  5. data/lib/tapioca/commands/annotations.rb +165 -33
  6. data/lib/tapioca/commands/check_shims.rb +91 -0
  7. data/lib/tapioca/commands/{init.rb → configure.rb} +1 -1
  8. data/lib/tapioca/commands/dsl.rb +1 -1
  9. data/lib/tapioca/commands/gem.rb +5 -5
  10. data/lib/tapioca/commands.rb +2 -1
  11. data/lib/tapioca/dsl/compiler.rb +1 -13
  12. data/lib/tapioca/dsl/compilers/active_model_attributes.rb +1 -1
  13. data/lib/tapioca/dsl/compilers/active_record_relations.rb +17 -0
  14. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +5 -4
  15. data/lib/tapioca/dsl/compilers/protobuf.rb +6 -0
  16. data/lib/tapioca/dsl/compilers.rb +0 -4
  17. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +2 -2
  18. data/lib/tapioca/dsl/pipeline.rb +0 -2
  19. data/lib/tapioca/dsl.rb +8 -0
  20. data/lib/tapioca/executor.rb +0 -3
  21. data/lib/tapioca/gem/events.rb +16 -2
  22. data/lib/tapioca/gem/listeners/base.rb +11 -0
  23. data/lib/tapioca/gem/listeners/dynamic_mixins.rb +5 -0
  24. data/lib/tapioca/gem/listeners/foreign_constants.rb +65 -0
  25. data/lib/tapioca/gem/listeners/methods.rb +6 -17
  26. data/lib/tapioca/gem/listeners/mixins.rb +31 -10
  27. data/lib/tapioca/gem/listeners/remove_empty_payload_scopes.rb +5 -0
  28. data/lib/tapioca/gem/listeners/sorbet_enums.rb +5 -0
  29. data/lib/tapioca/gem/listeners/sorbet_helpers.rb +5 -0
  30. data/lib/tapioca/gem/listeners/sorbet_props.rb +5 -0
  31. data/lib/tapioca/gem/listeners/sorbet_required_ancestors.rb +5 -0
  32. data/lib/tapioca/gem/listeners/sorbet_signatures.rb +6 -1
  33. data/lib/tapioca/gem/listeners/sorbet_type_variables.rb +5 -0
  34. data/lib/tapioca/gem/listeners/subconstants.rb +5 -0
  35. data/lib/tapioca/gem/listeners/yard_doc.rb +5 -0
  36. data/lib/tapioca/gem/listeners.rb +1 -0
  37. data/lib/tapioca/gem/pipeline.rb +58 -15
  38. data/lib/tapioca/gem.rb +6 -0
  39. data/lib/tapioca/gemfile.rb +7 -6
  40. data/lib/tapioca/helpers/cli_helper.rb +8 -2
  41. data/lib/tapioca/helpers/config_helper.rb +0 -2
  42. data/lib/tapioca/helpers/env_helper.rb +16 -0
  43. data/lib/tapioca/helpers/rbi_files_helper.rb +252 -0
  44. data/lib/tapioca/helpers/rbi_helper.rb +74 -94
  45. data/lib/tapioca/helpers/sorbet_helper.rb +2 -3
  46. data/lib/tapioca/helpers/test/content.rb +0 -2
  47. data/lib/tapioca/helpers/test/template.rb +0 -2
  48. data/lib/tapioca/internal.rb +34 -12
  49. data/lib/tapioca/rbi_ext/model.rb +2 -15
  50. data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +18 -16
  51. data/lib/tapioca/runtime/reflection.rb +27 -0
  52. data/lib/tapioca/runtime/trackers/constant_definition.rb +17 -7
  53. data/lib/tapioca/runtime/trackers/mixin.rb +49 -14
  54. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +1 -4
  55. data/lib/tapioca/static/requires_compiler.rb +0 -2
  56. data/lib/tapioca/static/symbol_loader.rb +26 -30
  57. data/lib/tapioca/static/symbol_table_parser.rb +0 -3
  58. data/lib/tapioca/version.rb +1 -1
  59. data/lib/tapioca.rb +3 -0
  60. metadata +22 -7
  61. data/lib/tapioca/dsl/helpers/param_helper.rb +0 -55
  62. data/lib/tapioca/helpers/shims_helper.rb +0 -115
  63. data/lib/tapioca/helpers/signatures_helper.rb +0 -17
  64. data/lib/tapioca/helpers/type_variable_helper.rb +0 -43
@@ -5,8 +5,9 @@ module Tapioca
5
5
  module Commands
6
6
  autoload :Command, "tapioca/commands/command"
7
7
  autoload :Annotations, "tapioca/commands/annotations"
8
+ autoload :CheckShims, "tapioca/commands/check_shims"
8
9
  autoload :Dsl, "tapioca/commands/dsl"
9
- autoload :Init, "tapioca/commands/init"
10
+ autoload :Configure, "tapioca/commands/configure"
10
11
  autoload :Gem, "tapioca/commands/gem"
11
12
  autoload :Require, "tapioca/commands/require"
12
13
  autoload :Todo, "tapioca/commands/todo"
@@ -1,12 +1,6 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "rbi"
5
- require "tapioca/rbi_ext/model"
6
- require "tapioca/rbi_formatter"
7
- require "tapioca/dsl/helpers/param_helper"
8
- require "tapioca/dsl/pipeline"
9
-
10
4
  module Tapioca
11
5
  module Dsl
12
6
  class Compiler
@@ -14,6 +8,7 @@ module Tapioca
14
8
  extend T::Helpers
15
9
  extend T::Generic
16
10
 
11
+ include RBIHelper
17
12
  include Runtime::Reflection
18
13
  extend Runtime::Reflection
19
14
 
@@ -119,8 +114,6 @@ module Tapioca
119
114
  )
120
115
  end
121
116
 
122
- include Helpers::ParamHelper
123
-
124
117
  sig { params(method_def: T.any(Method, UnboundMethod)).returns(T::Array[RBI::TypedParam]) }
125
118
  def compile_method_parameters_to_rbi(method_def)
126
119
  signature = signature_of(method_def)
@@ -175,11 +168,6 @@ module Tapioca
175
168
  "T.nilable(#{type})"
176
169
  end
177
170
  end
178
-
179
- sig { params(name: String).returns(T::Boolean) }
180
- def valid_parameter_name?(name)
181
- name.match?(/^[[[:alnum:]]_]+$/)
182
- end
183
171
  end
184
172
  end
185
173
  end
@@ -103,7 +103,7 @@ module Tapioca
103
103
  when ActiveModel::Type::Date
104
104
  "::Date"
105
105
  when ActiveModel::Type::DateTime, ActiveModel::Type::Time
106
- "::DateTime"
106
+ "::Time"
107
107
  when ActiveModel::Type::Decimal
108
108
  "::BigDecimal"
109
109
  when ActiveModel::Type::Float
@@ -543,6 +543,23 @@ module Tapioca
543
543
  ],
544
544
  return_type: constant_name
545
545
  )
546
+ when :find_sole_by
547
+ create_common_method(
548
+ "find_sole_by",
549
+ common_relation_methods_module,
550
+ parameters: [
551
+ create_param("arg", type: "T.untyped"),
552
+ create_rest_param("args", type: "T.untyped"),
553
+ ],
554
+ return_type: constant_name
555
+ )
556
+ when :sole
557
+ create_common_method(
558
+ "sole",
559
+ common_relation_methods_module,
560
+ parameters: [],
561
+ return_type: constant_name
562
+ )
546
563
  when :first, :last, :take
547
564
  create_common_method(
548
565
  method_name,
@@ -95,17 +95,18 @@ module Tapioca
95
95
  sig { override.void }
96
96
  def decorate
97
97
  stores = constant.typed_stores
98
- return if stores.values.flat_map(&:accessors).empty?
98
+ return if stores.values.all? { |store| store.accessors.empty? }
99
99
 
100
100
  root.create_path(constant) do |model|
101
101
  stores.values.each do |store_data|
102
- store_data.accessors.each do |accessor|
103
- field = store_data.fields[accessor]
102
+ store_data.accessors.each do |accessor, name|
103
+ field = store_data.fields.fetch(accessor)
104
104
  type = type_for(field.type_sym)
105
105
  type = as_nilable_type(type) if field.null
106
+ name ||= field.name # support < 1.5.0
106
107
 
107
108
  store_accessors_module = model.create_module("StoreAccessors")
108
- generate_methods(store_accessors_module, field.name.to_s, type)
109
+ generate_methods(store_accessors_module, name.to_s, type)
109
110
  model.create_include("StoreAccessors")
110
111
  end
111
112
  end
@@ -146,6 +146,11 @@ module Tapioca
146
146
  end
147
147
  end
148
148
 
149
+ sig { params(descriptor: Google::Protobuf::FieldDescriptor).returns(T::Boolean) }
150
+ def nilable_descriptor?(descriptor)
151
+ descriptor.label == :optional && descriptor.type == :message
152
+ end
153
+
149
154
  sig { params(descriptor: Google::Protobuf::FieldDescriptor).returns(Field) }
150
155
  def field_of(descriptor)
151
156
  if descriptor.label == :repeated
@@ -185,6 +190,7 @@ module Tapioca
185
190
  end
186
191
  else
187
192
  type = type_of(descriptor)
193
+ type = as_nilable_type(type) if nilable_descriptor?(descriptor)
188
194
 
189
195
  Field.new(
190
196
  name: descriptor.name,
@@ -1,10 +1,6 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "tapioca/rbi_ext/model"
5
- require "tapioca/dsl/helpers/param_helper"
6
- require "tapioca/dsl/pipeline"
7
-
8
4
  module Tapioca
9
5
  module Dsl
10
6
  module Compilers
@@ -35,7 +35,7 @@ module Tapioca
35
35
  when ActiveRecord::Type::Boolean
36
36
  "T::Boolean"
37
37
  when ActiveRecord::Type::DateTime, ActiveRecord::Type::Time
38
- "::DateTime"
38
+ "::Time"
39
39
  when ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter
40
40
  "::ActiveSupport::TimeWithZone"
41
41
  else
@@ -75,7 +75,7 @@ module Tapioca
75
75
  end
76
76
  end
77
77
 
78
- sig { params(column_type: Object).returns(String) }
78
+ sig { params(column_type: BasicObject).returns(String) }
79
79
  def handle_unknown_type(column_type)
80
80
  return "T.untyped" unless ActiveModel::Type::Value === column_type
81
81
  return "T.untyped" if Runtime::GenericTypeRegistry.generic_type_instance?(column_type)
@@ -1,8 +1,6 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "tapioca/dsl/compilers"
5
-
6
4
  module Tapioca
7
5
  module Dsl
8
6
  class Pipeline
data/lib/tapioca/dsl.rb CHANGED
@@ -1,6 +1,14 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "rbi"
5
+
4
6
  require "tapioca"
5
7
  require "tapioca/runtime/reflection"
8
+ require "tapioca/helpers/sorbet_helper"
9
+ require "tapioca/helpers/rbi_helper"
10
+ require "tapioca/rbi_ext/model"
11
+ require "tapioca/rbi_formatter"
12
+ require "tapioca/dsl/compilers"
13
+ require "tapioca/dsl/pipeline"
6
14
  require "tapioca/dsl/compiler"
@@ -1,9 +1,6 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "etc"
5
- require "parallel"
6
-
7
4
  module Tapioca
8
5
  class Executor
9
6
  extend T::Sig
@@ -1,8 +1,6 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "pathname"
5
-
6
4
  module Tapioca
7
5
  module Gem
8
6
  class Event
@@ -42,6 +40,20 @@ module Tapioca
42
40
  end
43
41
  end
44
42
 
43
+ class ForeignConstantFound < ConstantFound
44
+ extend T::Sig
45
+
46
+ sig { override.returns(Module) }
47
+ def constant
48
+ T.cast(@constant, Module)
49
+ end
50
+
51
+ sig { params(symbol: String, constant: Module).void }
52
+ def initialize(symbol, constant)
53
+ super
54
+ end
55
+ end
56
+
45
57
  class NodeAdded < Event
46
58
  extend T::Helpers
47
59
  extend T::Sig
@@ -88,6 +100,8 @@ module Tapioca
88
100
  end
89
101
  end
90
102
 
103
+ class ForeignScopeNodeAdded < ScopeNodeAdded; end
104
+
91
105
  class MethodNodeAdded < NodeAdded
92
106
  extend T::Sig
93
107
 
@@ -17,6 +17,8 @@ module Tapioca
17
17
 
18
18
  sig { params(event: NodeAdded).void }
19
19
  def dispatch(event)
20
+ return if ignore?(event)
21
+
20
22
  case event
21
23
  when ConstNodeAdded
22
24
  on_const(event)
@@ -42,6 +44,15 @@ module Tapioca
42
44
  sig { params(event: MethodNodeAdded).void }
43
45
  def on_method(event)
44
46
  end
47
+
48
+ sig { params(event: NodeAdded).returns(T::Boolean) }
49
+ def ignore?(event)
50
+ # Some listeners do not have to take any action on certain events. For example,
51
+ # almost every listener should skip ForeignScopeNodeAdded events in order not to generate
52
+ # unnecessary RBIs for foreign constants. This method should be overridden by listener
53
+ # subclasses to skip any events that aren't relevant to them.
54
+ false
55
+ end
45
56
  end
46
57
  end
47
58
  end
@@ -26,6 +26,11 @@ module Tapioca
26
26
  @pipeline.push_symbol(name) if name
27
27
  end
28
28
  end
29
+
30
+ sig { override.params(event: NodeAdded).returns(T::Boolean) }
31
+ def ignore?(event)
32
+ event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
33
+ end
29
34
  end
30
35
  end
31
36
  end
@@ -0,0 +1,65 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Tapioca
5
+ module Gem
6
+ module Listeners
7
+ class ForeignConstants < Base
8
+ extend T::Sig
9
+
10
+ include Runtime::Reflection
11
+
12
+ private
13
+
14
+ sig { override.params(event: ScopeNodeAdded).void }
15
+ def on_scope(event)
16
+ mixin = event.constant
17
+ return if Class === mixin # Classes can't be mixed into other constants
18
+
19
+ # There are cases where we want to process constants not declared by the current
20
+ # gem, i.e. "foreign constant". These are constants defined in another gem to which
21
+ # this gem is applying a mix-in. This pattern is especially common for gems that add
22
+ # behavior to Ruby standard library classes by mixing in modules to them.
23
+ #
24
+ # The way we identify these "foreign constants" is by asking the mixin tracker which
25
+ # constants have mixed in the current module that we are handling. We add all the
26
+ # constants that we discover to the pipeline to be processed.
27
+ Runtime::Trackers::Mixin.constants_with_mixin(mixin).each_value do |location_info|
28
+ location_info.each do |constant, location|
29
+ next unless mixed_in_by_gem?(location)
30
+
31
+ name = @pipeline.name_of(constant)
32
+
33
+ # Calling Tapioca::Gem::Pipeline#name_of on a singleton class returns `nil`.
34
+ # To handle this case, use string parsing to get the name of the singleton class's
35
+ # base constant. Then, generate RBIs as if the base constant is extending the mixin,
36
+ # which is functionally equivalent to including or prepending to the singleton class.
37
+ if !name && constant.singleton_class?
38
+ name = constant_name_from_singleton_class(constant)
39
+ next unless name
40
+
41
+ constant = T.cast(constantize(name), Module)
42
+ end
43
+
44
+ @pipeline.push_foreign_constant(name, constant) if name
45
+ end
46
+ end
47
+ end
48
+
49
+ sig do
50
+ params(
51
+ location: String,
52
+ ).returns(T::Boolean)
53
+ end
54
+ def mixed_in_by_gem?(location)
55
+ @pipeline.gem.contains_path?(location)
56
+ end
57
+
58
+ sig { override.params(event: NodeAdded).returns(T::Boolean) }
59
+ def ignore?(event)
60
+ event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -7,13 +7,9 @@ module Tapioca
7
7
  class Methods < Base
8
8
  extend T::Sig
9
9
 
10
+ include RBIHelper
10
11
  include Runtime::Reflection
11
12
 
12
- SPECIAL_METHOD_NAMES = T.let([
13
- "!", "~", "+@", "**", "-@", "*", "/", "%", "+", "-", "<<", ">>", "&", "|", "^",
14
- "<", "<=", "=>", ">", ">=", "==", "===", "!=", "=~", "!~", "<=>", "[]", "[]=", "`",
15
- ], T::Array[String])
16
-
17
13
  private
18
14
 
19
15
  sig { override.params(event: ScopeNodeAdded).void }
@@ -184,24 +180,17 @@ module Tapioca
184
180
  .include?(method_name.gsub(/=$/, "").to_sym)
185
181
  end
186
182
 
187
- sig { params(name: String).returns(T::Boolean) }
188
- def valid_method_name?(name)
189
- return true if SPECIAL_METHOD_NAMES.include?(name)
190
-
191
- !!name.match(/^[[:word:]]+[?!=]?$/)
192
- end
193
-
194
- sig { params(name: String).returns(T::Boolean) }
195
- def valid_parameter_name?(name)
196
- name.match?(/^[[[:alnum:]]_]+$/)
197
- end
198
-
199
183
  sig { params(constant: Module).returns(T.nilable(UnboundMethod)) }
200
184
  def initialize_method_for(constant)
201
185
  constant.instance_method(:initialize)
202
186
  rescue
203
187
  nil
204
188
  end
189
+
190
+ sig { override.params(event: NodeAdded).returns(T::Boolean) }
191
+ def ignore?(event)
192
+ event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
193
+ end
205
194
  end
206
195
  end
207
196
  end
@@ -26,19 +26,20 @@ module Tapioca
26
26
  end
27
27
 
28
28
  node = event.node
29
- add_mixins(node, prepends.reverse, Runtime::Trackers::Mixin::Type::Prepend)
30
- add_mixins(node, includes.reverse, Runtime::Trackers::Mixin::Type::Include)
31
- add_mixins(node, extends.reverse, Runtime::Trackers::Mixin::Type::Extend)
29
+ add_mixins(node, constant, prepends.reverse, Runtime::Trackers::Mixin::Type::Prepend)
30
+ add_mixins(node, constant, includes.reverse, Runtime::Trackers::Mixin::Type::Include)
31
+ add_mixins(node, constant, extends.reverse, Runtime::Trackers::Mixin::Type::Extend)
32
32
  end
33
33
 
34
34
  sig do
35
35
  params(
36
36
  tree: RBI::Tree,
37
+ constant: Module,
37
38
  mods: T::Array[Module],
38
39
  mixin_type: Runtime::Trackers::Mixin::Type
39
40
  ).void
40
41
  end
41
- def add_mixins(tree, mods, mixin_type)
42
+ def add_mixins(tree, constant, mods, mixin_type)
42
43
  mods
43
44
  .select do |mod|
44
45
  name = @pipeline.name_of(mod)
@@ -46,6 +47,8 @@ module Tapioca
46
47
  name && !filtered_mixin?(name)
47
48
  end
48
49
  .map do |mod|
50
+ next unless mixed_in_by_gem?(constant, mod, mixin_type)
51
+
49
52
  name = @pipeline.name_of(mod)
50
53
  @pipeline.push_symbol(name) if name
51
54
 
@@ -62,6 +65,25 @@ module Tapioca
62
65
  end
63
66
  end
64
67
 
68
+ sig do
69
+ params(
70
+ constant: Module,
71
+ mixin: Module,
72
+ mixin_type: Runtime::Trackers::Mixin::Type
73
+ ).returns(T::Boolean)
74
+ end
75
+ def mixed_in_by_gem?(constant, mixin, mixin_type)
76
+ mixin_location =
77
+ T.cast(
78
+ Runtime::Trackers::Mixin.constants_with_mixin(mixin).dig(mixin_type, constant),
79
+ T.nilable(String)
80
+ )
81
+
82
+ return true if mixin_location.nil?
83
+
84
+ @pipeline.gem.contains_path?(mixin_location)
85
+ end
86
+
65
87
  sig { params(mixin_name: String).returns(T::Boolean) }
66
88
  def filtered_mixin?(mixin_name)
67
89
  # filter T:: namespace mixins that aren't T::Props
@@ -71,9 +93,8 @@ module Tapioca
71
93
 
72
94
  sig { params(constant: Module).returns(T::Array[Module]) }
73
95
  def interesting_ancestors_of(constant)
74
- inherited_ancestors_ids = Set.new(
75
- inherited_ancestors_of(constant).map { |mod| object_id_of(mod) }
76
- )
96
+ inherited_ancestors = Set.new.compare_by_identity.merge(inherited_ancestors_of(constant))
97
+
77
98
  # TODO: There is actually a bug here where this will drop modules that
78
99
  # may be included twice. For example:
79
100
  #
@@ -91,9 +112,9 @@ module Tapioca
91
112
  #
92
113
  # Instead, we should only drop the tail matches of the ancestors and
93
114
  # inherited ancestors, past the location of the constant itself.
94
- constant.ancestors.reject do |mod|
95
- inherited_ancestors_ids.include?(object_id_of(mod))
96
- end
115
+ ancestors = Set.new.compare_by_identity.merge(ancestors_of(constant))
116
+
117
+ (ancestors - inherited_ancestors).to_a
97
118
  end
98
119
  end
99
120
  end
@@ -15,6 +15,11 @@ module Tapioca
15
15
  def on_scope(event)
16
16
  event.node.detach if @pipeline.symbol_in_payload?(event.symbol) && event.node.empty?
17
17
  end
18
+
19
+ sig { override.params(event: NodeAdded).returns(T::Boolean) }
20
+ def ignore?(event)
21
+ event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
22
+ end
18
23
  end
19
24
  end
20
25
  end
@@ -20,6 +20,11 @@ module Tapioca
20
20
 
21
21
  event.node << RBI::TEnumBlock.new(enums)
22
22
  end
23
+
24
+ sig { override.params(event: NodeAdded).returns(T::Boolean) }
25
+ def ignore?(event)
26
+ event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
27
+ end
23
28
  end
24
29
  end
25
30
  end
@@ -23,6 +23,11 @@ module Tapioca
23
23
  node << RBI::Helper.new("final") if T::Private::Final.final_module?(constant)
24
24
  node << RBI::Helper.new("sealed") if T::Private::Sealed.sealed_module?(constant)
25
25
  end
26
+
27
+ sig { override.params(event: NodeAdded).returns(T::Boolean) }
28
+ def ignore?(event)
29
+ event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
30
+ end
26
31
  end
27
32
  end
28
33
  end
@@ -27,6 +27,11 @@ module Tapioca
27
27
  end
28
28
  end
29
29
  end
30
+
31
+ sig { override.params(event: NodeAdded).returns(T::Boolean) }
32
+ def ignore?(event)
33
+ event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
34
+ end
30
35
  end
31
36
  end
32
37
  end
@@ -18,6 +18,11 @@ module Tapioca
18
18
  event.node << RBI::RequiresAncestor.new(ancestor.to_s)
19
19
  end
20
20
  end
21
+
22
+ sig { override.params(event: NodeAdded).returns(T::Boolean) }
23
+ def ignore?(event)
24
+ event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
25
+ end
21
26
  end
22
27
  end
23
28
  end
@@ -8,7 +8,7 @@ module Tapioca
8
8
  extend T::Sig
9
9
 
10
10
  include Runtime::Reflection
11
- include SignaturesHelper
11
+ include RBIHelper
12
12
 
13
13
  TYPE_PARAMETER_MATCHER = /T\.type_parameter\(:?([[:word:]]+)\)/
14
14
 
@@ -73,6 +73,11 @@ module Tapioca
73
73
 
74
74
  final_methods.include?(signature.method_name)
75
75
  end
76
+
77
+ sig { override.params(event: NodeAdded).returns(T::Boolean) }
78
+ def ignore?(event)
79
+ event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
80
+ end
76
81
  end
77
82
  end
78
83
  end
@@ -45,6 +45,11 @@ module Tapioca
45
45
 
46
46
  tree << RBI::Extend.new("T::Generic")
47
47
  end
48
+
49
+ sig { override.params(event: NodeAdded).returns(T::Boolean) }
50
+ def ignore?(event)
51
+ event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
52
+ end
48
53
  end
49
54
  end
50
55
  end
@@ -31,6 +31,11 @@ module Tapioca
31
31
  @pipeline.push_constant(name, subconstant)
32
32
  end
33
33
  end
34
+
35
+ sig { override.params(event: NodeAdded).returns(T::Boolean) }
36
+ def ignore?(event)
37
+ event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
38
+ end
34
39
  end
35
40
  end
36
41
  end
@@ -90,6 +90,11 @@ module Tapioca
90
90
 
91
91
  comments
92
92
  end
93
+
94
+ sig { override.params(event: NodeAdded).returns(T::Boolean) }
95
+ def ignore?(event)
96
+ event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
97
+ end
93
98
  end
94
99
  end
95
100
  end
@@ -13,4 +13,5 @@ require "tapioca/gem/listeners/sorbet_required_ancestors"
13
13
  require "tapioca/gem/listeners/sorbet_signatures"
14
14
  require "tapioca/gem/listeners/sorbet_type_variables"
15
15
  require "tapioca/gem/listeners/subconstants"
16
+ require "tapioca/gem/listeners/foreign_constants"
16
17
  require "tapioca/gem/listeners/yard_doc"