Skip to content

Commit aabba16

Browse files
authored
Fixed source generator parameter attribute issue. (#8852)
1 parent 850ee8d commit aabba16

File tree

5 files changed

+417
-19
lines changed

5 files changed

+417
-19
lines changed

src/HotChocolate/AspNetCore/benchmarks/k6/performance-data.json

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
{
2-
"timestamp": "2025-10-27T17:21:55Z",
2+
"timestamp": "2025-10-27T18:47:39Z",
33
"tests": {
44
"single-fetch": {
55
"name": "Single Fetch (50 products, names only)",
66
"response_time": {
7-
"min": 1.382076,
8-
"p50": 2.475944,
9-
"max": 49.944208,
10-
"avg": 2.676029151591642,
11-
"p90": 3.657028,
12-
"p95": 4.396307,
13-
"p99": 7.1375322
7+
"min": 1.358888,
8+
"p50": 2.36486,
9+
"max": 45.479555,
10+
"avg": 2.620814281867896,
11+
"p90": 3.824667,
12+
"p95": 4.719379,
13+
"p99": 7.028532199999996
1414
},
1515
"throughput": {
16-
"requests_per_second": 78.73544063728629,
16+
"requests_per_second": 78.74678749311089,
1717
"total_iterations": 7162
1818
},
1919
"reliability": {
@@ -23,17 +23,17 @@
2323
"dataloader": {
2424
"name": "DataLoader (50 products with brands)",
2525
"response_time": {
26-
"min": 2.650327,
27-
"p50": 4.266731,
28-
"max": 16.942261,
29-
"avg": 4.629691850414733,
30-
"p90": 6.3672417999999995,
31-
"p95": 7.656316799999996,
32-
"p99": 10.92578552
26+
"min": 2.657964,
27+
"p50": 4.092611,
28+
"max": 17.875767,
29+
"avg": 4.3978259245362485,
30+
"p90": 5.998234,
31+
"p95": 7.214835,
32+
"p99": 10.013211850000003
3333
},
3434
"throughput": {
35-
"requests_per_second": 78.5361528317672,
36-
"total_iterations": 7144
35+
"requests_per_second": 78.53109196590968,
36+
"total_iterations": 7147
3737
},
3838
"reliability": {
3939
"error_rate": 0

src/HotChocolate/Core/src/Types.Analyzers/FileBuilders/TypeFileBuilderBase.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,10 +644,20 @@ protected void WriteResolver(Resolver resolver, ILocalTypeLookup typeLookup)
644644

645645
using (Writer.IncreaseIndent())
646646
{
647+
var first = true;
647648
foreach (var attribute in parameter.Attributes)
648649
{
649-
Writer.WriteIndentedLine("{0}.", GenerateAttributeInstantiation(attribute));
650+
if (!first)
651+
{
652+
Writer.Write(',');
653+
Writer.WriteLine();
654+
}
655+
656+
Writer.WriteIndented(GenerateAttributeInstantiation(attribute));
657+
first = false;
650658
}
659+
660+
Writer.WriteLine();
651661
}
652662

653663
Writer.WriteIndentedLine("]);");

src/HotChocolate/Core/test/Types.Analyzers.Tests/ResolverTests.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,4 +270,52 @@ internal class Test
270270
}
271271
""").MatchMarkdownAsync();
272272
}
273+
274+
[Fact]
275+
public async Task Resolver_Parameter_With_One_Attribute()
276+
{
277+
await TestHelper.GetGeneratedSourceSnapshot(
278+
"""
279+
using HotChocolate;
280+
using HotChocolate.Types;
281+
using HotChocolate.Types.Relay;
282+
283+
namespace TestNamespace;
284+
285+
[ObjectType<Test>]
286+
internal static partial class TestType
287+
{
288+
public static int GetTest([ID] int test)
289+
{
290+
return test;
291+
}
292+
}
293+
294+
internal class Test;
295+
""").MatchMarkdownAsync();
296+
}
297+
298+
[Fact]
299+
public async Task Resolver_Parameter_With_Two_Attribute()
300+
{
301+
await TestHelper.GetGeneratedSourceSnapshot(
302+
"""
303+
using HotChocolate;
304+
using HotChocolate.Types;
305+
using HotChocolate.Types.Relay;
306+
307+
namespace TestNamespace;
308+
309+
[ObjectType<Test>]
310+
internal static partial class TestType
311+
{
312+
public static int GetTest([ID] [ID] int test)
313+
{
314+
return test;
315+
}
316+
}
317+
318+
internal class Test;
319+
""").MatchMarkdownAsync();
320+
}
273321
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# Resolver_Parameter_With_One_Attribute
2+
3+
## HotChocolateTypeModule.735550c.g.cs
4+
5+
```csharp
6+
// <auto-generated/>
7+
8+
#nullable enable
9+
#pragma warning disable
10+
11+
using System;
12+
using System.Runtime.CompilerServices;
13+
using HotChocolate;
14+
using HotChocolate.Types;
15+
using HotChocolate.Execution.Configuration;
16+
17+
namespace Microsoft.Extensions.DependencyInjection
18+
{
19+
public static partial class TestsTypesRequestExecutorBuilderExtensions
20+
{
21+
public static IRequestExecutorBuilder AddTestsTypes(this IRequestExecutorBuilder builder)
22+
{
23+
builder.ConfigureDescriptorContext(ctx => ctx.TypeConfiguration.TryAdd<global::TestNamespace.Test>(
24+
"Tests::TestNamespace.TestType",
25+
() => global::TestNamespace.TestType.Initialize));
26+
builder.AddType<ObjectType<global::TestNamespace.Test>>();
27+
return builder;
28+
}
29+
}
30+
}
31+
32+
```
33+
34+
## TestType.WaAdMHmlGJHjtEI4nqY7WA.hc.g.cs
35+
36+
```csharp
37+
// <auto-generated/>
38+
39+
#nullable enable
40+
#pragma warning disable
41+
42+
using System;
43+
using System.Runtime.CompilerServices;
44+
using HotChocolate;
45+
using HotChocolate.Types;
46+
using HotChocolate.Execution.Configuration;
47+
using Microsoft.Extensions.DependencyInjection;
48+
using HotChocolate.Internal;
49+
50+
namespace TestNamespace
51+
{
52+
internal static partial class TestType
53+
{
54+
internal static void Initialize(global::HotChocolate.Types.IObjectTypeDescriptor<global::TestNamespace.Test> descriptor)
55+
{
56+
var extension = descriptor.Extend();
57+
var configuration = extension.Configuration;
58+
var thisType = typeof(global::TestNamespace.TestType);
59+
var bindingResolver = extension.Context.ParameterBindingResolver;
60+
var resolvers = new __Resolvers(bindingResolver);
61+
62+
var naming = descriptor.Extend().Context.Naming;
63+
64+
descriptor
65+
.Field(naming.GetMemberName("Test", global::HotChocolate.Types.MemberKind.ObjectField))
66+
.ExtendWith(static (field, context) =>
67+
{
68+
var configuration = field.Configuration;
69+
var typeInspector = field.Context.TypeInspector;
70+
var bindingResolver = field.Context.ParameterBindingResolver;
71+
var naming = field.Context.Naming;
72+
73+
configuration.Type = typeInspector.GetTypeRef(typeof(global::HotChocolate.Internal.SourceGeneratedType<global::HotChocolate.Types.NonNullType<global::HotChocolate.Internal.NamedRuntimeType<int>>>), HotChocolate.Types.TypeContext.Output);
74+
configuration.ResultType = typeof(int);
75+
76+
configuration.SetSourceGeneratorFlags();
77+
78+
var bindingInfo = field.Context.ParameterBindingResolver;
79+
var parameter = context.Resolvers.CreateParameterDescriptor_GetTest_test();
80+
var parameterInfo = bindingInfo.GetBindingInfo(parameter);
81+
82+
if(parameterInfo.Kind is global::HotChocolate.Internal.ArgumentKind.Argument)
83+
{
84+
var argumentConfiguration = new global::HotChocolate.Types.Descriptors.Configurations.ArgumentConfiguration
85+
{
86+
Name = naming.GetMemberName("test", global::HotChocolate.Types.MemberKind.Argument),
87+
Type = typeInspector.GetTypeRef(typeof(global::HotChocolate.Internal.SourceGeneratedType<global::HotChocolate.Types.NonNullType<global::HotChocolate.Internal.NamedRuntimeType<int>>>), HotChocolate.Types.TypeContext.Input),
88+
RuntimeType = typeof(int)
89+
};
90+
91+
var argumentConfigurations = argumentConfiguration.Configurations;
92+
argumentConfigurations = argumentConfigurations.Add(new global::HotChocolate.Types.Relay.IDAttribute(null));
93+
argumentConfiguration.Configurations = argumentConfigurations;
94+
95+
configuration.Arguments.Add(argumentConfiguration);
96+
}
97+
98+
configuration.Resolvers = context.Resolvers.GetTest();
99+
},
100+
(Resolvers: resolvers, ThisType: thisType));
101+
102+
Configure(descriptor);
103+
}
104+
105+
static partial void Configure(global::HotChocolate.Types.IObjectTypeDescriptor<global::TestNamespace.Test> descriptor);
106+
107+
private sealed class __Resolvers
108+
{
109+
private readonly global::HotChocolate.Internal.IParameterBinding _binding_GetTest_test;
110+
111+
public __Resolvers(global::HotChocolate.Resolvers.ParameterBindingResolver bindingResolver)
112+
{
113+
_binding_GetTest_test = bindingResolver.GetBinding(CreateParameterDescriptor_GetTest_test());
114+
}
115+
116+
public global::HotChocolate.Internal.ParameterDescriptor CreateParameterDescriptor_GetTest_test()
117+
=> new HotChocolate.Internal.ParameterDescriptor(
118+
"test",
119+
typeof(int),
120+
isNullable: false,
121+
[
122+
new global::HotChocolate.Types.Relay.IDAttribute(null)
123+
]);
124+
125+
public HotChocolate.Resolvers.FieldResolverDelegates GetTest()
126+
{
127+
var isPureResolver = _binding_GetTest_test.IsPure;
128+
129+
return isPureResolver
130+
? new global::HotChocolate.Resolvers.FieldResolverDelegates(pureResolver: GetTest)
131+
: new global::HotChocolate.Resolvers.FieldResolverDelegates(resolver: c => new(GetTest(c)));
132+
}
133+
134+
private global::System.Object? GetTest(global::HotChocolate.Resolvers.IResolverContext context)
135+
{
136+
var args0 = _binding_GetTest_test.Execute<int>(context);
137+
var result = global::TestNamespace.TestType.GetTest(args0);
138+
return result;
139+
}
140+
}
141+
}
142+
}
143+
144+
145+
```
146+

0 commit comments

Comments
 (0)