Skip to content

Commit 6ddcc7c

Browse files
authored
Allow control over interfaces of generated DataLoader. (#7621)
1 parent 720cb95 commit 6ddcc7c

File tree

30 files changed

+313
-64
lines changed

30 files changed

+313
-64
lines changed

src/GreenDonut/src/Core/Attributes/DataLoaderDefaultsAttribute.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,9 @@ public sealed class DataLoaderDefaultsAttribute : Attribute
2020
/// Specifies if module registration code for DataLoaders shall be generated.
2121
/// </summary>
2222
public bool GenerateRegistrationCode { get; set; } = true;
23+
24+
/// <summary>
25+
/// Specifies if interfaces for DataLoaders shall be generated.
26+
/// </summary>
27+
public bool GenerateInterfaces { get; set; } = true;
2328
}

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

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,11 @@ public void WriteBeginDataLoaderClass(
8484
bool isPublic,
8585
DataLoaderKind kind,
8686
ITypeSymbol key,
87-
ITypeSymbol value)
87+
ITypeSymbol value,
88+
bool withInterface)
8889
{
8990
_writer.WriteIndentedLine(
90-
"{0} sealed class {1}",
91+
"{0} sealed partial class {1}",
9192
isPublic
9293
? "public"
9394
: "internal",
@@ -99,7 +100,10 @@ kind is DataLoaderKind.Group
99100
: ": global::GreenDonut.DataLoaderBase<{0}, {1}>",
100101
key.ToFullyQualified(),
101102
value.ToFullyQualified());
102-
_writer.WriteIndentedLine(", {0}", interfaceName);
103+
if (withInterface)
104+
{
105+
_writer.WriteIndentedLine(", {0}", interfaceName);
106+
}
103107
_writer.DecreaseIndent();
104108
_writer.WriteIndentedLine("{");
105109
_writer.IncreaseIndent();
@@ -509,22 +513,34 @@ kind is DataLoaderKind.Cache
509513

510514
public void WriteDataLoaderGroupClass(
511515
string groupClassName,
512-
IReadOnlyList<GroupedDataLoaderInfo> dataLoaders)
516+
IReadOnlyList<GroupedDataLoaderInfo> dataLoaders,
517+
bool withInterface)
513518
{
514-
_writer.WriteIndentedLine("public interface I{0}", groupClassName);
515-
_writer.WriteIndentedLine("{");
516-
_writer.IncreaseIndent();
517-
518-
foreach (var dataLoader in dataLoaders)
519+
if (withInterface)
519520
{
520-
_writer.WriteIndentedLine("{0} {1} {{ get; }}", dataLoader.InterfaceName, dataLoader.Name);
521+
_writer.WriteIndentedLine("public interface I{0}", groupClassName);
522+
_writer.WriteIndentedLine("{");
523+
_writer.IncreaseIndent();
524+
525+
foreach (var dataLoader in dataLoaders)
526+
{
527+
_writer.WriteIndentedLine("{0} {1} {{ get; }}", dataLoader.InterfaceName, dataLoader.Name);
528+
}
529+
530+
_writer.DecreaseIndent();
531+
_writer.WriteIndentedLine("}");
532+
_writer.WriteLine();
521533
}
522534

523-
_writer.DecreaseIndent();
524-
_writer.WriteIndentedLine("}");
525-
_writer.WriteLine();
535+
if (withInterface)
536+
{
537+
_writer.WriteIndentedLine("public sealed partial class {0} : I{0}", groupClassName);
538+
}
539+
else
540+
{
541+
_writer.WriteIndentedLine("public sealed partial class {0}", groupClassName);
542+
}
526543

527-
_writer.WriteIndentedLine("public sealed class {0} : I{0}", groupClassName);
528544
_writer.WriteIndentedLine("{");
529545
_writer.IncreaseIndent();
530546

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

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,26 @@ public void WriteAddDataLoader(string dataLoaderType)
8484
dataLoaderType);
8585
}
8686

