diff --git a/AyCode.Core.Serializers.SourceGenerator/AcBinarySourceGenerator.cs b/AyCode.Core.Serializers.SourceGenerator/AcBinarySourceGenerator.cs index c7556c5..fc85f56 100644 --- a/AyCode.Core.Serializers.SourceGenerator/AcBinarySourceGenerator.cs +++ b/AyCode.Core.Serializers.SourceGenerator/AcBinarySourceGenerator.cs @@ -835,6 +835,37 @@ public class AcBinarySourceGenerator : IIncrementalGenerator /// Emits direct object write — bypasses GetWrapper + WriteObject entirely. #region Scan Pass Code Generation + /// + /// Compile-time check: will EmitScanProp produce any scan work for this property? + /// When false, the entire block (including PropertyFilter guard) is skipped. + /// + private static bool HasScanWork(PropInfo p) => p.TypeKind switch + { + PropertyTypeKind.String => p.InterningFlags != 0, + PropertyTypeKind.Complex when p.HasGeneratedWriter => p.ChildNeedsScan, + PropertyTypeKind.Complex => true, + PropertyTypeKind.Collection => HasCollectionScanWork(p), + PropertyTypeKind.Dictionary => HasDictionaryScanWork(p), + _ => false + }; + + private static bool HasCollectionScanWork(PropInfo p) => p.ElementKind switch + { + PropertyTypeKind.String => p.InterningFlags != 0, + PropertyTypeKind.Complex when p.ElementHasGeneratedWriter && p.CollectionKind != null => p.ElementNeedsScan, + PropertyTypeKind.Complex => true, + _ => false + }; + + private static bool HasDictionaryScanWork(PropInfo p) + { + if (p.DictKeyKind == PropertyTypeKind.String && p.InterningFlags != 0) return true; + if (p.DictValueKind == PropertyTypeKind.String && p.InterningFlags != 0) return true; + if (p.DictValueKind == PropertyTypeKind.Complex && p.DictValueHasGeneratedWriter) return p.DictValueNeedsScan; + if (p.DictValueKind == PropertyTypeKind.Complex) return true; + return false; + } + /// /// Emits scan pass code for a single property. /// String: interning check + ScanInternString. @@ -844,6 +875,9 @@ public class AcBinarySourceGenerator : IIncrementalGenerator /// private static void EmitScanProp(StringBuilder sb, PropInfo p, string i, string fullTypeName) { + // Compile-time proven: no scan work for this property — skip entirely (including PropertyFilter guard) + if (!HasScanWork(p)) return; + var a = $"obj.{p.Name}"; // PropertyFilter: must match write pass — if filter skips property, scan must skip too