Properly attribute RBIs created by ActiveSupport.on_load
#2050
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Closes #2016
Closes #2048
Motivation
Currently, Tapioca is incorrectly attributing mixins performed by the
ActiveSupport.on_load
hooks.A quick summary of how things currently work: whenever a mixin (
include
,extend
,prepend
) is performed by a gem for which Tapioca is generating RBIs, we attribute that mixin to a specific location by looking at the backtrace of the call toinclude
/extend
/prepend
and finding the line that is tagged<top (required)>
(or<main>
if there is no other tag). This location may be in the gem code, or it may be in the code of another gem entirely.Then, we can filter those mixins based on where they happen -- only the mixins attributed to a gem get put in that gem's RBI.
This approach does not work when a mixin is performed based on an
ActiveSupport.on_load
hook because the location that is tagged<top (required)>
will be in Rails gem that is being hooked into, rather than in the gem that is performing theon_load
hook in the first place.Implementation
To fix this, we need to change how we choose the location for mixin attribution. The current implementation of this PR has it looking for
block in <class:ActiveRecord>
. I'm not super confident in this implementation because I'm sure it can be generalized for other use cases.Tests
See automated tests