Skip to content

Commit 5595ab5

Browse files
CopilotReubenBond
andcommitted
Add support for [Id] annotations on record primary constructor parameters
Co-authored-by: ReubenBond <203839+ReubenBond@users.noreply.github.com>
1 parent a2942b3 commit 5595ab5

File tree

5 files changed

+449
-3
lines changed

5 files changed

+449
-3
lines changed

src/Orleans.CodeGenerator/FieldIdAssignmentHelper.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ private bool ExtractFieldIdAnnotations()
7777
}
7878
else if (PropertyUtility.GetMatchingPrimaryConstructorParameter(prop, _constructorParameters) is { } prm)
7979
{
80-
id = CodeGenerator.GetId(_libraryTypes, prop);
80+
// Check for [Id] attribute on the primary constructor parameter
81+
id = CodeGenerator.GetId(_libraryTypes, prm);
8182
if (id.HasValue)
8283
{
8384
_symbols[member] = (id.Value, true);
@@ -108,7 +109,12 @@ private bool ExtractFieldIdAnnotations()
108109
var constructorParameter = _constructorParameters.FirstOrDefault(x => x.Name.Equals(property.Name, StringComparison.OrdinalIgnoreCase));
109110
if (constructorParameter is not null)
110111
{
111-
id = (uint)_constructorParameters.IndexOf(constructorParameter);
112+
// Check for [Id] attribute on the constructor parameter
113+
id = CodeGenerator.GetId(_libraryTypes, constructorParameter);
114+
if (!id.HasValue)
115+
{
116+
id = (uint)_constructorParameters.IndexOf(constructorParameter);
117+
}
112118
isConstructorParameter = true;
113119
}
114120
}

src/Orleans.Serialization.Abstractions/Annotations.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ public GetCompletionSourceMethodNameAttribute(string methodName)
258258
[AttributeUsage(
259259
AttributeTargets.Field
260260
| AttributeTargets.Property
261+
| AttributeTargets.Parameter
261262
| AttributeTargets.Class
262263
| AttributeTargets.Struct
263264
| AttributeTargets.Enum

test/Orleans.CodeGenerator.Tests/OrleansSourceGeneratorTests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,33 @@ public record class DemoDataRecordClass([property: Id(0)] string Value);
185185
[GenerateSerializer]
186186
public record DemoDataRecord([property: Id(0)] string Value);");
187187

188+
/// <summary>
189+
/// Tests serializer generation for records with [Id] attributes on primary constructor parameters.
190+
/// This is the new, more concise syntax that avoids the need for [property: Id(0)].
191+
/// Verifies that:
192+
/// - [Id] on constructor parameters is properly detected and used
193+
/// - Generated serializers correctly handle the property-parameter relationship
194+
/// - Both simple records and records with additional properties work correctly
195+
/// </summary>
196+
[Fact]
197+
public Task TestRecordsWithParameterIdAttributes() => AssertSuccessfulSourceGeneration(
198+
@"using Orleans;
199+
200+
namespace TestProject;
201+
202+
[GenerateSerializer]
203+
public record SimpleRecord([Id(0)] int Value, [Id(1)] string Name);
204+
205+
[GenerateSerializer]
206+
public record RecordWithExtraProperty([Id(0)] int Id, [Id(1)] string Name)
207+
{
208+
[Id(2)]
209+
public string Description { get; init; }
210+
}
211+
212+
[GenerateSerializer]
213+
public record struct RecordStructWithParameterId([Id(0)] string Value);");
214+
188215
/// <summary>
189216
/// Tests serializer generation for generic types.
190217
/// Generic types require:

0 commit comments

Comments
 (0)