Skip to content

Commit

Permalink
Merge pull request #110 from byme8/feature/constants
Browse files Browse the repository at this point in the history
Add support for C# constants
  • Loading branch information
byme8 authored Jun 23, 2024
2 parents c1b5efd + 3db51be commit aeab6b4
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 9 deletions.
36 changes: 36 additions & 0 deletions src/ZeroQL.SourceGenerators/Resolver/GraphQLConstantResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Linq;
using Microsoft.CodeAnalysis;

namespace ZeroQL.SourceGenerators.Resolver;

public static class GraphQLConstantResolver
{
public static string ToGraphQL(ITypeSymbol symbol, object value) =>
symbol switch
{
{ SpecialType: SpecialType.System_String } => $@"""{value}""",
{ TypeKind: TypeKind.Enum } => MaterializeEnum(symbol, value),
_ => value.ToString(),
};

private static string MaterializeEnum(ITypeSymbol symbol, object value)
{
if (symbol is not INamedTypeSymbol enumType)
{
return value.ToString();
}

var graphQLName = enumType
.GetMembers()
.OfType<IFieldSymbol>()
.FirstOrDefault(o => o.ConstantValue?.Equals(value) ?? false)
?.GetAttributes()
.FirstOrDefault(o => o.AttributeClass?.Name == "GraphQLNameAttribute")
?.ConstructorArguments
.FirstOrDefault()
.Value?
.ToString();

return graphQLName!;
}
}
5 changes: 5 additions & 0 deletions src/ZeroQL.SourceGenerators/Resolver/GraphQLQueryResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,11 @@ private static Result<string> HandleArgumentAsVariable(GraphQLResolveContext con
return Failed(identifierName, Descriptors.GraphQLVariableShouldBeLocal);
}

case ILocalSymbol { HasConstantValue: true } localSymbol:
{
var constantValue = localSymbol.ConstantValue!;
return GraphQLConstantResolver.ToGraphQL(localSymbol.Type, constantValue);
}
case ILocalSymbol localSymbol:
{
var graphQLType = parameter.ToGraphQLType();
Expand Down
19 changes: 18 additions & 1 deletion src/ZeroQL.Tests/Core/TestExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ public static async Task<byte[]> CompileToRealAssemblyAsBytes(this Project proje

if (error != null)
{
throw new Exception(error.GetMessage());
var message = error.GetMessage();
var preview = error.Location.Preview();
throw new Exception($"{message} {preview}");
}

using var memoryStream = new MemoryStream();
Expand Down Expand Up @@ -177,4 +179,19 @@ public static SettingsTask Track(this SettingsTask settingsTask, string value, [
settingsTask.AddScrubber(o => o.Replace(value, name));
return settingsTask;
}

public static string Preview(this Location location)
{
var sourceTree = location.SourceTree!;
var span = location.GetLineSpan();
var line = span.StartLinePosition.Line;
var character = span.StartLinePosition.Character;
var source = sourceTree
.ToString()
.Split('\r', '\n');

var lineWithPreview = source[line].Insert(character, "^");

return lineWithPreview;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
Query: mutation { addUser(firstName: "John", lastName: "Smith") { id } },
Data: {
Value: 10
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
Query: mutation { addUserKindPascal(userKindPascal: Good)},
Data: 12
}
42 changes: 34 additions & 8 deletions src/ZeroQL.Tests/SourceGeneration/QueryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,7 @@ public async Task QueryPreviewGenerated()
.Where(o => o.Location.SourceTree!.ToString().Contains("Program"))
.First(o => o.Id == Descriptors.GraphQLQueryPreview.Id);

var startLinePosition = queryPreview.Location.GetLineSpan().StartLinePosition;
var line = startLinePosition.Line;
var character = startLinePosition.Character;
var source = queryPreview.Location.SourceTree!
.ToString()
.Split('\r', '\n');

var lineWithPreview = source[line].Insert(character, "^");
var lineWithPreview = queryPreview.Location.Preview();

await Verify(lineWithPreview);
}
Expand Down Expand Up @@ -432,6 +425,39 @@ public async Task SupportForVariablesPassedViaClosure()

await Verify(response);
}

[Fact]
public async Task SupportForConstants()
{
var csharpQuery = """
const string firstName = "John";
const string lastName = "Smith";
var response = await qlClient.Mutation(m => m.AddUser(firstName, lastName, o => o.Id));
""";

var project = await TestProject.Project
.ReplacePartOfDocumentAsync("Program.cs", (TestProject.FullLine, csharpQuery));

var response = await project.Execute();

await Verify(response);
}

[Fact]
public async Task SupportForEnumConstants()
{
var csharpQuery = """
const UserKindPascal kind = UserKindPascal.Good;
var response = await qlClient.Mutation(m => m.AddUserKindPascal(kind));
""";

var project = await TestProject.Project
.ReplacePartOfDocumentAsync("Program.cs", (TestProject.FullLine, csharpQuery));

var response = await project.Execute();

await Verify(response);
}

[Fact]
public async Task NamedArgumentsAreSupported()
Expand Down

0 comments on commit aeab6b4

Please sign in to comment.