- Benchmark charset profiles are now length-consistent: all *Short = 40 chars, all *Long = 280 chars, across ASCII, Latin1, CJK BMP, Cyrillic, and Mixed. - `CharsetSuffixes` was rewritten with new profiles and base-string repetition for compile-time constants. - Menu/configuration updated for new profiles, selection logic, and improved descriptions. - Docs updated to reflect new profiles, lengths, and serialization tier impacts. - `StringSmall` deserialization split into `ReadStringSmallCompact` and `ReadStringSmallFastWire`; all call sites now dispatch by mode, clarifying the hot path. - SGen codegen and runtime dispatch tables updated for the new decode split. - Binary marker docs clarified: only Intern/Metadata/Polymorph features are wire-symmetric for reader case omission; RefHandling is not. - Added `BINARY_STRICT_SGEN.md` planning doc for a SGen-only, attribute-required, AOT-friendly NuGet package. |
||
|---|---|---|
| .. | ||
| AcBinarySourceGenerator.Diagnostics.cs | ||
| AcBinarySourceGenerator.GenInit.cs | ||
| AcBinarySourceGenerator.GenReader.cs | ||
| AcBinarySourceGenerator.GenWriter.cs | ||
| AcBinarySourceGenerator.GetClassInfo.cs | ||
| AcBinarySourceGenerator.Models.cs | ||
| AcBinarySourceGenerator.TypeAnalysis.cs | ||
| AcBinarySourceGenerator.cs | ||
| AyCode.Core.Serializers.SourceGenerator.csproj | ||
| README.md | ||
README.md
AyCode.Core.Serializers.SourceGenerator
Roslyn incremental source generator that produces optimized IGeneratedBinaryWriter and IGeneratedBinaryReader implementations for types marked with [AcBinarySerializable]. Eliminates runtime reflection on serialization hot paths.
Targets netstandard2.0 (required for Roslyn analyzers/generators).
Key Files
AcBinarySourceGenerator.cs— Single-fileIIncrementalGenerator(~2100 lines). Generates:{ClassName}_GeneratedWriter— Per-type writer withScanObject()+WriteProperties()methods. Handles primitives, strings (with interning), collections, dictionaries, complex nested types, and polymorphic objects.{ClassName}_GeneratedReader— Per-type reader withReadProperties()method.ModuleInitializer— Auto-registers all generated writers/readers at startup.- Circular reference detection with
ACBIN001diagnostic warning.
Slot Allocation
Each generated writer reserves a unique type slot via AcBinarySerializer.AllocateWrapperSlot() (static field initializer, Interlocked.Increment).
- Slots 0–63 — reserved for runtime polymorphic types (assigned dynamically on first encounter)
- Slots 64+ — source-generated types (allocated at
[ModuleInitializer]registration time)
Slot indices are NOT stable across compilations. The order depends on Roslyn's ForAttributeWithMetadataName() enumeration order, which may vary between builds. This is fine because slots are only meaningful within a single serialization/deserialization session — they are never persisted to disk or sent over the wire as slot indices (the wire format uses type names or metadata hashes for cross-session/cross-type compatibility).
Feature Flags
The [AcBinarySerializable] attribute supports per-type feature control:
enableMetadata— Property hash metadata for cross-type deserializationenableIdTracking— IId-based reference trackingenableRefHandling— General reference trackingenableInternString— String interning/deduplication
Disabled features eliminate corresponding code blocks from generated output (zero dead code).
Dependencies
| Dependency | Purpose |
|---|---|
Microsoft.CodeAnalysis.CSharp |
Roslyn syntax/semantic APIs |
Microsoft.CodeAnalysis.Analyzers |
Analyzer best practices |