Skip to content

Commit

Permalink
Only generate mixin RBIs for foreign constants
Browse files Browse the repository at this point in the history
  • Loading branch information
egiurleo committed Jun 3, 2022
1 parent 0a5148d commit 70ddb65
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 9 deletions.
2 changes: 2 additions & 0 deletions lib/tapioca/gem/events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ def initialize(symbol, constant, node)
end
end

class ForeignScopeNodeAdded < ScopeNodeAdded; end

class MethodNodeAdded < NodeAdded
extend T::Sig

Expand Down
11 changes: 11 additions & 0 deletions lib/tapioca/gem/listeners/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ def initialize(pipeline)

sig { params(event: NodeAdded).void }
def dispatch(event)
return if should_skip?(event)

case event
when ConstNodeAdded
on_const(event)
Expand All @@ -42,6 +44,15 @@ def on_scope(event)
sig { params(event: MethodNodeAdded).void }
def on_method(event)
end

sig { params(event: NodeAdded).returns(T::Boolean) }
def should_skip?(event)
# Some listeners do not have to take any action on certain events. For example,
# almost every listener should skip ForeignScopeNodeAdded events in order not to generate
# unnecessary RBIs for foreign constants. This method should be overridden by listener
# subclasses to skip events that are not relevant to them.
event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
end
end
end
end
Expand Down
5 changes: 5 additions & 0 deletions lib/tapioca/gem/listeners/mixins.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ def interesting_ancestors_of(constant)
inherited_ancestors_ids.include?(object_id_of(mod))
end
end

sig { params(event: NodeAdded).returns(T::Boolean) }
def should_skip?(event)
false
end
end
end
end
Expand Down
18 changes: 16 additions & 2 deletions lib/tapioca/gem/pipeline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,20 @@ def push_const(symbol, constant, node)
@events << Gem::ConstNodeAdded.new(symbol, constant, node)
end

sig { params(symbol: String, constant: Module, node: RBI::Scope).void.checked(:never) }
sig do
params(symbol: String, constant: Module, node: RBI::Scope).void.checked(:never)
end
def push_scope(symbol, constant, node)
@events << Gem::ScopeNodeAdded.new(symbol, constant, node)
end

sig do
params(symbol: String, constant: Module, node: RBI::Scope).void.checked(:never)
end
def push_foreign_scope(symbol, constant, node)
@events << Gem::ForeignScopeNodeAdded.new(symbol, constant, node)
end

sig do
params(
symbol: String,
Expand Down Expand Up @@ -256,7 +265,12 @@ def compile_module(name, constant, foreign_constant: false)
RBI::Module.new(name)
end

push_scope(name, constant, scope)
if foreign_constant
push_foreign_scope(name, constant, scope)
else
push_scope(name, constant, scope)
end

@root << scope
end

Expand Down
47 changes: 46 additions & 1 deletion spec/tapioca/cli/gem_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1074,10 +1074,55 @@ def foo(a, b, c, d, e, f, g, h); end
assert_success_status(result)
end

it "must do mixin attribution properly" do
# This is pattern is taken from the private `typed_parameters` gem.
typed_parameters = mock_gem("typed_parameters", "0.3.0") do
write("lib/typed_parameters.rb", <<~RUBY)
require "action_controller"
module TypedParameters
end
# This dynamic mixin should be generated in the gem RBI
ActionController::Parameters.include(TypedParameters)
RUBY
end

@project.require_real_gem("actionpack", "6.1.4.4")
@project.require_mock_gem(typed_parameters)

@project.bundle_install

response = @project.tapioca("gem actionpack typed_parameters")

assert_includes(response.out, "Compiled actionpack")
assert_includes(response.out, "Compiled typed_parameters")

# TODO: Uncomment when addressing part 2 of tapioca#890
# actionpack_rbi = @project.read("sorbet/rbi/gems/actionpack@6.1.4.4.rbi")
# actionpack RBI should have nothing in it about `TypedParameters`
# refute_includes(actionpack_rbi, "TypedParameters")

assert_project_file_equal("sorbet/rbi/gems/typed_parameters@0.3.0.rbi", <<~RBI)
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `typed_parameters` gem.
# Please instead update this file by running `bin/tapioca gem typed_parameters`.
class ActionController::Parameters
include ::TypedParameters
end
module TypedParameters; end
RBI
end

it "must generate RBIs for constants defined in a different gem but with mixins in this gem" do
foo = mock_gem("foo", "0.0.1") do
write("lib/foo.rb", <<~RBI)
class Foo; end
class Foo
def baz; end
def buzz; end
end
RBI
end

Expand Down
6 changes: 0 additions & 6 deletions spec/tapioca/gem/pipeline_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -542,9 +542,6 @@ class String
include ::Foo::Bar
extend ::JSON::Ext::Generator::GeneratorMethods::String::Extend
end
String::BLANK_RE = T.let(T.unsafe(nil), Regexp)
String::ENCODED_BLANKS = T.let(T.unsafe(nil), Concurrent::Map)
RBI

assert_equal(output, compile)
Expand Down Expand Up @@ -597,9 +594,6 @@ class String
include ::Foo::Bar
extend ::JSON::Ext::Generator::GeneratorMethods::String::Extend
end
String::BLANK_RE = T.let(T.unsafe(nil), Regexp)
String::ENCODED_BLANKS = T.let(T.unsafe(nil), Concurrent::Map)
RBI

assert_equal(output, compile)
Expand Down

0 comments on commit 70ddb65

Please sign in to comment.