Skip to content

Commit 037b69a

Browse files
authored
Allow for internal DataLoader modules and groups. (#8028)
1 parent 09a7c51 commit 037b69a

15 files changed

+486
-41
lines changed

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@
1313
"*.targets": "xml",
1414
"*.tasks": "xml"
1515
},
16-
"dotnet.defaultSolution": "src/All.sln"
16+
"dotnet.defaultSolution": "src/All.slnx"
1717
}

global.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"sdk": {
3-
"version": "9.0.100",
3+
"version": "9.0.200",
44
"rollForward": "latestMinor"
55
}
66
}

src/GreenDonut/src/GreenDonut.Abstractions/Attributes/DataLoaderModuleAttribute.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,9 @@ public DataLoaderModuleAttribute(string name)
2323
/// </summary>
2424
/// <value></value>
2525
public string Name { get; }
26+
27+
/// <summary>
28+
/// Specifies if the generated module shall be internal.
29+
/// </summary>
30+
public bool IsInternal { get; set; }
2631
}

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -567,11 +567,16 @@ kind is DataLoaderKind.Cache
567567
public void WriteDataLoaderGroupClass(
568568
string groupClassName,
569569
IReadOnlyList<GroupedDataLoaderInfo> dataLoaders,
570-
bool withInterface)
570+
bool withInterface,
571+
bool isInterfacePublic,
572+
bool isClassPublic)
571573
{
572574
if (withInterface)
573575
{
574-
_writer.WriteIndentedLine("public interface I{0}", groupClassName);
576+
_writer.WriteIndentedLine(
577+
"{0} interface I{1}",
578+
isInterfacePublic ? "public" : "internal",
579+
groupClassName);
575580
_writer.WriteIndentedLine("{");
576581
_writer.IncreaseIndent();
577582

@@ -587,11 +592,17 @@ public void WriteDataLoaderGroupClass(
587592

588593
if (withInterface)
589594
{
590-
_writer.WriteIndentedLine("public sealed partial class {0} : I{0}", groupClassName);
595+
_writer.WriteIndentedLine(
596+
"{0} sealed partial class {1} : I{1}",
597+
isClassPublic ? "public" : "internal",
598+
groupClassName);
591599
}
592600
else
593601
{
594-
_writer.WriteIndentedLine("public sealed partial class {0}", groupClassName);
602+
_writer.WriteIndentedLine(
603+
"{0} sealed partial class {1}",
604+
isClassPublic ? "public" : "internal",
605+
groupClassName);
595606
}
596607

597608
_writer.WriteIndentedLine("{");

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@ public void WriteEndNamespace()
4444
_writer.WriteIndentedLine("}");
4545
}
4646

47-
public void WriteBeginClass()
47+
public void WriteBeginClass(bool isInternal)
4848
{
4949
_writer.WriteIndentedLine(
50-
"public static partial class {0}DataLoaderServiceExtensions",
50+
"{0} static partial class {1}DataLoaderServiceExtensions",
51+
isInternal ? "internal" : "public",
5152
_moduleName);
5253
_writer.WriteIndentedLine("{");
5354
_writer.IncreaseIndent();

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,15 @@ private static void WriteDataLoader(
106106
t.InterfaceName,
107107
t.IsInterfacePublic ?? isPublic));
108108

109-
buffer ??= new();
109+
buffer ??= [];
110110
buffer.Clear();
111111
buffer.AddRange(dataLoaderGroups);
112-
generator.WriteDataLoaderGroupClass(dataLoaderGroup.Key, buffer, defaults.GenerateInterfaces);
112+
generator.WriteDataLoaderGroupClass(
113+
dataLoaderGroup.Key,
114+
buffer,
115+
defaults.GenerateInterfaces,
116+
defaults.IsInterfacePublic ?? true,
117+
defaults.IsPublic ?? true);
113118
}
114119

115120
generator.WriteEndNamespace();

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public void Generate(
2626

2727
generator.WriteHeader();
2828
generator.WriteBeginNamespace();
29-
generator.WriteBeginClass();
29+
generator.WriteBeginClass(module.IsInternal);
3030
generator.WriteBeginRegistrationMethod();
3131

3232
foreach (var syntaxInfo in syntaxInfos)
@@ -81,7 +81,9 @@ public void Generate(
8181
{
8282
if (syntaxInfo is DataLoaderModuleInfo module)
8383
{
84-
return new DataLoaderModuleInfo(GeneratorUtils.SanitizeIdentifier(module.ModuleName));
84+
return new DataLoaderModuleInfo(
85+
GeneratorUtils.SanitizeIdentifier(module.ModuleName),
86+
module.IsInternal);
8587
}
8688
}
8789

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

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -92,26 +92,6 @@ static bool IsDataLoaderGroupAttribute(INamedTypeSymbol? attributeClass)
9292
return null;
9393
}
9494

95-
private static bool IsTypeName(INamedTypeSymbol? type, string containingNamespace, string typeName)
96-
{
97-
if (type is null)
98-
{
99-
return false;
100-
}
101-
102-
while (type != null)
103-
{
104-
if (type.MetadataName == typeName && type.ContainingNamespace?.ToDisplayString() == containingNamespace)
105-
{
106-
return true;
107-
}
108-
109-
type = type.BaseType;
110-
}
111-
112-
return false;
113-
}
114-
11595
public static bool? IsScoped(
11696
this SeparatedSyntaxList<AttributeArgumentSyntax> arguments,
11797
GeneratorSyntaxContext context)
@@ -307,6 +287,27 @@ public static string[] GetLookups(this AttributeData attribute)
307287
return null;
308288
}
309289

290+
public static bool IsModuleInternal(
291+
this SeparatedSyntaxList<AttributeArgumentSyntax> arguments,
292+
GeneratorSyntaxContext context)
293+
{
294+
var argumentSyntax = arguments.FirstOrDefault(
295+
t => t.NameEquals?.Name.ToFullString().Trim() == "IsInternal");
296+
297+
if (argumentSyntax is not null)
298+
{
299+
var valueExpression = argumentSyntax.Expression;
300+
var value = context.SemanticModel.GetConstantValue(valueExpression).Value;
301+
302+
if (value is bool b)
303+
{
304+
return b;
305+
}
306+
}
307+
308+
return false;
309+
}
310+
310311
public static bool RegisterService(
311312
this SeparatedSyntaxList<AttributeArgumentSyntax> arguments,
312313
GeneratorSyntaxContext context)
@@ -319,9 +320,9 @@ public static bool RegisterService(
319320
var valueExpression = argumentSyntax.Expression;
320321
var value = context.SemanticModel.GetConstantValue(valueExpression).Value;
321322

322-
if (value is not null)
323+
if (value is bool b)
323324
{
324-
return (bool)value;
325+
return b;
325326
}
326327
}
327328

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
using HotChocolate.Types.Analyzers.Models;
44
using Microsoft.CodeAnalysis;
55
using Microsoft.CodeAnalysis.CSharp.Syntax;
6+
using HotChocolate.Types.Analyzers.Helpers;
67
using static System.StringComparison;
78
using static HotChocolate.Types.Analyzers.WellKnownAttributes;
8-
using static HotChocolate.Types.Analyzers.WellKnownTypes;
99

1010
namespace HotChocolate.Types.Analyzers.Inspectors;
1111

@@ -31,11 +31,14 @@ public bool TryHandle(
3131
var fullName = attributeContainingTypeSymbol.ToDisplayString();
3232

3333
if (fullName.Equals(DataLoaderModuleAttribute, Ordinal) &&
34-
attributeSyntax.ArgumentList is { Arguments.Count: > 0, })
34+
attributeSyntax.ArgumentList is { Arguments.Count: > 0 })
3535
{
36+
3637
var nameExpr = attributeSyntax.ArgumentList.Arguments[0].Expression;
3738
var name = context.SemanticModel.GetConstantValue(nameExpr).ToString();
38-
syntaxInfo = new DataLoaderModuleInfo(name);
39+
syntaxInfo = new DataLoaderModuleInfo(
40+
name,
41+
attributeSyntax.ArgumentList.Arguments.IsModuleInternal(context));
3942
return true;
4043
}
4144
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using Microsoft.CodeAnalysis.CSharp.Syntax;
66
using static System.StringComparison;
77
using static HotChocolate.Types.Analyzers.WellKnownAttributes;
8-
using static HotChocolate.Types.Analyzers.WellKnownTypes;
98

109
namespace HotChocolate.Types.Analyzers.Inspectors;
1110

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
namespace HotChocolate.Types.Analyzers.Models;
22

3-
public sealed class DataLoaderModuleInfo(string moduleName) : SyntaxInfo
3+
public sealed class DataLoaderModuleInfo(string moduleName, bool isInternal) : SyntaxInfo
44
{
55
public string ModuleName { get; } = moduleName;
66

7+
public bool IsInternal { get; } = isInternal;
8+
79
public override string OrderByKey => ModuleName;
810

911
public override bool Equals(object? obj)
@@ -13,8 +15,9 @@ public override bool Equals(SyntaxInfo obj)
1315
=> obj is DataLoaderModuleInfo other && Equals(other);
1416

1517
private bool Equals(DataLoaderModuleInfo other)
16-
=> string.Equals(ModuleName, other.ModuleName, StringComparison.Ordinal);
18+
=> string.Equals(ModuleName, other.ModuleName, StringComparison.Ordinal)
19+
&& IsInternal == other.IsInternal;
1720

1821
public override int GetHashCode()
19-
=> HashCode.Combine(ModuleName);
22+
=> HashCode.Combine(ModuleName, IsInternal);
2023
}

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

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,4 +579,90 @@ public static Task<IDictionary<int, string>> GetEntityByIdAsync(
579579
}
580580
""").MatchMarkdownAsync();
581581
}
582+
583+
[Fact]
584+
public async Task Generate_DataLoader_Module_As_Internal()
585+
{
586+
await TestHelper.GetGeneratedSourceSnapshot(
587+
"""
588+
using System.Collections.Generic;
589+
using System.Threading;
590+
using System.Threading.Tasks;
591+
using HotChocolate;
592+
using GreenDonut;
593+
594+
[assembly: GreenDonut.DataLoaderModule("Abc", IsInternal = true)]
595+
596+
namespace TestNamespace;
597+
598+
internal static class TestClass
599+
{
600+
[DataLoader]
601+
public static Task<IDictionary<int, string>> GetEntityByIdAsync(
602+
IReadOnlyList<int> entityIds,
603+
GreenDonut.Data.IPredicateBuilder predicate,
604+
CancellationToken cancellationToken)
605+
=> default!;
606+
}
607+
""").MatchMarkdownAsync();
608+
}
609+
610+
[Fact]
611+
public async Task Generate_DataLoader_Module_As_Internal_Implementation_As_Internal()
612+
{
613+
await TestHelper.GetGeneratedSourceSnapshot(
614+
"""
615+
using System.Collections.Generic;
616+
using System.Threading;
617+
using System.Threading.Tasks;
618+
using HotChocolate;
619+
using GreenDonut;
620+
621+
[assembly: GreenDonut.DataLoaderModule("Abc", IsInternal = true)]
622+
[assembly: GreenDonut.DataLoaderDefaults(
623+
AccessModifier = GreenDonut.DataLoaderAccessModifier.PublicInterface)]
624+
625+
namespace TestNamespace;
626+
627+
internal static class TestClass
628+
{
629+
[DataLoader]
630+
public static Task<IDictionary<int, string>> GetEntityByIdAsync(
631+
IReadOnlyList<int> entityIds,
632+
GreenDonut.Data.IPredicateBuilder predicate,
633+
CancellationToken cancellationToken)
634+
=> default!;
635+
}
636+
""").MatchMarkdownAsync();
637+
}
638+
639+
[Fact]
640+
public async Task Generate_DataLoader_Module_As_Internal_Implementation_As_Internal_With_Group()
641+
{
642+
await TestHelper.GetGeneratedSourceSnapshot(
643+
"""
644+
using System.Collections.Generic;
645+
using System.Threading;
646+
using System.Threading.Tasks;
647+
using HotChocolate;
648+
using GreenDonut;
649+
650+
[assembly: GreenDonut.DataLoaderModule("Abc", IsInternal = true)]
651+
[assembly: GreenDonut.DataLoaderDefaults(
652+
AccessModifier = GreenDonut.DataLoaderAccessModifier.PublicInterface)]
653+
654+
namespace TestNamespace;
655+
656+
[DataLoaderGroup("Test123")]
657+
internal static class TestClass
658+
{
659+
[DataLoader]
660+
public static Task<IDictionary<int, string>> GetEntityByIdAsync(
661+
IReadOnlyList<int> entityIds,
662+
GreenDonut.Data.IPredicateBuilder predicate,
663+
CancellationToken cancellationToken)
664+
=> default!;
665+
}
666+
""").MatchMarkdownAsync();
667+
}
582668
}

0 commit comments

Comments
 (0)