Source for the
Datacute.IncrementalGeneratorExtensions
NuGet package, which adds source files that provide additional functionality for incremental source generators in .NET.
Breaking down the tagline...
Source for the
Datacute.IncrementalGeneratorExtensions
NuGet package ...
This GitHub repository is for the development of a NuGet package named
Datacute.IncrementalGeneratorExtensions
.
... which adds source files ...
The NuGet package provides an incremental source generator, which adds source code to be compiled in with the consuming project's own source files.
... that provide additional functionality for incremental source generators in .NET.
The added source files are various extensions methods and supporting classes to help with the development of incremental source generators in .NET.
- SourceTextGenerator Base Class
- Provides a base class for incremental source generators that handles the boilerplate of generating a partial class (or similar) file for an instance of a marker attribute.
- EquatableImmutableArray
- Provides an
EquatableImmutableArray<T>
type which enables value-based equality comparison of array contents, rather than the reference equality of the array instance itself, which is whatImmutableArray<T>
uses. - Incremental source generators produce new
ImmutableArray<T>
outputs within their pipelines, and by converting these toEquatableImmutableArray<T>
instances, the pipeline stages can be correctly identified as having no changes in their output.
- Provides an
- Attribute Context and Data
- Adds types and extension methods to simplify collecting data about each use of a marker attribute.
TypeContext
captures the type information.AttributeContextAndData
captures the attribute data, which includes theTypeContext
of the type marked by the attribute, and theTypeContext
of each of the containing types.AttributeContextAndData
has a generic type argument which is your type that holds information collected for the attribute, such as its positional and named arguments.
- Indented StringBuilder
- Provides a customisable
IndentingLineAppender
class that wraps aStringBuilder
and adds auto-indentation support, making it easier to generate indented source code. - Includes a
TabIndentingLineAppender
customisation that uses tabs for indentation.
- Provides a customisable
- Lightweight Tracing
- Provides a lightweight tracing mechanism and provides an easy way to integrate
with the incremental source generator's
WithTrackingName
diagnostic mechanism. - Supports usage counters and timing logs can be included as a comment in the generated source.
- Provides a lightweight tracing mechanism and provides an easy way to integrate
with the incremental source generator's
- Pipeline Generator Stages Enum
- Provides an enum
GeneratorStage
with descriptions for each stage of the generator, which can be used to track the execution flow in the Lightweight Tracing methods.
- Provides an enum
[Generator]
public sealed class DemoGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var usages = context.SelectAttributeContexts(
"MyNamespace.GenerateSomethingAttribute",
GenerateSomethingData.Collect);
context.RegisterSourceOutput(usages, static (spc, usage) =>
{
var gen = new GenerateSomethingSource(in usage, in spc.CancellationToken);
spc.AddSource(usage.CreateHintName("GenerateSomething"), gen.GetSourceText());
});
}
}
[AttributeUsage(AttributeTargets.Class)]
public sealed class GenerateSomethingAttribute : Attribute
{
public GenerateSomethingAttribute(string name) => Name = name;
public string Name { get; }
}
sealed class GenerateSomethingData : IEquatable<GenerateSomethingData>
{
public GenerateSomethingData(string name) => Name = name;
public string Name { get; }
// Equals / GetHashCode omitted for brevity
public static GenerateSomethingData Collect(GeneratorAttributeSyntaxContext c)
=> new GenerateSomethingData((string)c.Attributes[0].ConstructorArguments[0].Value);
}
sealed class GenerateSomethingSource : SourceTextGeneratorBase<GenerateSomethingData>
{
readonly GenerateSomethingData _data;
public GenerateSomethingSource(
in AttributeContextAndData<GenerateSomethingData> usage,
in CancellationToken token)
: base(in usage, in token) => _data = usage.AttributeData;
protected override void AppendCustomMembers()
=> Buffer.AppendLine($"public static string GeneratedName => \"{_data.Name}\";");
}
When the NuGet package is installed, a README file appears in the consuming project.
That README file contains details on how to hide it, and a brief introduction to the package's contents, and some links to further documentation.
The file can be hidden by adding a property to the .csproj
file:
<PropertyGroup>
<Datacute_IncludeReadmeFile>false</Datacute_IncludeReadmeFile>
</PropertyGroup>
Each included source file is enclosed in an #if
directive:
#if !DATACUTE_EXCLUDE_LIGHTWEIGHTTRACE
// ... rest of LightweightTrace.cs file ...
#endif
To disable the inclusion of a specific source file,
define the relevant constant in the consuming project's .csproj
file:
<PropertyGroup>
<DefineConstants>$(DefineConstants);DATACUTE_EXCLUDE_LIGHTWEIGHTTRACE</DefineConstants>
</PropertyGroup>
The file will still be generated, but it will not add anything to the compilation.
Each README targets a specific audience:
README.md
(this doc)- Audience: GitHub viewers, contributors and evaluators.
- Purpose: Explain project scope, features, architecture links, build & contribution basics.
PACKAGE_README.md
- Audience: Potential NuGet consumers browsing nuget.org packages.
- Purpose: Quick value summary, barest minimal example.
content/Datacute.IncrementalGeneratorExtensions.README.md
- Audience: Existing users inside their IDE after install.
- Purpose: Fast in‑project reference: feature list, exclusion flags, how to hide file, doc links.
docs
directory- Audience: Anyone needing more detail than the brief READMEs.
- Purpose: Online extended docs for each helper.
Guideline: Depth lives in docs/
; keep package README short; keep content README scannable.
- Andrew Lock | .NET Escapades
- Series: Creating a source generator
- In particular the 'Watch out for collection types' portion of part 9 Avoiding performance pitfalls in incremental generators
Datacute - Acute Information Revelation Tools