Set default if factory
prop is set
#833
Merged
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.
Motivation
Explained more in Shopify/rbi#122, but basically
T::Struct
fields have afactory
option, which is basically the same asdefault
but takes a proc so the value can be set dynamically. Like default, if a prop/const has a factory set you don't have to pass a value in the initializer.Tapioca does not handle the
factory
option so based on the generated RBI a field with a factory would seem to be required in the initializer when it actually isn't. This has just come up for us with our first usage of this option in one of our internal gems so we've had to monkey-patch tapioca for now.Implementation
I noticed that when we see
immutable: true
we put a Const, even if the field may have been defined viaprop :x, Integer, immutable: true
. It gives the same effect to the type checker while not necessarily being identical to the source code.I took the same approach here for factory. For type-checking purposes, we just want sorbet to know if a field has a factory it will be optional in the initializer. So where we were previously checking if a
default
was defined and settingdefault: T.unsafe(nil)
in the RBI, we now also check forfactory
and do the same (setdefault: T.unsafe(nil)
in the RBI).Tests
Added a test that was red before and green after.