Skip to content

Commit afcc578

Browse files
committed
NET7+ parsing support
1 parent 12c2206 commit afcc578

20 files changed

+175
-193
lines changed

global.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"sdk": {
3-
"version": "6.0.100",
3+
"version": "7.0.304",
44
"rollForward": "latestMinor",
55
"allowPrerelease": true
66
}

src/Strongly/EmbeddedSources.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ static class EmbeddedSources
1515
public const string ToStringKey = "[TO_STRING]";
1616
public const string DefaultToString = "Value[?].ToString()";
1717
public const string NumberStyleKey = "[NUMBER_STYLE]";
18-
public const string CtorKey = "[CTOR_VALUE]";
18+
public const string CtorValueKey = "[CTOR_VALUE]";
19+
public const string CtorKey = "[CTOR]";
1920
public const string DefaultCtor = "Value = value;";
2021

2122
internal static readonly string StronglyAttributeSource =
@@ -68,7 +69,7 @@ static class EmbeddedSources
6869
LoadEmbeddedResource("Base.Parsable_Number");
6970

7071
internal static readonly ResourceCollection GuidResources = new(
71-
typeof(Guid).FullName,
72+
typeof(Guid).FullName!,
7273
AutoGeneratedHeader,
7374
LoadEmbeddedResource("Guid.Guid_Base"),
7475
LoadEmbeddedResource("Guid.Guid_NewtonsoftJsonConverter"),
@@ -241,7 +242,7 @@ static class EmbeddedSources
241242
{
242243
TemplateVars =
243244
{
244-
[CtorKey] =
245+
[CtorValueKey] =
245246
"Value = value ?? throw new System.ArgumentNullException(nameof(value));",
246247
},
247248
};

src/Strongly/Parser.cs

+6-2
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,12 @@ public static bool IsAttributeTargetForGeneration(SyntaxNode node)
256256
break;
257257

258258
var location = attribute.ApplicationSyntaxReference?.GetSyntax(ct).GetLocation();
259-
return new StronglyConfiguration(backingType, converter, implementations, cast, math,
259+
260+
return new StronglyConfiguration(
261+
backingType,
262+
converter,
263+
implementations,
264+
cast, math,
260265
location);
261266
}
262267

@@ -312,7 +317,6 @@ or SyntaxKind.StructDeclaration
312317
or SyntaxKind.RecordDeclaration;
313318
}
314319

