Honor HasConversion<T>() for non-key reference properties in source-generated mappers - #146
Conversation
Co-authored-by: mrdevrobot <12503462+mrdevrobot@users.noreply.github.com>
HasConversion<T>() for non-key reference properties in source-generated mappers
|
@copilot I'd rather update the unit test with a SmartEnum more similar to the one presented by the issue opener. |
Co-authored-by: mrdevrobot <12503462+mrdevrobot@users.noreply.github.com>
Updated in commit b160aa4. The regression now uses |
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved converter ordering, null-handling, and numeric-cast issues remain in generated mapper code.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
This PR updates source-generated mappers so explicit HasConversion<T>() takes precedence for non-key reference properties, with SmartEnum-style regression coverage.
Changes:
- Reorders converter handling in write/read generation.
- Adds SmartEnum fixtures, configuration, and round-trip testing.
- Adds the supporting test dependency.
File summaries
| File | Description |
|---|---|
tests/BLite.Tests/SourceGeneratorFeaturesTests.cs |
Adds SmartEnum round-trip coverage. |
tests/BLite.Shared/TestDbContext.cs |
Registers the test collection and converter. |
tests/BLite.Shared/MockEntities.cs |
Adds SmartEnum test models and converter. |
tests/BLite.Shared/BLite.Shared.csproj |
Adds the SmartEnum package dependency. |
src/BLite.SourceGenerators/CodeGenerator.cs |
Updates converter precedence and generated mapper emission. |
Review details
Suppressed comments (1)
src/BLite.SourceGenerators/CodeGenerator.cs:860
- The read path has the same nullability mismatch for nonnullable-declared reference properties. If the stored value is BSON null, it calls
ReadString()/the provider reader without a null check;ReadStringexpects a string length and throws. Mirror the write-side reference-type guard here.
if (prop.IsNullable)
- Files reviewed: 5/5 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| } | ||
| else | ||
| { | ||
| sb.AppendLine($" {localVar} = _converter_{prop.Name}.ConvertFromProvider(reader.{converterReadMethod}{converterReadArgs});"); |
| var converterWriteMethod = GetPrimitiveWriteMethod(providerProp, allowKey: false); | ||
| if (converterWriteMethod != null) | ||
| { | ||
| if (prop.IsNullable) |
| } | ||
| sb.AppendLine($" }}"); | ||
| } | ||
| else if (prop.ConverterTypeName != null) |
HasConversion<T>()was not reliably applied to non-ID reference-type properties (e.g., SmartEnum-style types), so values could be serialized/deserialized through nested-object logic instead of the configured converter. This caused incorrect round-trips for properties likeGender.Generator fix: converter precedence
ConverterTypeNameare handled before nested-object/primitive branches.GenerateWriteProperty(...)GenerateReadPropertyToLocal(...)Regression coverage for SmartEnum-like scenario
DeviceWithSmartStatusSmartStatus+SmartStatusConverter : ValueConverter<SmartStatus, string>.Property(x => x.Status).HasConversion<SmartStatusConverter>()SmartStatus.Active) rather than nested-object materialization behavior.