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 use int 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


          ## 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.