Skip to content

Fix StaticGenerator to skip indexers, init-only properties - #1132

Open
frg2089 wants to merge 5 commits into
aaubry:masterfrom
frg2089:patch/generator
Open

frg2089 wants to merge 5 commits into
aaubry:masterfrom
frg2089:patch/generator

Conversation

@frg2089

@frg2089 frg2089 commented Sep 4, 2026 •

Copy link
Copy Markdown

Motivation

YamlDotNet.Analyzers.StaticGenerator was generating invalid C# code when encountering certain class members:

  1. Indexer properties (this[]) were included in generated IObjectAccessor switch statements, producing invalid code like case "this": v.this[] = ...
  2. Init-only properties were included in the Set method generation, but init accessors cannot be set after construction

Solution

  • Filter out IPropertySymbol.IsIndexer properties in SerializableSyntaxReceiver
  • Skip properties where SetMethod.IsInitOnly is true in ObjectAccessorFileGenerator and StaticTypeInspectorFile
  • Add <auto-generated> header and #pragma warning disable CS1591 to the generated source file so analyzers properly skip it

Changes

  • SerializableSyntaxReceiver.cs - Skip indexer properties
  • ObjectAccessorFileGenerator.cs - Skip init-only setters
  • StaticTypeInspectorFile.cs - Mark init-only properties as read-only
  • TypeFactoryGenerator.cs - Add auto-generated header and CS1591 pragma

…ration

Indexers have IPropertySymbol.Name == 'this' and IsIndexer == true. Including them causes the generator to emit invalid C# like 'case this[]: v.this[] = ...'. Filter out indexers by checking IsIndexer before adding them to PropertySymbols.
Init-only properties have SetMethod.IsInitOnly == true and cannot be set via IObjectAccessor.Set. Mark them as read-only in StaticTypeInspector and exclude them from setter generation in ObjectAccessorFileGenerator.
… Create

Classes without a parameterless constructor cannot be instantiated with new ClassName(). Add HasParameterlessConstructor property to ClassObject and filter them out in StaticObjectFactory.Create to avoid generating invalid new expressions.
Add the auto-generated comment block and disable CS1591 warning for the generated source file so analyzers properly skip analysis.
Copilot AI lite review requested due to automatic review settings September 4, 2026 13:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new factory filtering can unintentionally drop collection interface overrides and the parameterless-constructor check can still allow types that will generate uncompilable new T() calls.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR updates YamlDotNet.Analyzers.StaticGenerator to avoid generating invalid/unsupported C# for certain members and types (indexers, init-only properties, and types that can’t be instantiated), and to mark generated output as auto-generated to reduce analyzer noise.

Changes:

  • Excludes indexer properties from the serializable member set and skips init-only setters in generated object accessors.
  • Treats init-only properties as read-only in the generated type inspector metadata.
  • Filters StaticObjectFactory.Create registrations based on a new HasParameterlessConstructor flag and adds an auto-generated header + CS1591 suppression to generated sources.
File summaries
File Description
YamlDotNet.Analyzers.StaticGenerator/TypeFactoryGenerator.cs Adds auto-generated header and disables CS1591 in generated output.
YamlDotNet.Analyzers.StaticGenerator/StaticTypeInspectorFile.cs Marks init-only properties as read-only in generated property descriptors.
YamlDotNet.Analyzers.StaticGenerator/StaticObjectFactoryFile.cs Filters factory Create registrations based on parameterless-constructor availability.
YamlDotNet.Analyzers.StaticGenerator/SerializableSyntaxReceiver.cs Skips indexer properties when collecting serializable members.
YamlDotNet.Analyzers.StaticGenerator/ObjectAccessorFileGenerator.cs Avoids generating setters for init-only properties.
YamlDotNet.Analyzers.StaticGenerator/ClassObject.cs Introduces HasParameterlessConstructor used to decide whether types can be instantiated.
Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

bool isListOverride = false,
bool isDictionaryOverride = false)
{
HasParameterlessConstructor = moduleSymbol is INamedTypeSymbol namedTypeSymbol && namedTypeSymbol.InstanceConstructors.Any(c => c.Parameters.Length == 0);
Write("public override object Create(Type type)");
Write("{"); Indent();
foreach (var o in syntaxReceiver.Classes.Where(c => !c.Value.IsArray))
foreach (var o in syntaxReceiver.Classes.Where(c => !c.Value.IsArray && c.Value.HasParameterlessConstructor))
foreach (var property in classObject.PropertySymbols)
{
if (property.SetMethod != null)
if (property.SetMethod != null && !property.SetMethod.IsInitOnly)
Comment on lines +99 to 102
write("#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member", true);
write("#pragma warning disable CS8767 // Nullability of reference types", true);
write("#pragma warning disable CS8767 // Nullability of reference types", true);
write("#pragma warning disable CS8603 // Possible null reference return", true);
@frg2089 frg2089 changed the title Fix StaticGenerator to skip indexers, init-only properties, and classes without parameterless constructors Fix StaticGenerator to skip indexers, init-only properties Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants