You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Derived generated class in another assembly loses MarkDirty() in setters (SG3019): base [DirtyTrackingEntity] is not visible across assemblies #58
A [SerializationGenerator] class that derives from a generated, non-ISerializable class in another assembly gets generated setters with no MarkDirty() call, and the build fails with SG3019 (no dirty-tracking target). Within one assembly the same hierarchy works.
Where
SerializableEntityGeneration.BuildModel.cs resolves the dirty-tracking target for a derived class by walking classSymbol.BaseType?.HasDirtyTrackingEntity(compilation), which looks for the [DirtyTrackingEntity] field/property on the base. That member is private on the base (e.g. SpawnerEntry._parent), and private members of a referenced assembly are not imported into the compilation's metadata symbols, so the lookup finds nothing. Inheritance chaining itself works (the derived Serialize/Deserialize are emitted as override and call base.…; pinned by the NestedInheritance snapshot, #56), only the dirty-tracking resolution fails.
Observed
// Assembly B, base in assembly A (ModernUO UOContent)[SerializationGenerator(0)]publicpartialclassModernSpawnerEntry:SpawnerEntry{[SerializableField(0)]privatestring_script;// generated setter has no MarkDirty(); SG3019}
Workaround adopted in modernuo/ModernUO#2621: the base exposes protected BaseSpawner Parent => _parent; and every out-of-tree subclass re-declares [DirtyTrackingEntity] private BaseSpawner Owner => Parent;. That works but duplicates the declaration and produces a second, hiding MarkDirty() on the subclass.
Proposed fix
When the base type is generator-attributed (IsSerializableRecursive) but its [DirtyTrackingEntity] member is not visible, use the base's generated public virtual void MarkDirty() as the dirty target (it is public and always emitted for a tracked class): set markDirtyMethod = "MarkDirty()" and emitMarkDirtyMethod = false. Add a snapshot or compilation test with the base in a separate MetadataReference to cover the cross-assembly case, since the in-assembly NestedInheritance fixture cannot reproduce it.
Activity