87-
public void WriteAddDataLoader(string dataLoaderType, string dataLoaderInterfaceType)
87+
public void WriteAddDataLoader(
88+
string dataLoaderType,
89+
string dataLoaderInterfaceType,
90+
bool withInterface)
8891
{
89-
_writer.WriteIndentedLine(
90-
"global::{0}.AddDataLoader<global::{1}, global::{2}>(services);",
91-
WellKnownTypes.DataLoaderServiceCollectionExtension,
92-
dataLoaderInterfaceType,
93-
dataLoaderType);
92+
if (withInterface)
93+
{
94+
_writer.WriteIndentedLine(
95+
"global::{0}.AddDataLoader<global::{1}, global::{2}>(services);",
96+
WellKnownTypes.DataLoaderServiceCollectionExtension,
97+
dataLoaderInterfaceType,
98+
dataLoaderType);
99+
}
100+
else
101+
{
102+
_writer.WriteIndentedLine(
103+
"global::{0}.AddDataLoader<global::{1}>(services);",
104+
WellKnownTypes.DataLoaderServiceCollectionExtension,
105+
dataLoaderType);
106+
}
94107
}
95108

96109
public void WriteAddDataLoaderGroup(string groupType, string groupInterfaceType)

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

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ public void WriteRegisterObjectTypeExtensionHelpers()
133133
using (_writer.IncreaseIndent())
134134
{
135135
_writer.WriteIndentedLine(
136-
"var hooks = (global::System.Collections.Generic.List<" +
137-
"Action<IObjectTypeDescriptor<T>>>)" +
138-
"descriptor.Extend().Context.ContextData[hooksKey]!;");
136+
"var hooks = (global::System.Collections.Generic.List<"
137+
+ "Action<IObjectTypeDescriptor<T>>>)"
138+
+ "descriptor.Extend().Context.ContextData[hooksKey]!;");
139139
_writer.WriteIndentedLine("foreach (var configure in hooks)");
140140
_writer.WriteIndentedLine("{");
141141

@@ -169,8 +169,8 @@ public void WriteRegisterObjectTypeExtensionHelpers()
169169
_writer.WriteIndentedLine("}");
170170
_writer.WriteLine();
171171
_writer.WriteIndentedLine(
172-
"((System.Collections.Generic.List<Action<IObjectTypeDescriptor<T>>>)value!)" +
173-
".Add(initialize);");
172+
"((System.Collections.Generic.List<Action<IObjectTypeDescriptor<T>>>)value!)"
173+
+ ".Add(initialize);");
174174
}
175175

176176
_writer.WriteIndentedLine("});");
@@ -217,9 +217,9 @@ public void WriteRegisterInterfaceTypeExtensionHelpers()
217217
using (_writer.IncreaseIndent())
218218
{
219219
_writer.WriteIndentedLine(
220-
"var hooks = (global::System.Collections.Generic.List<" +
221-
"Action<IInterfaceTypeDescriptor<T>>>)" +
222-
"descriptor.Extend().Context.ContextData[hooksKey]!;");
220+
"var hooks = (global::System.Collections.Generic.List<"
221+
+ "Action<IInterfaceTypeDescriptor<T>>>)"
222+
+ "descriptor.Extend().Context.ContextData[hooksKey]!;");
223223
_writer.WriteIndentedLine("foreach (var configure in hooks)");
224224
_writer.WriteIndentedLine("{");
225225

@@ -253,8 +253,8 @@ public void WriteRegisterInterfaceTypeExtensionHelpers()
253253
_writer.WriteIndentedLine("}");
254254
_writer.WriteLine();
255255
_writer.WriteIndentedLine(
256-
"((System.Collections.Generic.List<Action<IInterfaceTypeDescriptor<T>>>)value!)" +
257-
".Add(initialize);");
256+
"((System.Collections.Generic.List<Action<IInterfaceTypeDescriptor<T>>>)value!)"
257+
+ ".Add(initialize);");
258258
}
259259

260260
_writer.WriteIndentedLine("});");
@@ -266,8 +266,25 @@ public void WriteRegisterInterfaceTypeExtensionHelpers()
266266
public void WriteRegisterDataLoader(string typeName)
267267
=> _writer.WriteIndentedLine("builder.AddDataLoader<global::{0}>();", typeName);
268268

269-
public void WriteRegisterDataLoader(string typeName, string interfaceTypeName)
270-
=> _writer.WriteIndentedLine("builder.AddDataLoader<global::{0}, global::{1}>();", interfaceTypeName, typeName);
269+
public void WriteRegisterDataLoader(
270+
string typeName,
271+
string interfaceTypeName,
272+
bool withInterface)
273+
{
274+
if (withInterface)
275+
{
276+
_writer.WriteIndentedLine(
277+
"builder.AddDataLoader<global::{0}, global::{1}>();",
278+
interfaceTypeName,
279+
typeName);
280+
}
281+
else
282+
{
283+
_writer.WriteIndentedLine(
284+
"builder.AddDataLoader<global::{0}>();",
285+
typeName);
286+
}
287+
}
271288

