Skip to content

Commit

Permalink
Merge pull request #105 from byme8/feature/allow-wrappers
Browse files Browse the repository at this point in the history
Feature/allow wrappers
  • Loading branch information
byme8 authored May 25, 2024
2 parents 0882e07 + 7ee2e45 commit 981e8ee
Show file tree
Hide file tree
Showing 43 changed files with 504 additions and 233 deletions.
13 changes: 12 additions & 1 deletion src/TestApp/ZeroQL.TestApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
using System.Net.Http;
using System.IO; // do not remove this
using System.Collections.Generic; // do not remove this
using System.Linq; // do not remove this
using System.Linq;
using System.Runtime.CompilerServices; // do not remove this
using System.Threading; // do not remove this
using System.Threading.Tasks;
using GraphQL.TestServer;
Expand All @@ -11,6 +12,7 @@
using ZeroQL.Pipelines; // do not remove this
using ZeroQL.Stores; // do not remove this
using ZeroQL.TestApp.Models;
using ZeroQL.TestApp.Services;

namespace ZeroQL.TestApp;

Expand Down Expand Up @@ -43,6 +45,15 @@ public static async Task<object> Execute(CancellationToken cancellationToken = d

return response;
}

public static async Task<T?> MakeQuery<T, TQuery, TMutation>(
GraphQLClient<TQuery, TMutation> client,
[GraphQLLambda]Func<TQuery, T> query,
[CallerArgumentExpression(nameof(query))] string queryKey = "")
where T : class
{
return await GraphQLClientMethodWrapper.MakeQuery(client, query, queryKey);
}
}

public class AddProfileImage
Expand Down
30 changes: 30 additions & 0 deletions src/TestApp/ZeroQL.TestApp/Services/GraphQLClientMethodWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;

namespace ZeroQL.TestApp.Services;

public class GraphQLClientMethodWrapper
{
public static async Task<T?> MakeQuery<T, TQuery, TMutation>(
GraphQLClient<TQuery, TMutation> client,
[GraphQLLambda]Func<TQuery, T> query,
[CallerArgumentExpression(nameof(query))] string queryKey = "")
where T : class
{
var result = await client.Query(query, queryKey: queryKey);

if (result.Errors != null)
{
Console.WriteLine("Errors:");
foreach (var error in result.Errors)
{
Console.WriteLine(error.Message);
}

return null;
}

return result.Data;
}
}
28 changes: 28 additions & 0 deletions src/TestApp/ZeroQL.TestApp/Services/GraphQLClientWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using GraphQL.TestServer;

namespace ZeroQL.TestApp.Services;

public class GraphQLClientWrapper
{
private readonly TestServerClient client;

public GraphQLClientWrapper(TestServerClient client)
{
this.client = client;
}

public async Task<TResult> QueryAsync<TResult>(
[GraphQLLambda]
Func<Query, TResult> query,
[CallerArgumentExpression(nameof(query))]
string queryKey = "")
where TResult : class
{
var result = await client.Query(query, queryKey: queryKey);

return result.Data!;
}
}
10 changes: 10 additions & 0 deletions src/ZeroQL.Runtime/Attributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,14 @@ public GraphQLQueryTemplate(string query)
}

public string Query { get; }
}

[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.GenericParameter)]
public class GraphQLLambda : Attribute
{
}

