Skip to content

Commit 98d54f7

Browse files
committed
Added source gen support.
1 parent ec2b814 commit 98d54f7

File tree

19 files changed

+538
-280
lines changed

19 files changed

+538
-280
lines changed

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

Lines changed: 98 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ private static string ToFullyQualifiedString(
240240
IMethodSymbol resolverMethod,
241241
ILocalTypeLookup typeLookup)
242242
{
243-
if (type.TypeKind is TypeKind.Error && typeLookup.TryGetTypeName(type, resolverMethod, out var typeDisplayName))
243+
if (type.TypeKind is TypeKind.Error
244+
&& typeLookup.TryGetTypeName(type, resolverMethod, out var typeDisplayName))
244245
{
245246
return typeDisplayName;
246247
}
@@ -528,84 +529,92 @@ private void AddResolverArguments(Resolver resolver, IMethodSymbol resolverMetho
528529
case ResolverParameterKind.CancellationToken:
529530
_writer.WriteIndentedLine("var args{0} = context.RequestAborted;", i);
530531
break;
532+
531533
case ResolverParameterKind.ClaimsPrincipal:
532534
_writer.WriteIndentedLine(
533535
"var args{0} = context.GetGlobalState<{1}>(\"ClaimsPrincipal\");",
534536
i,
535537
WellKnownTypes.ClaimsPrincipal);
536538
break;
539+
537540
case ResolverParameterKind.DocumentNode:
538541
_writer.WriteIndentedLine("var args{0} = context.Operation.Document;", i);
539542
break;
543+
540544
case ResolverParameterKind.EventMessage:
541545
_writer.WriteIndentedLine(
542546
"var args{0} = context.GetScopedState<{1}>("
543547
+ "global::HotChocolate.WellKnownContextData.EventMessage);",
544548
i,
545549
parameter.Type.ToFullyQualified());
546550
break;
551+
547552
case ResolverParameterKind.FieldNode:
548553
_writer.WriteIndentedLine(
549554
"var args{0} = context.Selection.SyntaxNode",
550555
i,
551556
parameter.Type.ToFullyQualified());
552557
break;
558+
553559
case ResolverParameterKind.OutputField:
554560
_writer.WriteIndentedLine(
555561
"var args{0} = context.Selection.Field",
556562
i,
557563
parameter.Type.ToFullyQualified());
558564
break;
565+
559566
case ResolverParameterKind.HttpContext:
560567
_writer.WriteIndentedLine(
561568
"var args{0} = context.GetGlobalState<global::{1}>(nameof(global::{1}))!;",
562569
i,
563570
WellKnownTypes.HttpContext);
564571
break;
572+
565573
case ResolverParameterKind.HttpRequest:
566574
_writer.WriteIndentedLine(
567575
"var args{0} = context.GetGlobalState<global::{1}>(nameof(global::{1}))?.Request!;",
568576
i,
569577
WellKnownTypes.HttpContext);
570578
break;
579+
571580
case ResolverParameterKind.HttpResponse:
572581
_writer.WriteIndentedLine(
573582
"var args{0} = context.GetGlobalState<global::{1}>(nameof(global::{1}))?.Response!;",
574583
i,
575584
WellKnownTypes.HttpContext);
576585
break;
586+
577587
case ResolverParameterKind.GetGlobalState when parameter.Parameter.HasExplicitDefaultValue:
578-
{
579-
var defaultValue = parameter.Parameter.ExplicitDefaultValue;
580-
var defaultValueString = GeneratorUtils.ConvertDefaultValueToString(defaultValue, parameter.Type);
588+
{
589+
var defaultValue = parameter.Parameter.ExplicitDefaultValue;
590+
var defaultValueString = GeneratorUtils.ConvertDefaultValueToString(defaultValue, parameter.Type);
591+
592+
_writer.WriteIndentedLine(
593+
"var args{0} = context.GetGlobalStateOrDefault<{1}{2}>(\"{3}\", {4});",
594+
i,
595+
parameter.Type.ToFullyQualified(),
596+
parameter.Type.IsNullableRefType() ? "?" : string.Empty,
597+
parameter.Key,
598+
defaultValueString);
599+
break;
600+
}
581601

582-
_writer.WriteIndentedLine(
583-
"var args{0} = context.GetGlobalStateOrDefault<{1}{2}>(\"{3}\", {4});",
584-
i,
585-
parameter.Type.ToFullyQualified(),
586-
parameter.Type.IsNullableRefType() ? "?" : string.Empty,
587-
parameter.Key,
588-
defaultValueString);
589-
break;
590-
}
591602
case ResolverParameterKind.GetGlobalState when !parameter.IsNullable:
592-
{
593603
_writer.WriteIndentedLine(
594-
"var args{0} = context.GetGlobalState<{1}>(\"{2}\");",
595-
i,
596-
parameter.Type.ToFullyQualified(),
597-
parameter.Key);
604+
"var args{0} = context.GetGlobalState<{1}>(\"{2}\");",
605+
i,
606+
parameter.Type.ToFullyQualified(),
607+
parameter.Key);
598608
break;
599-
}
609+
600610
case ResolverParameterKind.GetGlobalState:
601-
{
602611
_writer.WriteIndentedLine(
603612
"var args{0} = context.GetGlobalStateOrDefault<{1}>(\"{2}\");",
604613
i,
605614
parameter.Type.ToFullyQualified(),
606615
parameter.Key);
607616
break;
608-
}
617+
609618
case ResolverParameterKind.SetGlobalState:
610619
_writer.WriteIndentedLine(
611620
"var args{0} = new HotChocolate.SetState<{1}>("
@@ -614,38 +623,38 @@ private void AddResolverArguments(Resolver resolver, IMethodSymbol resolverMetho
614623
((INamedTypeSymbol)parameter.Type).TypeArguments[0].ToFullyQualified(),
615624
parameter.Key);
616625
break;
626+
617627
case ResolverParameterKind.GetScopedState when parameter.Parameter.HasExplicitDefaultValue:
618-
{
619-
var defaultValue = parameter.Parameter.ExplicitDefaultValue;
620-
var defaultValueString = GeneratorUtils.ConvertDefaultValueToString(defaultValue, parameter.Type);
628+
{
629+
var defaultValue = parameter.Parameter.ExplicitDefaultValue;
630+
var defaultValueString = GeneratorUtils.ConvertDefaultValueToString(defaultValue, parameter.Type);
631+
632+
_writer.WriteIndentedLine(
633+
"var args{0} = context.GetScopedStateOrDefault<{1}{2}>(\"{3}\", {4});",
634+
i,
635+
parameter.Type.ToFullyQualified(),
636+
parameter.Type.IsNullableRefType() ? "?" : string.Empty,
637+
parameter.Key,
638+
defaultValueString);
639+
break;
640+
}
621641

622-
_writer.WriteIndentedLine(
623-
"var args{0} = context.GetScopedStateOrDefault<{1}{2}>(\"{3}\", {4});",
624-
i,
625-
parameter.Type.ToFullyQualified(),
626-
parameter.Type.IsNullableRefType() ? "?" : string.Empty,
627-
parameter.Key,
628-
defaultValueString);
629-
break;
630-
}
631642
case ResolverParameterKind.GetScopedState when !parameter.IsNullable:
632-
{
633643
_writer.WriteIndentedLine(
634-
"var args{0} = context.GetScopedState<{1}>(\"{2}\");",
635-
i,
636-
parameter.Type.ToFullyQualified(),
637-
parameter.Key);
644+
"var args{0} = context.GetScopedState<{1}>(\"{2}\");",
645+
i,
646+
parameter.Type.ToFullyQualified(),
647+
parameter.Key);
638648
break;
639-
}
649+
640650
case ResolverParameterKind.GetScopedState:
641-
{
642651
_writer.WriteIndentedLine(
643-
"var args{0} = context.GetScopedStateOrDefault<{1}>(\"{2}\");",
644-
i,
645-
parameter.Type.ToFullyQualified(),
646-
parameter.Key);
652+
"var args{0} = context.GetScopedStateOrDefault<{1}>(\"{2}\");",
653+
i,
654+
parameter.Type.ToFullyQualified(),
655+
parameter.Key);
647656
break;
648-
}
657+
649658
case ResolverParameterKind.SetScopedState:
650659
_writer.WriteIndentedLine(
651660
"var args{0} = new HotChocolate.SetState<{1}>("
@@ -654,38 +663,38 @@ private void AddResolverArguments(Resolver resolver, IMethodSymbol resolverMetho
654663
((INamedTypeSymbol)parameter.Type).TypeArguments[0].ToFullyQualified(),
655664
parameter.Key);
656665
break;
666+
657667
case ResolverParameterKind.GetLocalState when parameter.Parameter.HasExplicitDefaultValue:
658-
{
659-
var defaultValue = parameter.Parameter.ExplicitDefaultValue;
660-
var defaultValueString = GeneratorUtils.ConvertDefaultValueToString(defaultValue, parameter.Type);
668+
{
669+
var defaultValue = parameter.Parameter.ExplicitDefaultValue;
670+
var defaultValueString = GeneratorUtils.ConvertDefaultValueToString(defaultValue, parameter.Type);
671+
672+
_writer.WriteIndentedLine(
673+
"var args{0} = context.GetLocalStateOrDefault<{1}{2}>(\"{3}\", {4});",
674+
i,
675+
parameter.Type.ToFullyQualified(),
676+
parameter.Type.IsNullableRefType() ? "?" : string.Empty,
677+
parameter.Key,
678+
defaultValueString);
679+
break;
680+
}
661681

662-
_writer.WriteIndentedLine(
663-
"var args{0} = context.GetLocalStateOrDefault<{1}{2}>(\"{3}\", {4});",
664-
i,
665-
parameter.Type.ToFullyQualified(),
666-
parameter.Type.IsNullableRefType() ? "?" : string.Empty,
667-
parameter.Key,
668-
defaultValueString);
669-
break;
670-
}
671682
case ResolverParameterKind.GetLocalState when !parameter.IsNullable:
672-
{
673683
_writer.WriteIndentedLine(
674-
"var args{0} = context.GetLocalState<{1}>(\"{2}\");",
675-
i,
676-
parameter.Type.ToFullyQualified(),
677-
parameter.Key);
684+
"var args{0} = context.GetLocalState<{1}>(\"{2}\");",
685+
i,
686+
parameter.Type.ToFullyQualified(),
687+
parameter.Key);
678688
break;
679-
}
689+
680690
case ResolverParameterKind.GetLocalState:
681-
{
682691
_writer.WriteIndentedLine(
683-
"var args{0} = context.GetLocalStateOrDefault<{1}>(\"{2}\");",
684-
i,
685-
parameter.Type.ToFullyQualified(),
686-
parameter.Key);
692+
"var args{0} = context.GetLocalStateOrDefault<{1}>(\"{2}\");",
693+
i,
694+
parameter.Type.ToFullyQualified(),
695+
parameter.Key);
687696
break;
688-
}
697+
689698
case ResolverParameterKind.SetLocalState:
690699
_writer.WriteIndentedLine(
691700
"var args{0} = new HotChocolate.SetState<{1}>("
@@ -705,6 +714,26 @@ private void AddResolverArguments(Resolver resolver, IMethodSymbol resolverMetho
705714
resolver.Member.Name,
706715
ToFullyQualifiedString(parameter.Type, resolverMethod, typeLookup));
707716
break;
717+
718+
case ResolverParameterKind.DataContext:
719+
var entityType = parameter.TypeParameters[0].ToFullyQualified();
720+
_writer.WriteIndentedLine("var args{0}_selection = context.Selection;", i);
721+
_writer.WriteIndentedLine("var args{0}_filter = context.GetFilterContext();", i);
722+
_writer.WriteIndentedLine("var args{0}_sorting = context.GetSortingContext();", i);
723+
_writer.WriteIndentedLine(
724+
"var args{0} = new global::{1}<{2}>(",
725+
i,
726+
WellKnownTypes.DataContext,
727+
entityType);
728+
using (_writer.IncreaseIndent())
729+
{
730+
_writer.WriteIndentedLine("args{0}_selection.AsSelector<{1}>(),", i, entityType);
731+
_writer.WriteIndentedLine("args{0}_filter?.AsPredicate<{1}>(),", i, entityType);
732+
_writer.WriteIndentedLine("args{0}_sorting?.AsSortDefinition<{1}>());", i, entityType);
733+
}
734+
735+
break;
736+
708737
default:
709738
throw new ArgumentOutOfRangeException();
710739
}

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

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,18 @@ public static bool IsSetState(this IParameterSymbol parameter)
110110
return false;
111111
}
112112

