[LOADED_DOCS: 3 files, no new loads]
Add compile-time error for object-typed props w/o polymorph Introduces ACBIN002: a compile-time diagnostic that errors if a [AcBinarySerializable] type declares a System.Object property while UsePolymorphType is false. This prevents silent wire corruption by requiring the developer to either enable polymorphic serialization, use a concrete type, or ignore the property. The check is integrated into the source generator initialization.
This commit is contained in:
parent
f051f32bfa
commit
a7f2d3605b
|
|
@ -53,6 +53,33 @@ public class AcBinarySourceGenerator : IIncrementalGenerator
|
|||
defaultSeverity: DiagnosticSeverity.Warning,
|
||||
isEnabledByDefault: true);
|
||||
|
||||
/// <summary>
|
||||
/// ACCORE-BIN-I-T7K3 compile-time guard: a property declared as <c>System.Object</c> requires
|
||||
/// polymorphic-prefix emit (<c>ObjectWithTypeName</c>) so the deserializer can resolve the
|
||||
/// concrete runtime type. When <see cref="UsePolymorphType"/> is <c>false</c>, the prefix is
|
||||
/// suppressed and the wire silently corrupts on round-trip (FixObj slot byte against
|
||||
/// <c>typeof(object)</c> at read-time → 0-byte object wrapper → reader position drifts →
|
||||
/// downstream <c>DECIMAL_DRIFT</c> / <c>IndexOutOfRangeException</c>).
|
||||
///
|
||||
/// Surface the misconfiguration at build time so the silent corruption is structurally
|
||||
/// impossible. Three escape hatches for the developer:
|
||||
/// 1. Enable the polymorphic feature (<see cref="UsePolymorphType"/> = true, or — once the
|
||||
/// planned <c>[AcBinarySerializable(EnablePolymorphicFeature = true)]</c> flag lands — set
|
||||
/// it on the type).
|
||||
/// 2. Change the property type to a concrete type (no polymorphism needed).
|
||||
/// 3. Mark the property with <c>[AcBinaryIgnore]</c> — ignored properties are filtered
|
||||
/// out at property enumeration, so this diagnostic does not fire for them.
|
||||
/// </summary>
|
||||
private static readonly DiagnosticDescriptor PolymorphicPropertyWithFeatureDisabledError = new(
|
||||
id: "ACBIN002",
|
||||
title: "Polymorphic property requires polymorphic feature enabled",
|
||||
messageFormat: "Type '{0}' contains property '{1}' declared as System.Object, but polymorphic serialization in the source generator is disabled (UsePolymorphType=false). " +
|
||||
"The generated writer would silently corrupt the wire on round-trip. " +
|
||||
"To fix: (1) enable polymorphic serialization, (2) change '{1}' to a concrete type, or (3) exclude it with [AcBinaryIgnore].",
|
||||
category: "AcBinarySerializer",
|
||||
defaultSeverity: DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true);
|
||||
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
var classDeclarations = context.SyntaxProvider
|
||||
|
|
@ -406,6 +433,7 @@ public class AcBinarySourceGenerator : IIncrementalGenerator
|
|||
if (valid.Count == 0) return;
|
||||
|
||||
DetectAndReportCycles(valid, context);
|
||||
DetectAndReportPolymorphicMisuse(valid, context);
|
||||
|
||||
foreach (var ci in valid)
|
||||
{
|
||||
|
|
@ -416,6 +444,30 @@ public class AcBinarySourceGenerator : IIncrementalGenerator
|
|||
context.AddSource("AcBinaryGeneratedWriters_Init.g.cs", SourceText.From(GenInit(valid), Encoding.UTF8));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ACCORE-BIN-I-T7K3 guard: emits <see cref="PolymorphicPropertyWithFeatureDisabledError"/>
|
||||
/// (ACBIN002) for every <c>System.Object</c>-declared property on any
|
||||
/// <c>[AcBinarySerializable]</c> type while <see cref="UsePolymorphType"/> is <c>false</c>.
|
||||
/// Short-circuits when the feature is enabled — no per-property work needed.
|
||||
/// </summary>
|
||||
private static void DetectAndReportPolymorphicMisuse(List<SerializableClassInfo> classes, SourceProductionContext spc)
|
||||
{
|
||||
if (UsePolymorphType) return; // Feature enabled → polymorphic prefix is emitted, no misuse possible.
|
||||
|
||||
foreach (var ci in classes)
|
||||
{
|
||||
foreach (var p in ci.Properties)
|
||||
{
|
||||
if (p.IsObjectDeclaredType)
|
||||
{
|
||||
spc.ReportDiagnostic(Diagnostic.Create(
|
||||
PolymorphicPropertyWithFeatureDisabledError, Location.None,
|
||||
ci.ClassName, p.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detects circular reference chains among [AcBinarySerializable] types at compile time
|
||||
/// and reports ACBIN001 warnings. Uses DFS with 3-color marking to find back-edges.
|
||||
|
|
|
|||
Loading…
Reference in New Issue