diff --git a/src/HotChocolate/Core/src/Types.Analyzers/Generators/DataLoaderGenerator.cs b/src/HotChocolate/Core/src/Types.Analyzers/Generators/DataLoaderGenerator.cs index 3752ef0a0bf..661fcfe3249 100644 --- a/src/HotChocolate/Core/src/Types.Analyzers/Generators/DataLoaderGenerator.cs +++ b/src/HotChocolate/Core/src/Types.Analyzers/Generators/DataLoaderGenerator.cs @@ -1,4 +1,5 @@ using System.Text; +using HotChocolate.Types.Analyzers.Helpers; using HotChocolate.Types.Analyzers.Inspectors; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; @@ -31,9 +32,7 @@ public class DataLoaderGenerator : ISyntaxGenerator DiagnosticSeverity.Error, isEnabledByDefault: true); - public void Initialize(IncrementalGeneratorPostInitializationContext context) - { - } + public void Initialize(IncrementalGeneratorPostInitializationContext context) { } public bool Consume(ISyntaxInfo syntaxInfo) => syntaxInfo is DataLoaderInfo or ModuleInfo or DataLoaderDefaultsInfo; @@ -57,7 +56,7 @@ compilation.AssemblyName is null var processed = new HashSet(StringComparer.Ordinal); var dataLoaders = new List(); - var sourceText = new StringBuilder(); + var sourceText = StringBuilderPool.Get(); sourceText.AppendLine("// "); sourceText.AppendLine("#nullable enable"); @@ -119,6 +118,7 @@ compilation.AssemblyName is null } else { + keyType = keyArg.Type; kind = DataLoaderKind.Cache; } @@ -159,6 +159,8 @@ compilation.AssemblyName is null WellKnownFileNames.DataLoaderFile, SourceText.From(sourceText.ToString(), Encoding.UTF8)); } + + StringBuilderPool.Return(sourceText); } private static void GenerateDataLoader( @@ -172,7 +174,7 @@ private static void GenerateDataLoader( Dictionary services, StringBuilder sourceText) { - var isScoped = dataLoader.IsScoped ?? defaults.Scoped ?? false; + var isScoped = dataLoader.IsScoped ?? defaults.Scoped ?? false; var isPublic = dataLoader.IsPublic ?? defaults.IsPublic ?? true; var isInterfacePublic = dataLoader.IsInterfacePublic ?? defaults.IsInterfacePublic ?? true; @@ -198,21 +200,17 @@ private static void GenerateDataLoader( if (kind is DataLoaderKind.Batch or DataLoaderKind.Cache) { sourceText.Append(" : global::GreenDonut.IDataLoader<"); - sourceText.Append("global::"); - sourceText.Append(ToTypeName(keyType)); + sourceText.Append(keyType.ToFullyQualified()); sourceText.Append(", "); - sourceText.Append("global::"); - sourceText.Append(ToTypeName(valueType)); + sourceText.Append(valueType.ToFullyQualified()); sourceText.Append(">"); } else if (kind is DataLoaderKind.Group) { sourceText.Append(" : global::GreenDonut.IDataLoader<"); - sourceText.Append("global::"); - sourceText.Append(ToTypeName(keyType)); + sourceText.Append(keyType.ToFullyQualified()); sourceText.Append(", "); - sourceText.Append("global::"); - sourceText.Append(ToTypeName(valueType)); + sourceText.Append(valueType.ToFullyQualified()); sourceText.Append("[]>"); } @@ -234,31 +232,25 @@ private static void GenerateDataLoader( if (kind is DataLoaderKind.Batch) { sourceText.Append(" : global::GreenDonut.BatchDataLoader<"); - sourceText.Append("global::"); - sourceText.Append(ToTypeName(keyType)); + sourceText.Append(keyType.ToFullyQualified()); sourceText.Append(", "); - sourceText.Append("global::"); - sourceText.Append(ToTypeName(valueType)); + sourceText.Append(valueType.ToFullyQualified()); sourceText.Append(">"); } else if (kind is DataLoaderKind.Group) { sourceText.Append(" : global::GreenDonut.GroupedDataLoader<"); - sourceText.Append("global::"); - sourceText.Append(ToTypeName(keyType)); + sourceText.Append(keyType.ToFullyQualified()); sourceText.Append(", "); - sourceText.Append("global::"); - sourceText.Append(ToTypeName(valueType)); + sourceText.Append(valueType.ToFullyQualified()); sourceText.Append(">"); } else if (kind is DataLoaderKind.Cache) { sourceText.Append(" : global::GreenDonut.CacheDataLoader<"); - sourceText.Append("global::"); - sourceText.Append(ToTypeName(keyType)); + sourceText.Append(keyType.ToFullyQualified()); sourceText.Append(", "); - sourceText.Append("global::"); - sourceText.Append(ToTypeName(valueType)); + sourceText.Append(valueType.ToFullyQualified()); sourceText.Append(">"); } @@ -266,7 +258,8 @@ private static void GenerateDataLoader( sourceText.AppendLine(interfaceName); sourceText.AppendLine(" {"); - sourceText.AppendLine(" private readonly IServiceProvider _services;"); + sourceText.AppendLine( + " private readonly global::System.IServiceProvider _services;"); sourceText.AppendLine(); if (kind is DataLoaderKind.Batch or DataLoaderKind.Group) @@ -279,7 +272,7 @@ private static void GenerateDataLoader( .Append(Indent) .Append(Indent) .Append(Indent) - .AppendLine("IServiceProvider services,"); + .AppendLine("global::System.IServiceProvider services,"); sourceText .Append(Indent) .Append(Indent) @@ -307,7 +300,7 @@ private static void GenerateDataLoader( .Append(Indent) .Append(Indent) .Append(Indent) - .AppendLine("IServiceProvider services,"); + .AppendLine("global::System.IServiceProvider services,"); sourceText .Append(Indent) .Append(Indent) @@ -324,47 +317,45 @@ private static void GenerateDataLoader( sourceText.AppendLine(" {"); sourceText.AppendLine(" _services = services ??"); - sourceText.AppendLine(" throw new ArgumentNullException(nameof(services));"); + sourceText.Append(" throw new global::") + .AppendLine("System.ArgumentNullException(nameof(services));"); sourceText.AppendLine(" }"); sourceText.AppendLine(); if (kind is DataLoaderKind.Batch) { - sourceText.Append($" protected override async {WellKnownTypes.Task}<"); - sourceText.Append($"global::{ReadOnlyDictionary}<"); - sourceText.Append("global::"); - sourceText.Append(ToTypeName(keyType)); - sourceText.Append(", global::"); - sourceText.Append(ToTypeName(valueType)); + sourceText.Append($" protected override async global::{WellKnownTypes.Task}<"); + sourceText.Append($"{ReadOnlyDictionary}<"); + sourceText.Append(keyType.ToFullyQualified()); + sourceText.Append(", "); + sourceText.Append(valueType.ToFullyQualified()); sourceText.Append(">> "); sourceText.AppendLine("LoadBatchAsync("); - sourceText.Append($" global::{ReadOnlyList}<"); - sourceText.AppendLine($"global::{ToTypeName(keyType)}> keys,"); + sourceText.Append($" {ReadOnlyList}<"); + sourceText.AppendLine($"{keyType.ToFullyQualified()}> keys,"); sourceText.AppendLine($" global::{WellKnownTypes.CancellationToken} ct)"); } else if (kind is DataLoaderKind.Group) { - sourceText.Append($" protected override async {WellKnownTypes.Task}<"); - sourceText.Append($"global::{Lookup}<"); - sourceText.Append("global::"); - sourceText.Append(ToTypeName(keyType)); - sourceText.Append(", global::"); - sourceText.Append(ToTypeName(valueType)); + sourceText.Append($" protected override async global::{WellKnownTypes.Task}<"); + sourceText.Append($"{Lookup}<"); + sourceText.Append(keyType.ToFullyQualified()); + sourceText.Append(", "); + sourceText.Append(valueType.ToFullyQualified()); sourceText.Append(">> "); sourceText.AppendLine("LoadGroupedBatchAsync("); - sourceText.Append($" global::{ReadOnlyList}<"); - sourceText.AppendLine($"global::{ToTypeName(keyType)}> keys,"); + sourceText.Append($" {ReadOnlyList}<"); + sourceText.AppendLine($"{keyType.ToFullyQualified()}> keys,"); sourceText.AppendLine($" global::{WellKnownTypes.CancellationToken} ct)"); } else if (kind is DataLoaderKind.Cache) { - sourceText.Append($" protected override async {WellKnownTypes.Task}<"); - sourceText.Append("global::"); - sourceText.Append(ToTypeName(valueType)); + sourceText.Append($" protected override async global::{WellKnownTypes.Task}<"); + sourceText.Append(valueType.ToFullyQualified()); sourceText.Append("> "); sourceText.AppendLine("LoadSingleAsync("); - sourceText.AppendLine($" global::{ToTypeName(keyType)} key,"); - sourceText.AppendLine($" global::{WellKnownTypes.CancellationToken} ct)"); + sourceText.AppendLine($" {keyType.ToFullyQualified()} key,"); + sourceText.AppendLine($" {WellKnownTypes.CancellationToken} ct)"); } sourceText.AppendLine(" {"); @@ -382,6 +373,7 @@ private static void GenerateDataLoader( sourceText.Append($" var p{item.Key} = "); sourceText.Append("scope.ServiceProvider.GetRequiredService<"); sourceText.Append(item.Value); + TestLog.Log("scoped: " + item.Value); sourceText.AppendLine(">();"); } } @@ -391,11 +383,12 @@ private static void GenerateDataLoader( { sourceText.Append($" var p{item.Key} = _services.GetRequiredService<"); sourceText.Append(item.Value); + TestLog.Log("non scoped: " + item.Value); sourceText.AppendLine(">();"); } } - sourceText.Append(" return await global::"); + sourceText.Append(" return await "); sourceText.Append(dataLoader.ContainingType); sourceText.Append("."); sourceText.Append(dataLoader.MethodName); @@ -468,9 +461,8 @@ private static void GenerateDataLoaderRegistrations( .Append(Indent) .Append(Indent) .Append("builder.AddDataLoader<") - .Append("global::") .Append(dataLoader.InterfaceFullName) - .Append(", global::") + .Append(", ") .Append(dataLoader.FullName) .AppendLine(">();"); } @@ -493,7 +485,7 @@ private void InspectDataLoaderParameters( for (var i = 1; i < dataLoader.MethodSymbol.Parameters.Length; i++) { var argument = dataLoader.MethodSymbol.Parameters[i]; - var argumentType = ToTypeName(argument.Type); + var argumentType = argument.Type.ToFullyQualified(); if (IsCancellationToken(argumentType)) { @@ -515,7 +507,7 @@ private void InspectDataLoaderParameters( private static bool IsKeysArgument(ITypeSymbol type) { if (type is INamedTypeSymbol { IsGenericType: true, TypeArguments.Length: 1 } namedType && - ReadOnlyList.Equals(ToTypeName(namedType), Ordinal)) + ReadOnlyList.Equals(ToTypeNameNoGenerics(namedType), Ordinal)) { return true; } @@ -526,7 +518,7 @@ private static bool IsKeysArgument(ITypeSymbol type) private static ITypeSymbol ExtractKeyType(ITypeSymbol type) { if (type is INamedTypeSymbol { IsGenericType: true, TypeArguments.Length: 1 } namedType && - ReadOnlyList.Equals(ToTypeName(namedType), Ordinal)) + ReadOnlyList.Equals(ToTypeNameNoGenerics(namedType), Ordinal)) { return namedType.TypeArguments[0]; } @@ -535,10 +527,8 @@ private static ITypeSymbol ExtractKeyType(ITypeSymbol type) } private static bool IsCancellationToken(string typeName) - => string.Equals(typeName, WellKnownTypes.CancellationToken); - - private static string ToTypeName(ITypeSymbol type) - => $"{type.ContainingNamespace}.{type.Name}"; + => string.Equals(typeName, WellKnownTypes.CancellationToken) || + string.Equals(typeName, GlobalCancellationToken); private static bool IsReturnTypeDictionary(ITypeSymbol returnType, ITypeSymbol keyType) { @@ -562,7 +552,7 @@ private static bool IsReturnTypeLookup(ITypeSymbol returnType, ITypeSymbol keyTy { var resultType = namedType.TypeArguments[0]; - if (ToTypeName(resultType).Equals(Lookup, Ordinal) && + if (ToTypeNameNoGenerics(resultType).Equals(Lookup, Ordinal) && resultType is INamedTypeSymbol { TypeArguments.Length: 2 } dictionaryType && dictionaryType.TypeArguments[0].Equals(keyType, SymbolEqualityComparer.Default)) { @@ -574,11 +564,11 @@ private static bool IsReturnTypeLookup(ITypeSymbol returnType, ITypeSymbol keyTy private static bool IsReadOnlyDictionary(ITypeSymbol type) { - if (!ToTypeName(type).Equals(ReadOnlyDictionary, Ordinal)) + if (!ToTypeNameNoGenerics(type).Equals(ReadOnlyDictionary, Ordinal)) { foreach (var interfaceSymbol in type.Interfaces) { - if (ToTypeName(interfaceSymbol).Equals(ReadOnlyDictionary, Ordinal)) + if (ToTypeNameNoGenerics(interfaceSymbol).Equals(ReadOnlyDictionary, Ordinal)) { return true; } @@ -608,4 +598,7 @@ private static ITypeSymbol ExtractValueType(ITypeSymbol returnType, DataLoaderKi throw new InvalidOperationException(); } + + private static string ToTypeNameNoGenerics(ITypeSymbol typeSymbol) + => $"{typeSymbol.ContainingNamespace}.{typeSymbol.Name}"; } diff --git a/src/HotChocolate/Core/src/Types.Analyzers/Generators/ModuleGenerator.cs b/src/HotChocolate/Core/src/Types.Analyzers/Generators/ModuleGenerator.cs index 3f66606b1e0..03335cdb718 100644 --- a/src/HotChocolate/Core/src/Types.Analyzers/Generators/ModuleGenerator.cs +++ b/src/HotChocolate/Core/src/Types.Analyzers/Generators/ModuleGenerator.cs @@ -1,4 +1,5 @@ using System.Text; +using HotChocolate.Types.Analyzers.Helpers; using HotChocolate.Types.Analyzers.Inspectors; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; @@ -38,38 +39,38 @@ compilation.AssemblyName is null return; } - var code = new StringBuilder(); - code.AppendLine("// "); - code.AppendLine("#nullable enable"); - code.AppendLine("using System;"); - code.AppendLine("using HotChocolate.Execution.Configuration;"); + var sourceText = StringBuilderPool.Get(); + sourceText.AppendLine("// "); + sourceText.AppendLine("#nullable enable"); + sourceText.AppendLine("using System;"); + sourceText.AppendLine("using HotChocolate.Execution.Configuration;"); - code.AppendLine(); - code.AppendLine("namespace Microsoft.Extensions.DependencyInjection"); - code.AppendLine("{"); + sourceText.AppendLine(); + sourceText.AppendLine("namespace Microsoft.Extensions.DependencyInjection"); + sourceText.AppendLine("{"); - code.Append(Indent) + sourceText.Append(Indent) .Append("public static partial class ") .Append(module.ModuleName) .AppendLine("RequestExecutorBuilderExtensions"); - code.Append(Indent) + sourceText.Append(Indent) .AppendLine("{"); - code.Append(Indent) + sourceText.Append(Indent) .Append(Indent) .Append("public static IRequestExecutorBuilder Add") .Append(module.ModuleName) .AppendLine("(this IRequestExecutorBuilder builder)"); - code.Append(Indent).Append(Indent).AppendLine("{"); + sourceText.Append(Indent).Append(Indent).AppendLine("{"); - code + sourceText .Append(Indent) .Append(Indent) .Append(Indent) .AppendLine("RegisterGeneratedDataLoader(builder);"); - code.AppendLine(); + sourceText.AppendLine(); var operations = OperationType.No; @@ -81,7 +82,7 @@ compilation.AssemblyName is null if ((module.Options & ModuleOptions.RegisterTypes) == ModuleOptions.RegisterTypes) { - code.Append(Indent) + sourceText.Append(Indent) .Append(Indent) .Append(Indent) .Append("builder.AddType<") @@ -96,7 +97,7 @@ compilation.AssemblyName is null { if (extension.IsStatic) { - code.Append(Indent) + sourceText.Append(Indent) .Append(Indent) .Append(Indent) .Append("builder.AddTypeExtension(typeof(") @@ -105,7 +106,7 @@ compilation.AssemblyName is null } else { - code.Append(Indent) + sourceText.Append(Indent) .Append(Indent) .Append(Indent) .Append("builder.AddTypeExtension<") @@ -125,7 +126,7 @@ compilation.AssemblyName is null if ((module.Options & ModuleOptions.RegisterDataLoader) == ModuleOptions.RegisterDataLoader) { - code.Append(Indent) + sourceText.Append(Indent) .Append(Indent) .Append(Indent) .Append("builder.AddDataLoader<") @@ -138,39 +139,40 @@ compilation.AssemblyName is null if ((operations & OperationType.Query) == OperationType.Query) { - WriteTryAddOperationType(code, OperationType.Query); + WriteTryAddOperationType(sourceText, OperationType.Query); } if ((operations & OperationType.Mutation) == OperationType.Mutation) { - WriteTryAddOperationType(code, OperationType.Mutation); + WriteTryAddOperationType(sourceText, OperationType.Mutation); } if ((operations & OperationType.Subscription) == OperationType.Subscription) { - WriteTryAddOperationType(code, OperationType.Subscription); + WriteTryAddOperationType(sourceText, OperationType.Subscription); } - code.Append(Indent).Append(Indent).Append(Indent).AppendLine("return builder;"); - code.Append(Indent).Append(Indent).AppendLine("}"); + sourceText.Append(Indent).Append(Indent).Append(Indent).AppendLine("return builder;"); + sourceText.Append(Indent).Append(Indent).AppendLine("}"); - code.AppendLine(); + sourceText.AppendLine(); - code + sourceText .Append(Indent) .Append(Indent) .Append("static partial void RegisterGeneratedDataLoader(") .AppendLine("IRequestExecutorBuilder builder);"); - code.Append(Indent).AppendLine("}"); + sourceText.Append(Indent).AppendLine("}"); - code.AppendLine("}"); + sourceText.AppendLine("}"); - context.AddSource(TypeModuleFile, SourceText.From(code.ToString(), Encoding.UTF8)); + context.AddSource(TypeModuleFile, SourceText.From(sourceText.ToString(), Encoding.UTF8)); + StringBuilderPool.Return(sourceText); } - private static void WriteTryAddOperationType(StringBuilder code, OperationType type) - => code.Append(Indent) + private static void WriteTryAddOperationType(StringBuilder sourceText, OperationType type) + => sourceText.Append(Indent) .Append(Indent) .Append(Indent) .Append("builder.ConfigureSchema(") diff --git a/src/HotChocolate/Core/src/Types.Analyzers/Inspectors/DataLoaderAttributeHelper.cs b/src/HotChocolate/Core/src/Types.Analyzers/Helpers/DataLoaderAttributeHelper.cs similarity index 99% rename from src/HotChocolate/Core/src/Types.Analyzers/Inspectors/DataLoaderAttributeHelper.cs rename to src/HotChocolate/Core/src/Types.Analyzers/Helpers/DataLoaderAttributeHelper.cs index b16cc463fff..222be1af159 100644 --- a/src/HotChocolate/Core/src/Types.Analyzers/Inspectors/DataLoaderAttributeHelper.cs +++ b/src/HotChocolate/Core/src/Types.Analyzers/Helpers/DataLoaderAttributeHelper.cs @@ -2,7 +2,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; -namespace HotChocolate.Types.Analyzers.Inspectors; +namespace HotChocolate.Types.Analyzers.Helpers; public static class DataLoaderAttributeHelper { diff --git a/src/HotChocolate/Core/src/Types.Analyzers/Helpers/StringBuilderPool.cs b/src/HotChocolate/Core/src/Types.Analyzers/Helpers/StringBuilderPool.cs new file mode 100644 index 00000000000..2f8fe5b7e15 --- /dev/null +++ b/src/HotChocolate/Core/src/Types.Analyzers/Helpers/StringBuilderPool.cs @@ -0,0 +1,20 @@ +using System.Text; + +namespace HotChocolate.Types.Analyzers.Helpers; + +public static class StringBuilderPool +{ + private static StringBuilder? _stringBuilder; + + public static StringBuilder Get() + { + var stringBuilder = Interlocked.Exchange(ref _stringBuilder, null); + return stringBuilder ?? new StringBuilder(); + } + + public static void Return(StringBuilder stringBuilder) + { + stringBuilder.Clear(); + Interlocked.CompareExchange(ref _stringBuilder, stringBuilder, null); + } +} diff --git a/src/HotChocolate/Core/src/Types.Analyzers/Helpers/SymbolExtensions.cs b/src/HotChocolate/Core/src/Types.Analyzers/Helpers/SymbolExtensions.cs new file mode 100644 index 00000000000..0473d15b7cc --- /dev/null +++ b/src/HotChocolate/Core/src/Types.Analyzers/Helpers/SymbolExtensions.cs @@ -0,0 +1,9 @@ +using Microsoft.CodeAnalysis; + +namespace HotChocolate.Types.Analyzers.Helpers; + +public static class SymbolExtensions +{ + public static string ToFullyQualified(this ITypeSymbol typeSymbol) + => typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); +} diff --git a/src/HotChocolate/Core/src/Types.Analyzers/Inspectors/DataLoaderDefaultsInspector.cs b/src/HotChocolate/Core/src/Types.Analyzers/Inspectors/DataLoaderDefaultsInspector.cs index 5b45513ff64..1845bffc3b9 100644 --- a/src/HotChocolate/Core/src/Types.Analyzers/Inspectors/DataLoaderDefaultsInspector.cs +++ b/src/HotChocolate/Core/src/Types.Analyzers/Inspectors/DataLoaderDefaultsInspector.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using HotChocolate.Types.Analyzers.Helpers; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using static System.StringComparison; diff --git a/src/HotChocolate/Core/src/Types.Analyzers/Inspectors/DataLoaderInfo.cs b/src/HotChocolate/Core/src/Types.Analyzers/Inspectors/DataLoaderInfo.cs index 8b4af7479bc..0f1f82bb113 100644 --- a/src/HotChocolate/Core/src/Types.Analyzers/Inspectors/DataLoaderInfo.cs +++ b/src/HotChocolate/Core/src/Types.Analyzers/Inspectors/DataLoaderInfo.cs @@ -1,3 +1,4 @@ +using HotChocolate.Types.Analyzers.Helpers; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -29,7 +30,7 @@ public DataLoaderInfo( MethodName = methodSymbol.Name; var type = methodSymbol.ContainingType; - ContainingType = $"{type.ContainingNamespace}.{type.Name}"; + ContainingType = type.ToDisplayString(); } public string Name { get; } diff --git a/src/HotChocolate/Core/src/Types.Analyzers/WellKnownTypes.cs b/src/HotChocolate/Core/src/Types.Analyzers/WellKnownTypes.cs index b556ed66813..1b2cd831b2a 100644 --- a/src/HotChocolate/Core/src/Types.Analyzers/WellKnownTypes.cs +++ b/src/HotChocolate/Core/src/Types.Analyzers/WellKnownTypes.cs @@ -18,6 +18,7 @@ public static class WellKnownTypes public const string EnumTypeExtension = "HotChocolate.Types.EnumTypeExtension"; public const string DataLoader = "GreenDonut.IDataLoader"; public const string CancellationToken = "System.Threading.CancellationToken"; + public const string GlobalCancellationToken = "global::System.Threading.CancellationToken"; public const string ReadOnlyList = "System.Collections.Generic.IReadOnlyList"; public const string ReadOnlyDictionary = "System.Collections.Generic.IReadOnlyDictionary"; public const string Lookup = "System.Linq.ILookup"; diff --git a/src/HotChocolate/Core/test/Types.Analyzers.Tests/SomeQuery.cs b/src/HotChocolate/Core/test/Types.Analyzers.Tests/SomeQuery.cs index 5f60a66e18f..0ed50c30710 100644 --- a/src/HotChocolate/Core/test/Types.Analyzers.Tests/SomeQuery.cs +++ b/src/HotChocolate/Core/test/Types.Analyzers.Tests/SomeQuery.cs @@ -20,9 +20,9 @@ public static class SomeQuery public static Book GetBook() => new() { Title = "SomeTitle" }; - public static Task WithDataLoader(IFoosByIdDataLoader foosById) + public static Task WithDataLoader(IFoosByIdDataLoader foosById, CancellationToken cancellationToken) { - return foosById.LoadAsync("a"); + return foosById.LoadAsync("a", cancellationToken); } [DataLoader] @@ -65,7 +65,7 @@ internal static async Task> GetFoosById( SomeService someService, CancellationToken cancellationToken) { - return ids.ToDictionary(t => t, t => t); + return await Task.FromResult(ids.ToDictionary(t => t, t => t)); } [DataLoader] @@ -74,20 +74,32 @@ public static async Task GetFoosById2( SomeService someService, CancellationToken cancellationToken) { - return "abc"; + return await Task.FromResult("abc"); } [DataLoader(ServiceScope = DataLoaderServiceScope.OriginalScope)] - public static async Task> GetFoosById3( + public static Task> GetFoosById3( IReadOnlyList ids, SomeService someService, CancellationToken cancellationToken) { return default!; } + + [DataLoader] + public static Task GetGenericById( + IReadOnlyList ids, + GenericService> someService, + CancellationToken cancellationToken) + { + return default!; + } } public class SomeService { } +public class GenericService +{ +} diff --git a/src/HotChocolate/Core/test/Types.Analyzers.Tests/ss.cs b/src/HotChocolate/Core/test/Types.Analyzers.Tests/ss.cs new file mode 100644 index 00000000000..e69de29bb2d