[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.GenericParameter)]
public class StaticLambda : Attribute
{
}
16 changes: 12 additions & 4 deletions src/ZeroQL.Runtime/GraphQLClientLambdaExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public static async Task<GraphQLResult<TResult>> Query<TVariables, TQuery, TMuta
this GraphQLClient<TQuery, TMutation> client,
string name,
TVariables variables,
[StaticLambda]
[GraphQLLambda]
Func<TVariables, TQuery, TResult> query,
CancellationToken cancellationToken = default,
[CallerArgumentExpression(nameof(query))] string queryKey = null!)
Expand All @@ -25,6 +27,8 @@ public static async Task<GraphQLResult<TResult>> Query<TVariables, TQuery, TMuta
public static async Task<GraphQLResult<TResult>> Query<TVariables, TQuery, TMutation, TResult>(
this GraphQLClient<TQuery, TMutation> client,
TVariables variables,
[StaticLambda]
[GraphQLLambda]
Func<TVariables, TQuery, TResult> query,
CancellationToken cancellationToken = default,
[CallerArgumentExpression(nameof(query))] string queryKey = null!)
Expand All @@ -35,7 +39,7 @@ public static async Task<GraphQLResult<TResult>> Query<TVariables, TQuery, TMuta
public static async Task<GraphQLResult<TResult>> Query<TQuery, TMutation, TResult>(
this GraphQLClient<TQuery, TMutation> client,
string name,
Func<TQuery, TResult> query,
[GraphQLLambda] Func<TQuery, TResult> query,
CancellationToken cancellationToken = default,
[CallerArgumentExpression(nameof(query))] string queryKey = null!)
{
Expand All @@ -49,7 +53,7 @@ public static async Task<GraphQLResult<TResult>> Query<TQuery, TMutation, TResul

public static async Task<GraphQLResult<TResult>> Query<TQuery, TMutation, TResult>(
this GraphQLClient<TQuery, TMutation> client,
Func<TQuery, TResult> query,
[GraphQLLambda] Func<TQuery, TResult> query,
CancellationToken cancellationToken = default,
[CallerArgumentExpression(nameof(query))] string queryKey = null!)
{
Expand All @@ -65,6 +69,8 @@ public static async Task<GraphQLResult<TResult>> Mutation<TVariables, TQuery, TM
this GraphQLClient<TQuery, TMutation> client,
string name,
TVariables variables,
[StaticLambda]
[GraphQLLambda]
Func<TVariables, TMutation, TResult> query,
CancellationToken cancellationToken = default,
[CallerArgumentExpression(nameof(query))] string queryKey = null!)
Expand All @@ -75,6 +81,8 @@ public static async Task<GraphQLResult<TResult>> Mutation<TVariables, TQuery, TM
public static async Task<GraphQLResult<TResult>> Mutation<TVariables, TQuery, TMutation, TResult>(
this GraphQLClient<TQuery, TMutation> client,
TVariables variables,
[StaticLambda]
[GraphQLLambda]
Func<TVariables, TMutation, TResult> query,
CancellationToken cancellationToken = default,
[CallerArgumentExpression(nameof(query))] string queryKey = null!)
Expand All @@ -85,7 +93,7 @@ public static async Task<GraphQLResult<TResult>> Mutation<TVariables, TQuery, TM
public static async Task<GraphQLResult<TResult>> Mutation<TQuery, TMutation, TResult>(
this GraphQLClient<TQuery, TMutation> client,
string name,
Func<TMutation, TResult> query,
[GraphQLLambda] Func<TMutation, TResult> query,
CancellationToken cancellationToken = default,
[CallerArgumentExpression(nameof(query))] string queryKey = null!)
{
Expand All @@ -99,7 +107,7 @@ public static async Task<GraphQLResult<TResult>> Mutation<TQuery, TMutation, TRe

public static async Task<GraphQLResult<TResult>> Mutation<TQuery, TMutation, TResult>(
this GraphQLClient<TQuery, TMutation> client,
Func<TMutation, TResult> query,
[GraphQLLambda] Func<TMutation, TResult> query,
CancellationToken cancellationToken = default,
[CallerArgumentExpression(nameof(query))] string queryKey = null!)
{
Expand Down
2 changes: 1 addition & 1 deletion src/ZeroQL.Runtime/Stores/QueryInfoProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class QueryInfo
public class QueryInfoProvider
{
public static QueryInfo Materialize<TQuery>(
Func<TQuery, object> query,
[GraphQLLambda]Func<TQuery, object> query,
[CallerArgumentExpression(nameof(query))] string queryKey = "")
{
var normalizedKey = QueryKey.Normalize(queryKey);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,25 +76,6 @@ private void Handle(SyntaxNodeAnalysisContext context)
method.Name,
requiredParameter.Parameter.Name));
}

// var argument = arguments[requiredParameter.Index];
// var argumentType = context.SemanticModel.GetSymbolInfo(argument.Expression);
// var type = argumentType.Symbol.GetNamedTypeSymbol();
// if (type is null)
// {
// continue;
// }
//
// if (SymbolEqualityComparer.Default.Equals(type, requiredParameter.Parameter.Type))
// {
// continue;
// }
//
// context.ReportDiagnostic(Diagnostic.Create(
// Descriptors.GraphQLQueryRequiredParameter,
// memberAccess.Name.GetLocation(),
// method.Name,
// requiredParameter.Parameter.Name));
}
}

Expand Down
76 changes: 31 additions & 45 deletions src/ZeroQL.SourceGenerators/Analyzers/QueryLambdaAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using ZeroQL.SourceGenerators.Extensions;
using ZeroQL.SourceGenerators.Resolver.Context;

