-
Notifications
You must be signed in to change notification settings - Fork 122
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
Conversation
493d965
to
e34c655
Compare
lib/tapioca/runtime/reflection.rb
Outdated
constant = constantize(namespace) | ||
next unless Module === constant | ||
|
||
name_of(constant) != namespace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we extract this as a private constant_name_differs_from_actual_namespace
method to facilitate reading? Maybe just adding a comment in the block would help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think of the comment I added?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect 👌
When compiling a gem, it is possible for the gem to define an alias that includes an alias from another gem in its namespace. For example: In gem foo: ``` module Foo; end F = Foo ``` In gem bar: ``` module Foo module Bar; end end F::B = Foo::Bar ``` Because the alias `F` is not originally defined in the gem `bar`, tapioca will not skip writing that alias to the RBI file of `bar`, which will cause a Sorbet error because the alias `F` will be defined in the RBI files for both `foo` and `bar`. Now, tapioca will not generate RBI for aliases originally defined in other gems.
e34c655
to
9cc3977
Compare
Motivation
When compiling a gem, it is possible for the gem to define an alias that includes an alias from another gem in its namespace.
For example, let's say we have gems
foo
andbar
:Then the RBIs might look something like this:
There are two issues with this RBI:
F = Foo
and another time in the lineF::B = Foo::Bar
)Foo::Bar
is defined twice inbar.rbi
This commit will cause the RBI for gem
bar
to skip over the lineF::B = Foo::Bar
, which will prevent the aliasF
from being defined twice in RBI.More Context
I found this issue when trying to generate RBI for the
eventmachine
andem-synchrony
gems.eventmachine
defines an aliasEM = EventMachine
, andem-synchrony
defines another aliasEM::S = EventMachine::Synchrony
. The resulting RBI files cause a Sorbet error becauseEM
is defined twice.Implementation
I implemented this change by adding an additional check to the
skip_alias?
method that determines whether the namespace of a constant contains an alias and skips compiling that constant if so.Tests
I added one test that fails without this change and passes with it. All other tests continue to pass. I have tested this in Shopify core and verified no new Sorbet errors.