113+
public static bool IsDataContext(this IParameterSymbol parameter)
114+
{
115+
if (parameter.Type is INamedTypeSymbol namedTypeSymbol
116+
&& namedTypeSymbol is { IsGenericType: true, TypeArguments.Length: 1 }
117+
&& namedTypeSymbol.ToDisplayString().StartsWith(WellKnownTypes.DataContextGeneric))
118+
{
119+
return true;
120+
}
121+
122+
return false;
123+
}
124+
113125
public static bool IsGlobalState(
114126
this IParameterSymbol parameter,
115127
[NotNullWhen(true)] out string? key)
@@ -118,7 +130,7 @@ public static bool IsGlobalState(
118130

119131
foreach (var attributeData in parameter.GetAttributes())
120132
{
121-
if (attributeData.AttributeClass?.ToDisplayString() == "HotChocolate.GlobalStateAttribute")
133+
if (IsOrInheritsFromAttribute(attributeData.AttributeClass, "HotChocolate.GlobalStateAttribute"))
122134
{
123135
if (attributeData.ConstructorArguments.Length == 1 &&
124136
attributeData.ConstructorArguments[0].Kind == TypedConstantKind.Primitive &&
@@ -153,7 +165,7 @@ public static bool IsScopedState(
153165

154166
foreach (var attributeData in parameter.GetAttributes())
155167
{
156-
if (attributeData.AttributeClass?.ToDisplayString() == "HotChocolate.ScopedStateAttribute")
168+
if (IsOrInheritsFromAttribute(attributeData.AttributeClass, "HotChocolate.ScopedStateAttribute"))
157169
{
158170
if (attributeData.ConstructorArguments.Length == 1 &&
159171
attributeData.ConstructorArguments[0].Kind == TypedConstantKind.Primitive &&
@@ -188,7 +200,7 @@ public static bool IsLocalState(
188200

189201
foreach (var attributeData in parameter.GetAttributes())
190202
{
191-
if (attributeData.AttributeClass?.ToDisplayString() == "HotChocolate.LocalStateAttribute")
203+
if (IsOrInheritsFromAttribute(attributeData.AttributeClass, "HotChocolate.LocalStateAttribute"))
192204
{
193205
if (attributeData.ConstructorArguments.Length == 1 &&
194206
attributeData.ConstructorArguments[0].Kind == TypedConstantKind.Primitive &&
@@ -395,7 +407,7 @@ public static bool IsListType(this ITypeSymbol typeSymbol, [NotNullWhen(true)] o
395407
return true;
396408
}
397409

398-
if(typeDefinition.Equals(WellKnownTypes.EnumerableDefinition, StringComparison.Ordinal))
410+
if (typeDefinition.Equals(WellKnownTypes.EnumerableDefinition, StringComparison.Ordinal))
399411
{
400412
elementType = namedTypeSymbol.TypeArguments[0].ToFullyQualified();
401413
return true;
@@ -479,4 +491,21 @@ private static bool IsPostProcessorAttribute(INamedTypeSymbol? attributeClass)
479491

480492
return false;
481493
}
494+
495+
private static bool IsOrInheritsFromAttribute(ITypeSymbol? attributeClass, string fullTypeName)
496+
{
497+
var current = attributeClass;
498+
499+
while (current != null)
500+
{
501+
if (current.ToDisplayString() == fullTypeName)
502+
{
503+
return true;
504+
}
505+
506+
current = current.BaseType;
507+
}
508+
509+
return false;
510+
}
482511
}

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Immutable;
12
using HotChocolate.Types.Analyzers.Helpers;
23
using Microsoft.CodeAnalysis;
34

@@ -20,6 +21,9 @@ public ResolverParameter(IParameterSymbol parameter, string? key, ResolverParame
2021

2122
public ITypeSymbol Type => Parameter.Type;
2223

24+
public ImmutableArray<ITypeSymbol> TypeParameters
25+
=> GetGenericTypeArgument(Type);
26+
2327
public IParameterSymbol Parameter { get; }
2428

2529
public ResolverParameterKind Kind { get; }
@@ -136,6 +140,22 @@ private static ResolverParameterKind GetParameterKind(
136140
return ResolverParameterKind.Argument;
137141
}
138142

143+
if (parameter.IsDataContext())
144+
{
145+
return ResolverParameterKind.DataContext;
146+
}
147+
139148
return ResolverParameterKind.Unknown;
140149
}
150+
151+
private static ImmutableArray<ITypeSymbol> GetGenericTypeArgument(ITypeSymbol typeSymbol)
152+
{
153+
if (typeSymbol is INamedTypeSymbol namedTypeSymbol && namedTypeSymbol.IsGenericType)
154+
{
155+
return namedTypeSymbol.TypeArguments;
156+
}
157+
158+
// Return null if it's not a generic type or index is out of bounds
159+
return ImmutableArray<ITypeSymbol>.Empty;
160+
}
141161
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ public enum ResolverParameterKind
2020
GetLocalState,
2121
SetLocalState,
2222
Service,
23-
Argument
23+
Argument,
24+
DataContext
2425
}

0 commit comments

Comments
 (0)