Repository navigation
[P2] Preserve null from a missing enum source-path intermediate #48
Description
Priority and scope
P2: a supported configured enum path throws for a missing nullable intermediate even when its destination enum is nullable.
Confirmed during the release audit on candidate develop commit 9c48bfd59fe586097ca18c4289c85f03e93e30bc. The same source does not work on published 3.0.0 (b9697f2f91aa737360479a434f7d3cc01ccaa8fd): it fails generated compilation with CS8081. PR #41 fixed the invalid nameof, exposing this remaining runtime null-propagation gap. This is not a regression from previously working 3.0.0 behavior.
Minimal reproduction
#nullable enable
using Mammoth.LiteMapper;
public enum From { None = 0, Ready = 1 }
public enum To { None = 0, Ready = 4 }
[LiteMapper]
public static partial class Mapper
{
[MapProperty(Source = "Child.State", Target = nameof(Target.State))]
public static partial Target Map(Source source);
}
public sealed class Source { public Child? Child { get; set; } }
public sealed class Child { public From State { get; set; } }
public sealed class Target { public To? State { get; set; } }
// Mapper.Map(new Source()).State should be null.
// Candidate throws ArgumentOutOfRangeException.Expected and actual
- Expected: missing
Childpropagates null toTo? State; presentReadymaps by name toTo.Ready. - Actual: a null path value reaches the by-name enum switch/default and throws
ArgumentOutOfRangeException. - Reproduced for new-object mapping, constructor-bound destination members, and existing-target updates with patch null skipping disabled.
- Controls pass when the enum leaf itself is nullable, when patch mode skips the missing path, and for equivalent nullable scalar paths.
The important shape is a nullable intermediate, a non-nullable enum leaf, and a nullable enum destination. Source-path traversal makes the effective value nullable despite the leaf symbol's non-nullable type.
Contract and acceptance criteria
Specification sections 9.4, 12.4, 13.1, 14.3 and 16.3 define source-path/null propagation and unknown enum-value behavior.
- Add runtime regressions for missing intermediate, known value and unknown numeric value across new-object mapping, constructor binding, and existing-target updates.
- A missing intermediate yields null for a nullable enum target; unknown non-null enum values retain the documented
ArgumentOutOfRangeException, stable path information and actual value. - Preserve nullable-leaf, scalar-path and patch-skip controls, single getter evaluation and existing update ordering.
- Cover relevant nullable intermediate shapes and both by-name/by-value enum paths without changing explicit converter precedence or nullable mismatch behavior.
- Verify warning-free C# 9-compatible generated source and representative package consumers, then full required CI.
- Update the documented limitation only after behavior is fixed and tested; public API and specification semantics remain unchanged.
Duplicate review and existing coverage
Reviewed repository issues including closed #27 and merged #41. Their scope fixed invalid exception-name expressions, not this remaining null-boundary behavior.
The existing enum regression checks compilation for this shape, and the usage guide records the remaining limitation. Runtime null assertions are needed.
This is a separate follow-up from configured nullable updater overload binding. No release, tag or package publication is part of this issue.
Prepared with OpenAI Codex.
Activity