Zomp.MethodCloning
1.0.20-alpha
dotnet add package Zomp.MethodCloning --version 1.0.20-alpha
NuGet\Install-Package Zomp.MethodCloning -Version 1.0.20-alpha
<PackageReference Include="Zomp.MethodCloning" Version="1.0.20-alpha"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="Zomp.MethodCloning" Version="1.0.20-alpha" />
<PackageReference Include="Zomp.MethodCloning"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add Zomp.MethodCloning --version 1.0.20-alpha
#r "nuget: Zomp.MethodCloning, 1.0.20-alpha"
#:package Zomp.MethodCloning@1.0.20-alpha
#addin nuget:?package=Zomp.MethodCloning&version=1.0.20-alpha&prerelease
#tool nuget:?package=Zomp.MethodCloning&version=1.0.20-alpha&prerelease
Zomp.MethodCloning
The plumbing for source generators that copy a method and change it.
Copying a method into a generated file sounds easy until the copy has to compile there. This package handles that part, so your generator only contains the change you actually want to make.
It powers Zomp.SyncMethodGenerator, which turns async methods into sync ones, and Zomp.MethodCloning.Variants, which replaces T4 templates.
What you get
| Piece | Does |
|---|---|
CloneTarget |
Finds the methods your attribute marks, on the method or its type |
MethodLocation |
Collects the namespaces, usings and partial types the copy needs |
CloningRewriter |
Fully qualifies every name, so the copy compiles anywhere |
ClonedMethodOutput |
Names the files, catches colliding copies and adds the output |
You derive from CloningRewriter, override what you change, and use its MapSymbol, MapTypeName and MapMemberName hooks to substitute types and names.
A whole generator, sketched
[Generator]
public sealed class CopyGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var copies = CloneTarget.ForAttribute(context.SyntaxProvider, "My.CopyAttribute")
.Select(static (target, ct) => Copy(target)!)
.Where(static copy => copy is not null);
ClonedMethodOutput.Register(context, copies, MyDiagnostics.Collision);
}
private static ClonedMethod? Copy(CloneTarget target)
{
var symbol = (IMethodSymbol)target.Context.TargetSymbol;
if (!MethodLocation.TryCreate(target.Syntax, symbol, out var location, out var root))
{
return null;
}
var copy = new RenameRewriter(target.Context.SemanticModel, target.Syntax).Visit(root);
return ClonedMethod.Create(location, target.Syntax, copy, disableNullable: false, ImmutableArray<ReportedDiagnostic>.Empty);
}
}
internal sealed class RenameRewriter(SemanticModel model, MethodDeclarationSyntax method)
: CloningRewriter(model, method)
{
public override SyntaxNode? VisitMethodDeclaration(MethodDeclarationSyntax node)
=> base.VisitMethodDeclaration(node) is MethodDeclarationSyntax copy
? copy.WithIdentifier(SyntaxFactory.Identifier(node.Identifier.ValueText + "Copy"))
: null;
}
Install
<PackageReference Include="Zomp.MethodCloning" PrivateAssets="all" />
It ships as source: the files compile into your generator as internal types. There is no DLL to bundle into analyzers/, and two generators can never disagree about its version.
Requirements
- C# 12 or later in the generator project.
- On
netstandard2.0, PolySharp for polyfills such asIsExternalInit. - Roslyn 4.8 or later. Define
ROSLYN_4_12_OR_GREATERorROSLYN_5_0_OR_GREATERwhen you compile against those, to get the newer code paths.
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.20-alpha | 0 | 9/13/2026 |