Skip to content

Add IncludeSubtypes to enable subtype cloning for non-abstract classes#44

Open
MizardX wants to merge 3 commits into
lofcz:nextfrom
MizardX:derived-types
Open

Add IncludeSubtypes to enable subtype cloning for non-abstract classes#44
MizardX wants to merge 3 commits into
lofcz:nextfrom
MizardX:derived-types

Conversation

@MizardX

@MizardX MizardX commented Jun 4, 2026

Copy link
Copy Markdown

This was written using mostly AI supervised by me.

Introduce IncludeSubtypes property to FastClonerClonableAttribute, allowing non-abstract base classes to opt into runtime subtype dispatch for FastDeepClone. Update code generation and type modeling to support this feature. Add documentation and tests to demonstrate and verify the new behavior.

[FastClonerClonable(IncludeSubtypes = true)]
public class Device
{
    public string Name { get; set; }
}

public class Phone : Device
{
    public string OS { get; set; }
}

Device device = new Phone { Name = "Pixel", OS = "Android" };
Device clone = device.FastDeepClone(); // Returns a cloned Phone

Closes #43

Introduce IncludeSubtypes property to FastClonerClonableAttribute, allowing non-abstract base classes to opt into runtime subtype dispatch for FastDeepClone. Update code generation and type modeling to support this feature. Add documentation and tests to demonstrate and verify the new behavior.
Copilot AI review requested due to automatic review settings June 4, 2026 15:32

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.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds opt-in runtime subtype dispatch for non-abstract base classes via a new IncludeSubtypes flag on [FastClonerClonable], and validates the behavior with new tests and documentation.

Changes:

  • Introduces FastClonerClonableAttribute.IncludeSubtypes and threads it through the source generator TypeModel.
  • Generates subtype-dispatch cloning code for non-abstract (class) roots when IncludeSubtypes = true.
  • Adds tests + README docs demonstrating/validating the new dispatch behavior.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/FastCloner.Tests/AbstractClassTests.cs Adds test fixtures and new tests covering IncludeSubtypes on concrete bases.
src/FastCloner.SourceGenerator/TypeModelFactory.cs Reads IncludeSubtypes from the attribute and triggers derived-type collection for dispatch.
src/FastCloner.SourceGenerator/TypeModel.cs Adds IncludeSubtypes to the generator’s type model.
src/FastCloner.SourceGenerator/ImplicitTypeAnalyzer.cs Updates TypeModel construction to use named args after adding a new record parameter.
src/FastCloner.SourceGenerator/DerivedTypeCollector.cs Updates TypeModel construction with named args (avoid positional mismatch).
src/FastCloner.SourceGenerator/CloneCodeGenerator.cs Implements generalized subtype dispatcher and uses it for abstract + opted-in concrete base classes.
src/FastCloner.SourceGenerator.Shared/FastClonerClonableAttribute.cs Adds the public IncludeSubtypes attribute property with XML docs.
README.md Documents opt-in subtype dispatch for non-abstract bases with an example.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/FastCloner.SourceGenerator/TypeModelFactory.cs Outdated
Comment thread src/FastCloner.SourceGenerator/TypeModelFactory.cs Outdated
Comment thread src/FastCloner.SourceGenerator/CloneCodeGenerator.cs
Comment thread src/FastCloner.SourceGenerator/CloneCodeGenerator.cs
Comment thread README.md
@lofcz

lofcz commented Jun 4, 2026

Copy link
Copy Markdown
Owner

@MizardX please be transparent about using AI. One simple way is to add a disclaimer to the top of the description.

Copilot AI review requested due to automatic review settings June 4, 2026 17:03

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.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (1)

src/FastCloner.SourceGenerator/TypeModelFactory.cs:1

  • This enumerates symbol.GetAttributes() multiple times and relies on ToDisplayString() string comparisons, which can add noticeable overhead in large solutions. Consider iterating attributes once and/or resolving attribute symbols via compilation.GetTypeByMetadataName(...) and comparing with SymbolEqualityComparer.Default to avoid repeated allocations.
using System;

Comment thread src/FastCloner.SourceGenerator/CloneCodeGenerator.cs
Comment thread src/FastCloner.SourceGenerator/CloneCodeGenerator.cs
Comment thread README.md
@MizardX

MizardX commented Jun 6, 2026

Copy link
Copy Markdown
Author

CI failed because of "Resource not accessible by integration". All builds and test either succeeded or were cancelled.

The Github token normally does not have permission to update the status of foreign commits (from PR's). Your current action Sibz/github-status-action@v1 tries anyway. The Github action set-commit-status instead skips this by default, unless the allowForks flag is set.

I tested the changes in this PR in my own project, and it seems to work as expected.

The only question is if [FastClonerClonable(IncludeSubtypes = true)] is the way to want specify this?

@MizardX

MizardX commented Jun 20, 2026

Copy link
Copy Markdown
Author

bump

Is there something that I must change? Is there some part you are unhappy about?

@lofcz

lofcz commented Jun 20, 2026

Copy link
Copy Markdown
Owner

hey, sorry about not replying earlier, I don't particularly like how this works, will need to think it trough. On the public API level and ergonomics . The request is valid but I wonder if there is a clearer way to go about it.

@MizardX

MizardX commented Jun 20, 2026

Copy link
Copy Markdown
Author

System.Text.Json has [JsonPolymorphic] and [JsonDerivedType]. [JsonPolymorphic] lets you specify what should happen for an unknown subtype via the JsonUnknownDerivedTypeHandling property. There is no automatic discovery of subtypes, so you have to list them with [JsonDerivedType].

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.

Cloning of subtypes on non-abstract type

3 participants