315-
316320
static IEnumerable<ConstructorInfo> GetConstructor(INamedTypeSymbol typeSymbol)
317321
{
318322
foreach (var ctor in typeSymbol.Constructors)

src/Strongly/SourceGenerationHelper.cs

+25-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Reflection;
5+
using System.Runtime.InteropServices;
46
using System.Text;
57

68
namespace Strongly;
@@ -85,7 +87,7 @@ static string CreateStrongValue(
8587
var implementations = ctx.Config.Implementations;
8688
var useParsable = implementations.IsSet(StronglyImplementations.Parsable);
8789
var useIFormattable = implementations.IsSet(StronglyImplementations.IFormattable);
88-
const bool useIParsable = false;
90+
var useIParsable = implementations.IsSet(StronglyImplementations.Parsable);
8991
var useIEquatable =
9092
!ctx.IsRecord && implementations.IsSet(StronglyImplementations.IEquatable);
9193
var useIComparable =
@@ -128,20 +130,23 @@ static string CreateStrongValue(
128130

129131
var hasCtor = ctx.Constructors.Any(c => c.ArgumentType == resources.InternalType);
130132
var baseDef = EmbeddedSources.BaseTypeDef.Value + resources.Base.Value;
131-
baseDef = baseDef.Replace("[CTOR]", hasCtor ? string.Empty : EmbeddedSources.Ctor.Value);
132-
133133
if (ctx.IsRecord)
134134
{
135-
var ctor = baseDef.Split('\n')
136-
.First(x => x.Trim().StartsWith("public TYPENAME("))
137-
.Trim().Split('(', ')')[1];
138-
sb.Append($"readonly partial record struct TYPENAME({ctor}): INTERFACES {{ \n ");
135+
var ctorIndex =
136+
baseDef.IndexOf(EmbeddedSources.CtorKey, StringComparison.InvariantCulture);
137+
138+
baseDef = baseDef
139+
.Substring(0, ctorIndex + EmbeddedSources.CtorKey.Length)
140+
.Replace("readonly partial struct", "readonly partial record struct")
141+
+ Environment.NewLine;
139142
}
140-
else
141-
sb.Append(baseDef);
142143

143-
ReplaceInterfaces(sb, useIEquatable, useIComparable, useIParsable, useIFormattable);
144+
baseDef = baseDef.Replace(EmbeddedSources.CtorKey,
145+
hasCtor ? string.Empty : EmbeddedSources.Ctor.Value);
144146

147+
sb.Append(baseDef);
148+
149+
ReplaceInterfaces(sb, useIEquatable, useIComparable, useIParsable, useIFormattable);
145150

146151
if (useIComparable) sb.AppendLine(resources.Comparable.Value);
147152
if (useIFormattable) sb.AppendLine(resources.Formattable.Value);
@@ -186,8 +191,8 @@ ctx.Config.Math is not (StronglyMath.None or StronglyMath.Default))
186191
? toStr
187192
: EmbeddedSources.DefaultToString);
188193

189-
sb.Replace(EmbeddedSources.CtorKey,
190-
resources.TemplateVars.TryGetValue(EmbeddedSources.CtorKey, out var ctorInit)
194+
sb.Replace(EmbeddedSources.CtorValueKey,
195+
resources.TemplateVars.TryGetValue(EmbeddedSources.CtorValueKey, out var ctorInit)
191196
? ctorInit
192197
: EmbeddedSources.DefaultCtor);
193198

@@ -219,9 +224,16 @@ bool useIFormattable
219224
var interfaces = new List<string>();
220225
if (useIComparable) interfaces.Add("System.IComparable<TYPENAME>");
221226
if (useIEquatable) interfaces.Add("System.IEquatable<TYPENAME>");
222-
if (useIParseable) interfaces.Add("System.IParsable<TYPENAME>");
223227
if (useIFormattable) interfaces.Add("System.IFormattable");
224228

229+
var interfacesNet7 = new List<string>();
230+
if (useIParseable) interfacesNet7.Add("System.IParsable<TYPENAME>");
231+
232+
if (interfaces.Count > 0 || interfacesNet7.Count > 0)
233+
sb.Replace("INTERFACES_NET7", string.Join(", ", interfaces.Concat(interfacesNet7)));
234+
else
235+
sb.Replace(": INTERFACES_NET7", string.Empty);
236+
225237
if (interfaces.Count > 0)
226238
sb.Replace("INTERFACES", string.Join(", ", interfaces));
227239
else

src/Strongly/Strongly.csproj

+11-11
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,26 @@
1111
</PropertyGroup>
1212

1313
<ItemGroup>
14-
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" PrivateAssets="all" />
15-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.2.0" PrivateAssets="all" />
16-
<ProjectReference Include="..\Strongly.Attributes\Strongly.Attributes.csproj" PrivateAssets="All" />
14+
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" PrivateAssets="all"/>
15+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.2.0" PrivateAssets="all"/>
16+
<ProjectReference Include="..\Strongly.Attributes\Strongly.Attributes.csproj" PrivateAssets="All"/>
1717
</ItemGroup>
1818

1919
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
20-
<PackageReference Include="IsExternalInit" Version="1.0.3" PrivateAssets="all" />
21-
<PackageReference Include="Nullable" Version="1.3.1" PrivateAssets="all" />
20+
<PackageReference Include="IsExternalInit" Version="1.0.3" PrivateAssets="all"/>
21+
<PackageReference Include="Nullable" Version="1.3.1" PrivateAssets="all"/>
2222
</ItemGroup>
2323

2424
<ItemGroup>
25-
<Compile Remove="Templates\**\*.cs" />
26-
<EmbeddedResource Include="Templates\**\*.cs" />
27-
<EmbeddedResource Include="..\Strongly.Attributes\*.cs" Link="Templates\Sources\%(Filename)%(Extension)" />
25+
<Compile Remove="Templates\**\*.cs"/>
26+
<EmbeddedResource Include="Templates\**\*.cs"/>
27+
<EmbeddedResource Include="..\Strongly.Attributes\*.cs" Link="Templates\Sources\%(Filename)%(Extension)"/>
2828
</ItemGroup>
2929

3030
<ItemGroup>
31-
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
32-
<None Include="$(OutputPath)\Strongly.Attributes.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
33-
<None Include="$(OutputPath)\Strongly.Attributes.dll" Pack="true" PackagePath="lib\netstandard2.0" Visible="true" />
31+
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false"/>
32+
<None Include="$(OutputPath)\Strongly.Attributes.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false"/>
33+
<None Include="$(OutputPath)\Strongly.Attributes.dll" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
3434
</ItemGroup>
3535

3636
</Project>

src/Strongly/Templates/Base/Base_Type.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11

22
[System.Diagnostics.DebuggerDisplay("{Value}", Type = "TYPENAME")]
3+
#if NET7_0_OR_GREATER
4+
readonly partial struct TYPENAME : INTERFACES_NET7
5+
#else
36
readonly partial struct TYPENAME : INTERFACES
7+
#endif
48
{
59
public BASE_TYPENAME Value { get; }
610

711
[CTOR]
8-
12+
913
public override int GetHashCode() => [GET_HASH_CODE];
1014
public static bool operator ==(TYPENAME a, TYPENAME b) => a.Equals(b);
1115
public static bool operator !=(TYPENAME a, TYPENAME b) => !(a == b);

src/Strongly/Templates/Base/Ctor.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
 public TYPENAME(BASE_TYPENAME value)
1+

2+
public TYPENAME(BASE_TYPENAME value)
23
{
34
[CTOR_VALUE]
4-
}
5+
}
6+

src/Strongly/Templates/Guid/Guid_IParsable.cs

-20
This file was deleted.

src/Strongly/Templates/Guid/Guid_Parsable.cs

+23-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
new TYPENAME(System.Guid.Parse(value));
33

44
public static bool TryParse(
5-
[System.Diagnostics.CodeAnalysis.NotNullWhen(true)]string value,
5+
[System.Diagnostics.CodeAnalysis.NotNullWhen(true)]string? value,
66
out TYPENAME result)
77
{
88
if (System.Guid.TryParse(value, out System.Guid parseResult))
@@ -13,3 +13,25 @@ public static bool TryParse(
1313
result = default;
1414
return false;
1515
}
16+
17+
#if NET7_0_OR_GREATER
18+
public static TYPENAME Parse(string value, System.IFormatProvider? provider) =>
19+
new TYPENAME(System.Guid.Parse(value, provider));
20+
21+
public static bool TryParse(
22+
[System.Diagnostics.CodeAnalysis.NotNullWhen(true)]string? value,
23+
System.IFormatProvider? provider,
24+
out TYPENAME result)
25+
{
26+
if (System.Guid.TryParse(
27+
value,
28+
provider,
29+
out System.Guid parseResult))
30+
{
31+
result = new TYPENAME(parseResult);
32+
return true;
33+
}
34+
result = default;
35+
return false;
36+
}
37+
#endif

src/Strongly/Templates/NewId/NewId_IParsable.cs

-19
This file was deleted.

src/Strongly/Templates/NewId/NewId_Parsable.cs

+27-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-

1+

2+
23
public static TYPENAME Parse(string value) =>
34
new TYPENAME(new MassTransit.NewId(in value));
45

56
public static bool TryParse(
6-
[System.Diagnostics.CodeAnalysis.NotNullWhen(true)]string value,
7+
[System.Diagnostics.CodeAnalysis.NotNullWhen(true)]string? value,
78
out TYPENAME result)
89
{
910
try
@@ -17,3 +18,27 @@ public static bool TryParse(
1718
return false;
1819
}
1920
}
21+
22+
#if NET7_0_OR_GREATER
23+
public static TYPENAME Parse(string value, System.IFormatProvider? provider)
24+
{
25+
var guid = System.Guid.Parse(value, provider);
26+
return new TYPENAME(MassTransit.NewId.FromSequentialGuid(in guid));
27+
}
28+
29+
public static bool TryParse(
30+
[System.Diagnostics.CodeAnalysis.NotNullWhen(true)]string? value,
31+
System.IFormatProvider? provider,
32+
out TYPENAME result)
33+
{
34+
if (System.Guid.TryParse(value, provider, out var guid))
35+
{
36+
result = new TYPENAME(MassTransit.NewId.FromSequentialGuid(in guid));
37+
return true;
38+
}
39+
40+
result = default;
41+
return false;
42+
}
43+
#endif
44+

src/Strongly/Templates/NullableString/NullableString_IParsable.cs

-13
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
1-
 public static TYPENAME Parse(string value) =>
1+

2+
public static TYPENAME Parse(string? value) =>
23
new TYPENAME(value?.Trim());
34

45
public static bool TryParse(
5-
[System.Diagnostics.CodeAnalysis.NotNullWhen(true)]string value,
6+
[System.Diagnostics.CodeAnalysis.NotNullWhen(true)]string? value,
67
out TYPENAME result)
78
{
89
result = new TYPENAME(value?.Trim());
910
return true;
1011
}
1112

12-
13-
13+
public static TYPENAME Parse(string? value, System.IFormatProvider? provider) => Parse(value);
14+
15+
public static bool TryParse(
16+
[System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
17+
string? value,
18+
System.IFormatProvider? provider,
19+
out TYPENAME result) => TryParse(value, out result);
20+

src/Strongly/Templates/String/String_IParsable.cs

-17
This file was deleted.

0 commit comments

Comments
 (0)