Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Skip compiling constants with alias from another gem in namespace #1756

Merged
merged 1 commit into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/tapioca/gem/pipeline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ def skip_constant?(name, constant)
def skip_alias?(name, constant)
return true if symbol_in_payload?(name)
return true unless constant_in_gem?(name)
return true if has_aliased_namespace?(name)

false
end
Expand Down
17 changes: 17 additions & 0 deletions lib/tapioca/runtime/reflection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,23 @@ def child_module_for_parent_with_name(parent, name)
def method_defined_by_forwardable_module?(method)
method.source_location&.first == Object.const_source_location(:Forwardable)&.first
end

sig { params(name: String).returns(T::Boolean) }
def has_aliased_namespace?(name)
name_parts = name.split("::")
name_parts.pop # drop the constant name, leaving just the namespace

name_parts.each_with_object([]) do |name_part, namespaces|
namespaces << "#{namespaces.last}::#{name_part}".delete_prefix("::")
end.any? do |namespace|
constant = constantize(namespace)
next unless Module === constant

# If the constant name doesn't match the namespace,
# the namespace must contain an alias
name_of(constant) != namespace
end
end
end
end
end
47 changes: 47 additions & 0 deletions spec/tapioca/cli/gem_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1631,6 +1631,53 @@ def baz; end
assert_empty_stderr(result)
assert_success_status(result)
end

it "does not generate RBI if namespace contains alias from different gem" do
foo = mock_gem("foo", "0.0.1") do
write!("lib/foo.rb", <<~RB)
module Foo; end
F = Foo
RB
end

bar = mock_gem("bar", "0.0.1") do
write!("lib/bar.rb", <<~RB)
module Foo
module Bar; end
end
F::B = Foo::Bar
RB
end

@project.require_mock_gem(foo, require: false)
@project.require_mock_gem(bar, require: false)

@project.bundle_install!
@project.tapioca("gem foo bar")

assert_project_file_equal("sorbet/rbi/gems/foo@0.0.1.rbi", <<~RBI)
# typed: true

# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `foo` gem.
# Please instead update this file by running `bin/tapioca gem foo`.

F = Foo
module Foo; end
RBI

assert_project_file_equal("sorbet/rbi/gems/bar@0.0.1.rbi", <<~RBI)
# typed: true

# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `bar` gem.
# Please instead update this file by running `bin/tapioca gem bar`.

module Foo; end
Foo::B = Foo::Bar
module Foo::Bar; end
RBI
end
end

describe "sync" do
Expand Down
Loading