Skip to content

Commit de92af8

Browse files
authored
Merge pull request #15 from datacute/release/1.2.0
Release 1.2.0
2 parents 3728ecf + ea0800e commit de92af8

24 files changed

Lines changed: 337 additions & 118 deletions

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.2.0] - 2026-05-02
11+
12+
### Changed
13+
- Generated properties now use the C# `field` keyword on compilers that support it (C# 14+), eliminating explicit backing fields
14+
15+
### Breaking Changes
16+
- On C# 14+ compilers, the `EmbeddedResource.BackingField` nested class is no longer generated. Code that directly accessed `EmbeddedResource.BackingField.PropertyName` will no longer compile. Implementations of the `ReadEmbeddedResourceValue` partial method are unaffected — the backing storage is passed to that method as a `ref` parameter regardless of whether it is backed by `field` or by the explicit `BackingField` class.
17+
1018
## [1.1.1] - 2025-08-03
1119

1220
### Added
@@ -83,7 +91,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8391
### Added
8492
- Support for overriding `ReadEmbeddedResourceValue` partial method
8593

86-
[Unreleased]: https://github.com/datacute/EmbeddedResourcePropertyGenerator/compare/1.1.1...HEAD
94+
[Unreleased]: https://github.com/datacute/EmbeddedResourcePropertyGenerator/compare/1.2.0...HEAD
95+
[1.2.0]: https://github.com/datacute/EmbeddedResourcePropertyGenerator/releases/tag/1.2.0
8796
[1.1.1]: https://github.com/datacute/EmbeddedResourcePropertyGenerator/releases/tag/1.1.1
8897
[1.1.0]: https://github.com/datacute/EmbeddedResourcePropertyGenerator/releases/tag/1.1.0
8998
[1.0.0]: https://github.com/datacute/EmbeddedResourcePropertyGenerator/releases/tag/1.0.0

EmbeddedResourcePropertyExample/EmbeddedResourcePropertyExample.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
<OutputType>Exe</OutputType>
88
<IsPackable>false</IsPackable>
9+
<LangVersion>14</LangVersion>
910
</PropertyGroup>
1011

1112
<PropertyGroup>

EmbeddedResourcePropertyGenerator.Tests/EmbeddedResourcePropertyGenerator.Tests.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
<OutputType>Exe</OutputType>
88
<IsTestProject>true</IsTestProject>
9+
<LangVersion>14</LangVersion>
910
</PropertyGroup>
1011

1112
<ItemGroup>
12-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
13+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="5.3.0" />
1314
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
1415
<PackageReference Include="Shouldly" Version="4.3.0" />
1516
<PackageReference Include="Verify.SourceGenerators" Version="2.5.0" />

