Source Generation
Intellenum leverages source generation to produce optimized enum implementations at compile time. This approach offers several advantages:
- Performance Optimization: Generated code is tailored to the specific enum, eliminating the overhead associated with reflection-based approaches.
- Code Clarity: The generated code is concise and readable, enhancing maintainability.
- Type Safety: Source generation enables compile-time validation of enum values, ensuring type safety and preventing runtime errors.
Generation Process
The core of Intellenum’s source generation is implemented in the src/Intellenum/Generators
directory. This directory houses the source generator’s logic, responsible for transforming user-defined enums into optimized implementations.
Example
Consider the following enum:
using Intellenum;
namespace Whatever;
[Intellenum(typeof(int))]
public partial class SomeEnum
{
public const int Value1 = 1;
public const int Value2 = 2;
}
Upon compilation, Intellenum’s source generator would analyze the enum and generate the following code:
// <auto-generated/>
#nullable enable
namespace Whatever
{
public partial class SomeEnum
{
private static readonly SomeEnum[] _values = new SomeEnum[]
{
new SomeEnum(1),
new SomeEnum(2)
};
private readonly int _value;
public SomeEnum(int value)
{
_value = value;
}
// Generated methods and properties for accessing and comparing enum values
// ...
}
}
The generated code includes:
- A private array containing all enum instances.
- A private field holding the underlying value for each instance.
- Methods and properties for accessing and comparing enum values.
Options
Source generation in Intellenum is highly customizable, allowing developers to fine-tune the generated code using a range of options:
- Underlying Type: Users can specify the underlying data type for the enum using the
Intellenum
attribute. For instance, to useint
as the underlying type:[Intellenum(typeof(int))] public partial class SomeEnum { // ... }
- Member Definitions: Individual members of the enum can be defined using the
Member
attribute. This attribute allows specifying both the member name and its underlying value. For example:[Intellenum(typeof(int))] [Member(name: "MyValue", value: 1)] public partial class SomeEnum { // ... }
- Static Members: Static members can be added to the generated code to provide access to various utilities related to the enum. For example:
using Intellenum; namespace Whatever { [Intellenum(typeof(int))] [Member("Value1", 1)] public partial class SomeEnum { public static SomeEnum Create(int value) { return new SomeEnum(value); } } }
Testing
Testing source generators presents unique challenges, as generators are invoked by the IDE rather than directly from code. Intellenum utilizes several techniques for testing:
- Snapshot Tests: Snapshot tests, found in the
tests/SnapshotTests
directory, create in-memory projects to exercise the generators under different configurations. These tests ensure the consistency of generated code across various frameworks and settings. - Consumer Tests: Consumer tests, located in the
tests/ConsumerTests
directory, validate the generated code by using it within applications. These tests verify that the generated code behaves as expected in real-world scenarios.
Examples
Refer to the samples
directory for illustrative examples showcasing Intellenum’s source generation capabilities and the variety of options available.
References
- Intellenum Project
- Intellenum.Examples
- Testing Documentation
- Intellenum Documentation
- Benchmarks Project
- EF Core Tips Documentation
- Testbench Project
- Installation Documentation
- ConsumerTests Project
- ProjectBuilder.cs
- SnippetGenerationFactory.cs
- TryParseGeneration.cs
- CompilationExtensions.cs
- IGenerateConversion.cs
- MemberGenerationTests.cs
## Top-Level Directory Explanations
<a class='local-link directory-link' data-ref="samples/" href="#samples/">samples/</a> - This directory contains example projects demonstrating the usage of Intellenum.
<a class='local-link directory-link' data-ref="samples/Intellenum.Examples/" href="#samples/Intellenum.Examples/">samples/Intellenum.Examples/</a> - Contains various example projects demonstrating different aspects of Intellenum, such as serialization, conversion, syntax examples, types, typical scenarios, and more.
<a class='local-link directory-link' data-ref="samples/WebApplication/" href="#samples/WebApplication/">samples/WebApplication/</a> - Contains a sample web application that uses Intellenum.
<a class='local-link directory-link' data-ref="src/" href="#src/">src/</a> - This directory contains the source code of the Intellenum library.
<a class='local-link directory-link' data-ref="src/Benchmarks/" href="#src/Benchmarks/">src/Benchmarks/</a> - Contains benchmark tests for the Intellenum library.
<a class='local-link directory-link' data-ref="src/Intellenum.CodeFixers/" href="#src/Intellenum.CodeFixers/">src/Intellenum.CodeFixers/</a> - Contains code fixers for the Intellenum library.
<a class='local-link directory-link' data-ref="src/Intellenum.SharedTypes/" href="#src/Intellenum.SharedTypes/">src/Intellenum.SharedTypes/</a> - Contains shared types used across the Intellenum library.
<a class='local-link directory-link' data-ref="src/Intellenum/" href="#src/Intellenum/">src/Intellenum/</a> - Contains the main source code for the Intellenum library. This directory is further divided into subdirectories for diagnostics, extensions, generators, member building, properties, rules, static constructor building, templates, and more.
<a class='local-link directory-link' data-ref="tests/" href="#tests/">tests/</a> - This directory contains test projects for the Intellenum library.
<a class='local-link directory-link' data-ref="tests/AnalyzerTests/" href="#tests/AnalyzerTests/">tests/AnalyzerTests/</a> - Contains unit tests for the Intellenum analyzer.
<a class='local-link directory-link' data-ref="tests/ConsumerTests/" href="#tests/ConsumerTests/">tests/ConsumerTests/</a> - Contains tests for consuming the Intellenum library.
<a class='local-link directory-link' data-ref="tests/Intellenum.Tests/" href="#tests/Intellenum.Tests/">tests/Intellenum.Tests/</a> - Contains additional tests for the Intellenum library.
<a class='local-link directory-link' data-ref="tests/Shared/" href="#tests/Shared/">tests/Shared/</a> - Contains shared test files.
<a class='local-link directory-link' data-ref="tests/SnapshotTests/" href="#tests/SnapshotTests/">tests/SnapshotTests/</a> - Contains snapshot tests for the Intellenum library.