-
-
Notifications
You must be signed in to change notification settings - Fork 154
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
fix: remove unneeded null conditional initializer #705
Conversation
Codecov Report
@@ Coverage Diff @@
## main #705 +/- ##
==========================================
- Coverage 91.45% 90.86% -0.60%
==========================================
Files 214 180 -34
Lines 7149 6325 -824
Branches 867 809 -58
==========================================
- Hits 6538 5747 -791
+ Misses 406 389 -17
+ Partials 205 189 -16
... and 107 files with indirect coverage changes 📣 Codecov offers a browser extension for seamless coverage viewing on GitHub. Try it in Chrome or Firefox today! |
4d0514a
to
8b522bf
Compare
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.
Thank you for this PR 😊
@@ -42,6 +42,17 @@ private void AddNullMemberInitializers(IMemberAssignmentMappingContainer contain | |||
if (!nullablePath.Member.CanSet) | |||
continue; | |||
|
|||
// if member is initialised with a non null value then skip | |||
if ( |
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.
Wouldn't it be easier to keep a set of mapped source members (in SetSourceMemberMapped
) and perform a simple lookup here? This way we wouldn't need to make the information public on the mapping.
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.
Wouldn't it be easier to keep a set of mapped source members (in SetSourceMemberMapped) and perform a simple lookup here?
Tried something similar but realised it would cause errors. If the source value is transformed we'd lose the type info ie target.Value = UserDefinedDoggyMapper(source.Value)
, here source.Value
may not be nullable but the user defined mapper might return a null value
Yeah, I'm not a fan of exposing the properties either.
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.
But even in this case, we shouldn't initialize the property afterwards, should we? Wouldn't this be strange? It probably is the case today, but I don't think this makes a lot of sense.
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.
I'm not sure what you mean, could you rephrase this please?
FYI this PR doesn't change the order of member instantiation. It is still possible to null initialise before a member is set. All this PR does is omit a null initializer if the source value is not nullable.
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.
Sorry for my bad english... I thought Mapperly should not generate a ??= new();
if previously another mapping assigned a value to this property. However, on a second thought I think we should keep the current behaviour. But isn't the described approach possible by simply adding a parameter to a Set...MemberMapped
method, whether the member is nullable or not?
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.
Have you pushed it in a branch so I can quickly look into it? 😊 Thank you!
This branch should have the changes as commit 99afa22. Do you want me to create a separate branch?
Note that I didn't remove my original modifications.
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.
Thanks for the commit. I tried a little around on the provided commit and came up with the following solution (available here):
- I exposed a
MemberTypeMapping
from theIMemberAssignmentMapping
SetTargetNonNullInitializedIfNonNullable
added toMembersContainerBuilderContext
to keep track of the non-nullable initialized target paths
With this the correct nullable initializers were applied. However, under some conditions the initializers were emitted after a nested mapping. I fixed this with:
- Introducing
IMemberAssignmentMappingOrContainer
to have a common interface forIMemberAssignmentMappingContainer
andIMemberAssignmentMapping
- Introducing an additional
List<IMemberAssignmentMappingOrContainer>
to keep the containers and mappings ordered - Adjusted the
MemberAssignmentMappingContainer.Build
to use the ordered list as source
I'm not super happy with this solution, but IMO it still exposes less information/complexity than TryGetMemberMapping
. WDYT?
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.
Sound good 👍
Does this mean this PR is no longer needed!?
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.
I've rebased this pr onto a recent branch with the changes, it doesn't appear to have improved.
Any idea of what to do next? The original hack of exposing the mapping worked, aside from that I can't remember what else I tried 😅
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.
Since I'm not really happy with the solutions discussed (and you don't seem to be either), I'm thinking about whether we should just remove the initialisation of these nullable values with the next major release/breaking change.
@TimothyMakkison any updates on this? Are you still working on this? 😊 Don't worry but otherwise I'd probably schedule this feature to be done by someone else... |
8b522bf
to
99afa22
Compare
Really sorry, should be able to fix this and the unmapped property warning PR. I'll need to install the preview before doing the unsafe accessors Haven't investigated the issue, but it looks like my tests are failing. I'll look into this in the morning. |
99afa22
to
7fd4711
Compare
Description
Add check to only insert a null initializer if the root value is uninitialized or initialized by a nullable type.
tbh I feel like mapperly shouldn't insert a null initializer if the root is mapped. Having a nullable path seems like an error and this obscures it.
Partially fixes #640
Checklist