272289
public void WriteRegisterDataLoaderGroup(string typeName, string interfaceTypeName)
273290
=> _writer.WriteIndentedLine(

src/HotChocolate/Core/src/Types.Analyzers/Generators/DataLoaderGenerator.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ private static void WriteDataLoader(
109109
buffer ??= new();
110110
buffer.Clear();
111111
buffer.AddRange(dataLoaderGroups);
112-
generator.WriteDataLoaderGroupClass(dataLoaderGroup.Key, buffer);
112+
generator.WriteDataLoaderGroupClass(dataLoaderGroup.Key, buffer, defaults.GenerateInterfaces);
113113
}
114114

115115
generator.WriteEndNamespace();
@@ -133,15 +133,19 @@ private static void GenerateDataLoader(
133133
var isPublic = dataLoader.IsPublic ?? defaults.IsPublic ?? true;
134134
var isInterfacePublic = dataLoader.IsInterfacePublic ?? defaults.IsInterfacePublic ?? true;
135135

136-
generator.WriteDataLoaderInterface(dataLoader.InterfaceName, isInterfacePublic, kind, keyType, valueType);
136+
if (defaults.GenerateInterfaces)
137+
{
138+
generator.WriteDataLoaderInterface(dataLoader.InterfaceName, isInterfacePublic, kind, keyType, valueType);
139+
}
137140

138141
generator.WriteBeginDataLoaderClass(
139142
dataLoader.Name,
140143
dataLoader.InterfaceName,
141144
isPublic,
142145
kind,
143146
keyType,
144-
valueType);
147+
valueType,
148+
defaults.GenerateInterfaces);
145149
generator.WriteDataLoaderConstructor(
146150
dataLoader.Name,
147151
kind,

src/HotChocolate/Core/src/Types.Analyzers/Generators/DataLoaderModuleGenerator.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Immutable;
22
using HotChocolate.Types.Analyzers.FileBuilders;
3+
using HotChocolate.Types.Analyzers.Helpers;
34
using HotChocolate.Types.Analyzers.Models;
45
using Microsoft.CodeAnalysis;
56

@@ -13,6 +14,7 @@ public void Generate(
1314
ImmutableArray<SyntaxInfo> syntaxInfos)
1415
{
1516
var module = GetDataLoaderModuleInfo(syntaxInfos);
17+
var dataLoaderDefaults = syntaxInfos.GetDataLoaderDefaults();
1618

1719
if (module is null || !syntaxInfos.Any(t => t is DataLoaderInfo or RegisterDataLoaderInfo))
1820
{
@@ -43,7 +45,7 @@ public void Generate(
4345
case DataLoaderInfo dataLoader:
4446
var typeName = $"{dataLoader.Namespace}.{dataLoader.Name}";
4547
var interfaceTypeName = $"{dataLoader.Namespace}.{dataLoader.InterfaceName}";
46-
generator.WriteAddDataLoader(typeName, interfaceTypeName);
48+
generator.WriteAddDataLoader(typeName, interfaceTypeName, dataLoaderDefaults.GenerateInterfaces);
4749

4850
if(dataLoader.Groups.Count > 0)
4951
{

src/HotChocolate/Core/src/Types.Analyzers/Generators/TypeModuleSyntaxGenerator.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ private static void WriteConfiguration(
4949
List<SyntaxInfo> syntaxInfos,
5050
ModuleInfo module)
5151
{
52+
var dataLoaderDefaults = syntaxInfos.GetDataLoaderDefaults();
5253
HashSet<(string InterfaceName, string ClassName)>? groups = null;
5354
using var generator = new ModuleFileBuilder(module.ModuleName, "Microsoft.Extensions.DependencyInjection");
5455

@@ -109,15 +110,20 @@ private static void WriteConfiguration(
109110
var typeName = $"{dataLoader.Namespace}.{dataLoader.Name}";
110111
var interfaceTypeName = $"{dataLoader.Namespace}.{dataLoader.InterfaceName}";
111112

112-
generator.WriteRegisterDataLoader(typeName, interfaceTypeName);
113+
generator.WriteRegisterDataLoader(
114+
typeName,
115+
interfaceTypeName,
116+
dataLoaderDefaults.GenerateInterfaces);
113117
hasConfigurations = true;
114118

115119
if(dataLoader.Groups.Count > 0)
116120
{
117121
groups ??= [];
118122
foreach (var groupName in dataLoader.Groups)
119123
{
120-
groups.Add(($"{dataLoader.Namespace}.I{groupName}", $"{dataLoader.Namespace}.{groupName}"));
124+
groups.Add((
125+
$"{dataLoader.Namespace}.I{groupName}",
126+
$"{dataLoader.Namespace}.{groupName}"));
121127
}
122128
}
123129
}

src/HotChocolate/Core/src/Types.Analyzers/Helpers/DataLoaderAttributeHelper.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,27 @@ public static bool RegisterService(
328328
return true;
329329
}
330330

331+
public static bool GenerateInterfaces(
332+
this SeparatedSyntaxList<AttributeArgumentSyntax> arguments,
333+
GeneratorSyntaxContext context)
334+
{
335+
var argumentSyntax = arguments.FirstOrDefault(
336+
t => t.NameEquals?.Name.ToFullString().Trim() == "GenerateInterfaces");
337+
338+
if (argumentSyntax is not null)
339+
{
340+
var valueExpression = argumentSyntax.Expression;
341+
var value = context.SemanticModel.GetConstantValue(valueExpression).Value;
342+
343+
if (value is not null)
344+
{
345+
return (bool)value;
346+
}
347+
}
348+
349+
return true;
350+
}
351+
331352
public static bool TryGetName(
332353
this AttributeData attribute,
333354
[NotNullWhen(true)] out string? name)

src/HotChocolate/Core/src/Types.Analyzers/Helpers/GeneratorUtils.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,21 @@ public static DataLoaderDefaultsInfo GetDataLoaderDefaults(
4141
}
4242
}
4343

44-
return new DataLoaderDefaultsInfo(null, null, true, true);
44+
return new DataLoaderDefaultsInfo(null, null, true, true, true);
45+
}
46+
47+
public static DataLoaderDefaultsInfo GetDataLoaderDefaults(
48+
this List<SyntaxInfo> syntaxInfos)
49+
{
50+
foreach (var syntaxInfo in syntaxInfos)
51+
{
52+
if (syntaxInfo is DataLoaderDefaultsInfo defaults)
53+
{
54+
return defaults;
55+
}
56+
}
57+
58+
return new DataLoaderDefaultsInfo(null, null, true, true, true);
4559
}
4660

4761
public static string CreateModuleName(string? assemblyName)

src/HotChocolate/Core/src/Types.Analyzers/Inspectors/DataLoaderDefaultsInspector.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public bool TryHandle(
3939
attribList.Arguments.IsScoped(context),
4040
attribList.Arguments.IsPublic(context),
4141
attribList.Arguments.IsInterfacePublic(context),
42-
attribList.Arguments.RegisterService(context));
42+
attribList.Arguments.RegisterService(context),
43+
attribList.Arguments.GenerateInterfaces(context));
4344
return true;
4445
}
4546
}

src/HotChocolate/Core/src/Types.Analyzers/Models/DataLoaderDefaultsInfo.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ public sealed class DataLoaderDefaultsInfo(
44
bool? scoped,
55
bool? isPublic,
66
bool? isInterfacePublic,
7-
bool registerServices)
7+
bool registerServices,
8+
bool generateInterfaces)
89
: SyntaxInfo
910
{
1011
public bool? Scoped { get; } = scoped;
@@ -15,6 +16,8 @@ public sealed class DataLoaderDefaultsInfo(
1516

1617
public bool RegisterServices { get; } = registerServices;
1718

19+
public bool GenerateInterfaces { get; } = generateInterfaces;
20+
1821
public override bool Equals(object? obj)
1922
=> obj is DataLoaderDefaultsInfo other && Equals(other);
2023

@@ -25,8 +28,9 @@ private bool Equals(DataLoaderDefaultsInfo other)
2528
=> Scoped.Equals(other.Scoped)
2629
&& IsPublic.Equals(other.IsPublic)
2730
&& IsInterfacePublic.Equals(other.IsInterfacePublic)
28-
&& RegisterServices.Equals(other.RegisterServices);
31+
&& RegisterServices.Equals(other.RegisterServices)
32+
&& GenerateInterfaces.Equals(other.GenerateInterfaces);
2933

3034
public override int GetHashCode()
31-
=> HashCode.Combine(Scoped, IsPublic, IsInterfacePublic, RegisterServices);
35+
=> HashCode.Combine(Scoped, IsPublic, IsInterfacePublic, RegisterServices, GenerateInterfaces);
3236
}

0 commit comments

Comments
 (0)