namespace ZeroQL.SourceGenerators.Analyzers;
Expand All @@ -26,15 +27,19 @@ public override void Initialize(AnalysisContext context)

private void Handle(SyntaxNodeAnalysisContext context)
{
if (context.Node is not InvocationExpressionSyntax invocation ||
invocation.Expression is not MemberAccessExpressionSyntax memberAccess ||
memberAccess.Name.Identifier.ValueText is not ("Query" or "Mutation" or "Materialize"))
if (context.Node is not InvocationExpressionSyntax invocation)
{
return;
}

var method = QueryAnalyzerHelper.ExtractQueryMethod(context.Compilation, invocation);
if (method is null)
var graphQLLambdaAttribute =
context.Compilation.GetTypeByMetadataName(SourceGeneratorInfo.GraphQLLambdaAttribute)!;
var graphQLLambdas = QueryAnalyzerHelper.ExtractQueryMethod(
context.Compilation,
invocation,
graphQLLambdaAttribute);

if (graphQLLambdas.Empty())
{
return;
}
Expand All @@ -44,51 +49,25 @@ memberAccess.Name.Identifier.ValueText is not ("Query" or "Mutation" or "Materia
return;
}

var possibleLambdaQuery = invocation.ArgumentList.Arguments
.LastOrDefault(o => o.Expression is LambdaExpressionSyntax)?
.Expression;
if (possibleLambdaQuery is not LambdaExpressionSyntax lambda)
{
return;
}
var lambdas = graphQLLambdas
.Select(o => invocation.ArgumentList.Arguments[o.Index])
.Select(o => (Argument: o, Expression: o.Expression as LambdaExpressionSyntax))
.Where(o => o.Expression is not null)
.ToArray();

if (lambda is ParenthesizedLambdaExpressionSyntax parenthesizedLambda
&& !parenthesizedLambda.Modifiers.Any(SyntaxKind.StaticKeyword))
if (lambdas.Empty())
{
context.ReportDiagnostic(Diagnostic.Create(
Descriptors.OnlyStaticLambda,
lambda.GetLocation()));
return;
}

if (context.CancellationToken.IsCancellationRequested)
{
return;
}

var innerLambdas = lambda
.DescendantNodes()
.OfType<LambdaExpressionSyntax>()
.ToArray();

foreach (var innerLambda in innerLambdas)
{
if (context.CancellationToken.IsCancellationRequested)
{
return;
}

if (QueryAnalyzerHelper.IsOpenLambda(innerLambda))
{
context.ReportDiagnostic(
Diagnostic.Create(
Descriptors.OpenLambdaIsNotAllowed,
innerLambda.GetLocation()));
}
}

var semanticModel = context.SemanticModel;
var resolver = new GraphQLLambdaLikeContextResolver();
var (lambdaContext, resolveError) =
var (result, resolveError) =
resolver.Resolve(invocation, semanticModel, context.CancellationToken).Unwrap();

if (context.CancellationToken.IsCancellationRequested)
Expand All @@ -107,20 +86,27 @@ memberAccess.Name.Identifier.ValueText is not ("Query" or "Mutation" or "Materia
context.ReportDiagnostic(Diagnostic
.Create(
Descriptors.FailedToConvert,
memberAccess.Name.GetLocation(),
invocation.GetLocationForPreview(),
resolveError.Message));
return;
}

context.ReportDiagnostic(Diagnostic.Create(
Descriptors.GraphQLQueryPreview,
memberAccess.Name.GetLocation(),
lambdaContext.OperationQuery));
if (result.LambdaContexts is null)
{
return;
}

foreach (var lambdaContext in result.LambdaContexts)
{
context.ReportDiagnostic(Diagnostic.Create(
Descriptors.GraphQLQueryPreview,
invocation.GetLocationForPreview(),
lambdaContext.OperationQuery));
}
}

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }
= ImmutableArray.Create(
Descriptors.OnlyStaticLambda,
Descriptors.FragmentsWithoutSyntaxTree,
Descriptors.OpenLambdaIsNotAllowed,
Descriptors.DontUseOutScopeValues,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ private void Handle(SyntaxNodeAnalysisContext context)

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }
= ImmutableArray.Create(
Descriptors.OnlyStaticLambda,
Descriptors.FragmentsWithoutSyntaxTree,
Descriptors.OpenLambdaIsNotAllowed,
Descriptors.DontUseOutScopeValues,
Expand Down
Loading

0 comments on commit 981e8ee

Please sign in to comment.