Skip to content

Commit

Permalink
Migrate to IIncrementalGenerator
Browse files Browse the repository at this point in the history
  • Loading branch information
Emik03 committed Oct 4, 2023
1 parent 3b1b150 commit 55407dc
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Remove="UnitGenerator"/>
<Compile Remove="$(Morsels)/Compile/**/*.cs"/>
<!-- <Compile Remove="$(Morsels)/Compile/**/*.cs"/>-->
<PackageReference Include="Emik.Unions" Version="2.1.1" PrivateAssets="all"/>
<PackageReference Include="Emik.Results" Version="2.1.1" PrivateAssets="all"/>
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Emik.SourceGenerators.Implicit.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<FileVersion>1.0.1</FileVersion>
<FileVersion>1.0.2</FileVersion>
<TargetFramework>netstandard2.0</TargetFramework>
<DisableDefaultDocumentation>true</DisableDefaultDocumentation>
<RepositoryUrl>https://github.com/Emik03/Emik.SourceGenerators.Implicit</RepositoryUrl>
Expand Down
22 changes: 22 additions & 0 deletions Emik.SourceGenerators.Implicit.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emik.SourceGenerators.Implicit", "Emik.SourceGenerators.Implicit.csproj", "{CD4C0027-DFD7-4C9A-B428-E5158E3D8B4A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emik.SourceGenerators.Implicit.Generated.Tests", "Emik.SourceGenerators.Implicit.Generated.Tests\Emik.SourceGenerators.Implicit.Generated.Tests.csproj", "{F97EB80D-9710-4130-BCD8-02E948B95E0F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CD4C0027-DFD7-4C9A-B428-E5158E3D8B4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CD4C0027-DFD7-4C9A-B428-E5158E3D8B4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CD4C0027-DFD7-4C9A-B428-E5158E3D8B4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CD4C0027-DFD7-4C9A-B428-E5158E3D8B4A}.Release|Any CPU.Build.0 = Release|Any CPU
{F97EB80D-9710-4130-BCD8-02E948B95E0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F97EB80D-9710-4130-BCD8-02E948B95E0F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F97EB80D-9710-4130-BCD8-02E948B95E0F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F97EB80D-9710-4130-BCD8-02E948B95E0F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

42 changes: 20 additions & 22 deletions Source/OperatorGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,29 @@
namespace Emik.SourceGenerators.Implicit;

/// <summary>The source generator that implements implicit operators.</summary>
#pragma warning disable RS1038
[Generator]
#pragma warning restore RS1038
public sealed class OperatorGenerator : ISourceGenerator
public sealed class OperatorGenerator : IIncrementalGenerator
{
/// <inheritdoc />
void ISourceGenerator.Execute(GeneratorExecutionContext context) =>
#if DEBUG
new BadLogger().Try(Go, context).Dispose();
#else
Go(context);
#endif
void IIncrementalGenerator.Initialize(IncrementalGeneratorInitializationContext context)
{
var typeProvider = context.SyntaxProvider.CreateSyntaxProvider(Is<BaseTypeDeclarationSyntax>, Target).Filter();
var provider = context.CompilationProvider.Combine(typeProvider.Collect());
context.RegisterSourceOutput(provider, Go);
}

/// <inheritdoc />
void ISourceGenerator.Initialize(GeneratorInitializationContext context) { }
static void Go(SourceProductionContext context, (Compilation Left, ImmutableArray<INamedTypeSymbol> Right) tuple)
{
var (compilation, types) = tuple;

foreach (var type in types)
if (type.Source(compilation) is { } source && type.HintName() is var hintName)
context.AddSource(hintName, source);
}

static void Go(GeneratorExecutionContext context) =>
context
.Compilation
.GetSymbolsWithName(_ => true, cancellationToken: context.CancellationToken)
.OfType<INamedTypeSymbol>()
.Where(SymbolPredicates.IsCandidate)
.Select(x => (x, Source: x.Source(context.Compilation)))
.Where(x => x.Source is not null)
.Select(x => (HintName: x.x.HintName(), x.Source))
.Lazily(x => context.AddSource(x.HintName, x.Source ?? throw Unreachable))
.Enumerate();
static INamedTypeSymbol? Target(GeneratorSyntaxContext context, CancellationToken token) =>
context.SemanticModel.GetSymbolInfo(context.Node, token).Symbol is INamedTypeSymbol { IsTupleType: false } x &&
x.IsCandidate()
? x
: null;
}
7 changes: 2 additions & 5 deletions Source/ParameterizedInterpolatedStringHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,9 @@ namespace Emik.SourceGenerators.Implicit;
/// <param name="formattedCount">The number of interpolation expressions in the interpolated string.</param>
// ReSharper disable ConvertClosureToMethodGroup
[InterpolatedStringHandler]
readonly ref struct ParameterizedInterpolatedStringHandler(
int literalLength,
[UsedImplicitly] int formattedCount
)
readonly ref struct ParameterizedInterpolatedStringHandler(int literalLength, int formattedCount)
{
readonly StringBuilder _builder = new(literalLength);
readonly StringBuilder _builder = new(literalLength + formattedCount);

/// <summary>Writes the specified string to the handler.</summary>
/// <param name="value">The string to write.</param>
Expand Down
8 changes: 4 additions & 4 deletions Source/SymbolStringifiers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ public static string HintName(this INamedTypeSymbol symbol) =>
/// <param name="compilation">The compilation that contains references to ValueTuple.</param>
/// <returns>The source of the parameter <paramref name="symbol"/>.</returns>
[Pure]
public static string? Source(this INamedTypeSymbol symbol, Compilation compilation) =>
public static string? Source(this INamedTypeSymbol? symbol, Compilation compilation) =>
Make(symbol, compilation) is { } initial
? (symbol as ISymbol)
? ((ISymbol?)symbol)
.FindPathToNull(x => x.ContainingWithoutGlobal())
.Aggregate(initial, Next)
.Then(HeaderAndFooter)
: null;

[Pure]
static string? Make(INamedTypeSymbol type, Compilation compilation)
static string? Make(INamedTypeSymbol? type, Compilation compilation)
{
const int MaxTypeParametersInValueTuple = 8;

Expand All @@ -46,7 +46,7 @@ bool LacksRequiredValueTupleReference(IMethodSymbol method) =>
compilation.GetTypeByMetadataName($"{nameof(System)}.{nameof(ValueTuple)}`{length}") is null;

return type
.InstanceConstructors
?.InstanceConstructors
.Where(type.IsRelativelyAccessible)
.Omit(type.HasEmptyParametersOrSingleInterfaceOrSingleSelf)
.Omit(type.HasSameParameters)
Expand Down

0 comments on commit 55407dc

Please sign in to comment.