tapioca icon indicating copy to clipboard operation
tapioca copied to clipboard

If a dynamic mixin happens more than once Tapioca forgets the original mixin location

Open paracycle opened this issue 2 years ago • 0 comments

If a gem performs a dynamic mixin like:

Bar.include(Foo)

Tapioca can pick that up using the mixin tracker. However, if another gem later tries to trigger the same dynamic mixin by calling the same method that performs it, the mixin tracker will update the location of the mixin to be the second invocation, thus attributing the mixin to the wrong gem.

The second time include Foo is called, it does not change the list of ancestors, however, since append_features is still called, Tapioca does the wrong thing.

This has happened to us with the mocha gem. In our Core monolith we have require "mocha/minitest" inside the Tapioca require.rb file, so that we can generate the proper gem RBI for Mocha. This require loads Mocha::API and includes it into Minitest::Test class. As a side effect of that include, we get dynamic includes for Mocha::ObjectMethods and Mocha::ClassMethods. Up to this point, all is well and Tapioca can properly handle these dynamic includes and attribute them to the Mocha gem. However, recently, an internal gem has been added to Core and it has code that also does a require "mocha/api" and include Mocha::API. This second include triggers the same dynamic includes and overwrites the dynamic include location for the two modules. As a result, Tapioca ends up attributing the dynamic includes to the other gem and does not generate the include Mocha::ObjectMethods and include Mocha::ClassMethods calls in the Mocha gem RBI file.

paracycle avatar Feb 21 '23 14:02 paracycle