Skip to content

Commit 56591ec

Browse files
authored
Incremental Generators (#1)
* changing pipeline for better caching * records
1 parent b6d13d2 commit 56591ec

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+5220
-5168
lines changed

Strongly.sln

+16-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 16
4-
VisualStudioVersion = 16.0.28803.352
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.5.33424.131
55
MinimumVisualStudioVersion = 15.0.26124.0
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EE1258BD-3422-4F55-B9CF-B4D6C95DAD68}"
77
EndProject
@@ -14,15 +14,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1414
version.props = version.props
1515
EndProjectSection
1616
EndProject
17-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Strongly", "src\Strongly\Strongly.csproj", "{9C0F3A36-ED47-4D0F-B736-EFC559C9E2DA}"
17+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strongly", "src\Strongly\Strongly.csproj", "{9C0F3A36-ED47-4D0F-B736-EFC559C9E2DA}"
1818
EndProject
19-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Strongly.Tests", "test\Strongly.Tests\Strongly.Tests.csproj", "{09F7364F-8CE9-4E9D-9BB7-B4CEBF682904}"
19+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strongly.Tests", "test\Strongly.Tests\Strongly.Tests.csproj", "{09F7364F-8CE9-4E9D-9BB7-B4CEBF682904}"
2020
EndProject
2121
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "build\_build.csproj", "{E13FB452-2D47-4719-8BAA-7B695D79AF3A}"
2222
EndProject
23-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Strongly.Attributes", "src\Strongly.Attributes\Strongly.Attributes.csproj", "{F25F6E67-E62A-4075-86CF-4C4EDD7E4883}"
23+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strongly.Attributes", "src\Strongly.Attributes\Strongly.Attributes.csproj", "{F25F6E67-E62A-4075-86CF-4C4EDD7E4883}"
2424
EndProject
25-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Strongly.EFCore", "src\Strongly.EFCore\Strongly.EFCore.csproj", "{69EA990E-9211-47FA-8715-9878C90587CF}"
25+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strongly.EFCore", "src\Strongly.EFCore\Strongly.EFCore.csproj", "{69EA990E-9211-47FA-8715-9878C90587CF}"
2626
EndProject
2727
Global
2828
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -34,8 +34,6 @@ Global
3434
Release|x86 = Release|x86
3535
EndGlobalSection
3636
GlobalSection(ProjectConfigurationPlatforms) = postSolution
37-
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38-
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
3937
{9C0F3A36-ED47-4D0F-B736-EFC559C9E2DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
4038
{9C0F3A36-ED47-4D0F-B736-EFC559C9E2DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
4139
{9C0F3A36-ED47-4D0F-B736-EFC559C9E2DA}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -60,6 +58,16 @@ Global
6058
{09F7364F-8CE9-4E9D-9BB7-B4CEBF682904}.Release|x64.Build.0 = Release|Any CPU
6159
{09F7364F-8CE9-4E9D-9BB7-B4CEBF682904}.Release|x86.ActiveCfg = Release|Any CPU
6260
{09F7364F-8CE9-4E9D-9BB7-B4CEBF682904}.Release|x86.Build.0 = Release|Any CPU
61+
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
62+
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Debug|x64.ActiveCfg = Debug|Any CPU
63+
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Debug|x64.Build.0 = Debug|Any CPU
64+
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Debug|x86.ActiveCfg = Debug|Any CPU
65+
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Debug|x86.Build.0 = Debug|Any CPU
66+
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
67+
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Release|x64.ActiveCfg = Release|Any CPU
68+
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Release|x64.Build.0 = Release|Any CPU
69+
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Release|x86.ActiveCfg = Release|Any CPU
70+
{E13FB452-2D47-4719-8BAA-7B695D79AF3A}.Release|x86.Build.0 = Release|Any CPU
6371
{F25F6E67-E62A-4075-86CF-4C4EDD7E4883}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
6472
{F25F6E67-E62A-4075-86CF-4C4EDD7E4883}.Debug|Any CPU.Build.0 = Debug|Any CPU
6573
{F25F6E67-E62A-4075-86CF-4C4EDD7E4883}.Debug|x64.ActiveCfg = Debug|Any CPU

src/Strongly.Attributes/StronglyConverter.cs

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ namespace Strongly
88
[Flags]
99
public enum StronglyConverter
1010
{
11-
// Used with HasFlag, so needs to be 1, 2, 4 etc
1211

1312
/// <summary>
1413
/// Don't create any converters for the strongly typed ID

src/Strongly.Attributes/StronglyDefaultsAttribute.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public sealed class StronglyDefaultsAttribute : Attribute
1717
/// <param name="converters">JSON library used to serialize/deserialize strongly-typed ID value.
1818
/// Defaults to <see cref="StronglyConverter.SystemTextJson"/> and <see cref="StronglyConverter.TypeConverter"/></param>
1919
/// <param name="implementations">Interfaces and patterns the strongly typed id should implement
20-
/// Defaults to <see cref="StronglyImplementations.IEquatable"/> and <see cref="StronglyImplementations.IComparable"/></param>
20+
/// Defaults to <see cref="StronglyImplementations.Parsable"/>,<see cref="StronglyImplementations.IEquatable"/> and <see cref="StronglyImplementations.IComparable"/></param>
2121
public StronglyDefaultsAttribute(
2222
StronglyType backingType = StronglyType.Default,
2323
StronglyConverter converters = StronglyConverter.Default,

src/Strongly.Attributes/StronglyImplementations.cs

+10-5
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ namespace Strongly
88
[Flags]
99
public enum StronglyImplementations
1010
{
11-
// Used with HasFlag, so needs to be 1, 2, 4 etc
12-
1311
/// <summary>
1412
/// Don't implement any additional members for the strongly typed ID
1513
/// </summary>
@@ -18,20 +16,27 @@ public enum StronglyImplementations
1816
/// <summary>
1917
/// Use the default implementations for the strongly typed Id.
2018
/// This will be the value provided in the <see cref="StronglyDefaultsAttribute"/>, which falls back to
21-
/// <see cref="IEquatable"/> and <see cref="IComparable"/>
19+
/// <see cref="Parsable"/>, <see cref="IEquatable"/> and <see cref="IComparable" />
2220
/// </summary>
2321
Default = 1,
2422

23+
// ReSharper disable once InconsistentNaming
24+
/// <summary>
25+
/// Implement the Parse/TryParse /> interface
26+
/// </summary>
27+
Parsable = 2,
28+
29+
2530
// ReSharper disable once InconsistentNaming
2631
/// <summary>
2732
/// Implement the <see cref="IEquatable{T}"/> interface
2833
/// </summary>
29-
IEquatable = 2,
34+
IEquatable = 4,
3035

3136
// ReSharper disable once InconsistentNaming
3237
/// <summary>
3338
/// Implement the <see cref="IComparable{T}"/> interface
3439
/// </summary>
35-
IComparable = 4,
40+
IComparable = 8,
3641
}
3742
}

src/Strongly.EFCore/StrongTypedValueConverterSelector.cs

+36-37
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,52 @@
33
using System.Linq;
44
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
55

6-
namespace Strongly.EFCore
7-
{
8-
using System;
6+
namespace Strongly.EFCore;
97

10-
class StrongTypedValueConverterSelector : ValueConverterSelector
11-
{
12-
readonly ConcurrentDictionary<(Type ModelClrType, Type ProviderClrType), ValueConverterInfo>
13-
converters = new();
8+
using System;
149

15-
public StrongTypedValueConverterSelector(ValueConverterSelectorDependencies dependencies) :
16-
base(
17-
dependencies)
18-
{
19-
}
10+
class StrongTypedValueConverterSelector : ValueConverterSelector
11+
{
12+
readonly ConcurrentDictionary<(Type ModelClrType, Type ProviderClrType), ValueConverterInfo>
13+
converters = new();
2014

21-
public override IEnumerable<ValueConverterInfo> Select(
22-
Type modelClrType,
23-
Type? providerClrType = null)
24-
{
25-
var baseConverters = base.Select(modelClrType, providerClrType);
26-
foreach (var converter in baseConverters)
27-
yield return converter;
15+
public StrongTypedValueConverterSelector(ValueConverterSelectorDependencies dependencies) :
16+
base(
17+
dependencies)
18+
{
19+
}
2820

29-
static Type? UnwrapNullableType(Type? type) =>
30-
type is null ? null : Nullable.GetUnderlyingType(type) ?? type;
21+
public override IEnumerable<ValueConverterInfo> Select(
22+
Type modelClrType,
23+
Type? providerClrType = null)
24+
{
25+
var baseConverters = base.Select(modelClrType, providerClrType);
26+
foreach (var converter in baseConverters)
27+
yield return converter;
3128

32-
var underlyingModelType = UnwrapNullableType(modelClrType);
33-
var underlyingProviderType = UnwrapNullableType(providerClrType);
29+
static Type? UnwrapNullableType(Type? type) =>
30+
type is null ? null : Nullable.GetUnderlyingType(type) ?? type;
3431

35-
if (underlyingProviderType is not null || underlyingModelType is null)
36-
yield break;
32+
var underlyingModelType = UnwrapNullableType(modelClrType);
33+
var underlyingProviderType = UnwrapNullableType(providerClrType);
3734

38-
var converterType = underlyingModelType.GetNestedTypes()
39-
.FirstOrDefault(t => t.IsAssignableTo(typeof(ValueConverter)));
35+
if (underlyingProviderType is not null || underlyingModelType is null)
36+
yield break;
4037

41-
if (converterType?.BaseType?.GenericTypeArguments.LastOrDefault() is not { } keyType)
42-
yield break;
38+
var converterType = underlyingModelType.GetNestedTypes()
39+
.FirstOrDefault(t => t.IsAssignableTo(typeof(ValueConverter)));
4340

44-
ValueConverter Factory(ValueConverterInfo info)
45-
{
46-
return (ValueConverter?) Activator.CreateInstance(converterType,
47-
info.MappingHints) ??
48-
throw new InvalidOperationException();
49-
}
41+
if (converterType?.BaseType?.GenericTypeArguments.LastOrDefault() is not { } keyType)
42+
yield break;
5043

51-
yield return converters.GetOrAdd((underlyingModelType, keyType),
52-
_ => new(modelClrType, keyType, Factory));
44+
ValueConverter Factory(ValueConverterInfo info)
45+
{
46+
return (ValueConverter?) Activator.CreateInstance(converterType,
47+
info.MappingHints) ??
48+
throw new InvalidOperationException();
5349
}
50+
51+
yield return converters.GetOrAdd((underlyingModelType, keyType),
52+
_ => new(modelClrType, keyType, Factory));
5453
}
5554
}

src/Strongly/Constants.cs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
namespace Strongly
1+
namespace Strongly;
2+
3+
static class Constants
24
{
3-
static class Constants
4-
{
5-
public const string Usage = nameof(Usage);
6-
}
5+
public const string Usage = nameof(Usage);
76
}
87

98
// TODO: types
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
using Microsoft.CodeAnalysis;
22

3-
namespace Strongly.Diagnostics
3+
namespace Strongly.Diagnostics;
4+
5+
static class InvalidBackingTypeDiagnostic
46
{
5-
static class InvalidBackingTypeDiagnostic
6-
{
7-
internal const string Id = "STI4";
8-
internal const string Message = "The StronglyType value provided is not a valid combination of flags";
9-
internal const string Title = "Invalid backing type";
7+
internal const string Id = "STG4";
8+
9+
internal const string Message =
10+
"The StronglyType value provided is not a valid combination of flags";
11+
12+
internal const string Title = "Invalid backing type";
1013

11-
public static Diagnostic Create(SyntaxNode currentNode) =>
12-
Diagnostic.Create(
13-
new DiagnosticDescriptor(
14-
Id, Title, Message, category: Constants.Usage, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
15-
currentNode.GetLocation());
16-
}
14+
public static Diagnostic Create(Location? location) =>
15+
Diagnostic.Create(
16+
new DiagnosticDescriptor(
17+
Id, Title, Message, category: Constants.Usage,
18+
defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
19+
location ?? Location.None);
1720
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
using Microsoft.CodeAnalysis;
22

3-
namespace Strongly.Diagnostics
3+
namespace Strongly.Diagnostics;
4+
5+
static class InvalidConverterDiagnostic
46
{
5-
static class InvalidConverterDiagnostic
6-
{
7-
internal const string Id = "STI3";
8-
internal const string Message = "The StronglyConverter value provided is not a valid combination of flags";
9-
internal const string Title = "Invalid converter";
7+
internal const string Id = "STG3";
8+
9+
internal const string Message =
10+
"The StronglyConverter value provided is not a valid combination of flags";
11+
12+
internal const string Title = "Invalid converter";
1013

11-
public static Diagnostic Create(SyntaxNode currentNode) =>
12-
Diagnostic.Create(
13-
new DiagnosticDescriptor(
14-
Id, Title, Message, category: Constants.Usage, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
15-
currentNode.GetLocation());
16-
}
14+
public static Diagnostic Create(Location? location) =>
15+
Diagnostic.Create(
16+
new DiagnosticDescriptor(
17+
Id, Title, Message, category: Constants.Usage,
18+
defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
19+
location ?? Location.None);
1720
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
using Microsoft.CodeAnalysis;
22

3-
namespace Strongly.Diagnostics
3+
namespace Strongly.Diagnostics;
4+
5+
static class InvalidImplementationsDiagnostic
46
{
5-
static class InvalidImplementationsDiagnostic
6-
{
7-
internal const string Id = "STI5";
8-
internal const string Message = "The StronglyImplementations value provided is not a valid combination of flags";
9-
internal const string Title = "Invalid implementations value";
7+
internal const string Id = "STG5";
8+
9+
internal const string Message =
10+
"The StronglyImplementations value provided is not a valid combination of flags";
11+
12+
internal const string Title = "Invalid implementations value";
1013

11-
public static Diagnostic Create(SyntaxNode currentNode) =>
12-
Diagnostic.Create(
13-
new DiagnosticDescriptor(
14-
Id, Title, Message, category: Constants.Usage, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
15-
currentNode.GetLocation());
16-
}
14+
public static Diagnostic Create(Location? currentNode) =>
15+
Diagnostic.Create(
16+
new DiagnosticDescriptor(
17+
Id, Title, Message, category: Constants.Usage,
18+
defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
19+
currentNode ?? Location.None);
1720
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
using Microsoft.CodeAnalysis;
22

3-
namespace Strongly.Diagnostics
3+
namespace Strongly.Diagnostics;
4+
5+
static class NotPartialDiagnostic
46
{
5-
static class NotPartialDiagnostic
6-
{
7-
internal const string Id = "STI2";
8-
internal const string Message = "The target of the Strongly attribute must be declared as partial.";
9-
internal const string Title = "Must be partial";
7+
internal const string Id = "STG2";
8+
internal const string Message = "The target of the Strongly attribute must be declared as partial.";
9+
internal const string Title = "Must be partial";
1010

11-
public static Diagnostic Create(SyntaxNode currentNode) =>
12-
Diagnostic.Create(
13-
new DiagnosticDescriptor(
14-
Id, Title, Message, category: Constants.Usage, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
15-
currentNode.GetLocation());
16-
}
11+
public static Diagnostic Create(SyntaxNode currentNode) =>
12+
Diagnostic.Create(
13+
new DiagnosticDescriptor(
14+
Id, Title, Message, category: Constants.Usage, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true),
15+
currentNode.GetLocation());
1716
}

0 commit comments

Comments
 (0)