Skip to content

Commit

Permalink
Incremental Generators (#1)
Browse files Browse the repository at this point in the history
* changing pipeline for better caching
* records
  • Loading branch information
lucasteles authored Mar 30, 2023
1 parent b6d13d2 commit 56591ec
Show file tree
Hide file tree
Showing 69 changed files with 5,220 additions and 5,168 deletions.
24 changes: 16 additions & 8 deletions Strongly.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.352
# Visual Studio Version 17
VisualStudioVersion = 17.5.33424.131
MinimumVisualStudioVersion = 15.0.26124.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EE1258BD-3422-4F55-B9CF-B4D6C95DAD68}"
EndProject
Expand All @@ -14,15 +14,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
version.props = version.props
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Strongly", "src\Strongly\Strongly.csproj", "{9C0F3A36-ED47-4D0F-B736-EFC559C9E2DA}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strongly", "src\Strongly\Strongly.csproj", "{9C0F3A36-ED47-4D0F-B736-EFC559C9E2DA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Strongly.Tests", "test\Strongly.Tests\Strongly.Tests.csproj", "{09F7364F-8CE9-4E9D-9BB7-B4CEBF682904}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strongly.Tests", "test\Strongly.Tests\Strongly.Tests.csproj", "{09F7364F-8CE9-4E9D-9BB7-B4CEBF682904}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "build\_build.csproj", "{E13FB452-2D47-4719-8BAA-7B695D79AF3A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Strongly.Attributes", "src\Strongly.Attributes\Strongly.Attributes.csproj", "{F25F6E67-E62A-4075-86CF-4C4EDD7E4883}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strongly.Attributes", "src\Strongly.Attributes\Strongly.Attributes.csproj", "{F25F6E67-E62A-4075-86CF-4C4EDD7E4883}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Strongly.EFCore", "src\Strongly.EFCore\Strongly.EFCore.csproj", "{69EA990E-9211-47FA-8715-9878C90587CF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strongly.EFCore", "src\Strongly.EFCore\Strongly.EFCore.csproj", "{69EA990E-9211-47FA-8715-9878C90587CF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -34,8 +34,6 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C0F3A36-ED47-4D0F-B736-EFC559C9E2DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C0F3A36-ED47-4D0F-B736-EFC559C9E2DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C0F3A36-ED47-4D0F-B736-EFC559C9E2DA}.Debug|x64.ActiveCfg = Debug|Any CPU
Expand All @@ -60,6 +58,16 @@ Global
{09F7364F-8CE9-4E9D-9BB7-B4CEBF682904}.Release|x64.Build.0 = Release|Any CPU
{09F7364F-8CE9-4E9D-9BB7-B4CEBF682904}.Release|x86.ActiveCfg = Release|Any CPU
{09F7364F-8CE9-4E9D-9BB7-B4CEBF682904}.Release|x86.Build.0 = Release|Any CPU
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Debug|x64.ActiveCfg = Debug|Any CPU
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Debug|x64.Build.0 = Debug|Any CPU
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Debug|x86.ActiveCfg = Debug|Any CPU
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Debug|x86.Build.0 = Debug|Any CPU
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Release|x64.ActiveCfg = Release|Any CPU
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Release|x64.Build.0 = Release|Any CPU
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Release|x86.ActiveCfg = Release|Any CPU
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Release|x86.Build.0 = Release|Any CPU
{F25F6E67-E62A-4075-86CF-4C4EDD7E4883}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F25F6E67-E62A-4075-86CF-4C4EDD7E4883}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F25F6E67-E62A-4075-86CF-4C4EDD7E4883}.Debug|x64.ActiveCfg = Debug|Any CPU
Expand Down
1 change: 0 additions & 1 deletion src/Strongly.Attributes/StronglyConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ namespace Strongly
[Flags]
public enum StronglyConverter
{
// Used with HasFlag, so needs to be 1, 2, 4 etc

/// <summary>
/// Don't create any converters for the strongly typed ID
Expand Down
2 changes: 1 addition & 1 deletion src/Strongly.Attributes/StronglyDefaultsAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public sealed class StronglyDefaultsAttribute : Attribute
/// <param name="converters">JSON library used to serialize/deserialize strongly-typed ID value.
/// Defaults to <see cref="StronglyConverter.SystemTextJson"/> and <see cref="StronglyConverter.TypeConverter"/></param>
/// <param name="implementations">Interfaces and patterns the strongly typed id should implement
/// Defaults to <see cref="StronglyImplementations.IEquatable"/> and <see cref="StronglyImplementations.IComparable"/></param>
/// Defaults to <see cref="StronglyImplementations.Parsable"/>,<see cref="StronglyImplementations.IEquatable"/> and <see cref="StronglyImplementations.IComparable"/></param>
public StronglyDefaultsAttribute(
StronglyType backingType = StronglyType.Default,
StronglyConverter converters = StronglyConverter.Default,
Expand Down
15 changes: 10 additions & 5 deletions src/Strongly.Attributes/StronglyImplementations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ namespace Strongly
[Flags]
public enum StronglyImplementations
{
// Used with HasFlag, so needs to be 1, 2, 4 etc

/// <summary>
/// Don't implement any additional members for the strongly typed ID
/// </summary>
Expand All @@ -18,20 +16,27 @@ public enum StronglyImplementations
/// <summary>
/// Use the default implementations for the strongly typed Id.
/// This will be the value provided in the <see cref="StronglyDefaultsAttribute"/>, which falls back to
/// <see cref="IEquatable"/> and <see cref="IComparable"/>
/// <see cref="Parsable"/>, <see cref="IEquatable"/> and <see cref="IComparable" />
/// </summary>
Default = 1,

// ReSharper disable once InconsistentNaming
/// <summary>
/// Implement the Parse/TryParse /> interface
/// </summary>
Parsable = 2,


// ReSharper disable once InconsistentNaming
/// <summary>
/// Implement the <see cref="IEquatable{T}"/> interface
/// </summary>
IEquatable = 2,
IEquatable = 4,

// ReSharper disable once InconsistentNaming
/// <summary>
/// Implement the <see cref="IComparable{T}"/> interface
/// </summary>
IComparable = 4,
IComparable = 8,
}
}
73 changes: 36 additions & 37 deletions src/Strongly.EFCore/StrongTypedValueConverterSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,52 @@
using System.Linq;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

namespace Strongly.EFCore
{
using System;
namespace Strongly.EFCore;

class StrongTypedValueConverterSelector : ValueConverterSelector
{
readonly ConcurrentDictionary<(Type ModelClrType, Type ProviderClrType), ValueConverterInfo>
converters = new();
using System;

public StrongTypedValueConverterSelector(ValueConverterSelectorDependencies dependencies) :
base(
dependencies)
{
}
class StrongTypedValueConverterSelector : ValueConverterSelector
{
readonly ConcurrentDictionary<(Type ModelClrType, Type ProviderClrType), ValueConverterInfo>
converters = new();

public override IEnumerable<ValueConverterInfo> Select(
Type modelClrType,
Type? providerClrType = null)
{
var baseConverters = base.Select(modelClrType, providerClrType);
foreach (var converter in baseConverters)
yield return converter;
public StrongTypedValueConverterSelector(ValueConverterSelectorDependencies dependencies) :
base(
dependencies)
{
}

static Type? UnwrapNullableType(Type? type) =>
type is null ? null : Nullable.GetUnderlyingType(type) ?? type;
public override IEnumerable<ValueConverterInfo> Select(
Type modelClrType,
Type? providerClrType = null)
{
var baseConverters = base.Select(modelClrType, providerClrType);
foreach (var converter in baseConverters)
yield return converter;

var underlyingModelType = UnwrapNullableType(modelClrType);
var underlyingProviderType = UnwrapNullableType(providerClrType);
static Type? UnwrapNullableType(Type? type) =>
type is null ? null : Nullable.GetUnderlyingType(type) ?? type;

if (underlyingProviderType is not null || underlyingModelType is null)
yield break;
var underlyingModelType = UnwrapNullableType(modelClrType);
var underlyingProviderType = UnwrapNullableType(providerClrType);

var converterType = underlyingModelType.GetNestedTypes()
.FirstOrDefault(t => t.IsAssignableTo(typeof(ValueConverter)));
if (underlyingProviderType is not null || underlyingModelType is null)
yield break;

if (converterType?.BaseType?.GenericTypeArguments.LastOrDefault() is not { } keyType)
yield break;
var converterType = underlyingModelType.GetNestedTypes()
.FirstOrDefault(t => t.IsAssignableTo(typeof(ValueConverter)));

ValueConverter Factory(ValueConverterInfo info)
{
return (ValueConverter?) Activator.CreateInstance(converterType,
info.MappingHints) ??
throw new InvalidOperationException();
}
if (converterType?.BaseType?.GenericTypeArguments.LastOrDefault() is not { } keyType)
yield break;

yield return converters.GetOrAdd((underlyingModelType, keyType),
_ => new(modelClrType, keyType, Factory));
ValueConverter Factory(ValueConverterInfo info)
{
return (ValueConverter?) Activator.CreateInstance(converterType,
info.MappingHints) ??
throw new InvalidOperationException();
}

yield return converters.GetOrAdd((underlyingModelType, keyType),
_ => new(modelClrType, keyType, Factory));
}
}
9 changes: 4 additions & 5 deletions src/Strongly/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
namespace Strongly
namespace Strongly;

static class Constants
{
static class Constants
{
public const string Usage = nameof(Usage);
}
public const string Usage = nameof(Usage);
}

// TODO: types
Expand Down
27 changes: 15 additions & 12 deletions src/Strongly/Diagnostics/InvalidBackingTypeDiagnostic.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
using Microsoft.CodeAnalysis;

namespace Strongly.Diagnostics
namespace Strongly.Diagnostics;

static class InvalidBackingTypeDiagnostic
{
static class InvalidBackingTypeDiagnostic
{
internal const string Id = "STI4";
internal const string Message = "The StronglyType value provided is not a valid combination of flags";
internal const string Title = "Invalid backing type";
internal const string Id = "STG4";

internal const string Message =
"The StronglyType value provided is not a valid combination of flags";

internal const string Title = "Invalid backing type";

public static Diagnostic Create(SyntaxNode currentNode) =>
Diagnostic.Create(
new DiagnosticDescriptor(
Id, Title, Message, category: Constants.Usage, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
currentNode.GetLocation());
}
public static Diagnostic Create(Location? location) =>
Diagnostic.Create(
new DiagnosticDescriptor(
Id, Title, Message, category: Constants.Usage,
defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
location ?? Location.None);
}
27 changes: 15 additions & 12 deletions src/Strongly/Diagnostics/InvalidConverterDiagnostic.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
using Microsoft.CodeAnalysis;

namespace Strongly.Diagnostics
namespace Strongly.Diagnostics;

static class InvalidConverterDiagnostic
{
static class InvalidConverterDiagnostic
{
internal const string Id = "STI3";
internal const string Message = "The StronglyConverter value provided is not a valid combination of flags";
internal const string Title = "Invalid converter";
internal const string Id = "STG3";

internal const string Message =
"The StronglyConverter value provided is not a valid combination of flags";

internal const string Title = "Invalid converter";

public static Diagnostic Create(SyntaxNode currentNode) =>
Diagnostic.Create(
new DiagnosticDescriptor(
Id, Title, Message, category: Constants.Usage, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
currentNode.GetLocation());
}
public static Diagnostic Create(Location? location) =>
Diagnostic.Create(
new DiagnosticDescriptor(
Id, Title, Message, category: Constants.Usage,
defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
location ?? Location.None);
}
27 changes: 15 additions & 12 deletions src/Strongly/Diagnostics/InvalidImplementationsDiagnostic.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
using Microsoft.CodeAnalysis;

namespace Strongly.Diagnostics
namespace Strongly.Diagnostics;

static class InvalidImplementationsDiagnostic
{
static class InvalidImplementationsDiagnostic
{
internal const string Id = "STI5";
internal const string Message = "The StronglyImplementations value provided is not a valid combination of flags";
internal const string Title = "Invalid implementations value";
internal const string Id = "STG5";

internal const string Message =
"The StronglyImplementations value provided is not a valid combination of flags";

internal const string Title = "Invalid implementations value";

public static Diagnostic Create(SyntaxNode currentNode) =>
Diagnostic.Create(
new DiagnosticDescriptor(
Id, Title, Message, category: Constants.Usage, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
currentNode.GetLocation());
}
public static Diagnostic Create(Location? currentNode) =>
Diagnostic.Create(
new DiagnosticDescriptor(
Id, Title, Message, category: Constants.Usage,
defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
currentNode ?? Location.None);
}
23 changes: 11 additions & 12 deletions src/Strongly/Diagnostics/NotPartialDiagnostic.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
using Microsoft.CodeAnalysis;

namespace Strongly.Diagnostics
namespace Strongly.Diagnostics;

static class NotPartialDiagnostic
{
static class NotPartialDiagnostic
{
internal const string Id = "STI2";
internal const string Message = "The target of the Strongly attribute must be declared as partial.";
internal const string Title = "Must be partial";
internal const string Id = "STG2";
internal const string Message = "The target of the Strongly attribute must be declared as partial.";
internal const string Title = "Must be partial";

public static Diagnostic Create(SyntaxNode currentNode) =>
Diagnostic.Create(
new DiagnosticDescriptor(
Id, Title, Message, category: Constants.Usage, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
currentNode.GetLocation());
}
public static Diagnostic Create(SyntaxNode currentNode) =>
Diagnostic.Create(
new DiagnosticDescriptor(
Id, Title, Message, category: Constants.Usage, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
currentNode.GetLocation());
}
Loading

0 comments on commit 56591ec

Please sign in to comment.