Skip to content

Commit efdef06

Browse files
[Analyzer] Fix FactoryTypeReference cache collision for shared CLR types (#9747)
1 parent b9a77ba commit efdef06

4 files changed

Lines changed: 56 additions & 1 deletion

File tree

src/HotChocolate/Core/src/Types/Types/Descriptors/TypeReferences/FactoryTypeReference.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ public string Key
4444
{
4545
get
4646
{
47-
field ??= TypeStructure.ToString(indented: false);
47+
if (field is null)
48+
{
49+
var structure = TypeStructure.ToString(indented: false);
50+
field = Context == TypeContext.None ? structure : $"{structure}_{Context}";
51+
}
52+
4853
return field;
4954
}
5055
}

src/HotChocolate/Core/test/Types.Analyzers.Integration.Tests/Product.cs renamed to src/HotChocolate/Core/test/Types.Analyzers.Integration.Tests/Types.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,24 @@ public static string ListNullableElementArgumentRef(List<string?> items)
109109

110110
public static string NullableListNullableElementArgumentRef(List<string?>? items)
111111
=> throw new Exception();
112+
113+
// Covers a regression where the same POCO used in both an output position
114+
// (resolver return) and an input position (mutation argument) emitted two
115+
// distinct GraphQL types but the FactoryTypeReference cache keyed only on
116+
// the syntactic structure, so one position reused the IType of the other.
117+
public static IReadOnlyCollection<Shape> GetShapes() => [];
118+
}
119+
120+
public class Shape
121+
{
122+
public required string Key { get; set; }
123+
public required string Name { get; set; }
124+
}
125+
126+
[MutationType]
127+
public static partial class Mutation
128+
{
129+
public static bool SaveShapes(IReadOnlyList<Shape> shapes) => true;
112130
}
113131

114132
public class IsSelectedNode

src/HotChocolate/Core/test/Types.Analyzers.Integration.Tests/__snapshots__/IntegrationTests.Schema_Snapshot.snap

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
schema {
22
query: Query
3+
mutation: Mutation
34
subscription: Subscription
45
}
56

@@ -92,9 +93,14 @@ type Query {
9293
listArgumentRef(items: [String!]!): String!
9394
listNullableElementArgumentRef(items: [String]!): String!
9495
nullableListNullableElementArgumentRef(items: [String]): String!
96+
shapes: [Shape!]!
9597
issue8057Entity(id: ID!): Issue8057Entity @cost(weight: "10")
9698
}
9799

100+
type Mutation {
101+
saveShapes(shapes: [ShapeInput!]!): Boolean!
102+
}
103+
98104
type Subscription {
99105
onProductAdded(categoryId: Int!): Int! @cost(weight: "10")
100106
onProductPriceChanged(productId: Int!): Int! @cost(weight: "10")
@@ -201,6 +207,11 @@ type ProductsEdge {
201207
node: Product!
202208
}
203209

210+
type Shape {
211+
key: String!
212+
name: String!
213+
}
214+
204215
type Television implements Product {
205216
argumentWithExplicitType(arg: Version!): String!
206217
nullableArgumentWithExplicitType(arg: Version): String!
@@ -218,6 +229,11 @@ interface Product {
218229
id: String!
219230
}
220231

232+
input ShapeInput {
233+
key: String!
234+
name: String!
235+
}
236+
221237
scalar Version
222238

223239
scalar Version2

src/HotChocolate/Core/test/Types.Analyzers.Integration.Tests/__snapshots__/IntegrationTests.Schema_Snapshot_Without_ConnectionName_Inference.snap

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
schema {
22
query: Query
3+
mutation: Mutation
34
subscription: Subscription
45
}
56

@@ -67,9 +68,14 @@ type Query {
6768
listArgumentRef(items: [String!]!): String!
6869
listNullableElementArgumentRef(items: [String]!): String!
6970
nullableListNullableElementArgumentRef(items: [String]): String!
71+
shapes: [Shape!]!
7072
issue8057Entity(id: ID!): Issue8057Entity
7173
}
7274

75+
type Mutation {
76+
saveShapes(shapes: [ShapeInput!]!): Boolean!
77+
}
78+
7379
type Subscription {
7480
onProductAdded(categoryId: Int!): Int!
7581
onProductPriceChanged(productId: Int!): Int!
@@ -158,6 +164,11 @@ type ProductEdge {
158164
node: Product!
159165
}
160166

167+
type Shape {
168+
key: String!
169+
name: String!
170+
}
171+
161172
type Television implements Product {
162173
argumentWithExplicitType(arg: Version!): String!
163174
nullableArgumentWithExplicitType(arg: Version): String!
@@ -175,6 +186,11 @@ interface Product {
175186
id: String!
176187
}
177188

189+
input ShapeInput {
190+
key: String!
191+
name: String!
192+
}
193+
178194
scalar Version
179195

180196
scalar Version2

0 commit comments

Comments
 (0)