EmbeddedResourcePropertyGenerator.Tests/GeneratorSnapshotTests.AlternateFolderSelectedCorrectly#Query.EmbeddedResourceProperties.g.verified.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ public static string Read(string resourceName)
3737
var resourceText = streamReader.ReadToEnd();
3838
return resourceText;
3939
}
40-
public static class BackingField
41-
{
42-
public static string? Example;
43-
}
4440
public static class ResourceName
4541
{
4642
public const string Example = "EmbeddedResourcePropertyGenerator.Tests.ResourceFolders.Queries.example.sql";
@@ -62,8 +58,8 @@ public static string Example
6258
{
6359
get
6460
{
65-
ReadEmbeddedResourceValue(ref EmbeddedResource.BackingField.Example, EmbeddedResource.ResourceName.Example, "Example");
66-
var value = EmbeddedResource.BackingField.Example ??= EmbeddedResource.Read(EmbeddedResource.ResourceName.Example);
61+
ReadEmbeddedResourceValue(ref field, EmbeddedResource.ResourceName.Example, "Example");
62+
var value = field ??= EmbeddedResource.Read(EmbeddedResource.ResourceName.Example);
6763
AlterEmbeddedResourceReturnValue(ref value, EmbeddedResource.ResourceName.Example, "Example");
6864
return value;
6965
}

EmbeddedResourcePropertyGenerator.Tests/GeneratorSnapshotTests.GeneratesEmbeddedResourcePropertiesCorrectly#Queries.EmbeddedResourceProperties.g.verified.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ public static string Read(string resourceName)
3737
var resourceText = streamReader.ReadToEnd();
3838
return resourceText;
3939
}
40-
public static class BackingField
41-
{
42-
public static string? Example;
43-
}
4440
public static class ResourceName
4541
{
4642
public const string Example = "EmbeddedResourcePropertyGenerator.Tests.Queries.example.txt";
@@ -62,8 +58,8 @@ public static string Example
6258
{
6359
get
6460
{
65-
ReadEmbeddedResourceValue(ref EmbeddedResource.BackingField.Example, EmbeddedResource.ResourceName.Example, "Example");
66-
var value = EmbeddedResource.BackingField.Example ??= EmbeddedResource.Read(EmbeddedResource.ResourceName.Example);
61+
ReadEmbeddedResourceValue(ref field, EmbeddedResource.ResourceName.Example, "Example");
62+
var value = field ??= EmbeddedResource.Read(EmbeddedResource.ResourceName.Example);
6763
AlterEmbeddedResourceReturnValue(ref value, EmbeddedResource.ResourceName.Example, "Example");
6864
return value;
6965
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//HintName: Queries.EmbeddedResourceProperties.g.cs
2+
//------------------------------------------------------------------------------
3+
// <auto-generated>
4+
// This code was generated by Datacute.EmbeddedResourcePropertyGenerator.
5+
// Version: 1.2.3
6+
// </auto-generated>
7+
//------------------------------------------------------------------------------
8+
9+
#nullable enable
10+
11+
/// <summary>
12+
/// This class's properties are generated from project files meeting the criteria:
13+
/// <list type="bullet">
14+
/// <item>
15+
/// <description>they are an <c>EmbeddedResource</c></description>
16+
/// </item>
17+
/// <item>
18+
/// <description>they are in the project folder <c>Queries</c></description>
19+
/// </item>
20+
/// <item>
21+
/// <description>they have the extension <c>.txt</c></description>
22+
/// </item>
23+
/// <item>
24+
/// <description>Number of matching resources: 1</description>
25+
/// </item>
26+
/// </list>
27+
/// </summary>
28+
public static partial class Queries
29+
{
30+
private static class EmbeddedResource
31+
{
32+
public static string Read(string resourceName)
33+
{
34+
var assembly = typeof(Queries).Assembly;
35+
using var stream = assembly.GetManifestResourceStream(resourceName)!;
36+
using var streamReader = new global::System.IO.StreamReader(stream, global::System.Text.Encoding.UTF8);
37+
var resourceText = streamReader.ReadToEnd();
38+
return resourceText;
39+
}
40+
public static class BackingField
41+
{
42+
public static string? Example;
43+
}
44+
public static class ResourceName
45+
{
46+
public const string Example = "EmbeddedResourcePropertyGenerator.Tests.Queries.example.txt";
47+
}
48+
}
49+
static partial void ReadEmbeddedResourceValue(ref string? backingField, string resourceName, string propertyName);
50+
static partial void AlterEmbeddedResourceReturnValue(ref string value, string resourceName, string propertyName);
51+
52+
/// <summary>Text value of the Embedded Resource: example.txt</summary>
53+
/// <value>
54+
/// <code>
55+
/// Example text content
56+
/// </code>
57+
/// </value>
58+
/// <remarks>
59+
/// The value is read from the embedded resource on first access.
60+
/// </remarks>
61+
public static string Example
62+
{
63+
get
64+
{
65+
ReadEmbeddedResourceValue(ref EmbeddedResource.BackingField.Example, EmbeddedResource.ResourceName.Example, "Example");
66+
var value = EmbeddedResource.BackingField.Example ??= EmbeddedResource.Read(EmbeddedResource.ResourceName.Example);
67+
AlterEmbeddedResourceReturnValue(ref value, EmbeddedResource.ResourceName.Example, "Example");
68+
return value;
69+
}
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//HintName: Queries.EmbeddedResourceProperties.g.cs
2+
//------------------------------------------------------------------------------
3+
// <auto-generated>
4+
// This code was generated by Datacute.EmbeddedResourcePropertyGenerator.
5+
// Version: 1.2.3
6+
// </auto-generated>
7+
//------------------------------------------------------------------------------
8+
9+
#nullable enable
10+
11+
/// <summary>
12+
/// This class's properties are generated from project files meeting the criteria:
13+
/// <list type="bullet">
14+
/// <item>
15+
/// <description>they are an <c>EmbeddedResource</c></description>
16+
/// </item>
17+
/// <item>
18+
/// <description>they are in the project folder <c>Queries</c></description>
19+
/// </item>
20+
/// <item>
21+
/// <description>they have the extension <c>.txt</c></description>
22+
/// </item>
23+
/// <item>
24+
/// <description>Number of matching resources: 1</description>
25+
/// </item>
26+
/// </list>
27+
/// </summary>
28+
public static partial class Queries
29+
{
30+
private static class EmbeddedResource
31+
{
32+
public static string Read(string resourceName)
33+
{
34+
var assembly = typeof(Queries).Assembly;
35+
using var stream = assembly.GetManifestResourceStream(resourceName)!;
36+
using var streamReader = new global::System.IO.StreamReader(stream, global::System.Text.Encoding.UTF8);
37+
var resourceText = streamReader.ReadToEnd();
38+
return resourceText;
39+
}
40+
public static class BackingField
41+
{
42+
public static string? Example;
43+
}
44+
public static class ResourceName
45+
{
46+
public const string Example = "EmbeddedResourcePropertyGenerator.Tests.Queries.example.txt";
47+
}
48+
}
49+
static partial void ReadEmbeddedResourceValue(ref string? backingField, string resourceName, string propertyName);
50+
static partial void AlterEmbeddedResourceReturnValue(ref string value, string resourceName, string propertyName);
51+
52+
/// <summary>Text value of the Embedded Resource: example.txt</summary>
53+
/// <value>
54+
/// <code>
55+
/// Example text content
56+
/// </code>
57+
/// </value>
58+
/// <remarks>
59+
/// The value is read from the embedded resource on first access.
60+
/// </remarks>
61+
public static string Example
62+
{
63+
get
64+
{
65+
ReadEmbeddedResourceValue(ref EmbeddedResource.BackingField.Example, EmbeddedResource.ResourceName.Example, "Example");
66+
var value = EmbeddedResource.BackingField.Example ??= EmbeddedResource.Read(EmbeddedResource.ResourceName.Example);
67+
AlterEmbeddedResourceReturnValue(ref value, EmbeddedResource.ResourceName.Example, "Example");
68+
return value;
69+
}
70+
}
71+
}

EmbeddedResourcePropertyGenerator.Tests/GeneratorSnapshotTests.GeneratesEmbeddedResourcePropertiesForInnerAndGenericClasses#OuterClass_T.InnerClass.EmbeddedResourceProperties.g.verified.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,6 @@ public static string Read(string resourceName)
3939
var resourceText = streamReader.ReadToEnd();
4040
return resourceText;
4141
}
42-
public static class BackingField
43-
{
44-
public static string? Example;
45-
}
4642
public static class ResourceName
4743
{
4844
public const string Example = "EmbeddedResourcePropertyGenerator.Tests.InnerClass.example.txt";
@@ -64,8 +60,8 @@ public static string Example
6460
{
6561
get
6662
{
67-
ReadEmbeddedResourceValue(ref EmbeddedResource.BackingField.Example, EmbeddedResource.ResourceName.Example, "Example");
68-
var value = EmbeddedResource.BackingField.Example ??= EmbeddedResource.Read(EmbeddedResource.ResourceName.Example);
63+
ReadEmbeddedResourceValue(ref field, EmbeddedResource.ResourceName.Example, "Example");
64+
var value = field ??= EmbeddedResource.Read(EmbeddedResource.ResourceName.Example);
6965
AlterEmbeddedResourceReturnValue(ref value, EmbeddedResource.ResourceName.Example, "Example");
7066
return value;
7167
}

EmbeddedResourcePropertyGenerator.Tests/GeneratorSnapshotTests.GeneratesEmbeddedResourcePropertiesWithNoProperties#Queries.EmbeddedResourceProperties.g.verified.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ public static string Read(string resourceName)
3737
var resourceText = streamReader.ReadToEnd();
3838
return resourceText;
3939
}
40-
public static class BackingField
41-
{
42-
}
4340
public static class ResourceName
4441
{
4542
}

EmbeddedResourcePropertyGenerator.Tests/GeneratorSnapshotTests.cs

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
using Datacute.EmbeddedResourcePropertyGenerator;
22
using Microsoft.CodeAnalysis;
3+
using Microsoft.CodeAnalysis.CSharp;
34

45
namespace EmbeddedResourcePropertyGenerator.Tests;
56

67
public class GeneratorSnapshotTests
78
{
8-
private static Task Verify(string source, List<AdditionalText>? additionalTexts = null)
9+
private static Task Verify(string source, List<AdditionalText>? additionalTexts = null, LanguageVersion languageVersion = LanguageVersion.CSharp14)
910
{
10-
return TestHelper.Verify<Generator>(source, additionalTexts);
11+
return TestHelper.Verify<Generator>(source, additionalTexts, languageVersion);
1112
}
1213

1314
[Fact]
@@ -119,6 +120,60 @@ public static partial class Query;
119120
return Verify(source, additionalTexts);
120121
}
121122

123+
[Fact]
124+
public Task GeneratesEmbeddedResourcePropertiesCorrectly_CSharp13()
125+
{
126+
var source = /* language=c# */
127+
"""
128+
using Datacute.EmbeddedResourcePropertyGenerator;
129+
130+
[EmbeddedResourceProperties]
131+
public static partial class Queries;
132+
""";
133+
134+
var additionalTexts = new List<AdditionalText>
135+
{
136+
new InMemoryAdditionalText(
137+
TestHelper.TestPath("Queries/example.txt"),
138+
"Example text content"),
139+
new InMemoryAdditionalText(
140+
TestHelper.TestPath("Queries/example2.file"),
141+
"Example text content with the wrong extension - should not be included"),
142+
new InMemoryAdditionalText(
143+
TestHelper.TestPath("WrongFolder/example3.txt"),
144+
"Example text content in the wrong folder - should not be included")
145+
};
146+
147+
return Verify(source, additionalTexts, LanguageVersion.CSharp13);
148+
}
149+
150+
[Fact]
151+
public Task GeneratesEmbeddedResourcePropertiesCorrectly_CSharp12()
152+
{
153+
var source = /* language=c# */
154+
"""
155+
using Datacute.EmbeddedResourcePropertyGenerator;
156+
157+
[EmbeddedResourceProperties]
158+
public static partial class Queries;
159+
""";
160+
161+
var additionalTexts = new List<AdditionalText>
162+
{
163+
new InMemoryAdditionalText(
164+
TestHelper.TestPath("Queries/example.txt"),
165+
"Example text content"),
166+
new InMemoryAdditionalText(
167+
TestHelper.TestPath("Queries/example2.file"),
168+
"Example text content with the wrong extension - should not be included"),
169+
new InMemoryAdditionalText(
170+
TestHelper.TestPath("WrongFolder/example3.txt"),
171+
"Example text content in the wrong folder - should not be included")
172+
};
173+
174+
return Verify(source, additionalTexts, LanguageVersion.CSharp12);
175+
}
176+
122177
[Fact]
123178
public Task GeneratesEmbeddedResourcePropertiesWithStrangeNamesCorrectly()
124179
{
@@ -169,7 +224,7 @@ public static partial class Queries;
169224
"special characters in file names")
170225
};
171226

172-
// Pass the source code to our helper and snapshot test the output
173-
return Verify(source, additionalTexts);
227+
// Intentionally use pre-C#14 so generated BackingField names are snapshot-tested.
228+
return Verify(source, additionalTexts, LanguageVersion.CSharp13);
174229
}
175230
}

0 commit comments

Comments
 (0)